mirror of
https://github.com/storytold/pdfcraft.git
synced 2026-10-30 04:58:34 -06:00
Merge PR #4058: M12: type or pick an architect's 1:N drawing scale in the Measure panel, applied at once
Conflicts: - crates/ui-egui/src/i18n/mod.rs: kept main's side (main dropped the per-language translation tests; the PR's drawing_scale_labels_are_translated_in_every_catalog is not carried over). - parity/acrobat-features.toml: measure.distance evidence: kept main's paths (tests/it/), appended the PR's two new entries.
This commit is contained in:
@@ -2040,6 +2040,10 @@
|
||||
Perimeter المحيط
|
||||
Area المساحة
|
||||
Drawing scale مقياس الرسم
|
||||
Scale المقياس
|
||||
Common scales مقاييس شائعة
|
||||
Enter a scale such as 1:50. أدخل مقياسًا مثل 1:50.
|
||||
Applying a scale switches units to m / mm. يؤدي تطبيق المقياس إلى تحويل الوحدات إلى م / مم.
|
||||
Snapping الانجذاب
|
||||
Export measurements تصدير القياسات
|
||||
Open a PDF to measure it. افتح ملف PDF لقياسه.
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 6 and column 47.
|
@@ -1902,6 +1902,10 @@
|
||||
Perimeter Периметър
|
||||
Area Площ
|
||||
Drawing scale Мащаб на чертежа
|
||||
Scale Мащаб
|
||||
Common scales Често използвани мащаби
|
||||
Enter a scale such as 1:50. Въведете мащаб, например 1:50.
|
||||
Applying a scale switches units to m / mm. Прилагането на мащаб превключва единиците на m / mm.
|
||||
Snapping Прилепване
|
||||
Export measurements Експортирай измерванията
|
||||
Open a PDF to measure it. Отворете PDF файл, за да го измервате.
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 8 and column 16.
|
@@ -2000,6 +2000,10 @@ action wizard Start Inicia
|
||||
Perimeter Perímetre
|
||||
Area Àrea
|
||||
Drawing scale Escala del dibuix
|
||||
Scale Escala
|
||||
Common scales Escales habituals
|
||||
Enter a scale such as 1:50. Introduïu una escala com 1:50.
|
||||
Applying a scale switches units to m / mm. En aplicar una escala, les unitats canvien a m / mm.
|
||||
Snapping Ajust
|
||||
Export measurements Exporta les mesures
|
||||
Open a PDF to measure it. Obre un PDF per mesurar-lo.
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 7 and column 3.
|
@@ -2003,6 +2003,10 @@
|
||||
Perimeter چێوە
|
||||
Area ڕووبەر
|
||||
Drawing scale پێوەری وێنەکێشان
|
||||
Scale پێوەر
|
||||
Common scales پێوەرە باوەکان
|
||||
Enter a scale such as 1:50. پێوەرێک بنووسە وەک 1:50.
|
||||
Applying a scale switches units to m / mm. جێبەجێکردنی پێوەر یەکەکان دەگۆڕێت بۆ م / ملم.
|
||||
Snapping لکاندن
|
||||
Export measurements هەناردەکردنی پێوانەکان
|
||||
Open a PDF to measure it. PDFێک بکەرەوە بۆ پێوانەکردنی.
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 6 and column 47.
|
@@ -2090,6 +2090,10 @@ key Space Mezerník
|
||||
Perimeter Obvod
|
||||
Area Plocha
|
||||
Drawing scale Měřítko výkresu
|
||||
Scale Měřítko
|
||||
Common scales Běžná měřítka
|
||||
Enter a scale such as 1:50. Zadejte měřítko, například 1:50.
|
||||
Applying a scale switches units to m / mm. Použití měřítka přepne jednotky na m / mm.
|
||||
Snapping Přichytávání
|
||||
Export measurements Exportovat měření
|
||||
Open a PDF to measure it. Otevřete PDF, které chcete měřit.
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 6 and column 47.
|
@@ -1976,6 +1976,10 @@
|
||||
Perimeter Umfang
|
||||
Area Fläche
|
||||
Drawing scale Zeichnungsmaßstab
|
||||
Scale Maßstab
|
||||
Common scales Gängige Maßstäbe
|
||||
Enter a scale such as 1:50. Geben Sie einen Maßstab wie 1:50 ein.
|
||||
Applying a scale switches units to m / mm. Beim Anwenden eines Maßstabs werden die Einheiten auf m / mm umgestellt.
|
||||
Snapping Einrasten
|
||||
Export measurements Messungen exportieren
|
||||
Open a PDF to measure it. Öffne ein PDF, um es zu messen.
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 6 and column 51.
|
@@ -1417,6 +1417,10 @@
|
||||
Perimeter Περίμετρος
|
||||
Area Εμβαδόν
|
||||
Drawing scale Κλίμακα σχεδίου
|
||||
Scale Κλίμακα
|
||||
Common scales Συνηθισμένες κλίμακες
|
||||
Enter a scale such as 1:50. Εισαγάγετε μια κλίμακα, όπως 1:50.
|
||||
Applying a scale switches units to m / mm. Η εφαρμογή κλίμακας αλλάζει τις μονάδες σε m / mm.
|
||||
Snapping Προσκόλληση
|
||||
Export measurements Εξαγωγή μετρήσεων
|
||||
Open a PDF to measure it. Ανοίξτε ένα PDF για να πραγματοποιήσετε μετρήσεις.
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 482 and column 9.
|
@@ -2056,6 +2056,10 @@ action wizard Start Iniciar
|
||||
Perimeter Perímetro
|
||||
Area Área
|
||||
Drawing scale Escala del dibujo
|
||||
Scale Escala
|
||||
Common scales Escalas habituales
|
||||
Enter a scale such as 1:50. Introduzca una escala como 1:50.
|
||||
Applying a scale switches units to m / mm. Al aplicar una escala, las unidades cambian a m / mm.
|
||||
Snapping Ajuste
|
||||
Export measurements Exportar mediciones
|
||||
Open a PDF to measure it. Abre un PDF para medirlo.
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 6 and column 60.
|
@@ -1978,6 +1978,10 @@
|
||||
Perimeter Ympärysmitta
|
||||
Area Pinta-ala
|
||||
Drawing scale Piirustuksen mittakaava
|
||||
Scale Mittakaava
|
||||
Common scales Yleiset mittakaavat
|
||||
Enter a scale such as 1:50. Anna mittakaava, esimerkiksi 1:50.
|
||||
Applying a scale switches units to m / mm. Mittakaavan käyttö vaihtaa yksiköiksi m / mm.
|
||||
Snapping Tartunta
|
||||
Export measurements Vie mittaukset
|
||||
Open a PDF to measure it. Avaa PDF mitataksesi sitä.
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 5 and column 47.
|
@@ -1971,6 +1971,10 @@
|
||||
Perimeter Périmètre
|
||||
Area Aire
|
||||
Drawing scale Échelle du dessin
|
||||
Scale Échelle
|
||||
Common scales Échelles courantes
|
||||
Enter a scale such as 1:50. Saisissez une échelle comme 1:50.
|
||||
Applying a scale switches units to m / mm. Appliquer une échelle passe les unités en m / mm.
|
||||
Snapping Accrochage
|
||||
Export measurements Exporter les mesures
|
||||
Open a PDF to measure it. Ouvrez un PDF pour le mesurer.
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 6 and column 39.
|
@@ -1961,6 +1961,10 @@
|
||||
Perimeter परिमाप
|
||||
Area क्षेत्रफल
|
||||
Drawing scale रेखाचित्र पैमाना
|
||||
Scale पैमाना
|
||||
Common scales सामान्य पैमाने
|
||||
Enter a scale such as 1:50. 1:50 जैसा पैमाना दर्ज करें।
|
||||
Applying a scale switches units to m / mm. पैमाना लागू करने पर इकाइयाँ m / mm में बदल जाती हैं।
|
||||
Snapping स्नैपिंग
|
||||
Export measurements मापन निर्यात करें
|
||||
Open a PDF to measure it. मापने के लिए एक पीडीएफ़ खोलें।
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 854 and column 12.
|
@@ -1961,6 +1961,10 @@
|
||||
Perimeter Kerület
|
||||
Area Terület
|
||||
Drawing scale Rajz méretaránya
|
||||
Scale Méretarány
|
||||
Common scales Gyakori méretarányok
|
||||
Enter a scale such as 1:50. Adjon meg egy méretarányt, például 1:50.
|
||||
Applying a scale switches units to m / mm. A méretarány alkalmazása m / mm mértékegységre vált.
|
||||
Snapping Illesztés
|
||||
Export measurements Mérések exportálása
|
||||
Open a PDF to measure it. Nyiss meg egy PDF-et a méréshez.
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 7 and column 44.
|
@@ -1392,6 +1392,10 @@
|
||||
Draw freehand Gambar bebas
|
||||
Drawing Gambar
|
||||
Drawing scale Skala gambar
|
||||
Scale Skala
|
||||
Common scales Skala umum
|
||||
Enter a scale such as 1:50. Masukkan skala seperti 1:50.
|
||||
Applying a scale switches units to m / mm. Menerapkan skala mengubah satuan menjadi m / mm.
|
||||
Drop-down list Daftar drop-down
|
||||
Duplicate pages Duplikat halaman
|
||||
Edit a PDF Edit PDF
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 483 and column 12.
|
@@ -2047,6 +2047,10 @@
|
||||
Perimeter Perimetro
|
||||
Area Area
|
||||
Drawing scale Scala del disegno
|
||||
Scale Scala
|
||||
Common scales Scale comuni
|
||||
Enter a scale such as 1:50. Inserisci una scala come 1:50.
|
||||
Applying a scale switches units to m / mm. Applicando una scala le unità passano a m / mm.
|
||||
Snapping Aggancio
|
||||
Export measurements Esporta misure
|
||||
Open a PDF to measure it. Apri un PDF per misurarlo.
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 6 and column 47.
|
@@ -2054,6 +2054,10 @@
|
||||
Perimeter 周長
|
||||
Area 面積
|
||||
Drawing scale 図面の縮尺
|
||||
Scale 縮尺
|
||||
Common scales よく使う縮尺
|
||||
Enter a scale such as 1:50. 1:50 のように縮尺を入力してください。
|
||||
Applying a scale switches units to m / mm. 縮尺を適用すると、単位が m / mm に切り替わります。
|
||||
Snapping スナップ
|
||||
Export measurements 測定結果を書き出す
|
||||
Open a PDF to measure it. 測定するPDFを開いてください。
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 6 and column 47.
|
@@ -1962,6 +1962,10 @@
|
||||
Perimeter Периметр
|
||||
Area Аудан
|
||||
Drawing scale Сызба масштабы
|
||||
Scale Масштаб
|
||||
Common scales Жиі қолданылатын масштабтар
|
||||
Enter a scale such as 1:50. 1:50 сияқты масштабты енгізіңіз.
|
||||
Applying a scale switches units to m / mm. Масштабты қолдану өлшем бірліктерін m / mm етіп ауыстырады.
|
||||
Snapping Түйістіру
|
||||
Export measurements Өлшемдерді экспорттау
|
||||
Open a PDF to measure it. Өлшеу үшін PDF құжатын ашыңыз.
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 859 and column 9.
|
@@ -1961,6 +1961,10 @@
|
||||
Perimeter 둘레
|
||||
Area 면적
|
||||
Drawing scale 도면 축척
|
||||
Scale 축척
|
||||
Common scales 자주 쓰는 축척
|
||||
Enter a scale such as 1:50. 1:50과 같은 축척을 입력하세요.
|
||||
Applying a scale switches units to m / mm. 축척을 적용하면 단위가 m / mm로 바뀝니다.
|
||||
Snapping 스냅
|
||||
Export measurements 측정값 내보내기
|
||||
Open a PDF to measure it. 측정할 PDF를 여세요.
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 854 and column 12.
|
@@ -2014,6 +2014,10 @@
|
||||
Perimeter ລວງຮອບ
|
||||
Area ເນື້ອທີ່
|
||||
Drawing scale ມາດຕາສ່ວນຮູບແຕ້ມ
|
||||
Scale ມາດຕາສ່ວນ
|
||||
Common scales ມາດຕາສ່ວນທີ່ໃຊ້ທົ່ວໄປ
|
||||
Enter a scale such as 1:50. ປ້ອນມາດຕາສ່ວນ ເຊັ່ນ 1:50.
|
||||
Applying a scale switches units to m / mm. ການນຳໃຊ້ມາດຕາສ່ວນຈະປ່ຽນຫົວໜ່ວຍເປັນ m / mm.
|
||||
Snapping ການດູດຈັບ
|
||||
Export measurements ສົ່ງອອກການວັດແທກ
|
||||
Open a PDF to measure it. ເປີດ PDF ເພື່ອວັດແທກ.
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 6 and column 32.
|
@@ -1452,6 +1452,10 @@
|
||||
Draw freehand Brėžti laisva ranka
|
||||
Drawing Brėžinys
|
||||
Drawing scale Brėžinio mastelis
|
||||
Scale Mastelis
|
||||
Common scales Dažni masteliai
|
||||
Enter a scale such as 1:50. Įveskite mastelį, pavyzdžiui, 1:50.
|
||||
Applying a scale switches units to m / mm. Pritaikius mastelį, vienetai pakeičiami į m / mm.
|
||||
Drop-down list Išskleidžiamasis sąrašas
|
||||
Duplicate pages Dubliuoti puslapius
|
||||
Edit a PDF Redaguoti PDF
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 406 and column 9.
|
@@ -1403,6 +1403,10 @@
|
||||
Draw freehand Tegn på frihånd
|
||||
Drawing Tegning
|
||||
Drawing scale Tegneskala
|
||||
Scale Målestokk
|
||||
Common scales Vanlige målestokker
|
||||
Enter a scale such as 1:50. Skriv inn en målestokk, for eksempel 1:50.
|
||||
Applying a scale switches units to m / mm. Når du bruker en målestokk, byttes enhetene til m / mm.
|
||||
Drop-down list Nedtrekksliste
|
||||
Duplicate pages Dupliser sider
|
||||
Edit a PDF Rediger en PDF
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 8 and column 16.
|
@@ -2034,6 +2034,10 @@
|
||||
Perimeter Obwód
|
||||
Area Pole powierzchni
|
||||
Drawing scale Skala rysunku
|
||||
Scale Skala
|
||||
Common scales Popularne skale
|
||||
Enter a scale such as 1:50. Wpisz skalę, na przykład 1:50.
|
||||
Applying a scale switches units to m / mm. Zastosowanie skali zmienia jednostki na m / mm.
|
||||
Snapping Przyciąganie
|
||||
Export measurements Eksportuj pomiary
|
||||
Open a PDF to measure it. Otwórz PDF, aby wykonać pomiar.
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 6 and column 47.
|
@@ -1775,6 +1775,10 @@
|
||||
Perimeter Perímetro
|
||||
Area Área
|
||||
Drawing scale Escala de desenho
|
||||
Scale Escala
|
||||
Common scales Escalas comuns
|
||||
Enter a scale such as 1:50. Digite uma escala como 1:50.
|
||||
Applying a scale switches units to m / mm. Aplicar uma escala muda as unidades para m / mm.
|
||||
Snapping Alinhamento inteligente
|
||||
Export measurements Exportar medições
|
||||
Open a PDF to measure it. Abra um PDF para medi-lo.
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 9 and column 16.
|
@@ -1401,6 +1401,10 @@
|
||||
Draw freehand Desenare liberă
|
||||
Drawing Desen
|
||||
Drawing scale Scara desenului
|
||||
Scale Scară
|
||||
Common scales Scări uzuale
|
||||
Enter a scale such as 1:50. Introduceți o scară, de exemplu 1:50.
|
||||
Applying a scale switches units to m / mm. Aplicarea unei scări schimbă unitățile în m / mm.
|
||||
Drop-down list Listă derulantă
|
||||
Duplicate pages Duplicare pagini
|
||||
Edit a PDF Editare PDF
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 3 and column 110.
|
@@ -2041,6 +2041,10 @@
|
||||
Perimeter Периметр
|
||||
Area Площадь
|
||||
Drawing scale Масштаб чертежа
|
||||
Scale Масштаб
|
||||
Common scales Распространённые масштабы
|
||||
Enter a scale such as 1:50. Введите масштаб, например 1:50.
|
||||
Applying a scale switches units to m / mm. При применении масштаба единицы переключаются на м / мм.
|
||||
Snapping Привязка
|
||||
Export measurements Экспортировать измерения
|
||||
Open a PDF to measure it. Откройте PDF для измерения.
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 9 and column 16.
|
@@ -654,6 +654,10 @@
|
||||
Draw your {what} below. Spodaj narišite: {what}.
|
||||
Drawing Risba
|
||||
Drawing scale Merilo risbe
|
||||
Scale Merilo
|
||||
Common scales Pogosta merila
|
||||
Enter a scale such as 1:50. Vnesite merilo, na primer 1:50.
|
||||
Applying a scale switches units to m / mm. Z uporabo merila se enote preklopijo na m / mm.
|
||||
Drop PDFs or folders here, or choose them. Spustite datoteke PDF ali mape sem ali jih izberite.
|
||||
Drop-down list Spustni seznam
|
||||
Dropdown Properties Lastnosti spustnega seznama
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 9 and column 16.
|
@@ -645,6 +645,10 @@
|
||||
Draw your {what} below. Vizato {what} më poshtë.
|
||||
Drawing Vizatim
|
||||
Drawing scale Shkalla e vizatimit
|
||||
Scale Shkalla
|
||||
Common scales Shkalla të zakonshme
|
||||
Enter a scale such as 1:50. Shkruani një shkallë si 1:50.
|
||||
Applying a scale switches units to m / mm. Zbatimi i një shkalle i kalon njësitë në m / mm.
|
||||
Drop PDFs or folders here, or choose them. Hidh PDF ose dosje këtu, ose zgjidh ato.
|
||||
Drop-down list Listë rënëse
|
||||
Dropdown Properties Vetitë e listës rënëse
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 9 and column 16.
|
@@ -1960,6 +1960,10 @@ action wizard Start ప్రారంభించు
|
||||
Perimeter చుట్టుకొలత
|
||||
Area వైశాల్యం
|
||||
Drawing scale డ్రాయింగ్ స్కేల్
|
||||
Scale స్కేల్
|
||||
Common scales సాధారణ స్కేల్లు
|
||||
Enter a scale such as 1:50. 1:50 వంటి స్కేల్ను నమోదు చేయండి.
|
||||
Applying a scale switches units to m / mm. స్కేల్ను వర్తింపజేస్తే యూనిట్లు m / mmకు మారతాయి.
|
||||
Snapping స్నాపింగ్
|
||||
Export measurements కొలతలను ఎగుమతి చేయి
|
||||
Open a PDF to measure it. కొలవడానికి ఒక PDFను తెరవండి.
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 13 and column 16.
|
@@ -1984,6 +1984,10 @@
|
||||
Perimeter เส้นรอบรูป
|
||||
Area พื้นที่
|
||||
Drawing scale มาตราส่วนของแบบ
|
||||
Scale มาตราส่วน
|
||||
Common scales มาตราส่วนที่ใช้บ่อย
|
||||
Enter a scale such as 1:50. ป้อนมาตราส่วน เช่น 1:50
|
||||
Applying a scale switches units to m / mm. การใช้มาตราส่วนจะเปลี่ยนหน่วยเป็น m / mm
|
||||
Snapping การยึด
|
||||
Export measurements ส่งออกการวัด
|
||||
Open a PDF to measure it. เปิด PDF เพื่อวัดระยะ
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 865 and column 12.
|
@@ -1934,6 +1934,10 @@
|
||||
Perimeter Çevre
|
||||
Area Alan
|
||||
Drawing scale Çizim ölçeği
|
||||
Scale Ölçek
|
||||
Common scales Yaygın ölçekler
|
||||
Enter a scale such as 1:50. 1:50 gibi bir ölçek girin.
|
||||
Applying a scale switches units to m / mm. Ölçek uygulamak birimleri m / mm olarak değiştirir.
|
||||
Snapping Yakalama
|
||||
Export measurements Ölçümleri dışa aktar
|
||||
Open a PDF to measure it. Ölçmek için bir PDF açın.
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 858 and column 9.
|
@@ -2038,6 +2038,10 @@
|
||||
Perimeter Периметр
|
||||
Area Площа
|
||||
Drawing scale Масштаб креслення
|
||||
Scale Масштаб
|
||||
Common scales Поширені масштаби
|
||||
Enter a scale such as 1:50. Введіть масштаб, наприклад 1:50.
|
||||
Applying a scale switches units to m / mm. Застосування масштабу перемикає одиниці на м / мм.
|
||||
Snapping Прив’язування
|
||||
Export measurements Експортувати вимірювання
|
||||
Open a PDF to measure it. Відкрийте PDF для вимірювання.
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 6 and column 47.
|
@@ -1441,6 +1441,10 @@ theme Appearance Giao diện
|
||||
Draw freehand Vẽ tự do
|
||||
Drawing Bản vẽ
|
||||
Drawing scale Tỷ lệ bản vẽ
|
||||
Scale Tỷ lệ
|
||||
Common scales Tỷ lệ thông dụng
|
||||
Enter a scale such as 1:50. Nhập một tỷ lệ như 1:50.
|
||||
Applying a scale switches units to m / mm. Áp dụng tỷ lệ sẽ chuyển đơn vị sang m / mm.
|
||||
Drop-down list Danh sách thả xuống
|
||||
Duplicate pages Nhân bản trang
|
||||
Edit a PDF Chỉnh sửa một PDF
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 493 and column 12.
|
@@ -1910,6 +1910,10 @@
|
||||
Perimeter 周长
|
||||
Area 面积
|
||||
Drawing scale 图面比例
|
||||
Scale 比例
|
||||
Common scales 常用比例
|
||||
Enter a scale such as 1:50. 请输入比例,例如 1:50。
|
||||
Applying a scale switches units to m / mm. 应用比例会将单位切换为 m / mm。
|
||||
Snapping 吸附
|
||||
Export measurements 导出测量结果
|
||||
Open a PDF to measure it. 打开 PDF 以进行测量。
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 9 and column 16.
|
@@ -2041,6 +2041,10 @@
|
||||
Perimeter 周長
|
||||
Area 面積
|
||||
Drawing scale 圖面比例
|
||||
Scale 比例
|
||||
Common scales 常用比例
|
||||
Enter a scale such as 1:50. 請輸入比例,例如 1:50。
|
||||
Applying a scale switches units to m / mm. 套用比例會將單位切換為 m / mm。
|
||||
Snapping 吸附
|
||||
Export measurements 匯出測量結果
|
||||
Open a PDF to measure it. 開啟 PDF 以進行測量。
|
||||
|
||||
|
Can't render this file because it contains an unexpected character in line 9 and column 16.
|
@@ -55,6 +55,10 @@ pub struct MeasureView {
|
||||
pub unit: String,
|
||||
/// The unit picked for the page side of the scale; `None` follows `unit`.
|
||||
pub page_unit: Option<PageUnit>,
|
||||
/// The "1:N" field of the drawing scale, as typed.
|
||||
pub ratio_text: String,
|
||||
/// The "1:N" field was edited and not yet applied.
|
||||
ratio_dirty: bool,
|
||||
pub precision: u8,
|
||||
pub name: String,
|
||||
pub whole_page: bool,
|
||||
@@ -83,6 +87,8 @@ impl Default for MeasureView {
|
||||
real_distance: 1.0,
|
||||
unit: "in".into(),
|
||||
page_unit: None,
|
||||
ratio_text: String::new(),
|
||||
ratio_dirty: false,
|
||||
precision: 2,
|
||||
name: "Drawing scale".into(),
|
||||
whole_page: true,
|
||||
@@ -99,6 +105,59 @@ impl Default for MeasureView {
|
||||
pub(crate) fn page_unit_of(picked: Option<PageUnit>, unit: &str, display: crate::units::Unit) -> PageUnit {
|
||||
picked.or_else(|| PageUnit::from_label(unit)).or_else(|| PageUnit::from_label(display.label())).unwrap_or(PageUnit::Pt)
|
||||
}
|
||||
/// Drawing scales an architect's rule offers, as the N of 1:N.
|
||||
pub(crate) const RATIOS: [f64; 10] = [1.0, 5.0, 10.0, 20.0, 25.0, 50.0, 100.0, 200.0, 500.0, 1000.0];
|
||||
/// "1:200", "1/200", "1 : 200" or a bare "200" (a comma works as the decimal mark), as the N of 1:N.
|
||||
/// `None` for anything else, for zero, negative or absurd values.
|
||||
pub(crate) fn parse_ratio(text: &str) -> Option<f64> {
|
||||
let text = text.trim().replace(',', ".");
|
||||
let n = match text.split_once([':', '/']) {
|
||||
Some((one, n)) => n.trim().parse::<f64>().ok()? / one.trim().parse::<f64>().ok()?,
|
||||
None => text.parse::<f64>().ok()?,
|
||||
};
|
||||
RATIO_RANGE.contains(&n).then_some(n)
|
||||
}
|
||||
/// The N of 1:N this panel accepts. The lower bound keeps the real distance (N / 1000 m) within the
|
||||
/// minimum of its field.
|
||||
const RATIO_RANGE: std::ops::RangeInclusive<f64> = 1e-3..=1e9;
|
||||
/// "1:200", or "1:2.5" for a ratio that isn't a whole number: the number as it is, so the field shows exactly what applies.
|
||||
pub(crate) fn format_ratio(n: f64) -> String {
|
||||
format!("1:{n}")
|
||||
}
|
||||
/// The N of 1:N the scale fields stand for, when they are a plain drawing scale (real distance in m or mm).
|
||||
fn ratio_of_fields(state: &MeasureView, display: crate::units::Unit) -> Option<f64> {
|
||||
let real_mm = match state.unit.trim() {
|
||||
"m" => state.real_distance * 1000.0,
|
||||
"mm" => state.real_distance,
|
||||
_ => return None,
|
||||
};
|
||||
let paper_mm = state.drawing_points * page_unit_of(state.page_unit, &state.unit, display).points() * 25.4 / 72.0;
|
||||
let n = real_mm / paper_mm;
|
||||
// Float noise from the unit conversions is rounded away; anything that isn't a clean ratio isn't one.
|
||||
let clean = (n * 1e6).round() / 1e6;
|
||||
(RATIO_RANGE.contains(&clean) && (clean - n).abs() <= 1e-9 * n).then_some(clean)
|
||||
}
|
||||
/// Make the "1:N" field and the common scale picked in its list say what the scale fields now hold: the ratio, or nothing.
|
||||
fn sync_ratio_text(state: &mut MeasureView, display: crate::units::Unit) {
|
||||
state.ratio_text = ratio_of_fields(state, display).map(format_ratio).unwrap_or_default();
|
||||
state.ratio_dirty = false;
|
||||
}
|
||||
/// What the scale fields hold, to notice a hand edit.
|
||||
fn scale_fields(state: &MeasureView) -> (f64, f64, String, Option<PageUnit>) {
|
||||
(state.drawing_points, state.real_distance, state.unit.clone(), state.page_unit)
|
||||
}
|
||||
/// Fill the scale fields for 1:N: 1 mm on the page is N mm, shown in metres. Returns `false`, changing nothing, when `n` is not a usable ratio.
|
||||
pub(crate) fn set_ratio(state: &mut MeasureView, n: f64) -> bool {
|
||||
if !RATIO_RANGE.contains(&n) {
|
||||
return false;
|
||||
}
|
||||
state.unit = "m".into();
|
||||
state.page_unit = Some(PageUnit::Mm);
|
||||
state.drawing_points = 1.0;
|
||||
state.real_distance = n / 1000.0;
|
||||
state.ratio_text = format_ratio(n);
|
||||
true
|
||||
}
|
||||
impl MeasureView {
|
||||
pub fn cancel(&mut self) {
|
||||
self.points.clear();
|
||||
@@ -330,6 +389,7 @@ fn panel_body(app: &mut PdfCraftApp, ui: &mut egui::Ui, _t: &Tokens) {
|
||||
state.page_unit = None;
|
||||
state.precision = scale.precision;
|
||||
}
|
||||
sync_ratio_text(state, units);
|
||||
}
|
||||
ui.label(tl!("Click vertices. Enter or double-click finishes a perimeter or area. Click the first point to close an area."));
|
||||
ui.label(tl!("Shift constrains to 45 degrees. Backspace removes a vertex. Escape cancels."));
|
||||
@@ -363,7 +423,28 @@ fn panel_body(app: &mut PdfCraftApp, ui: &mut egui::Ui, _t: &Tokens) {
|
||||
ui.add(egui::Slider::new(&mut state.sensitivity, 1.0..=20.0).text(tl!("Sensitivity")));
|
||||
}
|
||||
ui.separator();
|
||||
ui.label(tl!("Drawing scale"));
|
||||
// "1:N" fills the fields below and applies at once, as does picking a common scale.
|
||||
let mut chosen = None;
|
||||
let fields = scale_fields(state);
|
||||
ui.horizontal(|ui| {
|
||||
ui.label(tl!("Drawing scale")).on_hover_text(tl!("Applying a scale switches units to m / mm."));
|
||||
let typed = ui.add(crate::widgets::line(&mut state.ratio_text).hint_text("1:100").desired_width(56.0).char_limit(16));
|
||||
typed.widget_info(|| egui::WidgetInfo::labeled(egui::WidgetType::TextEdit, true, tl!("Scale")));
|
||||
state.ratio_dirty |= typed.changed();
|
||||
if typed.lost_focus() && std::mem::take(&mut state.ratio_dirty) {
|
||||
match parse_ratio(&state.ratio_text) {
|
||||
Some(n) => chosen = Some(n),
|
||||
None => state.error = Some(tl!("Enter a scale such as 1:50.").into()),
|
||||
}
|
||||
}
|
||||
egui::ComboBox::from_id_salt("measure-common-scales").selected_text(tl!("Common scales")).width(20.0).show_ui(ui, |ui| {
|
||||
for n in RATIOS {
|
||||
if ui.selectable_label(state.ratio_text == format_ratio(n), format_ratio(n)).clicked() {
|
||||
chosen = Some(n);
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
ui.horizontal(|ui| {
|
||||
ui.add(egui::DragValue::new(&mut state.drawing_points).range(0.000001..=1e9));
|
||||
let page_unit = page_unit_of(state.page_unit, &state.unit, units);
|
||||
@@ -382,6 +463,10 @@ fn panel_body(app: &mut PdfCraftApp, ui: &mut egui::Ui, _t: &Tokens) {
|
||||
ui.add(crate::widgets::line(&mut state.unit).desired_width(64.0).char_limit(12));
|
||||
ui.add(egui::DragValue::new(&mut state.precision).range(0..=6).prefix(format!("{} ", tl!("Decimals"))));
|
||||
});
|
||||
// A hand edit of the fields leaves the 1:N field showing the old ratio: say the new one.
|
||||
if scale_fields(state) != fields {
|
||||
sync_ratio_text(state, units);
|
||||
}
|
||||
if ui.button(tl!("Calibrate from two points")).clicked() {
|
||||
tool = Some(Tool::Calibrate);
|
||||
}
|
||||
@@ -427,7 +512,16 @@ fn panel_body(app: &mut PdfCraftApp, ui: &mut egui::Ui, _t: &Tokens) {
|
||||
}
|
||||
}
|
||||
let export = ui.button(tl!("Export measurements as CSV")).clicked();
|
||||
if apply && let Some(info) = info {
|
||||
if let Some(n) = chosen
|
||||
&& set_ratio(state, n)
|
||||
{
|
||||
state.error = None;
|
||||
}
|
||||
// Apply scale, or a 1:N typed or picked: the fields are applied to the document at once.
|
||||
if (apply || chosen.is_some())
|
||||
&& doc.allows_annotation()
|
||||
&& let Some(info) = info
|
||||
{
|
||||
let result =
|
||||
doc.measurement_to_user(page, [0.0, 0.0]).and_then(|a| doc.measurement_to_user(page, [1.0, 0.0]).map(|b| (a, b))).and_then(|(a, b)| {
|
||||
let page_unit = page_unit_of(state.page_unit, &state.unit, units);
|
||||
@@ -513,3 +607,125 @@ fn export_csv(app: &mut PdfCraftApp) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
/// What Apply scale builds from the panel's fields, then a distance read with it.
|
||||
fn measured(state: &MeasureView, from: Point, to: Point) -> f64 {
|
||||
let page_unit = page_unit_of(state.page_unit, &state.unit, crate::units::Unit::Points);
|
||||
let scale = Scale::ratio([0.0, 0.0], [1.0, 0.0], state.drawing_points, page_unit, state.real_distance, &state.unit, 4).expect("scale");
|
||||
measure::reading(Kind::Distance, &[from, to], &scale).expect("reading").value
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn typed_ratios_are_read_leniently() {
|
||||
assert_eq!(parse_ratio("1:200"), Some(200.0));
|
||||
assert_eq!(parse_ratio(" 1 : 50 "), Some(50.0));
|
||||
assert_eq!(parse_ratio("1/20"), Some(20.0));
|
||||
assert_eq!(parse_ratio("250"), Some(250.0));
|
||||
assert_eq!(parse_ratio("1:2,5"), Some(2.5));
|
||||
assert_eq!(parse_ratio("2:1"), Some(0.5));
|
||||
assert_eq!(parse_ratio("1:0.001"), Some(1e-3));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn invalid_ratios_are_refused() {
|
||||
for bad in [
|
||||
"", " ", ":", "1:", ":50", "1:0", "0", "-5", "1:-5", "0:5", "abc", "1:abc", "1:50:2", "1:inf", "NaN", "1e12", "1:1e12", "1:0.0001",
|
||||
"1:1e-6",
|
||||
] {
|
||||
assert_eq!(parse_ratio(bad), None, "{bad:?}");
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn ratios_are_written_as_people_say_them() {
|
||||
assert_eq!(format_ratio(50.0), "1:50");
|
||||
assert_eq!(format_ratio(2.5), "1:2.5");
|
||||
assert_eq!(format_ratio(0.5), "1:0.5");
|
||||
// Nothing is rounded away: the field reads the ratio that applies.
|
||||
assert_eq!(format_ratio(1.234), "1:1.234");
|
||||
assert_eq!(format_ratio(0.001), "1:0.001");
|
||||
assert_eq!(parse_ratio(&format_ratio(333.333333)), Some(333.333333));
|
||||
for n in RATIOS {
|
||||
assert_eq!(parse_ratio(&format_ratio(n)), Some(n));
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn every_offered_ratio_reads_paper_length_times_n_in_metres_whatever_the_unit_was() {
|
||||
for unit in ["mm", "cm", "m", "km", "in", "ft"] {
|
||||
for n in RATIOS {
|
||||
let mut state = MeasureView { unit: unit.into(), ..Default::default() };
|
||||
assert!(set_ratio(&mut state, n));
|
||||
assert_eq!(state.unit, "m");
|
||||
// 72 pt is one inch of paper: 25.4 mm x N, shown in metres.
|
||||
let v = measured(&state, [0.0, 0.0], [0.0, 72.0]);
|
||||
let expected = 25.4 * n / 1000.0;
|
||||
assert!((v - expected).abs() < 1e-9 * expected.max(1.0), "1:{n} in {unit} gave {v}, wanted {expected}");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn any_starting_unit_becomes_metres() {
|
||||
let mut state = MeasureView { unit: "yards?".into(), ..Default::default() };
|
||||
assert!(set_ratio(&mut state, 50.0));
|
||||
assert_eq!(state.unit, "m");
|
||||
// 1 mm of paper at 1:50 is 50 mm.
|
||||
let v = measured(&state, [0.0, 0.0], [72.0 / 25.4, 0.0]);
|
||||
assert!((v - 0.05).abs() < 1e-9, "{v}");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn the_smallest_ratio_keeps_the_real_distance_within_its_field() {
|
||||
let mut state = MeasureView::default();
|
||||
assert!(set_ratio(&mut state, parse_ratio("1:0.001").expect("ratio")));
|
||||
// The real-distance field accepts 0.000001 and no less.
|
||||
assert!(state.real_distance >= 0.000001, "{}", state.real_distance);
|
||||
assert!(!set_ratio(&mut state, 1e-4));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn the_ratio_field_follows_the_scale_fields() {
|
||||
let display = crate::units::Unit::Points;
|
||||
let mut state = MeasureView::default();
|
||||
for n in [50.0, 2.5, 1.234, 0.001, 1e9] {
|
||||
assert!(set_ratio(&mut state, n));
|
||||
sync_ratio_text(&mut state, display);
|
||||
assert_eq!(state.ratio_text, format_ratio(n), "1:{n}");
|
||||
}
|
||||
// A hand edit that is still a drawing scale reads as its ratio, in another page unit too.
|
||||
assert!(set_ratio(&mut state, 50.0));
|
||||
state.page_unit = Some(PageUnit::Cm);
|
||||
sync_ratio_text(&mut state, display);
|
||||
assert_eq!(state.ratio_text, "1:5");
|
||||
state.page_unit = Some(PageUnit::Mm);
|
||||
state.real_distance = 0.1;
|
||||
sync_ratio_text(&mut state, display);
|
||||
assert_eq!(state.ratio_text, "1:100");
|
||||
// One that isn't (another unit, or no ratio at all) empties it.
|
||||
state.unit = "ft".into();
|
||||
sync_ratio_text(&mut state, display);
|
||||
assert_eq!(state.ratio_text, "");
|
||||
state.unit = "m".into();
|
||||
state.real_distance = 0.1 / 3.0;
|
||||
sync_ratio_text(&mut state, display);
|
||||
assert_eq!(state.ratio_text, "");
|
||||
state.drawing_points = 0.0;
|
||||
sync_ratio_text(&mut state, display);
|
||||
assert_eq!(state.ratio_text, "");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn an_unusable_ratio_changes_nothing() {
|
||||
let mut state = MeasureView::default();
|
||||
let before = (state.drawing_points, state.real_distance, state.unit.clone(), state.page_unit);
|
||||
for n in [0.0, -1.0, f64::NAN, f64::INFINITY] {
|
||||
assert!(!set_ratio(&mut state, n));
|
||||
}
|
||||
assert_eq!((state.drawing_points, state.real_distance, state.unit.clone(), state.page_unit), before);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1364,6 +1364,58 @@ fn a_1_to_50_scale_in_millimetres_measures_a_10_mm_line_as_500_mm() {
|
||||
assert_eq!(measurements[0].reading.unit, "mm");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn a_plan_scale_picked_or_typed_applies_at_once() {
|
||||
use pdfcraft_engine::measure::{self, Kind};
|
||||
let (mut h, c) = harness_pages(1);
|
||||
let doc = h.state().views[0].id;
|
||||
ok(&mut h, &c, "ui.command", json!({"id":"measure.scale"}));
|
||||
h.run_steps(3);
|
||||
h.state_mut().views[0].measure.unit = "m".into();
|
||||
h.run_steps(2);
|
||||
// 60 mm of paper.
|
||||
let line = [[20.0, 20.0], [20.0 + 60.0 / 25.4 * 72.0, 20.0]];
|
||||
let read = |h: &Harness<'static, PdfCraftApp>| {
|
||||
let scale = h.state().session.get(doc).unwrap().measurement_scale(0, line[0]).unwrap();
|
||||
(measure::reading(Kind::Distance, &line, &scale).unwrap().label, scale.ratio)
|
||||
};
|
||||
// Picked from the common scales: no Apply click.
|
||||
h.get_by(|n| n.role() == egui::accesskit::Role::ComboBox && n.value().is_some_and(|v| v == "Common scales")).click();
|
||||
h.run_steps(2);
|
||||
h.get_by_label("1:200").click_accesskit();
|
||||
h.run_steps(3);
|
||||
assert_eq!(read(&h), ("12.00 m".to_string(), "1 mm = 0.2 m".to_string()));
|
||||
// Typed, in the other notations; leaving the field applies.
|
||||
fn field<'a>(h: &'a Harness<'static, PdfCraftApp>) -> egui_kittest::Node<'a> {
|
||||
h.get_by_role_and_label(egui::accesskit::Role::TextInput, "Scale")
|
||||
}
|
||||
for (typed, label) in [("1/50", "3.00 m"), ("1:100", "6.00 m")] {
|
||||
field(&h).click();
|
||||
h.run_steps(1);
|
||||
h.state_mut().views[0].measure.ratio_text.clear();
|
||||
field(&h).type_text(typed);
|
||||
h.run_steps(2);
|
||||
h.key_press(egui::Key::Enter);
|
||||
h.run_steps(3);
|
||||
assert_eq!(read(&h).0, label, "{typed}");
|
||||
}
|
||||
// Nonsense is refused with a message and leaves the page scale alone.
|
||||
let before = read(&h);
|
||||
field(&h).click();
|
||||
h.run_steps(1);
|
||||
h.state_mut().views[0].measure.ratio_text.clear();
|
||||
field(&h).type_text("1:0");
|
||||
h.run_steps(2);
|
||||
h.key_press(egui::Key::Enter);
|
||||
h.run_steps(3);
|
||||
assert_eq!(read(&h), before);
|
||||
assert!(h.state().views[0].measure.error.is_some());
|
||||
// The scale is one undoable edit.
|
||||
ok(&mut h, &c, "ui.command", json!({"id":"edit.undo"}));
|
||||
h.run_steps(2);
|
||||
assert_ne!(read(&h), before);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn docking_pointer_group_float_close_restore_and_document_commands() {
|
||||
use pdfcraft_ui_egui::docking::Panel;
|
||||
|
||||
@@ -4280,7 +4280,7 @@ milestone = "M12"
|
||||
status = "partial"
|
||||
commands = ["measure.distance"]
|
||||
tools = ["measure_distance"]
|
||||
evidence = ["crates/automation/tests/it/automation.rs::measurements_calibrate_draw_save_reopen_and_export", "crates/measure/src/tests.rs::calibrated_lengths_concave_areas_and_axis_scales", "crates/ui-egui/tests/it/control.rs::measurement_tools_draw_live_calibrate_save_and_export"]
|
||||
evidence = ["crates/automation/tests/it/automation.rs::measurements_calibrate_draw_save_reopen_and_export", "crates/measure/src/tests.rs::calibrated_lengths_concave_areas_and_axis_scales", "crates/ui-egui/tests/it/control.rs::measurement_tools_draw_live_calibrate_save_and_export", "crates/ui-egui/tests/it/control.rs::a_plan_scale_picked_or_typed_applies_at_once", "crates/ui-egui/src/measure_ui.rs::typed_ratios_are_read_leniently"]
|
||||
notes = "Two-point distance annotations with saved numeric captions and rectilinear scales. Partial: only single-unit decimal formats; compound (ft-in) and fractional formats are not supported (listed as unsupported, data kept), no leader lines or caption placement options, geospatial scales unsupported, and interop with Acrobat-authored measurements (reading theirs, Acrobat reading ours) is untested."
|
||||
|
||||
[[feature]]
|
||||
|
||||
Reference in New Issue
Block a user