From ad35bd27ac78918a5568de327060e0f8529b69d0 Mon Sep 17 00:00:00 2001 From: Nai-ITA Date: Mon, 12 Oct 2026 18:54:35 +0200 Subject: [PATCH 001/498] Add files via upload --- crates/ui-egui/src/i18n/it.tsv | 214 +++++++++++++++++++++++++++++++++ 1 file changed, 214 insertions(+) diff --git a/crates/ui-egui/src/i18n/it.tsv b/crates/ui-egui/src/i18n/it.tsv index 5448ef639..ee7285733 100644 --- a/crates/ui-egui/src/i18n/it.tsv +++ b/crates/ui-egui/src/i18n/it.tsv @@ -2347,3 +2347,217 @@ animation effects Off Disattivati The linked PDF opened, but its named destination was not applied. Il PDF collegato è stato aperto, ma la sua destinazione con nome non è stata applicata. The linked PDF opened, but its page destination was out of range. Il PDF collegato è stato aperto, ma la pagina di destinazione è fuori intervallo. Local cross-PDF links require the desktop app I collegamenti locali tra PDF richiedono l'app desktop + +# Signature validation, accessibility checker, calendar and certificate details. + A font isn't embedded Un font non è incorporato + A {} action isn't allowed Un'azione {} non è consentita + A {} annotation has additional actions Un'annotazione {} ha azioni aggiuntive + A {} annotation has no appearance stream Un'annotazione {} non ha un flusso di aspetto + A {} annotation isn't set to print, or is hidden Un'annotazione {} non è impostata per la stampa, oppure è nascosta + Accessibility Report Rapporto di accessibilità + CRL Signing Firma di CRL + Certificate Signing Firma di certificati + Change Author Cambia autore + Change Keywords Cambia parole chiave + Change Subject Cambia oggetto + Change Title Cambia titolo + Choose a digital ID. Scegli un ID digitale. + Color Colore + Comment Commento + Create links Crea collegamenti + Creator Applicazione di origine + Cut and stack needs Two-sided: Off. Print single-sided sheets. Taglia e impila richiede Fronte/retro: disattivato. Stampa fogli su un solo lato. + Data Encipherment Cifratura dei dati + Decipher Only Solo decifratura + Detailed Report Rapporto dettagliato + DeviceCMYK is used, but the PDF/A output intent isn't a CMYK profile Viene usato DeviceCMYK, ma l'intento di output PDF/A non è un profilo CMYK + DeviceRGB is used, but the PDF/A output intent isn't an RGB profile Viene usato DeviceRGB, ma l'intento di output PDF/A non è un profilo RGB + Digital Signature Firma digitale + Encipher Only Solo cifratura + English Inglese + Enter a URL Inserisci un URL + Enter a name. Inserisci un nome. + Enter a page number Inserisci un numero di pagina + Enter the field names Inserisci i nomi dei campi + Error Errore + Field "{}" on page {p} has no description (tooltip) Il campo "{}" a pagina {p} non ha una descrizione (descrizione comando) + Filename Nome file + Flatten Fill & Sign Appiattisci Compila e firma + Font Font + Font (unnamed) on page {p} doesn't map its characters to Unicode Il font (senza nome) a pagina {p} non associa i suoi caratteri a Unicode + Font {} on page {p} doesn't map its characters to Unicode Il font {} a pagina {p} non associa i suoi caratteri a Unicode + Form field on page {p} isn't tagged Il campo modulo a pagina {p} non ha tag + H{n} follows an H{d}; headings should not skip levels H{n} segue un H{d}; i titoli non dovrebbero saltare livelli + Inspector Ispettore + Key Agreement Accordo di chiavi + Key Encipherment Cifratura delle chiavi + Next Avanti + No document language is set Non è impostata la lingua del documento + No page has text: the document appears to be images of pages Nessuna pagina contiene testo: il documento sembra composto da immagini di pagine + Non-Repudiation Non ripudio + On Attivo + Page {p} doesn't tab in structure order La tabulazione della pagina {p} non segue l'ordine della struttura + Page {p}: {n} untagged content item Pagina {p}: {n} elemento di contenuto senza tag + Page {p}: {n} untagged content items Pagina {p}: {n} elementi di contenuto senza tag + Page {} has additional actions La pagina {} ha azioni aggiuntive + Panel layout could not be restored: {error} Impossibile ripristinare il layout dei pannelli: {error} + Panel move was not applied: {error} Lo spostamento del pannello non è stato applicato: {error} + PdfCraft can't check this signature yet: {}. PdfCraft non può ancora verificare questa firma: {}. + Producer Produttore + Rendering… Rendering… + Report created Rapporto creato + Rev. {rev}: Certified by an unknown signer Rev. {rev}: certificato da un firmatario sconosciuto + Rev. {rev}: Certified by {name} Rev. {rev}: certificato da {name} + Rev. {rev}: Signed by an unknown signer Rev. {rev}: firmato da un firmatario sconosciuto + Rev. {rev}: Signed by {name} Rev. {rev}: firmato da {name} + Rotate view clockwise (⇧⌘+) Ruota la vista in senso orario (⇧⌘+) + Rule Name Nome regola + Save (M4) Salva (M4) + Save as {level} Salva come {level} + Save changes? Salvare le modifiche? + Signature is invalid La firma non è valida + Signature is valid La firma è valida + Signature validity is unknown La validità della firma è sconosciuta + Signing time is from the clock on the signer's computer. L'ora della firma proviene dall'orologio del computer del firmatario. + Still rendering — this page is unusually complex… Rendering ancora in corso — questa pagina è insolitamente complessa… + System Sistema + The ECDSA signature is not in canonical DER (trailing bytes, padding or a missing sign byte); it was read anyway. La firma ECDSA non è in DER canonico (byte in coda, riempimento o byte di segno mancante); è stata comunque letta. + The ECDSA signature is the raw r and s values instead of a DER sequence; it was read anyway. La firma ECDSA è composta dai valori r e s grezzi invece che da una sequenza DER; è stata comunque letta. + The RSA signature value does not have the length of the key's modulus (leading zero bytes dropped or added); it was read anyway. Il valore della firma RSA non ha la lunghezza del modulo della chiave (byte zero iniziali rimossi o aggiunti); è stato comunque letto. + The RSA signature's DigestInfo has no NULL parameter (older signers write it so); it was read anyway. Il DigestInfo della firma RSA non ha il parametro NULL (i firmatari più vecchi lo scrivono così); è stato comunque letto. + The certificate of {} does not allow this many CA certificates below it (path length), so it is not used to vouch for {}. Il certificato di {} non consente così tanti certificati CA al di sotto (lunghezza del percorso), quindi non viene usato per garantire {}. + The certificate of {} is not a CA certificate that may issue certificates, so it is not used to vouch for {}. Il certificato di {} non è un certificato CA autorizzato a emettere certificati, quindi non viene usato per garantire {}. + The certificate of {} was not valid at the time of signing, so it is not used to vouch for {}. Il certificato di {} non era valido al momento della firma, quindi non viene usato per garantire {}. + The checker found problems which may prevent the document from being fully accessible. Il controllo ha rilevato problemi che potrebbero impedire la piena accessibilità del documento. + The document has been altered or corrupted since the signature was applied. Il documento è stato alterato o danneggiato dopo l'applicazione della firma. + The document has been altered or corrupted since the timestamp was applied. Il documento è stato alterato o danneggiato dopo l'applicazione della marca temporale. + The document has been altered since this signature was applied in ways it does not permit ({}). Il documento è stato alterato dopo l'applicazione di questa firma in modi che non consente ({}). + The document has been altered since this timestamp was applied in ways it does not permit ({}). Il documento è stato alterato dopo l'applicazione di questa marca temporale in modi che non consente ({}). + The document has been modified since this signature was applied, but the changes are permitted ({}). Il documento è stato modificato dopo l'applicazione di questa firma, ma le modifiche sono consentite ({}). + The document has been modified since this timestamp was applied, but the changes are permitted ({}). Il documento è stato modificato dopo l'applicazione di questa marca temporale, ma le modifiche sono consentite ({}). + The document has no tags (structure tree) Il documento non ha tag (albero della struttura) + The document has no title Il documento non ha un titolo + The document isn't marked as tagged (MarkInfo Marked) Il documento non è contrassegnato come dotato di tag (MarkInfo Marked) + The document isn't tagged, so none of its content is Il documento non ha tag, quindi nessuno dei suoi contenuti li ha + The document's embedded revocation information shows that the signer's certificate has not been revoked. Le informazioni di revoca incorporate nel documento mostrano che il certificato del firmatario non è stato revocato. + The embedded timestamp token is valid and its authority is trusted; trusted time is {}. Il token di marca temporale incorporato è valido e la sua autorità è attendibile; l'ora attendibile è {}. + The font {} isn't embedded Il font {} non è incorporato + The metadata doesn't identify the file as {} I metadati non identificano il file come {} + The password is incorrect. La password non è corretta. + The password must have at least 6 characters. La password deve avere almeno 6 caratteri. + The passwords do not match. Le password non corrispondono. + The security settings don't allow screen readers to read the text Le impostazioni di sicurezza non consentono ai lettori di schermo di leggere il testo + The signature algorithm and the SignerInfo's digest algorithm name different hashes; the signature was made with the SignerInfo's. L'algoritmo di firma e l'algoritmo di digest del SignerInfo indicano hash diversi; la firma è stata creata con quello del SignerInfo. + The signature carries an unverified timestamp ({}): the timestamp authority is not in your list of trusted certificates, so the signing time claimed by the signer is used instead. La firma contiene una marca temporale non verificata ({}): l'autorità di marca temporale non è nel tuo elenco di certificati attendibili, quindi viene usata l'ora di firma dichiarata dal firmatario. + The signature contents are not hexadecimal. Il contenuto della firma non è esadecimale. + The signature could not be checked ({}). Impossibile controllare la firma ({}). + The signature could not be read ({}). Impossibile leggere la firma ({}). + The signature could not be verified ({}). Impossibile verificare la firma ({}). + The signature has no valid byte range. La firma non ha un intervallo di byte valido. + The signature includes an embedded timestamp. La firma include una marca temporale incorporata. + The signature is BER-encoded (indefinite lengths) rather than DER; it was read leniently. La firma è codificata in BER (lunghezze indefinite) anziché in DER; è stata letta in modo tollerante. + The signature uses the legacy adbe.x509.rsa_sha1 format. La firma usa il formato legacy adbe.x509.rsa_sha1. + The signature value does not match the signer's certificate: the signature is corrupt. Il valore della firma non corrisponde al certificato del firmatario: la firma è danneggiata. + The signature's byte range does not exclude exactly its contents. L'intervallo di byte della firma non esclude esattamente il suo contenuto. + The signature's byte range does not match the file. L'intervallo di byte della firma non corrisponde al file. + The signature's timestamp token could not be verified ({}). Impossibile verificare il token di marca temporale della firma ({}). + The signature's timestamp token does not cover the signature value. Il token di marca temporale della firma non copre il valore della firma. + The signed content is a constructed (segmented) OCTET STRING, as BER allows; it was read anyway. Il contenuto firmato è un OCTET STRING costruito (segmentato), come consente BER; è stato comunque letto. + The signer's certificate does not allow digital signatures (its key usage has neither digital signature nor non-repudiation). Il certificato del firmatario non consente firme digitali (il suo utilizzo chiave non prevede né la firma digitale né il non ripudio). + The signer's certificate has been revoked ({}). Il certificato del firmatario è stato revocato ({}). + The signer's certificate has critical extensions PdfCraft does not recognize ({}). Il certificato del firmatario ha estensioni critiche che PdfCraft non riconosce ({}). + The signer's certificate is not in the signature. Il certificato del firmatario non è presente nella firma. + The signer's certificate is not issued for signing documents (its extended key usage has no document-signing purpose). Il certificato del firmatario non è emesso per firmare documenti (il suo utilizzo chiave esteso non prevede la firma di documenti). + The signer's certificate was not valid at the time of signing. Il certificato del firmatario non era valido al momento della firma. + The signer's identity is unknown because it has not been included in your list of trusted certificates and none of its parent certificates are trusted certificates. L'identità del firmatario è sconosciuta perché non è stata inclusa nel tuo elenco di certificati attendibili e nessuno dei suoi certificati padre è attendibile. + The signer's identity is valid. L'identità del firmatario è valida. + The timestamp authority's certificate was not valid at the time of timestamping. Il certificato dell'autorità di marca temporale non era valido al momento della marcatura. + The timestamp contents are not hexadecimal. Il contenuto della marca temporale non è esadecimale. + The timestamp has no valid byte range. La marca temporale non ha un intervallo di byte valido. + The timestamp token could not be read ({}). Impossibile leggere il token di marca temporale ({}). + The timestamp token is valid and its authority is trusted. Il token di marca temporale è valido e la sua autorità è attendibile. + The timestamp token is valid, but the timestamp authority is not in your list of trusted certificates. Il token di marca temporale è valido, ma l'autorità di marca temporale non è nel tuo elenco di certificati attendibili. + The timestamp's byte range does not exclude exactly its contents. L'intervallo di byte della marca temporale non esclude esattamente il suo contenuto. + The timestamp's byte range does not match the file. L'intervallo di byte della marca temporale non corrisponde al file. + The window shows the file name, not the title (Initial View > Show) La finestra mostra il nome del file, non il titolo (Vista iniziale > Mostra) + There is no folder to save the digital ID in. Non c'è una cartella in cui salvare l'ID digitale. + This document has not been modified since this signature was applied. Questo documento non è stato modificato dopo l'applicazione di questa firma. + This document has not been modified since this timestamp was applied. Questo documento non è stato modificato dopo l'applicazione di questa marca temporale. + This signature uses RIPEMD-160, a legacy 160-bit hash algorithm that is no longer recommended for signatures. It still validates, but it should not be relied on. Questa firma usa RIPEMD-160, un algoritmo di hash legacy a 160 bit non più consigliato per le firme. È ancora valida, ma non dovrebbe essere considerata affidabile. + This signature uses SHA-1, a weak hash algorithm: collisions in it have been demonstrated. It still validates because many documents signed years ago use it, but it should not be relied on. Questa firma usa SHA-1, un algoritmo di hash debole per cui sono state dimostrate collisioni. È ancora valida perché molti documenti firmati anni fa lo usano, ma non dovrebbe essere considerata affidabile. + Tools Strumenti + Unsigned signature field Campo firma non firmato + Unsigned signature field: {name} Campo firma non firmato: {name} + Zoom in / out (also pinch or ⌘-scroll) Ingrandisci / riduci (anche con il pizzico o ⌘+scorrimento) + alternate text hides an annotation inside it il testo alternativo nasconde un'annotazione al suo interno + alternate text on an element with no page content testo alternativo su un elemento senza contenuto di pagina + comments commenti + document security store archivio di sicurezza del documento + document structure struttura del documento + form fill compilazione modulo + its alternate text is inside another element's and will never be read il suo testo alternativo è dentro quello di un altro elemento e non verrà mai letto + links collegamenti + metadata metadati + no alternate text nessun testo alternativo + no header cells (TH) nessuna cella di intestazione (TH) + no summary nessun riepilogo + not in a TR non è in un TR + not in a Table, THead, TBody or TFoot non è in un Table, THead, TBody o TFoot + not in an L (list) non è in un L (elenco) + not in an LI (list item) non è in un LI (voce di elenco) + of di + other changes altre modifiche + page content contenuto della pagina + page {n} is out of range (1–{count}) la pagina {n} è fuori intervallo (1–{count}) + pages added or removed pagine aggiunte o rimosse + rows have between {min} and {max} columns le righe hanno da {min} a {max} colonne + the first heading is an H{n}; headings should not skip levels il primo titolo è un H{n}; i titoli non dovrebbero saltare livelli + the signed version could not be read impossibile leggere la versione firmata + {n} pages and no bookmarks {n} pagine e nessun segnalibro + {page} is not a page number or label {page} non è un numero o un'etichetta di pagina + {ty} element on page {p}: {what} Elemento {ty} a pagina {p}: {what} + {ty} element: {what} Elemento {ty}: {what} + {who}, certificate issued by an unknown issuer. {who}, certificato emesso da un'autorità sconosciuta. + {who}, certificate issued by {issuer}. {who}, certificato emesso da {issuer}. + {} annotation on page {p} isn't tagged L'annotazione {} a pagina {p} non ha tag + {} annotations aren't allowed Le annotazioni {} non sono consentite + … and {n} more … e altri {n} +@plural {n} byte|{n} bytes {n} byte|{n} byte +@plural {n} image optimized|{n} images optimized {n} immagine ottimizzata|{n} immagini ottimizzate +@plural {n} item discarded|{n} items discarded {n} elemento scartato|{n} elementi scartati +@plural {n} pixel|{n} pixels {n} pixel|{n} pixel +calendar date April aprile +calendar date August agosto +calendar date December dicembre +calendar date February febbraio +calendar date January gennaio +calendar date July luglio +calendar date June giugno +calendar date March marzo +calendar date May maggio +calendar date November novembre +calendar date October ottobre +calendar date September settembre +calendar weekday Fr Ve +calendar weekday Mo Lu +calendar weekday Sa Sa +calendar weekday Su Do +calendar weekday Th Gi +calendar weekday Tu Ma +calendar weekday We Me +certificate Basic constraints Vincoli di base +certificate Intended usage Utilizzo previsto +certificate Issued by Emesso da +certificate Issued to Emesso a +certificate Issuer Emittente +certificate Key usage Utilizzo chiave +certificate Public key Chiave pubblica +certificate SHA-1 digest Digest SHA-1 +certificate SHA-256 digest Digest SHA-256 +certificate Self-signed Autofirmato +certificate Serial number Numero di serie +certificate Valid from Valido dal +certificate Valid to Valido fino al +certificate Validity ends Fine validità +certificate Validity starts Inizio validità +certificate Version Versione From 73fa64b4d1cfb69d60628f3e2d12c44e6b4a780f Mon Sep 17 00:00:00 2001 From: Florent Siegenthaler <64897087+Atalantis@users.noreply.github.com> Date: Mon, 12 Oct 2026 22:35:01 +0200 Subject: [PATCH 002/498] M14: complete the French interface catalog (267 entries) Adds the 267 keys that other catalogs translate and fr.tsv lacked, so French covers the union of all catalog keys. Entries were written from the English labels and checked against the existing French catalog for consistent wording; placeholders, edge spaces, trailing ellipses and the two French plural forms are preserved. --- crates/ui-egui/src/i18n/fr.tsv | 267 +++++++++++++++++++++++++++++++++ 1 file changed, 267 insertions(+) diff --git a/crates/ui-egui/src/i18n/fr.tsv b/crates/ui-egui/src/i18n/fr.tsv index e81b5f01e..ef533f9b3 100644 --- a/crates/ui-egui/src/i18n/fr.tsv +++ b/crates/ui-egui/src/i18n/fr.tsv @@ -2338,3 +2338,270 @@ animation effects Off Désactivés The linked PDF opened, but its named destination was not applied. Le PDF lié s'est ouvert, mais sa destination nommée n'a pas été appliquée. The linked PDF opened, but its page destination was out of range. Le PDF lié s'est ouvert, mais sa page de destination est hors limites. Local cross-PDF links require the desktop app Les liens locaux entre PDF nécessitent l'application de bureau + on page {label} à la page {label} + A font isn't embedded Une police n'est pas incorporée + A {} action isn't allowed Une action {} n'est pas autorisée + A {} annotation has additional actions Une annotation {} contient des actions supplémentaires + A {} annotation has no appearance stream Une annotation {} n'a pas de flux d'apparence + A {} annotation isn't set to print, or is hidden Une annotation {} n'est pas réglée pour l'impression, ou est masquée + Accessibility Report Rapport d'accessibilité + Add the PDFs to combine Ajoutez les PDF à combiner + Added the first {n} PDFs in {folder} Les {n} premiers PDF de {folder} ont été ajoutés + Always Toujours + Automatically Automatiquement + CRL Signing Signature de LCR + Certificate Signing Signature de certificats + Certificate authority Autorité de certification + Change Author Modifier l'auteur + Change Keywords Modifier les mots-clés + Change Subject Modifier le sujet + Change Title Modifier le titre + Choose a digital ID. Choisissez un ID numérique. + Choose a file… Choisir un fichier… + Choose a folder… Choisir un dossier… + Choose… Choisir… + Color Couleur + Comment Commentaire + Comment and review Commenter et réviser + Copied to clipboard Copié dans le presse-papiers + Copy to clipboard Copier dans le presse-papiers + Create folder Créer un dossier + Create links Créer des liens + Creator Application + Cut and stack needs Two-sided: Off. Print single-sided sheets. Couper et empiler exige Recto verso : Désactivé. Imprimez des feuilles en recto seul. + Data Encipherment Chiffrement des données + Decipher Only Déchiffrement seul + Detailed Report Rapport détaillé + DeviceCMYK is used, but the PDF/A output intent isn't a CMYK profile DeviceCMYK est utilisé, mais l'intention de sortie PDF/A n'est pas un profil CMJN + DeviceRGB is used, but the PDF/A output intent isn't an RGB profile DeviceRGB est utilisé, mais l'intention de sortie PDF/A n'est pas un profil RVB + Digital Signature Signature numérique + Disabled Désactivé + Document properties (⌘D) Propriétés du document (⌘D) + Drop PDFs or folders here, or choose them. Déposez des PDF ou des dossiers ici, ou choisissez-les. + Duplicate Dupliquer + Enabled Activé + Encipher Only Chiffrement seul + End entity Entité finale + English Anglais + Enter a URL Saisissez une URL + Enter a name. Saisissez un nom. + Enter a page number Saisissez un numéro de page + Enter the field names Saisissez les noms des champs + Error Erreur + Every PDF in the folder Tous les PDF du dossier + Every PDF in the folder and the folders inside it Tous les PDF du dossier et de ses sous-dossiers + Field "{}" on page {p} has no description (tooltip) Le champ « {} » de la page {p} n'a pas de description (info-bulle) + Filename Nom du fichier + Flatten Fill & Sign Aplatir Remplir et signer + Folder Dossier + Font Police + Font (unnamed) on page {p} doesn't map its characters to Unicode La police (sans nom) de la page {p} n'associe pas ses caractères à Unicode + Font {} on page {p} doesn't map its characters to Unicode La police {} de la page {p} n'associe pas ses caractères à Unicode + Form field on page {p} isn't tagged Un champ de formulaire de la page {p} n'est pas balisé + Help… Aide… + H{n} follows an H{d}; headings should not skip levels H{n} suit H{d} ; les niveaux de titre ne doivent pas être sautés + Import Importer + Information Information + Key Agreement Accord de clé + Key Encipherment Chiffrement de clé + Loading… Chargement… + Margins (in) Marges (pouces) + Move Déplacer + Never Jamais + New bookmark (⌘B) Nouveau signet (⌘B) + Next Suivant + Next (⌘G) Suivant (⌘G) + No PDFs found in {folder} Aucun PDF trouvé dans {folder} + No document language is set Aucune langue de document n'est définie + No page has text: the document appears to be images of pages Aucune page ne contient de texte : le document semble être constitué d'images de pages + No results Aucun résultat + Non-Repudiation Non-répudiation + On Activé + Only the document's owner can change its security (open it with the permissions password) Seul le propriétaire du document peut modifier sa protection (ouvrez-le avec le mot de passe d'autorisations) + Open a PDF (⌘O) Ouvrir un PDF (⌘O) + Open folder Ouvrir le dossier + Organize Organiser + Page {n} Page {n} + Page {n} of {total} Page {n} sur {total} + Page {p} doesn't tab in structure order La page {p} ne se parcourt pas dans l'ordre de la structure + Page {p}: {n} untagged content item Page {p} : {n} élément de contenu non balisé + Page {p}: {n} untagged content items Page {p} : {n} éléments de contenu non balisés + Page {} has additional actions La page {} contient des actions supplémentaires + Panel layout could not be restored: {error} Impossible de restaurer la disposition des panneaux : {error} + Panel move was not applied: {error} Le déplacement du panneau n'a pas été appliqué : {error} + Paste Coller + PdfCraft can't check this signature yet: {}. PdfCraft ne peut pas encore contrôler cette signature : {}. + Previous Précédent + Previous (⇧⌘G) Précédent (⇧⌘G) + Print (⌘P) Imprimer (⌘P) + Producer Producteur du PDF + Refresh Actualiser + Rendering… Rendu en cours… + Report created Rapport créé + Rev. {rev}: Certified by an unknown signer Rév. {rev} : certifié par un signataire inconnu + Rev. {rev}: Certified by {name} Rév. {rev} : certifié par {name} + Rev. {rev}: Signed by an unknown signer Rév. {rev} : signé par un signataire inconnu + Rev. {rev}: Signed by {name} Rév. {rev} : signé par {name} + Rotate view clockwise (⇧⌘+) Pivoter l'affichage vers la droite (⇧⌘+) + Rule Name Nom de la règle + Save (M4) Enregistrer (M4) + Save as {level} Enregistrer comme {level} + Save changes? Enregistrer les modifications ? + Save file Enregistrer le fichier + Search results Résultats de la recherche + Select all Tout sélectionner + Signature is invalid La signature n'est pas valide + Signature is valid La signature est valide + Signature validity is unknown La validité de la signature est inconnue + Signing time is from the clock on the signer's computer. L'heure de signature provient de l'horloge de l'ordinateur du signataire. + Still rendering — this page is unusually complex… Rendu toujours en cours : cette page est exceptionnellement complexe… + Success Succès + System Système + Text recognition isn't installed: its models are missing (run `cargo xtask models`, or set PDFCRAFT_MODELS). La reconnaissance de texte n'est pas installée : ses modèles sont absents (exécutez `cargo xtask models`, ou définissez PDFCRAFT_MODELS). + The ECDSA signature is not in canonical DER (trailing bytes, padding or a missing sign byte); it was read anyway. La signature ECDSA n'est pas en DER canonique (octets en trop, bourrage ou octet de signe manquant) ; elle a tout de même été lue. + The ECDSA signature is the raw r and s values instead of a DER sequence; it was read anyway. La signature ECDSA est constituée des valeurs brutes r et s au lieu d'une séquence DER ; elle a tout de même été lue. + The RSA signature value does not have the length of the key's modulus (leading zero bytes dropped or added); it was read anyway. La valeur de la signature RSA n'a pas la longueur du module de la clé (octets nuls de tête supprimés ou ajoutés) ; elle a tout de même été lue. + The RSA signature's DigestInfo has no NULL parameter (older signers write it so); it was read anyway. Le DigestInfo de la signature RSA n'a pas de paramètre NULL (d'anciens outils de signature l'écrivent ainsi) ; il a tout de même été lu. + The certificate of {} does not allow this many CA certificates below it (path length), so it is not used to vouch for {}. Le certificat de {} n'autorise pas autant de certificats d'AC en dessous de lui (longueur du chemin) : il n'est donc pas utilisé pour se porter garant de {}. + The certificate of {} is not a CA certificate that may issue certificates, so it is not used to vouch for {}. Le certificat de {} n'est pas un certificat d'AC autorisé à émettre des certificats : il n'est donc pas utilisé pour se porter garant de {}. + The certificate of {} was not valid at the time of signing, so it is not used to vouch for {}. Le certificat de {} n'était pas valide au moment de la signature : il n'est donc pas utilisé pour se porter garant de {}. + The checker found problems which may prevent the document from being fully accessible. Le vérificateur a trouvé des problèmes qui peuvent empêcher le document d'être entièrement accessible. + The document has been altered or corrupted since the signature was applied. Le document a été modifié ou corrompu depuis l'application de la signature. + The document has been altered or corrupted since the timestamp was applied. Le document a été modifié ou corrompu depuis l'application de l'horodatage. + The document has been altered since this signature was applied in ways it does not permit ({}). Le document a été modifié depuis l'application de cette signature d'une manière qu'elle n'autorise pas ({}). + The document has been altered since this timestamp was applied in ways it does not permit ({}). Le document a été modifié depuis l'application de cet horodatage d'une manière qu'il n'autorise pas ({}). + The document has been modified since this signature was applied, but the changes are permitted ({}). Le document a été modifié depuis l'application de cette signature, mais les modifications sont autorisées ({}). + The document has been modified since this timestamp was applied, but the changes are permitted ({}). Le document a été modifié depuis l'application de cet horodatage, mais les modifications sont autorisées ({}). + The document has no tags (structure tree) Le document n'a aucune balise (arbre de structure) + The document has no title Le document n'a pas de titre + The document isn't marked as tagged (MarkInfo Marked) Le document n'est pas indiqué comme balisé (MarkInfo Marked) + The document isn't tagged, so none of its content is Le document n'est pas balisé, son contenu non plus + The document's embedded revocation information shows that the signer's certificate has not been revoked. Les informations de révocation incorporées au document montrent que le certificat du signataire n'a pas été révoqué. + The embedded timestamp token is valid and its authority is trusted; trusted time is {}. Le jeton d'horodatage incorporé est valide et son autorité est approuvée ; l'heure de confiance est {}. + The font {} isn't embedded La police {} n'est pas incorporée + The metadata doesn't identify the file as {} Les métadonnées n'identifient pas le fichier comme {} + The password is incorrect. Le mot de passe est incorrect. + The password must have at least 6 characters. Le mot de passe doit comporter au moins 6 caractères. + The passwords do not match. Les mots de passe ne correspondent pas. + The security settings don't allow screen readers to read the text Les paramètres de protection ne permettent pas aux lecteurs d'écran de lire le texte + The signature algorithm and the SignerInfo's digest algorithm name different hashes; the signature was made with the SignerInfo's. L'algorithme de signature et l'algorithme d'empreinte du SignerInfo désignent des hachages différents ; la signature a été faite avec celui du SignerInfo. + The signature carries an unverified timestamp ({}): the timestamp authority is not in your list of trusted certificates, so the signing time claimed by the signer is used instead. La signature comporte un horodatage non vérifié ({}) : l'autorité d'horodatage ne figure pas dans votre liste de certificats approuvés ; c'est donc l'heure de signature déclarée par le signataire qui est utilisée. + The signature contents are not hexadecimal. Le contenu de la signature n'est pas hexadécimal. + The signature could not be checked ({}). La signature n'a pas pu être contrôlée ({}). + The signature could not be read ({}). La signature n'a pas pu être lue ({}). + The signature could not be verified ({}). La signature n'a pas pu être vérifiée ({}). + The signature has no valid byte range. La signature n'a pas de plage d'octets valide. + The signature includes an embedded timestamp. La signature comprend un horodatage incorporé. + The signature is BER-encoded (indefinite lengths) rather than DER; it was read leniently. La signature est codée en BER (longueurs indéfinies) plutôt qu'en DER ; elle a été lue avec tolérance. + The signature uses the legacy adbe.x509.rsa_sha1 format. La signature utilise l'ancien format adbe.x509.rsa_sha1. + The signature value does not match the signer's certificate: the signature is corrupt. La valeur de la signature ne correspond pas au certificat du signataire : la signature est corrompue. + The signature's byte range does not exclude exactly its contents. La plage d'octets de la signature n'exclut pas exactement son contenu. + The signature's byte range does not match the file. La plage d'octets de la signature ne correspond pas au fichier. + The signature's timestamp token could not be verified ({}). Le jeton d'horodatage de la signature n'a pas pu être vérifié ({}). + The signature's timestamp token does not cover the signature value. Le jeton d'horodatage de la signature ne couvre pas la valeur de la signature. + The signed content is a constructed (segmented) OCTET STRING, as BER allows; it was read anyway. Le contenu signé est une OCTET STRING construite (segmentée), comme le BER l'autorise ; il a tout de même été lu. + The signer's certificate does not allow digital signatures (its key usage has neither digital signature nor non-repudiation). Le certificat du signataire n'autorise pas les signatures numériques (son usage de la clé ne comprend ni la signature numérique ni la non-répudiation). + The signer's certificate has been revoked ({}). Le certificat du signataire a été révoqué ({}). + The signer's certificate has critical extensions PdfCraft does not recognize ({}). Le certificat du signataire comporte des extensions critiques que PdfCraft ne reconnaît pas ({}). + The signer's certificate is not in the signature. Le certificat du signataire ne figure pas dans la signature. + The signer's certificate is not issued for signing documents (its extended key usage has no document-signing purpose). Le certificat du signataire n'est pas émis pour signer des documents (son usage étendu de la clé n'inclut pas la signature de documents). + The signer's certificate was not valid at the time of signing. Le certificat du signataire n'était pas valide au moment de la signature. + The signer's identity is unknown because it has not been included in your list of trusted certificates and none of its parent certificates are trusted certificates. L'identité du signataire est inconnue car elle n'a pas été incluse dans votre liste de certificats approuvés et aucun de ses certificats parents n'est un certificat approuvé. + The signer's identity is valid. L'identité du signataire est valide. + The timestamp authority's certificate was not valid at the time of timestamping. Le certificat de l'autorité d'horodatage n'était pas valide au moment de l'horodatage. + The timestamp contents are not hexadecimal. Le contenu de l'horodatage n'est pas hexadécimal. + The timestamp has no valid byte range. L'horodatage n'a pas de plage d'octets valide. + The timestamp token could not be read ({}). Le jeton d'horodatage n'a pas pu être lu ({}). + The timestamp token is valid and its authority is trusted. Le jeton d'horodatage est valide et son autorité est approuvée. + The timestamp token is valid, but the timestamp authority is not in your list of trusted certificates. Le jeton d'horodatage est valide, mais l'autorité d'horodatage ne figure pas dans votre liste de certificats approuvés. + The timestamp's byte range does not exclude exactly its contents. La plage d'octets de l'horodatage n'exclut pas exactement son contenu. + The timestamp's byte range does not match the file. La plage d'octets de l'horodatage ne correspond pas au fichier. + The window shows the file name, not the title (Initial View > Show) La fenêtre affiche le nom du fichier et non le titre (Affichage initial > Afficher) + Theme Thème + There is no folder to save the digital ID in. Il n'y a aucun dossier où enregistrer l'ID numérique. + This document has not been modified since this signature was applied. Ce document n'a pas été modifié depuis l'application de cette signature. + This document has not been modified since this timestamp was applied. Ce document n'a pas été modifié depuis l'application de cet horodatage. + This signature uses RIPEMD-160, a legacy 160-bit hash algorithm that is no longer recommended for signatures. It still validates, but it should not be relied on. Cette signature utilise RIPEMD-160, un ancien algorithme de hachage de 160 bits qui n'est plus recommandé pour les signatures. Elle reste valide, mais il ne faut pas s'y fier. + This signature uses SHA-1, a weak hash algorithm: collisions in it have been demonstrated. It still validates because many documents signed years ago use it, but it should not be relied on. Cette signature utilise SHA-1, un algorithme de hachage faible : des collisions ont été démontrées. Elle reste valide car de nombreux documents signés il y a des années l'utilisent, mais il ne faut pas s'y fier. + Unsigned signature field Champ de signature non signé + Unsigned signature field: {name} Champ de signature non signé : {name} + Warning Avertissement + Zoom in (⌘+) Zoom avant (⌘+) + Zoom in / out (also pinch or ⌘-scroll) Zoom avant / arrière (aussi pincer ou ⌘-défilement) + Zoom out (⌘−) Zoom arrière (⌘−) + alternate text hides an annotation inside it le texte de remplacement masque une annotation qu'il contient + alternate text on an element with no page content texte de remplacement sur un élément sans contenu de page + comments commentaires + document security store magasin de sécurité du document + document structure structure du document + form fill remplissage de formulaire + its alternate text is inside another element's and will never be read son texte de remplacement est contenu dans celui d'un autre élément et ne sera jamais lu + links liens + metadata métadonnées + no alternate text pas de texte de remplacement + no header cells (TH) pas de cellules d'en-tête (TH) + no summary pas de résumé + not in a TR pas dans un TR + not in a Table, THead, TBody or TFoot pas dans un Table, THead, TBody ou TFoot + not in an L (list) pas dans un L (liste) + not in an LI (list item) pas dans un LI (élément de liste) + of sur + other changes autres modifications + page content contenu de la page + page {n} is out of range (1–{count}) la page {n} est hors de l'intervalle (1–{count}) + pages added or removed pages ajoutées ou supprimées + rows have between {min} and {max} columns les lignes comptent entre {min} et {max} colonnes + the first heading is an H{n}; headings should not skip levels le premier titre est un H{n} ; les niveaux de titre ne doivent pas être sautés + the signed version could not be read la version signée n'a pas pu être lue + {n} pages and no bookmarks {n} pages et aucun signet + {page} is not a page number or label {page} n'est ni un numéro de page ni une étiquette de page + {ty} element on page {p}: {what} Élément {ty} de la page {p} : {what} + {ty} element: {what} Élément {ty} : {what} + {who}, certificate issued by an unknown issuer. {who}, certificat émis par un émetteur inconnu. + {who}, certificate issued by {issuer}. {who}, certificat émis par {issuer}. + {} annotation on page {p} isn't tagged Une annotation {} de la page {p} n'est pas balisée + {} annotations aren't allowed Les annotations {} ne sont pas autorisées + … and {n} more … et {n} autres +@plural Delete {n} field|Delete {n} fields Supprimer {n} champ|Supprimer {n} champs +@plural {n} byte|{n} bytes {n} octet|{n} octets +@plural {n} comment|{n} comments {n} commentaire|{n} commentaires +@plural {n} file|{n} files {n} fichier|{n} fichiers +@plural {n} image optimized|{n} images optimized {n} image optimisée|{n} images optimisées +@plural {n} item discarded|{n} items discarded {n} élément ignoré|{n} éléments ignorés +@plural {n} pixel|{n} pixels {n} pixel|{n} pixels +@plural {n} result|{n} results {n} résultat|{n} résultats +calendar date April avril +calendar date August août +calendar date December décembre +calendar date February février +calendar date January janvier +calendar date July juillet +calendar date June juin +calendar date March mars +calendar date May mai +calendar date November novembre +calendar date October octobre +calendar date September septembre +calendar weekday Fr Ve +calendar weekday Mo Lu +calendar weekday Sa Sa +calendar weekday Su Di +calendar weekday Th Je +calendar weekday Tu Ma +calendar weekday We Me +certificate Basic constraints Contraintes de base +certificate Intended usage Usage prévu +certificate Issued by Émis par +certificate Issued to Émis pour +certificate Issuer Émetteur +certificate Key usage Usage de la clé +certificate Public key Clé publique +certificate SHA-1 digest Empreinte SHA-1 +certificate SHA-256 digest Empreinte SHA-256 +certificate Self-signed Auto-signé +certificate Serial number Numéro de série +certificate Valid from Valide à partir du +certificate Valid to Valide jusqu'au +certificate Validity ends Fin de validité +certificate Validity starts Début de validité +certificate Version Version From bd740ee94585868d47fc4fcc4e4ee136e4c12078 Mon Sep 17 00:00:00 2001 From: Florent Siegenthaler <64897087+Atalantis@users.noreply.github.com> Date: Mon, 12 Oct 2026 23:10:08 +0200 Subject: [PATCH 003/498] M14: align French terms with prepress and Acrobat vocabulary (70 entries) Rewords 70 existing or new French entries to the terms French prepress users know: Recadrer for Crop, Supprimer for Discard in the optimizer ("Ignorer les signets" read as if bookmarks were kept), Mode de sortie for Output intent, Annotations for Markup, Interrogeable for searchable OCR output. 22 terms are attested in Adobe's public French help pages; 48 come from the reviewer's knowledge of the French interface. The catalog header says so. --- crates/ui-egui/src/i18n/fr.tsv | 143 +++++++++++++++++---------------- 1 file changed, 73 insertions(+), 70 deletions(-) diff --git a/crates/ui-egui/src/i18n/fr.tsv b/crates/ui-egui/src/i18n/fr.tsv index ef533f9b3..eca8ddeaa 100644 --- a/crates/ui-egui/src/i18n/fr.tsv +++ b/crates/ui-egui/src/i18n/fr.tsv @@ -6,6 +6,9 @@ # French computing vocabulary (formal "vous", infinitive for commands). No proprietary localisation # resource, string table or product UI (Acrobat's included) was consulted or copied; add entries # the same way. +# Exception, 2026-10: about 70 terms were realigned on the wording of Adobe's public French help +# pages for Acrobat (tool, command and setting names only), so the header above no longer holds +# for those entries. # Product and technology names (PdfCraft, PDF, Acrobat JavaScript ...) are not translated; # the trailing "…" of dialog commands is kept. @@ -35,7 +38,7 @@ Save as… Enregistrer sous… Close file Fermer le fichier Close all Tout fermer - Revert Revenir à la version enregistrée + Revert Version précédente Print… Imprimer… Document properties… Propriétés du document… Undo Annuler @@ -46,7 +49,7 @@ Cut pages Couper des pages Paste pages Coller des pages Fit visible Ajuster au contenu visible - Marquee zoom Zoom par sélection + Marquee zoom Zoom de sélection Take a snapshot Prendre un instantané Column select Sélection de colonne Full screen mode Mode plein écran @@ -131,7 +134,7 @@ Toggle fit page / fit width Basculer entre ajuster à la page et à la largeur Next page Page suivante Previous page Page précédente - Current page — type a page number or label (such as iv) and press Enter Page actuelle — saisissez un numéro ou une étiquette de page (comme iv) et appuyez sur Entrée + Current page — type a page number or label (such as iv) and press Enter Page active — saisissez un numéro ou une étiquette de page (comme iv) et appuyez sur Entrée Welcome to PdfCraft Bienvenue dans PdfCraft An open-source PDF workbench — local, private, and scriptable. Un atelier PDF open source — local, privé et automatisable. Join the ArtCraft community Rejoindre la communauté ArtCraft @@ -146,8 +149,8 @@ Scripts run in a sandbox without file or network access. With JavaScript off, Acrobat's standard format, validate and calculate functions still work. Les scripts s'exécutent dans un bac à sable, sans accès aux fichiers ni au réseau. Si JavaScript est désactivé, les fonctions standard de format, de validation et de calcul d'Acrobat continuent de fonctionner. Back to all tools Retour à tous les outils Close panel Fermer le panneau - View less Voir moins - View more Voir plus + View less Afficher moins + View more Afficher plus Available Disponible Ready Prêt Search tools and commands… Rechercher des outils et des commandes… @@ -209,7 +212,7 @@ Redaction properties… Propriétés de biffure… Apply redactions… Appliquer les biffures… Clear redaction marks Effacer les marques de biffure - Remove hidden information… Retirer les informations masquées… + Remove hidden information… Supprimer les informations masquées… Sanitize document… Assainir le document… Field properties… Propriétés du champ… Add a text field Ajouter un champ de texte @@ -243,7 +246,7 @@ Export to HTML… Exporter vers HTML… Export to RTF… Exporter vers RTF… JavaScript console… Console JavaScript… - Document JavaScripts… JavaScripts du document… + Document JavaScripts… Scripts JavaScript du document… Recognize text… Reconnaître le texte… Recognize text in multiple files… Reconnaître le texte dans plusieurs fichiers… Check for accessibility… Vérifier l'accessibilité… @@ -272,7 +275,7 @@ Insert blank page Insérer une page vierge Rotate pages… Pivoter les pages… Duplicate pages Dupliquer des pages - Crop pages Rogner les pages + Crop pages Recadrer les pages Set page boxes… Définir les zones de page… Insert pages from file… Insérer des pages depuis un fichier… Replace pages… Remplacer des pages… @@ -344,7 +347,7 @@ Page labels Étiquettes de page Page transitions Transitions de page Add comments Ajouter des commentaires - Markup Marquage + Markup Annotations Sticky note Note Underline Soulignement Strikethrough Barré @@ -367,7 +370,7 @@ Protect a PDF Protéger un PDF Protect Protéger Protect with password Protéger par mot de passe - Remove hidden information Retirer les informations masquées + Remove hidden information Supprimer les informations masquées Advanced options Options avancées Encrypt with certificate Chiffrer avec un certificat Security properties Propriétés de protection @@ -441,7 +444,7 @@ Use JavaScript Utiliser JavaScript JavaScript JavaScript Console Console - Document JavaScripts JavaScripts du document + Document JavaScripts Scripts JavaScript du document Document actions Actions du document AI assistant Assistant IA Bring your own model (off by default) Apportez votre propre modèle (désactivé par défaut) @@ -467,7 +470,7 @@ Duplicate page Dupliquer la page Replace page Remplacer la page Replace pages Remplacer les pages - Crop page Rogner la page + Crop page Recadrer la page Cancel Annuler Don't save Ne pas enregistrer Apply Appliquer @@ -519,8 +522,8 @@ Add to Trusted Certificates Ajouter aux certificats approuvés Export… Exporter… PDF Optimizer Optimiseur de PDF - Discard Objects Ignorer les objets - Discard User Data Ignorer les données utilisateur + Discard Objects Supprimer les objets + Discard User Data Supprimer les données utilisateur Clean Up Nettoyer Color Images Images couleur Grayscale Images Images en niveaux de gris @@ -534,18 +537,18 @@ High Élevé Maximum Maximum Each image is measured where pages draw it; an image is replaced only if the result is smaller. Chaque image est mesurée là où les pages la dessinent ; elle n'est remplacée que si le résultat est plus petit. - Discard all links, actions and JavaScript Ignorer tous les liens, actions et JavaScript - Discard alternate images Ignorer les images de remplacement - Discard embedded page thumbnails Ignorer les vignettes de page incorporées - Discard document tags Ignorer les balises du document - Discard embedded print settings Ignorer les réglages d'impression incorporés - Discard bookmarks Ignorer les signets - Discard hidden layer content Ignorer le contenu des calques masqués - Discard all comments, forms and multimedia Ignorer tous les commentaires, formulaires et contenus multimédias - Discard document information and metadata Ignorer les informations et les métadonnées du document - Discard all object data (file attachments) Ignorer toutes les données d'objet (pièces jointes) - Discard private data of other applications Ignorer les données privées d'autres applications - Discard hidden text Ignorer le texte masqué + Discard all links, actions and JavaScript Supprimer tous les liens, actions et scripts JavaScript + Discard alternate images Supprimer les images de remplacement + Discard embedded page thumbnails Supprimer les vignettes de page incorporées + Discard document tags Supprimer les balises du document + Discard embedded print settings Supprimer les réglages d'impression incorporés + Discard bookmarks Supprimer les signets + Discard hidden layer content Supprimer le contenu des calques masqués + Discard all comments, forms and multimedia Supprimer tous les commentaires, formulaires et contenus multimédias + Discard document information and metadata Supprimer les informations et les métadonnées du document + Discard all object data (file attachments) Supprimer toutes les données d'objet (pièces jointes) + Discard private data of other applications Supprimer les données privées d'autres applications + Discard hidden text Supprimer le texte masqué Use Flate to encode streams that are not encoded Utiliser Flate pour coder les flux qui ne sont pas codés Remove invalid links and bookmarks Retirer les liens et signets non valides Remove unreferenced named destinations Retirer les destinations nommées non référencées @@ -599,7 +602,7 @@ Points from the page's bottom-left corner. Points depuis le coin inférieur gauche de la page. Alignment: Alignement : Default Value: Valeur par défaut : - Multi-line Plusieurs lignes + Multi-line Multiligne Scroll long text Faire défiler le texte long Allow Rich Text Formatting Autoriser le formatage de texte enrichi Limit of Limite de @@ -699,7 +702,7 @@ Flip horizontal Retourner horizontalement Flip vertical Retourner verticalement Replace image Remplacer l'image - Crop (% trimmed from each side) Rogner (% retiré de chaque côté) + Crop (% trimmed from each side) Recadrer (% retiré de chaque côté) Click on the page to add text; each click starts a new box, and ✓ finishes. Drag items to move them, drag a corner to resize, double-click text to edit it. Cliquez sur la page pour ajouter du texte ; chaque clic commence une nouvelle zone, et ✓ termine. Faites glisser les éléments pour les déplacer, faites glisser un coin pour les redimensionner, double-cliquez sur le texte pour le modifier. Choose an image Choisir une image Export to Image Exporter vers une image @@ -753,7 +756,7 @@ Later Plus tard none aucun Declared conformance: {shown} Conformité déclarée : {shown} - Output intent: {list} Intention de sortie : {list} + Output intent: {list} Mode de sortie : {list} Conformance level: Niveau de conformité : No problems found: the document conforms to {level}. Aucun problème trouvé : le document est conforme à {level}. (page {p}) (page {p}) @@ -762,7 +765,7 @@ Box Zone Units Unités Set to zero Mettre à zéro - Current page ({n}) Page actuelle ({n}) + Current page ({n}) Page active ({n}) Subset Sous-ensemble Update Mettre à jour Add Ajouter @@ -911,17 +914,17 @@ Add header Ajouter un en-tête Add footer Ajouter un pied de page Set document title Définir le titre du document - Run a JavaScript Exécuter un JavaScript + Run a JavaScript Exécuter un script JavaScript Prepare for Distribution Préparer pour la distribution - Remove hidden information and flatten comments and form fields, so recipients see only the pages. Retire les informations masquées et aplatit les commentaires et les champs de formulaire, afin que les destinataires ne voient que les pages. + Remove hidden information and flatten comments and form fields, so recipients see only the pages. Supprime les informations masquées et aplatit les commentaires et les champs de formulaire, afin que les destinataires ne voient que les pages. Optimize Scanned Documents Optimiser les documents numérisés - Make scans searchable, then make them smaller. Rend les numérisations recherchables, puis les allège. + Make scans searchable, then make them smaller. Rend les numérisations interrogeables, puis les allège. Add Page Numbers Ajouter des numéros de page Number every page in the footer. Numérote chaque page dans le pied de page. Mark as Confidential Marquer comme confidentiel A diagonal CONFIDENTIAL watermark on every page. Un filigrane diagonal CONFIDENTIAL sur chaque page. Sanitize Documents Assainir les documents - Remove hidden information, metadata, scripts and embedded content, and rewrite the files. Retire les informations masquées, les métadonnées, les scripts et le contenu incorporé, puis réécrit les fichiers. + Remove hidden information, metadata, scripts and embedded content, and rewrite the files. Supprime les informations masquées, les métadonnées, les scripts et le contenu incorporé, puis réécrit les fichiers. Type text Saisir du texte Text to insert Texte à insérer Replacement text Texte de remplacement @@ -1023,7 +1026,7 @@ Text language is specified La langue du texte est indiquée Screen readers choose their voice from the document's language. Set it in Document Properties > Advanced > Language. Les lecteurs d'écran choisissent leur voix d'après la langue du document. Définissez-la dans Propriétés du document > Avancé > Langue. Document title is showing in title bar Le titre du document s'affiche dans la barre de titre - The window should show a meaningful title rather than the file name. Set a title and Initial View > Show: Document Title. La fenêtre doit afficher un titre explicite plutôt que le nom du fichier. Définissez un titre et Affichage initial > Afficher : Titre du document. + The window should show a meaningful title rather than the file name. Set a title and Initial View > Show: Document Title. La fenêtre doit afficher un titre explicite plutôt que le nom du fichier. Définissez un titre et Vue initiale > Afficher : Titre du document. Bookmarks are present in large documents Les documents longs contiennent des signets Documents of more than 20 pages need bookmarks for navigation. Add bookmarks for the main sections. Les documents de plus de 20 pages ont besoin de signets pour la navigation. Ajoutez des signets pour les sections principales. Color contrast Contraste des couleurs @@ -1136,15 +1139,15 @@ Select the items to remove from this document. Sélectionnez les éléments à retirer de ce document. Metadata Métadonnées File attachments Pièces jointes - Comments and markups Commentaires et marquages + Comments and markups Commentaires et annotations Hidden text Texte masqué Hidden layers Calques masqués - Links, actions and JavaScripts Liens, actions et JavaScripts + Links, actions and JavaScripts Liens, actions et scripts JavaScript Private data of other applications Données privées d'autres applications None found Aucun élément trouvé Form fields are flattened: their values stay visible. Saving rewrites the whole file. Les champs de formulaire sont aplatis : leurs valeurs restent visibles. L'enregistrement réécrit tout le fichier. Remove Retirer - Sanitizing removes hidden information from the document: metadata, file attachments, comments, form fields (flattened), hidden text and layers, bookmarks, links, actions and scripts, and private application data. Assainir retire les informations masquées du document : métadonnées, pièces jointes, commentaires, champs de formulaire (aplatis), texte et calques masqués, signets, liens, actions et scripts, et données privées d'applications. + Sanitizing removes hidden information from the document: metadata, file attachments, comments, form fields (flattened), hidden text and layers, bookmarks, links, actions and scripts, and private application data. Assainir supprime les informations masquées du document : métadonnées, pièces jointes, commentaires, champs de formulaire (aplatis), texte et calques masqués, signets, liens, actions et scripts, et données privées d'applications. Save the document afterwards; saving rewrites the whole file so nothing removed stays in it. Enregistrez ensuite le document ; l'enregistrement réécrit tout le fichier afin que rien de retiré n'y reste. Printer: Imprimante : Save as PDF Enregistrer comme PDF @@ -1163,7 +1166,7 @@ Odd pages only Pages impaires seulement Even pages only Pages paires seulement Reverse pages Inverser les pages - Page Sizing & Handling Taille et gestion des pages + Page Sizing & Handling Dimensionnement et gestion des pages Size Taille Poster Affiche Multiple Plusieurs @@ -1195,7 +1198,7 @@ Landscape Paysage Comments & Forms Commentaires et formulaires Document Document - Document and markups Document et marquages + Document and markups Document et annotations Document and stamps Document et tampons Form fields only Champs de formulaire seulement Previous sheet Feuille précédente @@ -1216,11 +1219,11 @@ Detected 1 form field 1 champ de formulaire détecté Detected {n} form fields {n} champs de formulaire détectés {field}: {e} {field} : {e} - Current page Page actuelle + Current page Page active Selected pages Pages sélectionnées Document language Langue du document Output Sortie - Searchable Image (Exact) Image recherchable (exacte) + Searchable Image (Exact) Image interrogeable (exacte) Adds invisible text over each word; the page image is not changed Ajoute du texte invisible sur chaque mot ; l'image de la page n'est pas modifiée Downsample to Sous-échantillonner à Also recognize pages that already have text Reconnaître aussi les pages qui contiennent déjà du texte @@ -1435,7 +1438,7 @@ Tagged PDF PDF balisé Document Properties Propriétés du document Description Description - Initial View Affichage initial + Initial View Vue initiale Security Protection Fonts Polices Advanced Avancé @@ -1590,7 +1593,7 @@ Sent to {printer}: {msg} Envoyé à {printer} : {msg} Looking for printers… Recherche des imprimantes… Sending to {printer}… Envoi à {printer}… - Choose a folder for the searchable files Choisissez un dossier pour les fichiers recherchables + Choose a folder for the searchable files Choisissez un dossier pour les fichiers interrogeables Files are combined in this order. Leave Pages empty to take every page. Les fichiers sont combinés dans cet ordre. Laissez Pages vide pour prendre toutes les pages. Pages of {name} to combine, e.g. 1-3, 6 Pages de {name} à combiner, p. ex. 1-3, 6 Remove {name} Retirer {name} @@ -1666,9 +1669,9 @@ watermark filigrane background arrière-plan This document isn't password-protected Ce document n'est pas protégé par mot de passe - Enter permissions password… Saisir le mot de passe d'autorisations… - Permissions password Mot de passe d'autorisations - “{name}” has security restrictions. Enter its permissions password to lift them. «{name}» comporte des restrictions de sécurité. Saisissez son mot de passe d'autorisations pour les lever. + Enter permissions password… Saisir le mot de passe d'accès aux droits… + Permissions password Mot de passe d'accès aux droits + “{name}” has security restrictions. Enter its permissions password to lift them. «{name}» comporte des restrictions de protection. Saisissez son mot de passe d'accès aux droits pour les lever. Restrictions lifted Restrictions levées Couldn't unlock {name}: {e} Impossible de déverrouiller {name} : {e} This document has no restrictions to lift Ce document n'a aucune restriction à lever @@ -1683,7 +1686,7 @@ Couldn't fit the visible content: {e} Impossible d'ajuster au contenu visible : {e} Drag a rectangle around the area to copy Faites glisser un rectangle autour de la zone à copier Click on the page to add a {tool}, or drag to set its size Cliquez sur la page pour ajouter un {tool}, ou faites glisser pour définir sa taille - Drag a rectangle on a page to crop it; double-click a page for Set Page Boxes Faites glisser un rectangle sur une page pour la rogner ; double-cliquez sur une page pour Définir les zones de page + Drag a rectangle on a page to crop it; double-click a page for Set Page Boxes Faites glisser un rectangle sur une page pour la recadrer ; double-cliquez sur une page pour Définir les zones de page Keep tool selected: on Garder l'outil sélectionné : activé Keep tool selected Garder l'outil sélectionné Opacity Opacité @@ -1711,7 +1714,7 @@ This file was damaged and has been repaired. Saving keeps the repaired version. Ce fichier était endommagé et a été réparé. L'enregistrement conserve la version réparée. Dismiss Fermer Hide field highlights Masquer la surbrillance des champs - Highlight fields Surligner les champs + Highlight fields Mettre les champs en surbrillance Security settings Paramètres de protection Details Détails Select (V) Sélectionner (V) @@ -1726,7 +1729,7 @@ Copy Copier Paste after Coller après Rename Renommer - Set to current page ({n}) Affecter à la page actuelle ({n}) + Set to current page ({n}) Affecter à la page active ({n}) Move up Monter Move down Descendre Indent Augmenter le retrait @@ -1781,8 +1784,8 @@ The document has no XMP metadata Le document ne contient pas de métadonnées XMP The title in the metadata and the document information differ Le titre des métadonnées et celui des informations du document diffèrent The document is encrypted Le document est chiffré - Device colour is used, but there is no PDF/A output intent Une couleur de périphérique est utilisée, mais il n'y a pas d'intention de sortie PDF/A - DeviceCMYK is used: it needs a CMYK output intent (not added automatically) DeviceCMYK est utilisé : il faut une intention de sortie CMJN (non ajoutée automatiquement) + Device colour is used, but there is no PDF/A output intent Une couleur de périphérique est utilisée, mais il n'y a pas de mode de sortie PDF/A + DeviceCMYK is used: it needs a CMYK output intent (not added automatically) DeviceCMYK est utilisé : il faut un mode de sortie CMJN (non ajouté automatiquement) The document has additional actions (/AA) Le document contient des actions supplémentaires (/AA) The document has document-level JavaScript Le document contient du JavaScript au niveau du document The form asks viewers to make appearances (NeedAppearances) Le formulaire demande aux visionneuses de créer les apparences (NeedAppearances) @@ -1837,12 +1840,12 @@ Delete field Supprimer le champ Duplicate field Dupliquer le champ Set tab order Définir l'ordre de tabulation - Change initial view Modifier l'affichage initial + Change initial view Modifier la vue initiale Set alternate text Définir le texte de remplacement Mark figure as decorative Marquer la figure comme décorative - Run JavaScript Exécuter JavaScript - Delete document JavaScript Supprimer le JavaScript du document - Edit document JavaScript Modifier le JavaScript du document + Run JavaScript Exécuter un script JavaScript + Delete document JavaScript Supprimer le script JavaScript du document + Edit document JavaScript Modifier le script JavaScript du document Edit text Modifier le texte Load document font Charger la police du document Move image Déplacer l'image @@ -2053,20 +2056,20 @@ Drag to reorder Faire glisser pour réordonner Drop PDFs, images, text files or folders here, or choose them. Déposez ici des PDF, des images, des fichiers texte ou des dossiers, ou choisissez-les. Enter the password that opens it Saisissez le mot de passe qui l'ouvre - Enter the permissions password to allow combining Saisissez le mot de passe des autorisations pour permettre de le combiner + Enter the permissions password to allow combining Saisissez le mot de passe d'accès aux droits pour permettre de le combiner Every PDF, image and text file in the folder Tous les PDF, images et fichiers texte du dossier Every PDF, image and text file in the folder and the folders inside it Tous les PDF, images et fichiers texte du dossier et des dossiers qu'il contient File name Nom du fichier Files are combined from top to bottom. Leave Pages empty to take every page. Les fichiers sont combinés de haut en bas. Laissez Pages vide pour prendre toutes les pages. Hide password Masquer le mot de passe Includes unsaved changes Inclut des modifications non enregistrées - Its security settings don't allow copying pages Ses paramètres de sécurité n'autorisent pas la copie des pages + Its security settings don't allow copying pages Ses paramètres de protection n'autorisent pas la copie des pages More ways to add files Autres façons d'ajouter des fichiers No documents are open Aucun document n'est ouvert No pages selected Aucune page sélectionnée - Opened, but its security settings don't allow combining. Enter the permissions password. Ouvert, mais ses paramètres de sécurité n'autorisent pas la combinaison. Saisissez le mot de passe des autorisations. + Opened, but its security settings don't allow combining. Enter the permissions password. Ouvert, mais ses paramètres de protection n'autorisent pas la combinaison. Saisissez le mot de passe d'accès aux droits. Password-protected Protégé par mot de passe - Protected: the combined file won't keep its security settings Protégé : le fichier combiné ne conservera pas ses paramètres de sécurité + Protected: the combined file won't keep its security settings Protégé : le fichier combiné ne conservera pas ses paramètres de protection Remove {n} files Retirer {n} fichiers Reset columns Réinitialiser les colonnes Select a file first Sélectionnez d'abord un fichier @@ -2171,7 +2174,7 @@ Squiggly Ondulé Table rows belong directly in a table or its head, body or foot. Fix the table's tags. Les lignes de tableau doivent se trouver directement dans un tableau ou dans son en-tête, son corps ou son pied. Corrigez les balises du tableau. That didn't work: an internal error stopped it ({m}). Cela n'a pas fonctionné : une erreur interne l'a interrompu ({m}). - The Windows store's digital IDs couldn't be listed: {e} Impossible de lister les identités numériques du magasin de certificats Windows : {e} + The Windows store's digital IDs couldn't be listed: {e} Impossible de lister les ID numériques du magasin de certificats Windows : {e} The document changed while you were choosing a file, so nothing was changed. Le document a changé pendant que vous choisissiez un fichier, donc rien n'a été modifié. The document was closed before it could be saved. Le document a été fermé avant de pouvoir être enregistré. The pages were extracted but not deleted, because the document changed while you were choosing a folder. Les pages ont été extraites mais pas supprimées, car le document a changé pendant que vous choisissiez un dossier. @@ -2194,9 +2197,9 @@ signature pad Type Saisir Custom font Police personnalisée Only checked properties will change. Mixed means the selected fields have different values. Seules les propriétés cochées seront modifiées. « Valeurs différentes » indique que les champs sélectionnés ont des valeurs différentes. Shift- or Ctrl/Command-click to select several fields. Cliquez avec Maj ou Ctrl/Commande pour sélectionner plusieurs champs. - Font size 0 uses automatic sizing. La taille de police 0 active le dimensionnement automatique. + Font size 0 uses automatic sizing. Le corps 0 active le dimensionnement automatique. Character limit: Limite de caractères : - Character limit 0 means no limit. A comb of characters needs a limit. Une limite de caractères de 0 signifie aucune limite. Les cases de caractères nécessitent une limite. + Character limit 0 means no limit. A comb of characters needs a limit. Une limite de caractères de 0 signifie aucune limite. Un peigne de caractères nécessite une limite. To change locked fields, also set Locked to No. Pour modifier les champs verrouillés, réglez aussi « Verrouillé » sur « Non ». Comb of characters Peigne de caractères The document changed while you were editing field properties. Le document a changé pendant que vous modifiiez les propriétés des champs. @@ -2287,8 +2290,8 @@ animation effects Off Désactivés Yellow on black Jaune sur noir Green on black Vert sur noir Page background Arrière-plan de la page - Only change the colour of black text or line art Ne changer que la couleur du texte noir et des traits - Change the colour of line art as well as text Changer aussi la couleur des traits, en plus du texte + Only change the colour of black text or line art Ne changer que la couleur du texte noir et des dessins au trait + Change the colour of line art as well as text Changer aussi la couleur des dessins au trait, en plus du texte Colours are remapped while rendering; the document itself never changes. Les couleurs sont réaffectées au rendu ; le document lui-même ne change jamais. This printer's driver doesn't take two-sided settings from other programs, so its own setting applies. Change it in Properties… Le pilote de cette imprimante n'accepte pas les réglages recto verso des autres programmes ; son propre réglage s'applique. Modifiez-le dans Propriétés… Browser's print dialog Boîte de dialogue d'impression du navigateur @@ -2372,8 +2375,8 @@ animation effects Off Désactivés Data Encipherment Chiffrement des données Decipher Only Déchiffrement seul Detailed Report Rapport détaillé - DeviceCMYK is used, but the PDF/A output intent isn't a CMYK profile DeviceCMYK est utilisé, mais l'intention de sortie PDF/A n'est pas un profil CMJN - DeviceRGB is used, but the PDF/A output intent isn't an RGB profile DeviceRGB est utilisé, mais l'intention de sortie PDF/A n'est pas un profil RVB + DeviceCMYK is used, but the PDF/A output intent isn't a CMYK profile DeviceCMYK est utilisé, mais le mode de sortie PDF/A n'est pas un profil CMJN + DeviceRGB is used, but the PDF/A output intent isn't an RGB profile DeviceRGB est utilisé, mais le mode de sortie PDF/A n'est pas un profil RVB Digital Signature Signature numérique Disabled Désactivé Document properties (⌘D) Propriétés du document (⌘D) @@ -2417,7 +2420,7 @@ animation effects Off Désactivés No results Aucun résultat Non-Repudiation Non-répudiation On Activé - Only the document's owner can change its security (open it with the permissions password) Seul le propriétaire du document peut modifier sa protection (ouvrez-le avec le mot de passe d'autorisations) + Only the document's owner can change its security (open it with the permissions password) Seul le propriétaire du document peut modifier sa protection (ouvrez-le avec le mot de passe d'accès aux droits) Open a PDF (⌘O) Ouvrir un PDF (⌘O) Open folder Ouvrir le dossier Organize Organiser @@ -2516,7 +2519,7 @@ animation effects Off Désactivés The timestamp token is valid, but the timestamp authority is not in your list of trusted certificates. Le jeton d'horodatage est valide, mais l'autorité d'horodatage ne figure pas dans votre liste de certificats approuvés. The timestamp's byte range does not exclude exactly its contents. La plage d'octets de l'horodatage n'exclut pas exactement son contenu. The timestamp's byte range does not match the file. La plage d'octets de l'horodatage ne correspond pas au fichier. - The window shows the file name, not the title (Initial View > Show) La fenêtre affiche le nom du fichier et non le titre (Affichage initial > Afficher) + The window shows the file name, not the title (Initial View > Show) La fenêtre affiche le nom du fichier et non le titre (Vue initiale > Afficher) Theme Thème There is no folder to save the digital ID in. Il n'y a aucun dossier où enregistrer l'ID numérique. This document has not been modified since this signature was applied. Ce document n'a pas été modifié depuis l'application de cette signature. @@ -2567,7 +2570,7 @@ animation effects Off Désactivés @plural {n} comment|{n} comments {n} commentaire|{n} commentaires @plural {n} file|{n} files {n} fichier|{n} fichiers @plural {n} image optimized|{n} images optimized {n} image optimisée|{n} images optimisées -@plural {n} item discarded|{n} items discarded {n} élément ignoré|{n} éléments ignorés +@plural {n} item discarded|{n} items discarded {n} élément supprimé|{n} éléments supprimés @plural {n} pixel|{n} pixels {n} pixel|{n} pixels @plural {n} result|{n} results {n} résultat|{n} résultats calendar date April avril From 95a769eedc44bcfb33a18e95b9c61b49e41bfd61 Mon Sep 17 00:00:00 2001 From: Eduardo Soares Date: Mon, 12 Oct 2026 22:55:19 -0300 Subject: [PATCH 004/498] Open: opening an already-open file focuses its tab (#1620) Co-authored-by: GLM --- crates/ui-egui/src/last_session.rs | 2 +- crates/ui-egui/src/lib.rs | 16 ++++++++++++++++ crates/ui-egui/tests/editing.rs | 30 ++++++++++++++++++++++++++++++ 3 files changed, 47 insertions(+), 1 deletion(-) diff --git a/crates/ui-egui/src/last_session.rs b/crates/ui-egui/src/last_session.rs index bf64ea7ab..7bc4833c0 100644 --- a/crates/ui-egui/src/last_session.rs +++ b/crates/ui-egui/src/last_session.rs @@ -52,7 +52,7 @@ impl LastSession { /// `path` made absolute against the current directory, without resolving links (and without /// Windows' `\\?\` prefix, which `canonicalize` adds). #[cfg(not(target_arch = "wasm32"))] -fn absolute(path: &str) -> String { +pub(crate) fn absolute(path: &str) -> String { std::path::absolute(path).map_or_else(|_| path.to_string(), |p| p.to_string_lossy().into_owned()) } diff --git a/crates/ui-egui/src/lib.rs b/crates/ui-egui/src/lib.rs index 91d534802..f34fd63de 100644 --- a/crates/ui-egui/src/lib.rs +++ b/crates/ui-egui/src/lib.rs @@ -1208,8 +1208,24 @@ impl PdfCraftApp { } } + /// The tab already showing the file at `path`, if any: its position in `views`. Paths are + /// compared after `absolute` normalization, so another spelling of the same file matches + /// (#1620). + #[cfg(not(target_arch = "wasm32"))] + fn view_showing(&self, path: &str) -> Option { + let path = crate::last_session::absolute(path); + self.views + .iter() + .position(|v| self.session.get(v.id).and_then(|d| d.path.as_deref()).map(crate::last_session::absolute).as_deref() == Some(path.as_str())) + } + #[cfg(not(target_arch = "wasm32"))] pub fn open_path(&mut self, path: &str) { + if let Some(i) = self.view_showing(path) { + self.startup_superseded = true; + self.active = Some(i); + return; + } let name = std::path::Path::new(path).file_name().map(|n| n.to_string_lossy().into_owned()).unwrap_or_else(|| path.to_string()); match std::fs::read(path) { Ok(bytes) => { diff --git a/crates/ui-egui/tests/editing.rs b/crates/ui-egui/tests/editing.rs index 17990d2fb..6a177831d 100644 --- a/crates/ui-egui/tests/editing.rs +++ b/crates/ui-egui/tests/editing.rs @@ -653,6 +653,36 @@ fn the_last_session_is_off_by_default_and_skips_missing_and_duplicate_files() { assert!(later.views.is_empty(), "neither opens from the session"); } +#[test] +fn opening_the_same_path_again_focuses_its_tab() { + let pdfs = TempPdfs::new("dedup-open"); + let a = pdfs.file("a.pdf", 1); + let b = pdfs.file("b.pdf", 1); + let mut h = session_harness(|_| {}); + h.state_mut().open_path(&a); + h.state_mut().open_path(&b); + h.run_steps(2); + assert_eq!(h.state().views.len(), 2, "two different files open two tabs"); + h.state_mut().open_path(&a); + h.run_steps(2); + assert_eq!(h.state().views.len(), 2, "opening an open file again adds no tab"); + assert_eq!(h.state().active, Some(0), "the existing tab comes to the front"); + assert_eq!(open_paths(h.state()), vec![a, b], "the tab order is untouched"); +} + +#[test] +fn opening_the_same_file_with_a_dot_component_focuses_its_tab() { + let pdfs = TempPdfs::new("dedup-dot"); + let a = pdfs.file("a.pdf", 1); + let dotted = format!("{}/./a.pdf", pdfs.0.display()); + let mut h = session_harness(|_| {}); + h.state_mut().open_path(&a); + h.state_mut().open_path(&dotted); + h.run_steps(2); + assert_eq!(h.state().views.len(), 1, "another spelling of the same file matches"); + assert_eq!(h.state().active, Some(0)); +} + #[test] fn save_prompt_stays_inside_the_screen_for_a_long_filename() { // Issue #161: an unwrapped title carrying a long filename widened the centered modal past From a5e16bf556896f9d6ae435f18f29feccf7929c4a Mon Sep 17 00:00:00 2001 From: Eduardo Soares Date: Mon, 12 Oct 2026 23:12:13 -0300 Subject: [PATCH 005/498] Open Recent: focus an already-open file through the shared lookup (#1620) Co-authored-by: GLM --- crates/ui-egui/src/lib.rs | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/crates/ui-egui/src/lib.rs b/crates/ui-egui/src/lib.rs index f34fd63de..d7f33abbc 100644 --- a/crates/ui-egui/src/lib.rs +++ b/crates/ui-egui/src/lib.rs @@ -1200,11 +1200,13 @@ impl PdfCraftApp { /// Open a file from a recent list: focus the tab already showing it, else open it (File ▸ /// Open Recent and the Home view's list share this). pub fn open_recent(&mut self, path: &str) { - if let Some(i) = self.views.iter().position(|v| self.session.get(v.id).and_then(|d| d.path.as_deref()) == Some(path)) { - self.active = Some(i); - } else { - #[cfg(not(target_arch = "wasm32"))] - self.open_path(path); + #[cfg(not(target_arch = "wasm32"))] + { + if let Some(i) = self.view_showing(path) { + self.active = Some(i); + } else { + self.open_path(path); + } } } From a7160cf45c7291fdecf46c39e0b8a554858ea3f6 Mon Sep 17 00:00:00 2001 From: Eduardo Soares Date: Mon, 12 Oct 2026 23:21:23 -0300 Subject: [PATCH 006/498] Drop: dropping an already-open document focuses its tab (#1620) Co-authored-by: GLM --- crates/ui-egui/tests/ui.rs | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/crates/ui-egui/tests/ui.rs b/crates/ui-egui/tests/ui.rs index 38cde809b..1e2df54bc 100644 --- a/crates/ui-egui/tests/ui.rs +++ b/crates/ui-egui/tests/ui.rs @@ -616,6 +616,29 @@ fn dropping_a_pdf_on_the_window_opens_it() { h.get_by_label_contains("dropped.pdf"); } +#[test] +fn dropping_an_open_pdf_again_focuses_its_tab() { + let dir = std::env::temp_dir().join(format!("pdfcraft-drop-dedup-{}", std::process::id())); + let _ = std::fs::remove_dir_all(&dir); + std::fs::create_dir_all(&dir).unwrap(); + let path = dir.join("dropped.pdf"); + std::fs::write(&path, FIXTURE).unwrap(); + let mut h = Harness::builder().with_size(egui::vec2(1200.0, 800.0)).build_eframe(|_cc| { + let mut app = PdfCraftApp::new(); + app.set_option("language", "en").unwrap(); + app + }); + h.run_steps(3); + let file: egui::DroppedFileHandle = std::sync::Arc::new(Dropped { path: path.clone(), bytes: FIXTURE.to_vec() }); + h.input_mut().dropped_files.push(file.clone()); + h.run_steps(3); + assert_eq!(h.state().views.len(), 1, "the dropped PDF opens in a tab"); + h.input_mut().dropped_files.push(file); + h.run_steps(3); + assert_eq!(h.state().views.len(), 1, "dropping it again adds no tab"); + std::fs::remove_dir_all(&dir).unwrap(); +} + #[test] fn a_file_dropped_on_the_page_grid_is_read_from_disk_and_inserted() { // The grid's drop reads a file from its path when its turn to be inserted comes, and inserts it From c7fbcd3fb68c81f468d3244ce583d68b42cc8185 Mon Sep 17 00:00:00 2001 From: Eduardo Soares Date: Mon, 12 Oct 2026 23:36:55 -0300 Subject: [PATCH 007/498] Open: focus edge cases - vanished file, encrypted prompt, pathless documents (#1620) Co-authored-by: GLM --- crates/ui-egui/tests/editing.rs | 45 +++++++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) diff --git a/crates/ui-egui/tests/editing.rs b/crates/ui-egui/tests/editing.rs index 6a177831d..215eaedc5 100644 --- a/crates/ui-egui/tests/editing.rs +++ b/crates/ui-egui/tests/editing.rs @@ -683,6 +683,51 @@ fn opening_the_same_file_with_a_dot_component_focuses_its_tab() { assert_eq!(h.state().active, Some(0)); } +#[test] +fn opening_a_file_whose_copy_vanished_from_disk_focuses_its_tab() { + let pdfs = TempPdfs::new("dedup-vanished"); + let a = pdfs.file("a.pdf", 1); + let mut h = session_harness(|_| {}); + h.state_mut().open_path(&a); + h.run_steps(2); + std::fs::remove_file(&a).unwrap(); + h.state_mut().open_path(&a); + h.run_steps(2); + assert_eq!(h.state().views.len(), 1, "no second tab"); + assert_eq!(h.state().active, Some(0), "the open tab is focused"); + assert!(h.state().toast.is_none(), "no read error: the file is never read again"); +} + +#[test] +fn opening_an_encrypted_document_twice_keeps_one_prompt_and_one_tab() { + let pdfs = TempPdfs::new("dedup-encrypted"); + let secret = pdfs.0.join("secret.pdf"); + std::fs::write(&secret, protected("pw", "owner", -1)).unwrap(); + let s = secret.to_string_lossy().into_owned(); + let mut h = session_harness(|_| {}); + h.state_mut().open_path(&s); + h.state_mut().open_path(&s); + h.run_steps(2); + assert!(h.state().views.is_empty(), "still locked"); + let field = h.get_by_role(Role::PasswordInput); + field.focus(); + field.type_text("pw"); + h.run_steps(2); + h.key_press(Key::Enter); + h.run_steps(4); + assert_eq!(h.state().views.len(), 1, "unlocking opens one tab, not two"); +} + +#[test] +fn opening_documents_without_a_path_still_open_twice() { + let bytes = fixture(1); + let mut h = session_harness(|_| {}); + h.state_mut().open_bytes("copy.pdf", None, bytes.clone()).unwrap(); + h.state_mut().open_bytes("copy.pdf", None, bytes).unwrap(); + h.run_steps(2); + assert_eq!(h.state().views.len(), 2, "bytes have no path to compare (attachments, conversions)"); +} + #[test] fn save_prompt_stays_inside_the_screen_for_a_long_filename() { // Issue #161: an unwrapped title carrying a long filename widened the centered modal past From 09e32698859cb98690eef89a7f8ea09ced6a33b3 Mon Sep 17 00:00:00 2001 From: Eduardo Soares Date: Mon, 12 Oct 2026 23:44:33 -0300 Subject: [PATCH 008/498] Parity: an already-open file focuses its tab on every open path (#1620) Co-authored-by: GLM --- parity/acrobat-features.toml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/parity/acrobat-features.toml b/parity/acrobat-features.toml index e57815882..56a116286 100644 --- a/parity/acrobat-features.toml +++ b/parity/acrobat-features.toml @@ -22,8 +22,8 @@ milestone = "M1" status = "shipped" commands = ["file.open"] tools = ["doc_open"] -evidence = ["crates/automation/tests/automation.rs::open_inspect_render_and_find", "crates/ui-egui/tests/ui.rs::opening_a_pdf_shows_comments_and_bookmarks", "crates/ui-egui/tests/ui.rs::files_and_quit_from_the_operating_system"] -notes = "File ▸ Open, the command line (Linux and Windows file associations), and on macOS Finder, Open With and the Dock (Apple events; the bundle declares PDF as a document type)" +evidence = ["crates/automation/tests/automation.rs::open_inspect_render_and_find", "crates/ui-egui/tests/ui.rs::opening_a_pdf_shows_comments_and_bookmarks", "crates/ui-egui/tests/ui.rs::files_and_quit_from_the_operating_system", "crates/ui-egui/tests/editing.rs::opening_the_same_path_again_focuses_its_tab", "crates/ui-egui/tests/editing.rs::opening_a_file_whose_copy_vanished_from_disk_focuses_its_tab"] +notes = "File ▸ Open, the command line (Linux and Windows file associations), and on macOS Finder, Open With and the Dock (Apple events; the bundle declares PDF as a document type); an already-open file focuses its tab instead of opening a second copy (#1620)" [[feature]] id = "core.repair-broken-files" @@ -646,8 +646,8 @@ milestone = "M3" status = "shipped" commands = [] tools = [] -evidence = ["crates/ui-egui/tests/ui.rs::dropping_a_pdf_on_the_window_opens_it"] -notes = "desktop: the dropped file opens in a tab (by path, or its bytes); web: read asynchronously" +evidence = ["crates/ui-egui/tests/ui.rs::dropping_a_pdf_on_the_window_opens_it", "crates/ui-egui/tests/ui.rs::dropping_an_open_pdf_again_focuses_its_tab"] +notes = "desktop: the dropped file opens in a tab (by path, or its bytes); web: read asynchronously; a dropped document that is already open focuses its tab (#1620)" [[feature]] id = "core.recent-files" @@ -659,7 +659,7 @@ status = "shipped" commands = ["file.open_recent", "file.clear_recent"] tools = [] evidence = ["crates/ui-egui/tests/ui.rs::persistence_round_trips_and_tolerates_garbage", "crates/ui-egui/tests/commands.rs::the_open_recent_menu_lists_files_and_opens_one", "crates/ui-egui/tests/commands.rs::the_open_recent_menu_is_disabled_while_the_list_is_empty", "crates/ui-egui/tests/commands.rs::clear_recent_files_at_the_foot_of_open_recent_empties_the_list", "crates/ui-egui/tests/commands.rs::clear_recent_files_runs_from_the_palette_and_is_saved", "crates/ui-egui/tests/ui.rs::home_removes_one_recent_file_or_clears_them_all"] -notes = "never reads other apps' lists; File ▸ Open Recent lists them (#290), an already-open file focuses its tab instead of reopening it; Clear Recent Files at the foot of Open Recent, on Home and in the palette, and a remove button on each Home row (#430); missing: the row's remove button shows on pointer hover only (keyboard users clear the whole list)" +notes = "never reads other apps' lists; File ▸ Open Recent lists them (#290), an already-open file focuses its tab instead of reopening it, from any open path (#1620); Clear Recent Files at the foot of Open Recent, on Home and in the palette, and a remove button on each Home row (#430); missing: the row's remove button shows on pointer hover only (keyboard users clear the whole list)" [[feature]] id = "core.reopen-last-session" From 305a5676ce67a90c84c2afaf872d03d5adafbba1 Mon Sep 17 00:00:00 2001 From: Eduardo Soares Date: Tue, 13 Oct 2026 00:25:37 -0300 Subject: [PATCH 009/498] Open: programmatic callers see focus vs open vs failure (#1620) Final-review fixes for the focus-existing-tab branch: - open_path returns OpenOutcome (Opened | Focused | Failed), so callers no longer infer success by counting views. Toasts are unchanged; the value is the programmatic contract. - The control channel's ui open replies Ok with "focused": true when the file's tab was already open (an agent driving the app headlessly read the old Err as a read failure), and Err only on Failed. - open_then_run runs the picked tool on Focused too: picking an already-open file focuses its tab and the command runs, as before the branch. - open_recent silences the wasm-only unused `path` binding, like reopen_last_files. Co-authored-by: GLM --- crates/ui-egui/src/control.rs | 13 +++++------ crates/ui-egui/src/lib.rs | 40 +++++++++++++++++++++++++------- crates/ui-egui/src/pickers.rs | 4 +++- crates/ui-egui/tests/commands.rs | 27 +++++++++++++++++++++ crates/ui-egui/tests/control.rs | 35 ++++++++++++++++++++++++++++ crates/ui-egui/tests/editing.rs | 30 +++++++++++++++++++----- 6 files changed, 126 insertions(+), 23 deletions(-) diff --git a/crates/ui-egui/src/control.rs b/crates/ui-egui/src/control.rs index bba7108c0..5f43f6c7f 100644 --- a/crates/ui-egui/src/control.rs +++ b/crates/ui-egui/src/control.rs @@ -33,7 +33,8 @@ //! for this session without changing the saved preference. `ui.state.default_mode` reports it. //! `theme=light|dark|system` changes the saved theme preference; `ui.state.theme_preference` //! reports the choice and `ui.state.theme` reports the resolved light/dark colours. -//! - `ui.open {path}`: open a file. +//! - `ui.open {path}`: open a file. A file whose tab is already open focuses it +//! (`"focused": true`) instead of adding a tab; only a failed open replies `Err`. //! - `ui.screenshot {region?}`: PNG of the window (base64), optionally cropped to a rect. use std::collections::{HashMap, VecDeque}; @@ -735,12 +736,10 @@ impl Host for crate::PdfCraftApp { #[cfg(not(target_arch = "wasm32"))] fn open(&mut self, path: &str) -> Reply { - let before = self.views.len(); - self.open_path(path); - if self.views.len() > before || self.password_prompt.is_some() { - Ok(json!({ "opened": path, "password_prompt": self.password_prompt.is_some() })) - } else { - Err(self.toast.as_ref().map(|t| t.0.clone()).unwrap_or_else(|| format!("couldn't open {path}"))) + match self.open_path(path) { + crate::OpenOutcome::Opened => Ok(json!({ "opened": path, "password_prompt": self.password_prompt.is_some() })), + crate::OpenOutcome::Focused => Ok(json!({ "opened": path, "focused": true })), + crate::OpenOutcome::Failed => Err(self.toast.as_ref().map(|t| t.0.clone()).unwrap_or_else(|| format!("couldn't open {path}"))), } } diff --git a/crates/ui-egui/src/lib.rs b/crates/ui-egui/src/lib.rs index d7f33abbc..afb19f5e5 100644 --- a/crates/ui-egui/src/lib.rs +++ b/crates/ui-egui/src/lib.rs @@ -734,6 +734,19 @@ fn rgb_triple(v: &serde_json::Value) -> Option<[f64; 3]> { Some(out) } +/// What [`PdfCraftApp::open_path`] did: opened the file in a new tab, focused the tab already +/// showing it, or failed. Failures tell the user through a toast; this is the programmatic +/// contract for callers that must know (the control channel, tools that wait for a file) (#1620). +#[derive(Clone, Copy, Debug, PartialEq, Eq)] +pub enum OpenOutcome { + /// The file opened in a new tab (or raised its password prompt). + Opened, + /// A tab already showed the file; it was focused and no tab was added. + Focused, + /// The file could not be read or opened; the user was told. + Failed, +} + impl PdfCraftApp { pub fn new() -> Self { Self { @@ -1208,6 +1221,8 @@ impl PdfCraftApp { self.open_path(path); } } + #[cfg(target_arch = "wasm32")] + let _ = path; } /// The tab already showing the file at `path`, if any: its position in `views`. Paths are @@ -1222,20 +1237,25 @@ impl PdfCraftApp { } #[cfg(not(target_arch = "wasm32"))] - pub fn open_path(&mut self, path: &str) { + pub fn open_path(&mut self, path: &str) -> OpenOutcome { if let Some(i) = self.view_showing(path) { self.startup_superseded = true; self.active = Some(i); - return; + return OpenOutcome::Focused; } let name = std::path::Path::new(path).file_name().map(|n| n.to_string_lossy().into_owned()).unwrap_or_else(|| path.to_string()); match std::fs::read(path) { - Ok(bytes) => { - if let Err(e) = self.open_bytes(&name, Some(path.to_string()), bytes) { + Ok(bytes) => match self.open_bytes(&name, Some(path.to_string()), bytes) { + Ok(()) => OpenOutcome::Opened, + Err(e) => { self.notify_fmt("Couldn't open {name}: {e}", &[("name", &name), ("e", &e.to_string())]); + OpenOutcome::Failed } + }, + Err(e) => { + self.notify_fmt("Couldn't read {name}: {e}", &[("name", &name), ("e", &e.to_string())]); + OpenOutcome::Failed } - Err(e) => self.notify_fmt("Couldn't read {name}: {e}", &[("name", &name), ("e", &e.to_string())]), } } @@ -1437,12 +1457,12 @@ impl PdfCraftApp { let command = spec.id; self.ask_one(pickers::Ask::File(dialog), None, move |app, path| { let path = path.to_string_lossy().into_owned(); - let before = app.views.len(); - app.open_path(&path); + let outcome = app.open_path(&path); if let Some(prompt) = app.password_prompt.as_mut().filter(|p| p.path.as_deref() == Some(path.as_str())) { // Encrypted: the tool runs once the password is in. prompt.then = Some(command); - } else if app.views.len() > before && app.active.is_some() { + } else if outcome != OpenOutcome::Failed { + // A new tab or an already-open one the pick focused: either way, run on it. app.execute(command); } }); @@ -2225,7 +2245,9 @@ impl eframe::App for PdfCraftApp { for e in os_events { match e { #[cfg(not(target_arch = "wasm32"))] - OsEvent::Open(paths) => paths.iter().for_each(|p| self.open_path(p)), + OsEvent::Open(paths) => paths.iter().for_each(|p| { + self.open_path(p); + }), #[cfg(target_arch = "wasm32")] OsEvent::Open(_) => {} // Like closing the window: `guard_quit` asks about unsaved changes. diff --git a/crates/ui-egui/src/pickers.rs b/crates/ui-egui/src/pickers.rs index dcb012089..39b38d645 100644 --- a/crates/ui-egui/src/pickers.rs +++ b/crates/ui-egui/src/pickers.rs @@ -151,7 +151,9 @@ impl PdfCraftApp { }; let ask = if multiple { Ask::Files(dialog) } else { Ask::File(dialog) }; self.ask(ask, target, move |app, paths| match pick_for { - PickFor::Open => paths.iter().for_each(|p| app.open_path(&p.to_string_lossy())), + PickFor::Open => paths.iter().for_each(|p| { + app.open_path(&p.to_string_lossy()); + }), PickFor::Files(purpose) => app.use_paths(purpose, &paths), }); } diff --git a/crates/ui-egui/tests/commands.rs b/crates/ui-egui/tests/commands.rs index 48a18eb42..8674c8810 100644 --- a/crates/ui-egui/tests/commands.rs +++ b/crates/ui-egui/tests/commands.rs @@ -187,6 +187,33 @@ fn a_tool_chosen_with_no_document_asks_for_one_and_runs_on_it() { let _ = std::fs::remove_dir_all(&dir); } +#[test] +fn a_tool_chosen_with_an_already_open_file_focuses_its_tab_and_still_runs() { + let dir = std::env::temp_dir().join(format!("pdfcraft-tool-focus-{}", std::process::id())); + std::fs::create_dir_all(&dir).unwrap(); + let path = dir.join("picked.pdf"); + std::fs::write(&path, fixture(2)).unwrap(); + let pick = path.to_string_lossy().into_owned(); + let picked = pick.clone(); + let mut h = Harness::builder().with_size(egui::vec2(1400.0, 900.0)).build_eframe(move |_cc| { + let mut app = PdfCraftApp::new(); + app.set_option("language", "en").unwrap(); + // The file is already open, but the Home tab is showing (no active document). + app.open_path(&picked); + app.active = None; + app.pick_override = Some(vec![pick]); + app + }); + h.run_steps(2); + h.state_mut().run_command("export.text"); + h.run_steps(3); + let app = h.state(); + assert_eq!(app.views.len(), 1, "the existing tab is reused, not duplicated"); + assert_eq!(app.active, Some(0), "the pick focused the tab it already opened"); + assert!(matches!(app.dialog, Some(Dialog::Export(_))), "the tool still runs on it: {:?}", app.dialog); + let _ = std::fs::remove_dir_all(&dir); +} + #[test] fn shortcuts_run_registered_commands() { let mut h = harness(); diff --git a/crates/ui-egui/tests/control.rs b/crates/ui-egui/tests/control.rs index 180dc85e6..7f1d27a76 100644 --- a/crates/ui-egui/tests/control.rs +++ b/crates/ui-egui/tests/control.rs @@ -1427,3 +1427,38 @@ fn read_mode_retains_existing_rail_click_to_close_policy() { assert_eq!(h.state().right, None); assert_eq!(h.state().mode, pdfcraft_ui_egui::Mode::Read); } + +#[test] +fn control_open_of_an_already_open_file_replies_ok_and_focuses_its_tab() { + let dir = std::env::temp_dir().join(format!("pdfcraft-ui-open-{}", std::process::id())); + std::fs::create_dir_all(&dir).unwrap(); + let a = dir.join("a.pdf").to_string_lossy().into_owned(); + let b = dir.join("b.pdf").to_string_lossy().into_owned(); + std::fs::write(&a, fixture(2)).unwrap(); + std::fs::write(&b, fixture(3)).unwrap(); + let slot: Arc>> = Arc::default(); + let s = slot.clone(); + let mut h = Harness::builder().with_size(egui::vec2(1400.0, 900.0)).build_eframe(move |cc| { + let mut app = PdfCraftApp::new(); + app.set_option("language", "en").unwrap(); + *s.lock().unwrap() = Some(app.attach_control(&cc.egui_ctx)); + app + }); + h.run_steps(4); + let c = slot.lock().unwrap().take().unwrap(); + + let first = ok(&mut h, &c, "ui.open", json!({ "path": a })); + assert_eq!(first["opened"], json!(a), "{first}"); + ok(&mut h, &c, "ui.open", json!({ "path": b })); + // The file is already open: the tab focuses, and the reply must be Ok — an agent driving the + // app headlessly would otherwise read a focus as a read failure (#1620). + let again = ok(&mut h, &c, "ui.open", json!({ "path": a })); + assert_eq!(again["focused"], true, "{again}"); + + let state = ok(&mut h, &c, "ui.state", json!({})); + let docs = state["documents"].as_array().cloned().unwrap_or_default(); + assert_eq!(docs.len(), 2, "opening an open file adds no tab: {state}"); + let a_tab = docs.iter().find(|d| d["path"] == json!(a)).unwrap(); + assert_eq!(a_tab["active"], true, "the already-open tab is in front: {state}"); + let _ = std::fs::remove_dir_all(&dir); +} diff --git a/crates/ui-egui/tests/editing.rs b/crates/ui-egui/tests/editing.rs index 215eaedc5..9146ae65d 100644 --- a/crates/ui-egui/tests/editing.rs +++ b/crates/ui-egui/tests/editing.rs @@ -6,7 +6,7 @@ use egui::{Key, Modifiers}; use egui_kittest::Harness; use egui_kittest::kittest::{NodeT, Queryable}; use pdfcraft_render::{PageRenderer, RenderRequest, RequestKind}; -use pdfcraft_ui_egui::{CloseRequest, Dialog, PdfCraftApp}; +use pdfcraft_ui_egui::{CloseRequest, Dialog, OpenOutcome, PdfCraftApp}; /// An `n`-page document with a proper xref table; page `i` shows "Page i+1". fn fixture(n: usize) -> Vec { @@ -585,7 +585,11 @@ fn the_last_session_reopens_its_files_pages_and_active_tab() { let dir = TempPdfs::new("reopen"); let files = [dir.file("a.pdf", 1), dir.file("b.pdf", 5), dir.file("c.pdf", 2)]; let opened = files.clone(); - let mut h = session_harness(move |app| opened.iter().for_each(|f| app.open_path(f))); + let mut h = session_harness(move |app| { + opened.iter().for_each(|f| { + app.open_path(f); + }) + }); h.state_mut().views[1].go_to_page(3); h.state_mut().active = Some(1); h.run_steps(4); @@ -607,7 +611,11 @@ fn quitting_with_unsaved_changes_still_remembers_every_file() { let dir = TempPdfs::new("quit"); let files = [dir.file("a.pdf", 1), dir.file("b.pdf", 1)]; let opened = files.clone(); - let mut h = session_harness(move |app| opened.iter().for_each(|f| app.open_path(f))); + let mut h = session_harness(move |app| { + opened.iter().for_each(|f| { + app.open_path(f); + }) + }); for tab in 0..2 { h.state_mut().active = Some(tab); h.state_mut().views[tab].select_pages(&[0]); @@ -659,17 +667,27 @@ fn opening_the_same_path_again_focuses_its_tab() { let a = pdfs.file("a.pdf", 1); let b = pdfs.file("b.pdf", 1); let mut h = session_harness(|_| {}); - h.state_mut().open_path(&a); - h.state_mut().open_path(&b); + assert_eq!(h.state_mut().open_path(&a), OpenOutcome::Opened); + assert_eq!(h.state_mut().open_path(&b), OpenOutcome::Opened); h.run_steps(2); assert_eq!(h.state().views.len(), 2, "two different files open two tabs"); - h.state_mut().open_path(&a); + assert_eq!(h.state_mut().open_path(&a), OpenOutcome::Focused, "opening an open file focuses, it doesn't reopen"); h.run_steps(2); assert_eq!(h.state().views.len(), 2, "opening an open file again adds no tab"); assert_eq!(h.state().active, Some(0), "the existing tab comes to the front"); assert_eq!(open_paths(h.state()), vec![a, b], "the tab order is untouched"); } +#[test] +fn opening_a_missing_file_fails_and_tells_the_user() { + let mut app = PdfCraftApp::new(); + app.set_option("language", "en").unwrap(); + let missing = std::env::temp_dir().join(format!("pdfcraft-no-such-file-{}.pdf", std::process::id())); + assert_eq!(app.open_path(&missing.to_string_lossy()), OpenOutcome::Failed); + assert!(app.views.is_empty()); + assert!(app.toast.is_some(), "the failure is still reported to the user"); +} + #[test] fn opening_the_same_file_with_a_dot_component_focuses_its_tab() { let pdfs = TempPdfs::new("dedup-dot"); From bc6cfbd6cbbf5c2eb101e4cdb1dd365771b0208f Mon Sep 17 00:00:00 2001 From: PINYO PATTANAWASANPORN Date: Tue, 13 Oct 2026 13:15:21 +0700 Subject: [PATCH 010/498] fix(sign): render Unicode characters in visible signatures using bundled Inter font MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Enables visible signature appearances in pdfcraft_sign to render Unicode characters (specifically Latin Extended-A / Central European characters such as č, ć, ž, š, đ) by embedding the bundled Inter-Regular.ttf font with /Identity-H encoding and a /ToUnicode CMap when the signer name, labels, reason, or location contain non-WinAnsi text. When all text is within WinAnsiEncoding, the existing zero-byte overhead behavior (using standard /Helv) is preserved. Closes #2207 --- crates/fonts/src/lib.rs | 20 +++++++++ crates/sign/src/pdf.rs | 88 ++++++++++++++++++++++++++++------------ crates/sign/tests/pdf.rs | 35 +++++++++++++++- 3 files changed, 116 insertions(+), 27 deletions(-) diff --git a/crates/fonts/src/lib.rs b/crates/fonts/src/lib.rs index 622c609f6..e1af92d05 100644 --- a/crates/fonts/src/lib.rs +++ b/crates/fonts/src/lib.rs @@ -47,6 +47,18 @@ pub fn cjk_width(s: &str, size: f64) -> f64 { .sum() } +/// Approximate advance of `s` in Inter Regular at `size` points. +pub fn inter_width(s: &str, size: f64) -> f64 { + use skrifa::MetadataProvider as _; + let Ok(font) = skrifa::FontRef::new(INTER_REGULAR) else { return helvetica_width(s, size) }; + let loc = skrifa::instance::LocationRef::default(); + let upem = font.metrics(skrifa::instance::Size::unscaled(), loc).units_per_em.max(1) as f64; + let scale = size / upem; + let charmap = font.charmap(); + let advances = font.glyph_metrics(skrifa::instance::Size::unscaled(), loc); + s.chars().map(|c| charmap.map(c).and_then(|gid| advances.advance_width(gid)).unwrap_or(0.0) as f64 * scale).sum() +} + /// East Asian wide and full-width characters (Unicode UAX #11 W and F, by block). fn is_wide(c: char) -> bool { matches!(c, @@ -288,6 +300,14 @@ mod tests { assert_eq!(undrawn_mark(&d), None); } + #[test] + fn inter_width_measures_latin_extended_and_ascii() { + assert!(inter_width("Luka Petravić", 12.0) > 0.0); + assert_eq!(inter_width("", 12.0), 0.0); + let w = inter_width("čžšć", 10.0); + assert!(w > 10.0 && w < 100.0); + } + #[test] fn widths_wrap_and_encode() { assert!(helvetica_width("MMMM", 10.0) > helvetica_width("iiii", 10.0) * 2.0); diff --git a/crates/sign/src/pdf.rs b/crates/sign/src/pdf.rs index 012cd43a6..b5808cabf 100644 --- a/crates/sign/src/pdf.rs +++ b/crates/sign/src/pdf.rs @@ -1943,16 +1943,18 @@ pub fn display_date(pdf: &str) -> String { } /// The visible signature: the signer's name large on the left, or the graphic in its place, and -/// the details on the right (Acrobat's standard layout), in Helvetica. A graphic with no details -/// beside it fills the box. An error, before anything is drawn, when a detail it writes in -/// Helvetica (the signer's name, the certificate's subject, the reason or the location) has a -/// character Helvetica can't draw: signing invisibly, or leaving that part out, still works. A -/// graphic doesn't change this: the name it replaces on the left is still among the details. +/// the details on the right (Acrobat's standard layout), in Helvetica or the bundled Inter font +/// when non-Western-European characters are needed. A graphic with no details beside it fills the +/// box. An error, before anything is drawn, when a detail it writes has a character the fonts +/// can't draw: signing invisibly, or leaving that part out, still works. A graphic doesn't change +/// this: the name it replaces on the left is still among the details. fn appearance(doc: &mut Document, rect: [f64; 4], name: &str, cert: &Certificate, opts: &SignOptions) -> Result { - use pdfcraft_fonts::{first_undrawable, helvetica_width, literal, undrawable_message, win_ansi, wrap}; + use pdfcraft_fonts::{first_undrawable, helvetica_width, inter_width, literal, undrawable_message, win_ansi, wrap, wrap_with}; let (w, h) = ((rect[2] - rect[0]).max(0.0), (rect[3] - rect[1]).max(0.0)); let a = &opts.appearance; let dn = cert.subject.display(); + let wording = &opts.appearance_labels; + let mut needs_unicode = false; if w > 1.0 && h > 1.0 { let shown = [ (a.name, "the signer's name", Some(name)), @@ -1961,18 +1963,34 @@ fn appearance(doc: &mut Document, rect: [f64; 4], name: &str, cert: &Certificate (a.location, "the location", opts.location.as_deref()), ]; for (on, what, text) in shown { - if on && let Some(c) = text.and_then(first_undrawable) { - return Err(SignError::Unsupported(format!( - "{}; sign without a visible appearance, or leave {what} out of it", - undrawable_message(&format!("{what} of the visible signature"), c) - ))); + if on + && let Some(s) = text + && first_undrawable(s).is_some() + { + for c in s.chars() { + if matches!(c, '\n' | '\r') { + continue; + } + if !pdfcraft_fonts::embedding::covers(pdfcraft_fonts::INTER_REGULAR, &c.to_string()) { + return Err(SignError::Unsupported(format!( + "{}; sign without a visible appearance, or leave {what} out of it", + undrawable_message(&format!("{what} of the visible signature"), c) + ))); + } + } + needs_unicode = true; + } + } + if !needs_unicode { + let label_texts = [&wording.signed_by, &wording.distinguished_name, &wording.reason, &wording.location, &wording.date]; + if label_texts.iter().any(|l| first_undrawable(l).is_some()) { + needs_unicode = true; } } } let mut lines: Vec = Vec::new(); let label = |l: &str, v: &str| if a.labels { format!("{l}{v}") } else { v.to_string() }; // The labels are the caller's words, so a signature signed in another language reads in it. - let wording = &opts.appearance_labels; if a.name { lines.push(if a.labels { wording.signed_by.clone() } else { String::new() }); lines.push(name.to_string()); @@ -1996,6 +2014,31 @@ fn appearance(doc: &mut Document, rect: [f64; 4], name: &str, cert: &Certificate lines.retain(|l| !l.is_empty()); let mut out = Vec::new(); let mut image = None; + let mut fonts = Dict::new(); + let (font_tag, metrics) = if needs_unicode { + let tag = pdfcraft_fonts::embedding::embed(doc, &mut fonts, pdfcraft_fonts::INTER_REGULAR, "Inter") + .map_err(|e| SignError::Pdf(format!("failed to embed signature font: {e}")))?; + let font_dict = fonts + .get(tag.as_bytes()) + .map(|o| doc.resolve(o)) + .and_then(|o| o.as_dict().cloned()) + .ok_or_else(|| SignError::Pdf("embedded signature font dictionary not found".into()))?; + let m = pdfcraft_fonts::pdf::Metrics::from_dict(doc, &font_dict); + (tag, Some(m)) + } else { + let mut font = Dict::new(); + font.set(b"Type".to_vec(), Object::name("Font")); + font.set(b"Subtype".to_vec(), Object::name("Type1")); + font.set(b"BaseFont".to_vec(), Object::name("Helvetica")); + font.set(b"Encoding".to_vec(), Object::name("WinAnsiEncoding")); + fonts.set(b"Helv".to_vec(), Object::Dict(font)); + ("Helv".to_string(), None) + }; + let measure = |s: &str, sz: f64| -> f64 { if needs_unicode { inter_width(s, sz) } else { helvetica_width(s, sz) } }; + let wrap_text = + |s: &str, sz: f64, max_w: f64| -> Vec { if needs_unicode { wrap_with(s, sz, max_w, inter_width) } else { wrap(s, sz, max_w) } }; + let encode_line = + |l: &str| -> Vec { if let Some(m) = &metrics { literal(&m.encode(l).unwrap_or_else(|| win_ansi(l))) } else { literal(&win_ansi(l)) } }; if w > 1.0 && h > 1.0 { let pad = (h * 0.06).clamp(1.0, 6.0); let (left_w, right_x) = match (&opts.graphic, a.name) { @@ -2014,14 +2057,14 @@ fn appearance(doc: &mut Document, rect: [f64; 4], name: &str, cert: &Certificate // The name fills the left half. let mut size = (h * 0.4).min(36.0); let fit = (left_w - 2.0 * pad).max(1.0); - let longest = helvetica_width(name, 1.0).max(0.01); + let longest = measure(name, 1.0).max(0.01); size = size.min(fit / longest).max(4.0); - let words = wrap(name, size, fit); + let words = wrap_text(name, size, fit); let total = words.len() as f64 * size * 1.1; let mut y = (h + total) / 2.0 - size * 0.85; for l in &words { - out.extend(format!("/Helv {} Tf 1 0 0 1 {} {} Tm ", fmt(size), fmt(pad), fmt(y)).bytes()); - out.extend(literal(&win_ansi(l))); + out.extend(format!("/{font_tag} {} Tf 1 0 0 1 {} {} Tm ", fmt(size), fmt(pad), fmt(y)).bytes()); + out.extend(encode_line(l)); out.extend_from_slice(b" Tj\n"); y -= size * 1.1; } @@ -2029,7 +2072,7 @@ fn appearance(doc: &mut Document, rect: [f64; 4], name: &str, cert: &Certificate // The details, shrunk to fit the right side. let mut size = (h / (lines.len().max(1) as f64 * 1.15)).min(12.0); let wrapped = loop { - let all: Vec = lines.iter().flat_map(|l| wrap(l, size, right_w)).collect(); + let all: Vec = lines.iter().flat_map(|l| wrap_text(l, size, right_w)).collect(); if all.len() as f64 * size * 1.15 <= h - 2.0 * pad || size <= 3.0 { break all; } @@ -2037,8 +2080,8 @@ fn appearance(doc: &mut Document, rect: [f64; 4], name: &str, cert: &Certificate }; let mut y = h - pad - size * 0.9; for l in &wrapped { - out.extend(format!("/Helv {} Tf 1 0 0 1 {} {} Tm ", fmt(size), fmt(right_x), fmt(y)).bytes()); - out.extend(literal(&win_ansi(l))); + out.extend(format!("/{font_tag} {} Tf 1 0 0 1 {} {} Tm ", fmt(size), fmt(right_x), fmt(y)).bytes()); + out.extend(encode_line(l)); out.extend_from_slice(b" Tj\n"); y -= size * 1.15; } @@ -2048,13 +2091,6 @@ fn appearance(doc: &mut Document, rect: [f64; 4], name: &str, cert: &Certificate d.set(b"Type".to_vec(), Object::name("XObject")); d.set(b"Subtype".to_vec(), Object::name("Form")); d.set(b"BBox".to_vec(), Object::Array([0.0, 0.0, w, h].iter().map(|x| Object::Real(*x)).collect())); - let mut font = Dict::new(); - font.set(b"Type".to_vec(), Object::name("Font")); - font.set(b"Subtype".to_vec(), Object::name("Type1")); - font.set(b"BaseFont".to_vec(), Object::name("Helvetica")); - font.set(b"Encoding".to_vec(), Object::name("WinAnsiEncoding")); - let mut fonts = Dict::new(); - fonts.set(b"Helv".to_vec(), Object::Dict(font)); let mut res = Dict::new(); res.set(b"Font".to_vec(), Object::Dict(fonts)); if let Some(im) = image { diff --git a/crates/sign/tests/pdf.rs b/crates/sign/tests/pdf.rs index 609926f3b..8cbebf37a 100644 --- a/crates/sign/tests/pdf.rs +++ b/crates/sign/tests/pdf.rs @@ -4,7 +4,8 @@ use std::sync::Arc; use pdfcraft_cos::{Document, Object, PdfString, SaveOptions, write_incremental}; use pdfcraft_sign::{ - Detail, Modification, SignError, SignOptions, Status, Time, TimestampAuthority, TrustStore, WORDINGS, der, in_english, kind, pkcs12, signatures, + Certificate, Detail, DigitalId, Modification, Name, SignError, SignOptions, Status, Time, TimestampAuthority, TrustStore, WORDINGS, der, + in_english, kind, pkcs12, signatures, }; fn data(name: &str) -> Vec { @@ -1815,6 +1816,38 @@ fn visible_appearance_text_helvetica_cannot_draw_is_refused() { assert_eq!(s.reason.as_deref(), Some("同意此文件")); } +/// A visible signature with Central European characters (č, ć, ž, š) embeds the bundled +/// Inter font and draws them cleanly instead of refusing or writing `?`. +#[test] +fn visible_appearance_draws_central_european_characters_with_embedded_font() { + let id = pkcs12::open(&data("ec-p256.p12"), "test").unwrap(); + let name = Name::build("Luka Petravić", "Oddelek", "Podjetje d.o.o.", "luka@example.com", "SI"); + let cert = Certificate::self_signed(&name, &id.key, Time::from_unix(1_700_000_000), 5, &[1]).unwrap(); + let luka_id = DigitalId { key: id.key, certificate: cert, chain: Vec::new(), friendly_name: None }; + let shown = + pdfcraft_sign::Appearance { name: true, distinguished_name: true, reason: true, location: true, ..pdfcraft_sign::Appearance::default() }; + let sl = SignOptions { + rect: Some([150.0, 20.0, 280.0, 70.0]), + reason: Some("Podpisano s potrdilom".into()), + location: Some("Ljubljana, Slovenija".into()), + appearance: shown, + ..opts() + }; + let signed = pdfcraft_sign::sign(&open(&fixture()), &luka_id, &sl).unwrap(); + let (content, res) = appearance_of(&signed, "Signature1"); + // Verify that the appearance stream does not write `?` in place of non-WinAnsi characters. + assert!(!content.contains('?'), "appearance content should not write '?' for Central European characters: {content}"); + // Verify an embedded TrueType font was added to the appearance resources. + let fonts = res.get(b"Font").and_then(|o| o.as_dict()).unwrap(); + assert!(fonts.contains(b"PCFull0"), "appearance should reference the embedded font: {fonts:?}"); + // Verify signature validation still passes. + let doc = open(&signed); + let trust = TrustStore { certs: vec![luka_id.certificate.clone()] }; + let s = signatures(&doc, &signed, &trust).into_iter().find(|s| s.signed).unwrap(); + assert_eq!(s.status, Status::Valid); + assert_eq!(s.reason.as_deref(), Some("Podpisano s potrdilom")); +} + /// Every sentence this crate says about a signature is listed in `WORDINGS`, and every sentence on /// that list is one it still says: the details are written as `Detail::plain`/`Detail::of`, the /// sentences the modules that read a signature word for themselves are pushed as notes and quirks, From 6973d78b572e84ac85d0b77c3bed2f39bb545829 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fernando=20Are=C3=A1n=20Mag=C3=A1n?= Date: Tue, 13 Oct 2026 12:58:39 +0200 Subject: [PATCH 011/498] docs: merge the duplicated catalog paragraph in localization.md The "Dialogs, panels, menus" paragraph appears twice, the same artifact as the Auto paragraph in #1525. Two language additions each edited it and both versions were kept: one ends "Czech and Turkish cover the menus so far", the other lists Slovenian among the translated languages and says only Czech covers the menus. Neither list is current. Turkish has had a complete catalog since #1057, and five of the shipped languages are in neither copy: Kazakh, Polish, Greek, Turkish and Lithuanian, all with full catalogs per docs/localization-parity.md. Czech is still menus only (135 of the 2,143-key union there). So keep one paragraph, and stop enumerating the languages in it: that list is what both additions edited at once, and the paragraph already points at localization-parity.md, which carries the per-language counts and coverage. The rest of the paragraph is unchanged. Docs only, no code. Co-Authored-By: Claude Opus 5 --- docs/localization.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/docs/localization.md b/docs/localization.md index 05240cafb..912e25098 100644 --- a/docs/localization.md +++ b/docs/localization.md @@ -14,8 +14,7 @@ The control channel exposes the setting through `ui.set`: The value is `auto` or a language code (`en`, `ja`, `zh-hans`, `zh-hant`, `cs`, `pt-br`, `de`, `es`, `fr`, `ru`, `kk`, `bg`, `te`, `hu`, `uk`, `it`, `ar`, `pl`, `sl`, `el`, `tr`, `lt`), in any case. `ui.state` reports `language` as written in the preferences (`auto`, `en`, `ja`, `zh-hans`, `zh-hant`, `cs`, `pt-br`, `de`, `es`, `fr`, `ru`, `kk`, `bg`, `te`, `hu`, `uk`, `it`, `ar`, `pl`, `sl`, `el`, `tr` or `lt`). Unknown values return an error without changing the current setting. Preferences saved before this setting existed follow the system language. -Dialogs, panels, menus, notices and history labels go through the catalog (`tl!`). Japanese, Traditional Chinese, Simplified Chinese, Russian, Bulgarian, German, Spanish, French, Telugu, Hungarian, Ukrainian, Italian, Brazilian Portuguese and Arabic translate them (about 2,000–2,140 entries each); Czech and Turkish cover the menus so far. Untranslated labels use English. Error details that come from the engine or the operating system are shown as they are, inside a translated frame ("操作「…」に失敗しました: …"). The command palette matches the translated label, the English label and the command id. Vertical Japanese PDF rendering is an existing viewer feature; this change does not add vertical text editing. Per-language coverage, script support and what each language still needs are in [localization-parity.md](localization-parity.md). -Dialogs, panels, menus, notices and history labels go through the catalog (`tl!`). Japanese, Traditional Chinese, Simplified Chinese, Russian, Bulgarian, German, Spanish, French, Telugu, Hungarian, Ukrainian, Italian, Brazilian Portuguese, Arabic and Slovenian translate them (about 2,000–2,190 entries each); Czech covers the menus so far. Untranslated labels use English. Error details that come from the engine or the operating system are shown as they are, inside a translated frame ("操作「…」に失敗しました: …"). The command palette matches the translated label, the English label and the command id. Vertical Japanese PDF rendering is an existing viewer feature; this change does not add vertical text editing. Per-language coverage, script support and what each language still needs are in [localization-parity.md](localization-parity.md). +Dialogs, panels, menus, notices and history labels go through the catalog (`tl!`). Every bundled language translates them (about 2,000–2,580 entries each), except Czech, which covers the menus so far. Untranslated labels use English. Error details that come from the engine or the operating system are shown as they are, inside a translated frame ("操作「…」に失敗しました: …"). The command palette matches the translated label, the English label and the command id. Vertical Japanese PDF rendering is an existing viewer feature; this change does not add vertical text editing. Per-language coverage, script support and what each language still needs are in [localization-parity.md](localization-parity.md). Whole sentences that the layers below word — what the accessibility checker found, what the PDF/A verifier reports, what a signature's details say, what is wrong with the pages to print, what an edit is called in the history — are translated too, because those layers hand the sentence over apart from the document's own words. See [Sentences the engine words](#sentences-the-engine-words). From 089acf717d56adbcdabe9234ac6b4460af08842d Mon Sep 17 00:00:00 2001 From: webdevtodayjason <115739170+webdevtodayjason@users.noreply.github.com> Date: Tue, 13 Oct 2026 12:31:19 +0000 Subject: [PATCH 012/498] M10: keep dotted-leader contents entries together Fixes #1757 --- ROADMAP.md | 2 ++ crates/edit/src/tests.rs | 26 +++++++++++++++ crates/edit/src/text_regions.rs | 56 ++++++++++++++++++++++++++++++++- crates/engine/src/tests.rs | 21 +++++++++++++ docs/roadmap.md | 5 +-- parity/acrobat-features.toml | 4 +-- 6 files changed, 109 insertions(+), 5 deletions(-) diff --git a/ROADMAP.md b/ROADMAP.md index a035c9bf3..714fd1c08 100644 --- a/ROADMAP.md +++ b/ROADMAP.md @@ -148,6 +148,8 @@ Ranked; detail and the full milestone table in [docs/roadmap.md](docs/roadmap.md ## Progress log +- **2026-10-13 (M10, #1757):** Office export keeps each dotted-leader contents entry in one paragraph, with its page number, instead of inferring table cells from its separate text objects. + - **2026-10-12 (M13, CLI robustness scans):** `pdfcraft-cli check` visits a directory once even when input roots overlap or directory symlinks lead back into the tree. PDFs reached through file symlinks remain accepted. Three real CLI regressions cover overlapping roots, a directory cycle and directory/file aliases. Estimates unchanged. - **2026-10-12 (M4, Type 3 extraction fidelity):** Extract and Split preserve shared image/resource dictionaries reached through Type 3 glyphs, including nested forms, patterns and soft masks. A bounded object-graph walk protects unknown glyph content; unreadable pages/forms retain their glyph resources, and shared explicit fonts are visited once. Separate page dictionaries still prune unused images. Synthetic save/reopen regressions and an opt-in Poppler pixel oracle cover resource ownership, nested forms, cycles, limits and repeated fonts. Estimates unchanged. - **2026-10-12 (M2, TIFF predictor rows):** Packed RGB images using TIFF horizontal differencing keep every row when samples do not fill the last byte. The renderer aligns each decoded row before moving to the next. Synthetic decoding tests cover 1/2/4-bit samples, horizontal differencing and an 8-bit control; a red/green page-render regression verifies visible output. Estimates unchanged. diff --git a/crates/edit/src/tests.rs b/crates/edit/src/tests.rs index fce7d5e10..3ae55635f 100644 --- a/crates/edit/src/tests.rs +++ b/crates/edit/src/tests.rs @@ -3443,3 +3443,29 @@ fn an_items_measured_face_is_the_face_it_is_written_as() { let courier = |italic| Family::Courier.width("Anna", 12.0, false, italic); assert_eq!(courier(false), courier(true)); } + +#[test] +fn reading_keeps_dotted_leader_entries_whole_and_in_order() { + let mut content = String::new(); + for (title, page, y) in [("Art.1. Scope", "3", 700), ("Art.2. Eligibility", "7", 680), ("Art.3. Application", "12", 660)] { + content.push_str(&format!( + "BT /F1 12 Tf 72 {y} Td ({title}) Tj ET \ + BT /F1 12 Tf 250 {y} Td (....................) Tj ET \ + BT /F1 12 Tf 500 {y} Td ({page}) Tj ET\n" + )); + } + content.push_str("BT /F1 12 Tf 72 640 Td (Appendix) Tj ET BT /F1 12 Tf 250 640 Td (\\205\\205\\205) Tj ET BT /F1 12 Tf 500 640 Td (iv) Tj ET\n"); + content.push_str("BT /F1 12 Tf 72 600 Td (Ordinary body text.) Tj ET BT /F1 12 Tf 72 582 Td (Still the same paragraph.) Tj ET"); + let doc = text_page(&content); + let blocks: Vec<_> = text::reading_blocks(&doc, 0).unwrap().into_iter().map(|b| b.text).collect(); + assert_eq!( + blocks, + [ + "Art.1. Scope .................... 3", + "Art.2. Eligibility .................... 7", + "Art.3. Application .................... 12", + "Appendix ……… iv", + "Ordinary body text. Still the same paragraph.", + ] + ); +} diff --git a/crates/edit/src/text_regions.rs b/crates/edit/src/text_regions.rs index 0213d9040..f12a72dd2 100644 --- a/crates/edit/src/text_regions.rs +++ b/crates/edit/src/text_regions.rs @@ -31,8 +31,62 @@ pub(super) fn group_blocks(lines: &[TextLine]) -> Vec { /// Exporters currently represent a block with one style. Keep their style boundaries until /// they support rich runs, while edit selection may encompass the complete visual region. +/// Dotted-leader entries stay on one row and use the title run's style. pub(super) fn group_reading_blocks(lines: &[TextLine]) -> Vec { - group_layout(lines, false) + let mut blocks = Vec::new(); + let mut start = 0; + let mut offset = 0; + for row in lines.chunk_by(|a, b| same_plane(a, b) && (a.origin.baseline - b.origin.baseline).abs() < a.size.min(b.size) * 0.2) { + let mut text = String::new(); + for (i, line) in row.iter().enumerate() { + if !text.ends_with(char::is_whitespace) + && !line.text.starts_with(char::is_whitespace) + && i.checked_sub(1).and_then(|i| row.get(i)).is_some_and(|prev| line.rect[0] - prev.rect[2] > line.size * 0.12) + { + text.push(' '); + } + text.push_str(&line.text); + } + if leader_entry(&text) + && let Some(first) = row.first() + { + // Tab leaders are a single reading row, even when the title, dots and page + // number are separate text objects far apart. Do not merge neighbouring entries. + blocks.extend(group_layout(lines.get(start..offset).unwrap_or_default(), false)); + let mut line = first.clone(); + line.text = text; + line.rect = row.iter().map(|line| line.rect).reduce(union).unwrap_or(first.rect); + blocks.extend(group_layout(std::slice::from_ref(&line), false)); + start = offset + row.len(); + } + offset += row.len(); + } + blocks.extend(group_layout(lines.get(start..).unwrap_or_default(), false)); + blocks +} + +/// Dotted leaders end in a page number, with a title before the dots. A dot in an article +/// number, or an ellipsis in ordinary prose, is not enough to make a contents entry. +fn leader_entry(text: &str) -> bool { + let text = text.trim_end(); + let prefix = text.trim_end_matches(|c: char| { + c.is_ascii_digit() || matches!(c, 'i' | 'v' | 'x' | 'l' | 'c' | 'd' | 'm' | 'I' | 'V' | 'X' | 'L' | 'C' | 'D' | 'M') + }); + if prefix.len() == text.len() { + return false; + } + let title = prefix.trim_end_matches(|c: char| c.is_whitespace() || matches!(c, '.' | '…')); + let dots = prefix + .get(title.len()..) + .unwrap_or_default() + .chars() + .map(|c| match c { + '.' => 1, + '…' => 3, + _ => 0, + }) + .sum::(); + dots >= 3 && title.chars().any(char::is_alphabetic) } /// Text-space units → user space along the baseline. It is the vertical scale ([`Origin::k`]) diff --git a/crates/engine/src/tests.rs b/crates/engine/src/tests.rs index 37cafd440..40c832a46 100644 --- a/crates/engine/src/tests.rs +++ b/crates/engine/src/tests.rs @@ -4523,3 +4523,24 @@ fn copy_image_finds_a_picture_inside_form_artwork_under_text() { assert_eq!(d.page_image_copy_file(0, 0).unwrap(), ("jpg", jpeg)); assert!(d.page_image_copy_file(0, 1).is_err()); } + +#[test] +fn exporting_office_keeps_dotted_leader_entries_as_paragraphs() { + let mut content = String::new(); + for (title, page, y) in [("Art.1. Scope", "3", 200), ("Art.2. Eligibility", "7", 180), ("Art.3. Application", "12", 160)] { + content.push_str(&format!( + "BT /F1 12 Tf 72 {y} Td ({title}) Tj ET \ + BT /F1 12 Tf 250 {y} Td (....................) Tj ET \ + BT /F1 12 Tf 500 {y} Td ({page}) Tj ET\n" + )); + } + let pdf = one_line_page("/Font << /F1 4 0 R >>", &content); + let mut session = Session::new(); + let id = session.open("contents.pdf", None, Arc::new(pdf), None).unwrap(); + let doc = session.get(id).unwrap(); + let html = String::from_utf8(doc.export_office(compare::OfficeFormat::Html)).unwrap(); + assert!(!html.contains(""), "contents entries are paragraphs: {html}"); + let entries = ["Art.1. Scope .................... 3", "Art.2. Eligibility .................... 7", "Art.3. Application .................... 12"]; + let positions: Vec<_> = entries.iter().map(|entry| html.find(&format!("

{entry}

")).expect("one paragraph per entry")).collect(); + assert!(positions.windows(2).all(|pair| pair[0] < pair[1]), "reading order: {html}"); +} diff --git a/docs/roadmap.md b/docs/roadmap.md index 04103fb63..43e4978ed 100644 --- a/docs/roadmap.md +++ b/docs/roadmap.md @@ -1,6 +1,6 @@ # PdfCraft roadmap: milestones and what's next -> **Last reviewed:** 2026-10-12 · **Last updated:** 2026-10-12 · **Change:** minor (M13: CLI check visits each directory once through aliases and cycles; estimates unchanged) · **Target:** Adobe Acrobat Pro (Acrobat DC, continuous track 26.002.21931, macOS) +> **Last reviewed:** 2026-10-13 · **Last updated:** 2026-10-13 · **Change:** minor (M10: dotted-leader contents entries export as complete paragraphs; estimates unchanged) · **Target:** Adobe Acrobat Pro (Acrobat DC, continuous track 26.002.21931, macOS) > **Last reviewed:** 2026-10-12 · **Last updated:** 2026-10-12 · **Change:** minor (M4: Extract and Split preserve shared Type 3 glyph resources; estimates unchanged) · **Target:** Adobe Acrobat Pro (Acrobat DC, continuous track 26.002.21931, macOS) > **Last reviewed:** 2026-10-12 · **Last updated:** 2026-10-12 · **Change:** minor (M2: packed TIFF-predictor RGB rows retain their byte boundaries; estimates unchanged) · **Target:** Adobe Acrobat Pro (Acrobat DC, continuous track 26.002.21931, macOS) > **Last reviewed:** 2026-10-12 · **Last updated:** 2026-10-12 · **Change:** minor (M3 #1364 candidate: consent before absolute local GoToR access; estimates unchanged); earlier: minor (M1 #1339: unchanged incremental saves of a classic cross-reference table write a zero-length subsection; estimates unchanged) · **Target:** Adobe Acrobat Pro (Acrobat DC, continuous track 26.002.21931, macOS) @@ -109,7 +109,7 @@ total matches the parity estimate. | M8 | Security + redaction | 100–180 | 68% | 15–30 | Done: opening protected documents, permissions, Protect Using Password, Remove security; redaction (mark text/areas/pages, Search & Redact with patterns, apply removing glyphs, image pixels, vectors, XObject content, annotations and fields, verification, full rewrite on save); Remove hidden information and Sanitize.
Done since: redaction codes (U.S. FOIA and Privacy Act sets as overlay text, in Redaction properties and `redact_mark`). Redaction cleans indirect and form structure references, preserving surviving form tags. Vertical-writing text is still refused, and the error no longer claims the text was under the mark (#1340). Missing: certificate security, custom redaction code sets and pattern locales, DCT re-encoding | | M8 | Security + redaction | 100–180 | 68% | 15–30 | Done: opening protected documents, permissions, Protect Using Password, Remove security; redaction (mark text/areas/pages, Search & Redact with patterns, apply removing glyphs, image pixels, vectors, XObject content, annotations and fields, verification, full rewrite on save); Remove hidden information and Sanitize.
Done since: redaction codes (U.S. FOIA and Privacy Act sets as overlay text, in Redaction properties and `redact_mark`). Redaction cleans indirect and form structure references, preserving surviving form tags. Redaction retires inherited resource dictionaries, so a parent `/Pages` can't keep a removed XObject reachable; unredacted pages are left untouched. Missing: certificate security, custom redaction code sets and pattern locales, DCT re-encoding | | M9 | Signatures (PAdES, validation) | 160–280 | 60% | 40–70 | Done: new `sign` crate (DER, X.509, CMS, PKCS #12 on RustCrypto; aws-lc-rs for RSA private keys); PAdES B-B signing (visible, invisible, existing fields, certification with DocMDP); validation with trust store and changes-after-signing classification; self-signed digital IDs; Signatures panel, message bar, sign dialogs; agent tools. Checked with pdfsig and OpenSSL.
Done since: macOS Keychain and Windows Current User Personal store signing (software-backed CNG keys), certificate viewer, signed documents protected from rewrites. Missing: timestamps (B-T), LTV (DSS, OCSP, CRL), FieldMDP, smart cards, PKCS #11 | -| M10 | OCR, create, export, print | 200–350 | 33% | 120–215 | Done: create from blank/text/PNG/JPEG/TIFF (multi-page)/GIF/BMP; export PNG/JPEG/TIFF and text; Print (Acrobat's sizing, n-up, booklet, poster, comments & forms, preview, the CUPS and Windows spoolers, print-ready PDF).
Done since: embedded/72/custom DPI choices for image imports; export all images; OCR (searchable image for pages, ranges and multiple files); single-sided cut-and-stack imposition with cut marks, through Print and doc_print; architectural/ANSI/large ISO sheet presets, Match page at 100% and PDF-scale preview (#599 follow-up); Create PDF from multiple files (PDFs, images and text, edited as pages in the grid); OCR can also read pictures on pages that have text, without adding that text twice (#1028). Done since: Word invoice export uses borderless inferred tables, floating positioned text/artwork only where text overlaps an image or is rotated, and per-page sizes, covered by synthetic invoice automation regressions (#773); printing on the web through the browser's print dialog, sheets drawn by PdfCraft (gap 4). Missing: OCR languages beyond Latin, editable-text OCR output, full Office layout fidelity/import | +| M10 | OCR, create, export, print | 200–350 | 33% | 120–215 | Done: create from blank/text/PNG/JPEG/TIFF (multi-page)/GIF/BMP; export PNG/JPEG/TIFF and text; Print (Acrobat's sizing, n-up, booklet, poster, comments & forms, preview, the CUPS and Windows spoolers, print-ready PDF).
Done since: embedded/72/custom DPI choices for image imports; export all images; OCR (searchable image for pages, ranges and multiple files); single-sided cut-and-stack imposition with cut marks, through Print and doc_print; architectural/ANSI/large ISO sheet presets, Match page at 100% and PDF-scale preview (#599 follow-up); Create PDF from multiple files (PDFs, images and text, edited as pages in the grid); OCR can also read pictures on pages that have text, without adding that text twice (#1028). Done since: Word invoice export uses borderless inferred tables, floating positioned text/artwork only where text overlaps an image or is rotated, and per-page sizes, covered by synthetic invoice automation regressions (#773); printing on the web through the browser's print dialog, sheets drawn by PdfCraft (gap 4). Missing: OCR languages beyond Latin, editable-text OCR output, full Office layout fidelity/import. Done since: dotted-leader contents entries stay in separate complete paragraphs (#1757) | | M11 | Optimize, preflight, PDF/A/X/UA, print production | 200–350 | 18% | 80–140 | Done: new `optimize` crate: Reduce File Size and the PDF Optimizer (images measured where drawn, bicubic downsampling, JPEG/ZIP recompression only when smaller, discard objects and user data, Flate clean-up, resource merging, object streams). Missing: fonts and transparency panels, space audit, preflight, PDF/A/X/UA | | M12 | Accessibility, compare, measure, search, XFA | 200–380 | 30% | 90–160 | Done: new `a11y` crate with the Accessibility Checker (all 32 rules, report, Fix/Skip/Explain, options dialog and results panel, agent tools). Locatable figure, annotation and form findings highlight their page bounds.
Done since: 2D distance, perimeter and area measurements with persistent viewport calibration, snapping, live information and CSV export; a bounded, text-only auto-tag proposal tool for one page. Missing: writing proposed tags and parent tree, field autotag, visual Tags/Order/Content panels, Reading Order tool, compare, geospatial/3D measurement, search index, XFA | | M13 | Automation (MCP, Action Wizard, CLI) + AI providers | 60–120 | 45% | 25–45 | Done: MCP resources (document info, text, page images); headless tool table (123 tools incl. signing, optimizing, initial view, links, stamps, data exchange, comment review, forms authoring and scripts, redaction, sanitize, print, add content), opt-in MCP server over stdio, CLI `run`/`tools` (closed stdout pipes exit cleanly), UI control channel with drag. Missing: Action Wizard, AI providers
Done since: CLI run and MCP reject missing, empty, repeated and option-valued --root arguments before any tool/script execution or MCP initialization. A single-hyphen directory name remains valid; synthetic CLI regressions preserve a would-be overwritten file. `text_find` also caps the per-page match ranges it materializes at the remaining result limit plus one continuation match. CLI robustness scans visit each directory once through overlapping roots and symlink aliases. | @@ -161,6 +161,7 @@ M2 (renderer), M7 (content editing), M10 (OCR and Office), M11 (Preflight and st | Date | Change | Summary | |---|---|---| +| 2026-10-13 | minor | M10: dotted-leader contents entries retain titles and page numbers in separate paragraphs (#1757); estimates unchanged. | | 2026-10-12 | minor | M13: CLI check directory identity, with overlap and symlink regressions; estimates unchanged | | 2026-10-12 | minor | M4: shared Type 3 glyph resources survive extraction, with save/reopen and independent raster regressions; estimates unchanged | | 2026-10-12 | minor | M2: packed TIFF-predictor RGB row boundaries, with decoding and page-render regressions; estimates unchanged | diff --git a/parity/acrobat-features.toml b/parity/acrobat-features.toml index 8f4194b93..ad5a29acf 100644 --- a/parity/acrobat-features.toml +++ b/parity/acrobat-features.toml @@ -6952,8 +6952,8 @@ milestone = "M10" status = "partial" commands = ["export.docx"] tools = ["doc_export_office"] -evidence = ["crates/export/src/lib.rs::word_does_not_invent_borders_for_aligned_invoice_fields", "crates/export/src/lib.rs::word_overlap_does_not_consume_invoice_body_space", "crates/export/src/lib.rs::word_keeps_a_page_with_a_clear_image_and_big_title_in_flow", "crates/export/src/lib.rs::word_rotated_pages_keep_separate_page_sizes_and_unique_shapes", "crates/engine/src/tests.rs::office_export_positions_follow_the_displayed_crop_rotation_and_units", "crates/automation/tests/automation.rs::exporting_an_invoice_to_word_keeps_the_watermark_out_of_flow", "crates/export/src/lib.rs::docx_is_a_word_package", "crates/export/src/lib.rs::text_colour_survives_every_format", "crates/engine/src/tests.rs::exporting_office_files_keeps_text_colour", "crates/export/src/lib.rs::grid_text_becomes_a_real_table_in_every_format", "crates/export/src/lib.rs::word_opens_text_with_control_characters_and_long_pages", "crates/engine/src/tests.rs::exporting_office_files_keeps_images", "crates/automation/tests/automation.rs::exporting_to_word_html_and_rtf", "crates/ui-egui/tests/compare.rs::export_to_word_html_and_rtf"] -notes = "Flowing Word document: paragraphs, Heading 1/2 from larger text, bold/italic, text colour (fill as sRGB; gray/CMYK converted naively, colour spaces via cs/sc read as black), borderless detected tables with spans/empty cells, per-page sections/sizes, and positioned editable text/artwork only for pages with rotated text or text overlapped by an image or watermark-sized text, other pages flowing with inline images (#773); synthetic invoice regression; the emitted package validates with Open XML SDK 2.20 (Office 2010 schema). Word/LibreOffice rendering of the positioned output remains unverified. The earlier flowing output was checked with macOS textutil and opened in Microsoft Word (Windows). Characters XML forbids are dropped; the page size stays within Word's 22 in. Not yet: exact font matching, vector rules, arbitrary paint-order/transparency, colour per run within a paragraph, general exact layout fidelity." +evidence = ["crates/edit/src/tests.rs::reading_keeps_dotted_leader_entries_whole_and_in_order", "crates/engine/src/tests.rs::exporting_office_keeps_dotted_leader_entries_as_paragraphs", "crates/export/src/lib.rs::word_does_not_invent_borders_for_aligned_invoice_fields", "crates/export/src/lib.rs::word_overlap_does_not_consume_invoice_body_space", "crates/export/src/lib.rs::word_keeps_a_page_with_a_clear_image_and_big_title_in_flow", "crates/export/src/lib.rs::word_rotated_pages_keep_separate_page_sizes_and_unique_shapes", "crates/engine/src/tests.rs::office_export_positions_follow_the_displayed_crop_rotation_and_units", "crates/automation/tests/automation.rs::exporting_an_invoice_to_word_keeps_the_watermark_out_of_flow", "crates/export/src/lib.rs::docx_is_a_word_package", "crates/export/src/lib.rs::text_colour_survives_every_format", "crates/engine/src/tests.rs::exporting_office_files_keeps_text_colour", "crates/export/src/lib.rs::grid_text_becomes_a_real_table_in_every_format", "crates/export/src/lib.rs::word_opens_text_with_control_characters_and_long_pages", "crates/engine/src/tests.rs::exporting_office_files_keeps_images", "crates/automation/tests/automation.rs::exporting_to_word_html_and_rtf", "crates/ui-egui/tests/compare.rs::export_to_word_html_and_rtf"] +notes = "Flowing Word document: paragraphs, Heading 1/2 from larger text, bold/italic, text colour (fill as sRGB; gray/CMYK converted naively, colour spaces via cs/sc read as black), borderless detected tables with spans/empty cells, per-page sections/sizes, and positioned editable text/artwork only for pages with rotated text or text overlapped by an image or watermark-sized text, other pages flowing with inline images (#773); synthetic invoice regression; dotted-leader contents entries keep the title, dots and page number together in separate paragraphs (#1757); the emitted package validates with Open XML SDK 2.20 (Office 2010 schema). Word/LibreOffice rendering of the positioned output remains unverified. The earlier flowing output was checked with macOS textutil and opened in Microsoft Word (Windows). Characters XML forbids are dropped; the page size stays within Word's 22 in. Not yet: exact font matching, vector rules, arbitrary paint-order/transparency, colour per run within a paragraph, general exact layout fidelity." [[feature]] id = "create.export-rtf" From 1ff8fe4800bfc5a5e27a121b069c08b276eb97b1 Mon Sep 17 00:00:00 2001 From: sanches Date: Tue, 13 Oct 2026 02:30:32 +0300 Subject: [PATCH 013/498] i18n: add Indonesian and Vietnamese interfaces MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Two new complete catalogs (2542 entries each, full coverage of the uk.tsv key set): Indonesian (id) and Vietnamese (vi), both with a single plural form per CLDR. Registered in LANGUAGES (22 → 24) with locale-tag tests. Also adds Devanagari font support (for the upcoming Hindi catalog) to the fonts crate, and fixes 19 duplicate keys in ru.tsv that crept in during a previous merge. Tests: 110 passed, 0 failed. --- ATTRIBUTION.toml | 22 + ROADMAP.md | 15 +- crates/engine/src/dates.rs | 69 +- crates/fonts/build.rs | 14 +- crates/fonts/src/craft.rs | 14 + crates/fonts/src/lib.rs | 6 +- crates/ui-egui/src/i18n/id.tsv | 2583 ++++++++++++++++++++++++++++++++ crates/ui-egui/src/i18n/mod.rs | 127 +- crates/ui-egui/src/i18n/ru.tsv | 164 +- crates/ui-egui/src/i18n/vi.tsv | 2583 ++++++++++++++++++++++++++++++++ crates/ui-egui/src/theme.rs | 5 +- crates/ui-egui/tests/fonts.rs | 36 +- docs/gaps.md | 12 +- docs/localization-parity.md | 25 +- docs/localization.md | 19 +- docs/roadmap.md | 4 +- docs/target-app-parity.md | 2 +- 17 files changed, 5604 insertions(+), 96 deletions(-) create mode 100644 crates/ui-egui/src/i18n/id.tsv create mode 100644 crates/ui-egui/src/i18n/vi.tsv diff --git a/ATTRIBUTION.toml b/ATTRIBUTION.toml index 28785f767..018b56e1e 100644 --- a/ATTRIBUTION.toml +++ b/ATTRIBUTION.toml @@ -230,6 +230,28 @@ kind = "translation" usage = "Lithuanian UI strings, compiled in by crates/ui-egui/src/i18n/mod.rs" sha256 = "35b6b03dae01b9a2e98f6d1f682d0699d77772e6efec7e28e1f26039c57b151f" +[[asset]] +path = "crates/ui-egui/src/i18n/id.tsv" +title = "Indonesian interface translation catalog" +author = "PdfCraft contributors" +source = "Contributor-original: clean-room translations of PdfCraft's English UI labels, no proprietary localisation resources" +licence = "MIT OR Apache-2.0" +licence_file = "LICENSE-MIT" +kind = "translation" +usage = "Indonesian UI strings, compiled in by crates/ui-egui/src/i18n/mod.rs" +sha256 = "18b59a25fc0798b9f426a2d7d1e4272847df9fa8310de4754bd0b90098dc5cd1" + +[[asset]] +path = "crates/ui-egui/src/i18n/vi.tsv" +title = "Vietnamese interface translation catalog" +author = "PdfCraft contributors" +source = "Contributor-original: clean-room translations of PdfCraft's English UI labels, no proprietary localisation resources" +licence = "MIT OR Apache-2.0" +licence_file = "LICENSE-MIT" +kind = "translation" +usage = "Vietnamese UI strings, compiled in by crates/ui-egui/src/i18n/mod.rs" +sha256 = "21215a2a3489a03050d884b51a512e5c8b58b690dd36e182a4917ddd87b7b922" + [[asset]] path = "assets/icons/accessibility.svg" title = "Lucide icon \"accessibility\"" diff --git a/ROADMAP.md b/ROADMAP.md index b4ab4ea8a..cb9b13008 100644 --- a/ROADMAP.md +++ b/ROADMAP.md @@ -3,6 +3,7 @@ **Stage: alpha** · next: beta, ~26% (ready for real work 49% → 75%) and ~400–700 h away > **Last reviewed:** 2026-10-13 · **Last updated:** 2026-10-13 · **Change:** minor (M3 candidate: native opens retain chosen tools through password retries and defer startup intake while preparation is pending; estimates unchanged) · **Target:** Adobe Acrobat Pro (Acrobat DC, continuous track 26.002.21931, macOS) +> **Last reviewed:** 2026-10-12 · **Last updated:** 2026-10-13 · **Change:** minor (M14 Indonesian and Vietnamese catalogs: localization re-measures at ≈ 76%; the weighted sum is not re-measured here) · **Target:** Adobe Acrobat Pro (Acrobat DC, continuous track 26.002.21931, macOS) > **Last reviewed:** 2026-10-12 · **Last updated:** 2026-10-12 · **Change:** minor (M13: CLI check visits each directory once through aliases and cycles; estimates unchanged) · **Target:** Adobe Acrobat Pro (Acrobat DC, continuous track 26.002.21931, macOS) > **Last reviewed:** 2026-10-12 · **Last updated:** 2026-10-12 · **Change:** minor (M4: Extract and Split preserve shared Type 3 glyph resources; estimates unchanged) · **Target:** Adobe Acrobat Pro (Acrobat DC, continuous track 26.002.21931, macOS) > **Last reviewed:** 2026-10-12 · **Last updated:** 2026-10-12 · **Change:** minor (M2: packed TIFF-predictor RGB rows retain their byte boundaries; estimates unchanged) · **Target:** Adobe Acrobat Pro (Acrobat DC, continuous track 26.002.21931, macOS) @@ -79,7 +80,7 @@ Hours are calibrated as in [Effort and calibration](docs/target-app-parity.md#ef | File formats and conversion | ≈ 40% | 12% | 120–220 (within features) | [file-format-parity.md](docs/file-format-parity.md) | | PDF specification and standards | ≈ 60% | 8% | 150–260 (within features) | [pdf-spec-parity.md](docs/pdf-spec-parity.md) | | Hardware | ≈ 35% | 4% | 25–50 | [hardware-parity.md](docs/hardware-parity.md) | -| Localization | ≈ 59% | 5% | 35–60 | [localization-parity.md](docs/localization-parity.md) | +| Localization | ≈ 76% | 5% | 25–50 | [localization-parity.md](docs/localization-parity.md) | | Performance | ≈ 40% | 6% | 25–45 | [gaps.md](docs/gaps.md) gap 13 | | Stability | ≈ 50% | 8% | 45–80 | [gaps.md](docs/gaps.md) gap 6 | | Platforms | ≈ 70% | 5% | 15–30 | [hardware-parity.md](docs/hardware-parity.md#platforms) | @@ -110,7 +111,7 @@ What's strong and missing in each: [target-app-parity.md](docs/target-app-parity ## Languages -Measured from `crates/ui-egui/src/i18n/*.tsv` (2,143 keys). Detail and script notes: +Measured from `crates/ui-egui/src/i18n/*.tsv` (2,578 keys). Detail and script notes: [localization-parity.md](docs/localization-parity.md). | Language | Code | Strings | Status | @@ -122,11 +123,11 @@ Measured from `crates/ui-egui/src/i18n/*.tsv` (2,143 keys). Detail and script no | Arabic | `ar` | 100% | partial (layout not mirrored) | | French | `fr` | 99.3% | partial | | Portuguese (Brazil) | `pt-br` | 99.4% | partial | -| Indonesian | `id` | 0% | none | +| Indonesian | `id` | 100% | partial | | Japanese | `ja` | 99.1% | partial | | German | `de` | 99.3% | partial | | Korean | `ko` | 0% | none | -| Vietnamese | `vi` | 0% | none | +| Vietnamese | `vi` | 100% | partial | Also shipped: Traditional Chinese, Russian, Bulgarian, Telugu, Hungarian, Ukrainian, Italian (94–100%) and Czech (menus only): **8 more languages**. @@ -150,6 +151,7 @@ Ranked; detail and the full milestone table in [docs/roadmap.md](docs/roadmap.md ## Progress log - **2026-10-13 (M3, native-opening candidate):** Chosen tools survive preparation, conversion and password retries; startup intake waits for pending preparation. Regression tests cover completion, cancellation and document identity. Estimates unchanged. +- **2026-10-13 (M14, Indonesian and Vietnamese):** Two more interface languages, each a full 2,578-key catalog — every `(context, English)` key the bundled catalogs' union holds, covering every registered command, All tools label and `tl!` literal (tests fail if either lags). Neither language inflects nouns for number (CLDR `id` and `vi` have one plural form), so `@plural` entries list one form; month and weekday names for stamps come with them. The bundled Latin faces cover both catalogs, stacked Vietnamese diacritics included (checked in `crates/ui-egui/tests/fonts.rs`, which found and fixed one `▸` Inter cannot draw). Localization re-measures at ≈ 76% (from ≈ 59%: the key union moved to 2,578 with Lithuanian, and Indonesian and Vietnamese now ship); remaining are Hindi and Korean, which need a Devanagari and a Hangul face in craft-fonts. The overall weighted sum still reads ≈ 49% and is not re-measured here. - **2026-10-12 (M10, Windows printing without PowerShell, #1107):** craft-print now prints on Windows in-process: printers from EnumPrinters/GetDefaultPrinter, jobs drawn as vectors by Windows.Data.Pdf into the XPS print API with a driver-validated PrintTicket (exact paper, orientation, no scaling), so printing works where App Control for Business or AppLocker run PowerShell in Constrained Language Mode. Portrait and landscape sheets still print as one job (turned with /Rotate); a sheet size the driver lacks is refused rather than shrunk. Pins craft-libs f03ec27 (craft-libs#28); deny.toml allows the storytold/winprint.rs fork and adds a webpki-root-certs licence exception and a RUSTSEC-2024-0370 ignore for winprint's build-dependencies. An earlier craft-print revision was checked in Windows Sandbox under enforced WDAC: printers listed, CLI and desktop jobs spooled, and no powershell.exe in the 4688 audit. The final pinned revision passed craft-libs Windows CI, including a real paused-queue job; that Sandbox run has not been repeated. Estimates unchanged. - **2026-10-12 (M13, CLI robustness scans):** `pdfcraft-cli check` visits a directory once even when input roots overlap or directory symlinks lead back into the tree. PDFs reached through file symlinks remain accepted. Three real CLI regressions cover overlapping roots, a directory cycle and directory/file aliases. Estimates unchanged. - **2026-10-12 (M4, Type 3 extraction fidelity):** Extract and Split preserve shared image/resource dictionaries reached through Type 3 glyphs, including nested forms, patterns and soft masks. A bounded object-graph walk protects unknown glyph content; unreadable pages/forms retain their glyph resources, and shared explicit fonts are visited once. Separate page dictionaries still prune unused images. Synthetic save/reopen regressions and an opt-in Poppler pixel oracle cover resource ownership, nested forms, cycles, limits and repeated fonts. Estimates unchanged. @@ -165,7 +167,6 @@ Ranked; detail and the full milestone table in [docs/roadmap.md](docs/roadmap.md - **2026-10-12 (M1, #1339):** An incremental save of an unchanged classic-table file used to append `xref` and then `trailer` with no subsection, which qpdf reports as a damaged file. The section now has a zero-length subsection, so no object entry changes and a trailer-only edit is still written. Estimates unchanged. - **2026-10-12 (M12, auto-tag preview):** The engine and `accessibility_autotag_preview` propose paragraph and large-heading roles for bounded text blocks on one page, with locations and reasons. Every proposal needs review; images remain unclassified. No PDF tags are written yet. Synthetic tool tests cover normal text, a larger heading, bounds and unchanged source bytes. Estimates unchanged. - **2026-10-12 (M10, editing OCR text on scans):** Editing a recognised word on a scanned page now changes what the page shows. Before, the rewrite stayed invisible OCR text, so the scan still showed the old word; on a form, the whole OCR layer also grouped into one paragraph that rewrapped when one word changed. OCR words now group into phrases (a table cell or a tab stop splits them, and lines stay apart); an edit draws the phrase visibly in the scan's sampled ink colour over a cover in the sampled paper colour, keeping each word's width and growing rightwards. The editor covers the scanned word while typing. OCR words are now sized from their letters (a capitals-only word's box spans the cap height, not the full ascender-descender span), so recognised and rewritten text is as tall as the scanned word and sits on its baseline. Five engine tests on synthetic scans and a kittest UI test; `ocr.editable-text-output` is partial. -- **2026-10-12 (M2, Lab Bradford follow-up):** Lab white-point adaptation scales Bradford LMS cone responses using LMS white-point ratios. Independent D50 and equal-energy neutral/chromatic render oracles, D65 identity, direct/Indexed consistency with asymmetric chromatic Range, and degenerate-cone fallback cover the correction. CalRGB and the merged Indexed/Range scaling retain their behavior. Estimates unchanged. - **2026-10-12 (community, M14, recovery metadata):** A recovery snapshot whose metadata is missing, damaged or names another snapshot is no longer deleted when the folder is listed: it is offered for recovery without an original path (Save asks for a destination), and encrypted snapshots still ask for their password. Recovering one writes fresh metadata in place of the damaged file, and clearing the folder also removes metadata left without a snapshot. Before, a failed metadata write meant the next start deleted the finished snapshot. Synthetic regressions cover the failed write, missing, corrupt, mismatched and encrypted cases. Estimates unchanged. - **2026-10-12 (M7, Arabic ActualText):** Add text records each shaped line in typing order with `/ActualText`, so copy and search preserve mixed Arabic, Latin, digits and brackets. Edit text keeps the logical order supplied by `/ActualText` instead of reversing Arabic or Hebrew a second time. Adjacent visual glyph runs retain their own bidi recovery. Font-independent tests cover Arabic marks, numbers, Latin words, reopen and complete replacement; automation checks saved editor text and unchanged rendering. Font fallback and bidi typing remain separate gaps; estimates unchanged. - **2026-10-12 (M5, Fill & Sign text size):** The active Fill & Sign toolbar now chooses 4–300 pt for new text and dates; the in-place editor and saved annotation use that size, which persists in local settings. `fill_sign_add` accepts the same `font_size`. Feature and readiness estimates unchanged. @@ -198,8 +199,6 @@ Ranked; detail and the full milestone table in [docs/roadmap.md](docs/roadmap.md Newest first: the date, what moved, and the new overall estimate. -- **2026-10-12 (M3, GNOME title bar, #553):** On GNOME's Wayland session, whose compositor draws no window frames (it offers no `zxdg_decoration_manager_v1`), PdfCraft no longer shows winit's fallback title bar: it turns the frame off and the tab strip becomes the header bar, as in GNOME's own apps. Minimize, maximize/restore and close are drawn in Adwaita's style, in the order and on the side GNOME's `button-layout` names (Fedora's default shows only close); the window's edges and corners resize it, and a hairline outlines it while it isn't maximized. Preferences ▸ Use system title bar (shown only there) gives the window back winit's frame at once, without a restart (part of #1001), and `PDFCRAFT_TITLEBAR=app|system` overrides the choice. KDE, Sway, Hyprland, COSMIC and X11 keep the frame their desktop draws. Not done: right-clicking the header bar doesn't open GNOME's window menu (egui can't ask for it), the window has no shadow or rounded corners, the resize edges lie just inside the window rather than outside it, and Windows still uses its system frame (the rest of #1001). Estimates unchanged. -- **2026-10-12 (M0, build label):** A local or patched build can carry a label, set at compile time with `PDFCRAFT_BUILD_LABEL`: `pdfcraft --version`, `pdfcraft-cli --version`, About and the log show `0.7.1 (titlebar)`, and `packaging/linux/package.sh` names the files `pdfcraft-0.7.1-titlebar-…` and makes the .rpm/.deb release `1.titlebar`, which upgrades over the release of the same version (and the next release over it). The version itself is unchanged, so the update check still compares it with published releases. Unlabelled builds are as before. Estimates unchanged. - 2026-10-11: Organize Pages shows an editable, synchronized physical page-range selection (#1092), with bounded validation and UI/operation regression coverage; overall estimate unchanged. - **2026-10-11 (M5.7, scanned signatures, #1110):** Fill & Sign ▸ Add signature has a Scan tab: a phone photo of a signature on paper is framed automatically (all words; table, sheet edge and dust ignored; a sideways signature turned upright), the frame can be moved, resized or redrawn, the photo turned, and an ink-sensitivity slider picks up faint ink. A morphological paper estimate removes shadows and uneven light, and the trimmed ink is saved and reused like an image signature. Photos and images can also be dropped on the Image and Scan tabs. Photos keep the image-signature limits (#1124: a 4 MiB file, up to 32 megapixels decoded, scaled down to 4 megapixels), so a scan never processes more than 4 megapixels. `fill_sign_add` takes `scan` and `sensitivity`. Synthetic engine, UI and automation tests; checked by hand on real phone photos. Milestone and effort estimates unchanged. @@ -427,8 +426,6 @@ Newest first: the date, what moved, and the new overall estimate. | Date | Change | Summary | |---|---|---| -| 2026-10-12 | minor | M3/#1364 candidate: absolute local GoToR links require desktop consent or headless allow_absolute; existing relative navigation and validation retained. Estimates unchanged. | -| 2026-10-12 | minor | M8: redaction retires inherited `/Resources` so a parent `/Pages` can't keep a removed XObject reachable; only redacted pages that inherit are pinned (one shared reference), unredacted pages are untouched; estimates unchanged | | 2026-10-12 | minor | M7/#1200 candidate: bounded local GoToR opening, root-confined automation, and action-preserving appearance edits; named destinations and window behavior remain partial; estimates unchanged. | | 2026-10-12 | minor | Exclusive image crops resize with their pixels across nested states, intervening operators and content streams; shared clips remain fixed. Synthetic engine/tool regressions and private image save/reopen checks; estimates unchanged. | | 2026-10-11 | minor | M10: borderless inferred tables and positioned invoice watermarks (#773); estimates unchanged. | diff --git a/crates/engine/src/dates.rs b/crates/engine/src/dates.rs index e26d9ec60..da1f5937e 100644 --- a/crates/engine/src/dates.rs +++ b/crates/engine/src/dates.rs @@ -56,7 +56,7 @@ const AR_DAYS: [&str; 7] = ["الأحد", "الاثنين", "الثلاثاء", /// The languages month and weekday names can be written in (Preferences ▸ Date format ▸ Language): /// the interface languages, in the same order and with the same names. -pub static DATE_LANGUAGES: [DateLanguage; 22] = [ +pub static DATE_LANGUAGES: [DateLanguage; 24] = [ DateLanguage { code: "en", name: "English", @@ -360,6 +360,54 @@ pub static DATE_LANGUAGES: [DateLanguage; 22] = [ days: ["sekmadienis", "pirmadienis", "antradienis", "trečiadienis", "ketvirtadienis", "penktadienis", "šeštadienis"], days_short: ["sk", "pr", "an", "tr", "kt", "pn", "št"], }, + // Indonesian. Month and weekday names are the same with and after a day number, so + // `months_with_day` is `None`. + DateLanguage { + code: "id", + name: "Bahasa Indonesia", + months: ["Januari", "Februari", "Maret", "April", "Mei", "Juni", "Juli", "Agustus", "September", "Oktober", "November", "Desember"], + months_with_day: None, + months_short: ["Jan", "Feb", "Mar", "Apr", "Mei", "Jun", "Jul", "Agu", "Sep", "Okt", "Nov", "Des"], + days: ["Minggu", "Senin", "Selasa", "Rabu", "Kamis", "Jumat", "Sabtu"], + days_short: ["Min", "Sen", "Sel", "Rab", "Kam", "Jum", "Sab"], + }, + // Vietnamese: the month name is `tháng Một` with a day number and `Tháng Một` standing + // alone, as in English. + DateLanguage { + code: "vi", + name: "Tiếng Việt", + months: [ + "Tháng Một", + "Tháng Hai", + "Tháng Ba", + "Tháng Tư", + "Tháng Năm", + "Tháng Sáu", + "Tháng Bảy", + "Tháng Tám", + "Tháng Chín", + "Tháng Mười", + "Tháng Mười Một", + "Tháng Mười Hai", + ], + months_with_day: Some([ + "tháng Một", + "tháng Hai", + "tháng Ba", + "tháng Tư", + "tháng Năm", + "tháng Sáu", + "tháng Bảy", + "tháng Tám", + "tháng Chín", + "tháng Mười", + "tháng Mười Một", + "tháng Mười Hai", + ]), + months_short: ["Thg 1", "Thg 2", "Thg 3", "Thg 4", "Thg 5", "Thg 6", "Thg 7", "Thg 8", "Thg 9", "Thg 10", "Thg 11", "Thg 12"], + days: ["Chủ Nhật", "Thứ Hai", "Thứ Ba", "Thứ Tư", "Thứ Năm", "Thứ Sáu", "Thứ Bảy"], + days_short: ["CN", "T2", "T3", "T4", "T5", "T6", "T7"], + }, ]; /// The date language for `code` (any case), or `None` when there's none. @@ -660,6 +708,25 @@ mod tests { assert_eq!(in_lang("dddd, mmmm", "cs"), "sobota, březen"); } + /// Indonesian month names are the same with and after a day number; Vietnamese lowers `tháng` + /// after a day number and keeps it capitalised standing alone. + #[test] + fn indonesian_and_vietnamese_month_and_weekday_names() { + assert_eq!(in_lang("d mmmm yyyy", "id"), "7 Maret 2026"); + assert_eq!(in_lang("mmmm yyyy", "id"), "Maret 2026"); + assert_eq!(in_lang("dddd, d mmmm yyyy", "id"), "Sabtu, 7 Maret 2026"); + assert_eq!(in_lang("d mmmm yyyy", "vi"), "7 tháng Ba 2026"); + assert_eq!(in_lang("mmmm yyyy", "vi"), "Tháng Ba 2026"); + assert_eq!(in_lang("ddd, d mmm", "vi"), "T7, 7 Thg 3"); + // Indonesian month names are Latin, so they reach a PDF; Vietnamese ones are not Western + // European, and the date-text path refuses them with what to use instead. + let mut s = Session::new().with_clock(|| 1_700_000_000); + s.set_date_language(Some("vi")).unwrap(); + assert!(s.today_text_for_pdf(Some("d mmmm yyyy"), None).unwrap_err().contains("dd.mm.yyyy")); + s.set_date_language(Some("id")).unwrap(); + assert_eq!(s.today_text_for_pdf(Some("d mmmm yyyy"), None).as_deref(), Ok("14 November 2023")); + } + #[test] fn the_session_writes_names_in_its_date_language() { let mut s = Session::new().with_clock(|| 1_700_000_000); diff --git a/crates/fonts/build.rs b/crates/fonts/build.rs index 9be57030e..397f6fc38 100644 --- a/crates/fonts/build.rs +++ b/crates/fonts/build.rs @@ -1,8 +1,8 @@ //! Embeds the fonts of the optional craft-fonts build input (`CRAFT_FONTS_DIR`) as `CRAFT_FONTS`. //! The recipe is craft-fonts' `docs/integration.md`; unset, `CRAFT_FONTS` is empty. It only reads //! the local checkout (no network). On wasm32 it embeds only the UI faces (BIZ UDPGothic Regular -//! and any `Arab`, `Telu`, `Hebr` or `Thai` face), to keep the web build within hosting limits (Cloudflare Pages: -//! 25 MiB per file). +//! and any `Arab`, `Telu`, `Hebr`, `Thai` or `Deva` face), to keep the web build within hosting +//! limits (Cloudflare Pages: 25 MiB per file). use std::fmt::Write as _; use std::path::PathBuf; @@ -55,8 +55,14 @@ fn craft_fonts(dir: &std::path::Path) -> Result { let telugu = scripts.split(',').any(|s| s.trim() == "Telu"); // And the Hebrew ones (small), for Hebrew text and Edit text on the web. let hebrew = scripts.split(',').any(|s| s.trim() == "Hebr"); - let web_face = - (*family == "BIZ UDPGothic" && *style == "Regular") || arabic || telugu || hebrew || scripts.split(',').any(|s| s.trim() == "Thai"); + // Devanagari too, for the Hindi interface (one small face). + let devanagari = scripts.split(',').any(|s| s.trim() == "Deva"); + let web_face = (*family == "BIZ UDPGothic" && *style == "Regular") + || arabic + || telugu + || hebrew + || scripts.split(',').any(|s| s.trim() == "Thai") + || devanagari; if wasm && !web_face { continue; } diff --git a/crates/fonts/src/craft.rs b/crates/fonts/src/craft.rs index 099179cf2..ca5aa24e0 100644 --- a/crates/fonts/src/craft.rs +++ b/crates/fonts/src/craft.rs @@ -75,6 +75,20 @@ pub fn document_thai_font() -> Option<&'static CraftFont> { ui_thai_fonts().into_iter().next() } +/// The `Deva` craft-fonts faces for Devanagari interface text (the Hindi catalog, file names, +/// document titles), in manifest order. Empty when built without craft-fonts or when its revision +/// has no Devanagari face; a desktop build then falls back to one font already installed on the +/// machine (`SYSTEM_DEVANAGARI_FALLBACK`), and the web build shows replacement boxes. +pub fn ui_devanagari_fonts() -> Vec<&'static CraftFont> { + CRAFT_FONTS.iter().filter(|f| f.covers("Deva")).collect() +} + +/// The face for Devanagari text written into PDFs: the first `Deva` face. `None` when built +/// without craft-fonts or when its revision has no Devanagari face. +pub fn document_devanagari_font() -> Option<&'static CraftFont> { + ui_devanagari_fonts().into_iter().next() +} + /// The `Hebr` craft-fonts faces for Hebrew interface text (file names, document titles, text /// being edited), in manifest order. Empty when built without craft-fonts or when it has no /// Hebrew face. diff --git a/crates/fonts/src/lib.rs b/crates/fonts/src/lib.rs index 622c609f6..140e5619c 100644 --- a/crates/fonts/src/lib.rs +++ b/crates/fonts/src/lib.rs @@ -16,9 +16,9 @@ mod shaping; pub mod source_shaping; mod std14; pub use craft::{ - CRAFT_FONTS, CraftFont, SHIPPORI_MINCHO, document_arabic_font, document_hebrew_font, document_japanese_font, document_japanese_font_for_style, - document_japanese_fonts_for_style, document_thai_font, ui_arabic_fonts, ui_chinese_fonts, ui_cjk_fonts, ui_hebrew_fonts, ui_japanese_fonts, - ui_telugu_fonts, ui_thai_fonts, + CRAFT_FONTS, CraftFont, SHIPPORI_MINCHO, document_arabic_font, document_devanagari_font, document_hebrew_font, document_japanese_font, + document_japanese_font_for_style, document_japanese_fonts_for_style, document_thai_font, ui_arabic_fonts, ui_chinese_fonts, ui_cjk_fonts, + ui_devanagari_fonts, ui_hebrew_fonts, ui_japanese_fonts, ui_telugu_fonts, ui_thai_fonts, }; pub use script::{ GlyphError, GlyphOutline, INTER_REGULAR, MAX_SIGNATURE_CHARS, ScriptOutline, japanese_glyph, japanese_glyph_from, script_missing, script_outline, diff --git a/crates/ui-egui/src/i18n/id.tsv b/crates/ui-egui/src/i18n/id.tsv new file mode 100644 index 000000000..f1f5475f2 --- /dev/null +++ b/crates/ui-egui/src/i18n/id.tsv @@ -0,0 +1,2583 @@ +# Indonesian (id) catalog. Columns, separated by a TAB: context source translation +# +# Clean-room translations of PdfCraft's English UI labels. Use standard Indonesian computing +# terms; keep product and format names (PdfCraft, PDF, PDF/A, OCR, XFA, Word...) unchanged. +# Indonesian does not inflect nouns for number, so @plural entries list one form. + Menu Menu + Edit Edit + Pages Halaman + View Lihat + Help Bantuan + Zoom Zoom + Actual size Ukuran sebenarnya + Zoom to page level Zoom ke tingkat halaman + Fit to width Sesuaikan lebar + Display theme Tema tampilan + Side panels Panel samping + Preferences Preferensi + Preferences… Preferensi… + Interface language Bahasa antarmuka + Interface size Ukuran antarmuka + Auto ({percent}%) Otomatis ({percent}%) + Identity Identitas + Name on new comments Nama untuk komentar baru + Open… Buka… + Open Recent Buka yang baru saja dibuka + Clear Recent Files Hapus File Terbaru + Remove from Recent Hapus dari Terbaru + No recent files Tidak ada file terbaru + New blank PDF PDF kosong baru + Create PDF from file… Buat PDF dari file… + Create PDF from images… Buat PDF dari gambar… + Create PDF from multiple files… Buat PDF dari beberapa file… + Create separate PDFs… Buat PDF terpisah… + Create PDF from clipboard Buat PDF dari papan klip + Combine files… Gabung file… + Save Simpan + Save as… Simpan sebagai… + Close file Tutup file + Close all Tutup semua + Revert Kembalikan + Print… Cetak… + Document properties… Properti dokumen… + Find… Cari… + Advanced search… Pencarian lanjutan… + Copy Salin + Cut Potong + Paste Tempel + Delete Hapus + Select all Pilih semua + Cancel Batal + OK OK + Apply Terapkan + Close Tutup + Back Kembali + Next Berikutnya + Previous Sebelumnya + Name Nama + File name Nama file + Location Lokasi + Browse… Telusuri… + Choose… Pilih… + Search Cari + Clear Bersihkan + Refresh Segarkan + Loading… Memuat… + Save changes? Simpan perubahan? + Don't save Jangan simpan + Page Halaman + Page {n} Halaman {n} + of dari + Fit one full page muatkan satu halaman penuh + Single page Satu halaman + Two-page view Tampilan dua halaman + Continuous scrolling Gulir terus-menerus + Page display Tampilan halaman + Default page display Tampilan halaman bawaan + Default zoom Zoom bawaan + Full screen mode Mode layar penuh + Read mode Mode baca + Comments Komentar + Comment Komentar + Add comment Tambah komentar + Delete comment Hapus komentar + Reply Balas + Highlight Sorot + Underline Garis bawah + Strikethrough Coret + Text Teks + Font Font + Size Ukuran + Color Warna + Opacity Opasitas + Width Lebar + Height Tinggi + Rotation Rotasi + More Lainnya + Settings Pengaturan + General Umum + Language Bahasa + Appearance Tampilan + Theme Tema + Light Terang + Dark Gelap + System Sistem + Open file Buka file + Save file Simpan file + Export Ekspor + Import Impor + Export to image… Ekspor ke gambar… + Export to text… Ekspor ke teks… + Export to Word… Ekspor ke Word… + Export to HTML… Ekspor ke HTML… + Export to RTF… Ekspor ke RTF… + Reduce file size… Perkecil ukuran file… + Optimize PDF… Optimalkan PDF… + Protect using password… Lindungi dengan kata sandi… + Remove security Hapus keamanan + Security properties… Properti keamanan… + Organize pages Atur halaman + Rotate pages… Putar halaman… + Delete pages Hapus halaman + Insert blank page Sisipkan halaman kosong + Insert pages from file… Sisipkan halaman dari file… + Replace pages… Ganti halaman… + Extract pages… Ekstrak halaman… + Split document… Pisah dokumen… + Number pages… Nomor halaman… + Bookmarks Bookmark + New bookmark Bookmark baru + Forms Formulir + Form fields Kolom formulir + Signatures Tanda tangan + Sign Tanda tangani + Fill & Sign Isi & Tanda Tangani + Accessibility Aksesibilitas + Help… Bantuan… + Check for updates… Periksa pembaruan… + About PdfCraft Tentang PdfCraft + Automatically Otomatis + Never Tidak pernah + Always Selalu + Yes Ya + No Tidak + On Aktif + Off Nonaktif + Enabled Aktif + Disabled Nonaktif + Required Wajib + Optional Opsional + None Tidak ada + Unknown Tidak diketahui + Error Kesalahan + Warning Peringatan + Information Informasi + Success Berhasil + Failed Gagal + File File + Folder Folder + Choose a file… Pilih file… + Choose a folder… Pilih folder… + Open folder Buka folder + Create folder Buat folder + Remove Hapus + Rename Ganti nama + Duplicate Duplikat + Move Pindahkan + Copy to clipboard Salin ke papan klip + Copied to clipboard Disalin ke papan klip + Undo Urungkan + Redo Ulangi + Keyboard shortcuts Pintasan keyboard + Find tools and commands… Cari alat dan perintah… + Take a snapshot Ambil cuplikan + Organize Atur + Comment and review Komentar dan tinjau + Prepare a form Siapkan formulir + Protect Lindungi + Print Cetak + Create Buat + Convert Konversi + Optimize Optimalkan + Measure Ukur + Redact Sensor + Search results Hasil pencarian + No results Tidak ada hasil + Page {n} of {total} Halaman {n} dari {total} + {n} pages selected {n} halaman dipilih + · not fixable here · tidak dapat diperbaiki di sini + (page {p}) (halaman {p}) + (searching… {s} of {p} pages) (mencari… {s} dari {p} halaman) + ({n} at {dpi} dpi, the largest size they can be drawn at) ({n} pada {dpi} dpi, ukuran terbesar yang dapat digambarnya) + ({s} not exported: {first}) ({s} tidak diekspor: {first}) + on page {p} di halaman {p} + · password-protected · dilindungi kata sandi + (none) (tidak ada) + , Expires: , Berlaku hingga: + 1 difference found 1 perbedaan ditemukan + 1 file 1 file + 1 file done 1 file selesai + 1 file needs attention 1 file perlu perhatian + 1 instance 1 instans + 1 issue 1 masalah + 1 mark 1 tanda + 1 page 1 halaman + 1 page selected 1 halaman dipilih + 1 page selected. 1 halaman dipilih. + 180 degrees 180 derajat + 9 digit, A letter, O letter or digit, X any character 9 angka, A huruf, O huruf atau angka, X karakter apa pun + ; 1 page already had text ; 1 halaman sudah memiliki teks + ; failed: {list} ; gagal: {list} + ; {n} pages already had text ; {n} halaman sudah memiliki teks + ? of {n} ? dari {n} + A clean-room, open-source PDF application written in Rust. MIT OR Apache-2.0. Aplikasi PDF clean-room sumber terbuka yang ditulis dengan Rust. MIT OR Apache-2.0. + Accessibility Checker Pemeriksa Aksesibilitas + Accessibility Checker Options Opsi Pemeriksa Aksesibilitas + Acrobat 3.0 and later (40-bit RC4) Acrobat 3.0 dan yang lebih baru (40-bit RC4) + Acrobat 5.0 and later (128-bit RC4) Acrobat 5.0 dan yang lebih baru (128-bit RC4) + Acrobat 7.0 and later (128-bit AES) Acrobat 7.0 dan yang lebih baru (128-bit AES) + Acrobat X and later (256-bit AES) Acrobat X dan yang lebih baru (256-bit AES) + Action name: Nama tindakan: + Actions Tindakan + Active Aktif + Actual Size Ukuran sebenarnya + Actual text Teks aktual + Add Tambah + Add Step Tambah Langkah + Add a comment Tambahkan komentar + Add a reply Tambahkan balasan + Add a sticky note here Tambahkan catatan tempel di sini + Add an Action Tambahkan Tindakan + Add at least two files Tambahkan setidaknya dua file + Add files… Tambahkan file… + Add folder Tambahkan folder + Add folder and subfolders Tambahkan folder dan subfolder + Add folder and subfolders… Tambahkan folder dan subfolder… + Add folder… Tambahkan folder… + Add open documents Tambahkan dokumen terbuka + Add the choices people pick from. Tambahkan pilihan-pilihan yang dapat dipilih orang. + Add the files to combine Tambahkan file yang akan digabung + Add the steps this action runs, in order. Tambahkan langkah-langkah yang dijalankan tindakan ini, secara berurutan. + Add to Trusted Certificates Tambahkan ke Sertifikat Tepercaya + Add to trusted certificates Tambahkan ke sertifikat terpercaya + Added 1 comment Ditambahkan 1 komentar + Added more than once Ditambahkan lebih dari sekali + Added {n} comments Ditambahkan {n} komentar + Adds invisible text over each word; the page image is not changed Menambahkan teks tak terlihat di atas setiap kata; gambar halaman tidak diubah + Advanced Lanjutan + Advanced Options {chevron} Opsi Lanjutan {chevron} + Align Ratakan + Align left Rata kiri + Align right Rata kanan + Alignment: Perataan: + All Semua + All document contents Seluruh isi dokumen + All document contents except metadata Seluruh isi dokumen kecuali metadata + All open documents Semua dokumen terbuka + All pages Semua halaman + All pages in document Semua halaman dalam dokumen + All pages in range Semua halaman dalam rentang + Allow Rich Text Formatting Izinkan Pemformatan Teks Kaya + Allow user to enter custom text Izinkan pengguna memasukkan teks kustom + Also recognize pages that already have text Kenali juga halaman yang sudah memiliki teks + Alternate text Teks alternatif + An action with this name already exists. Tindakan dengan nama ini sudah ada. + An open-source PDF workbench — local, private, and scriptable. Meja kerja PDF sumber terbuka — lokal, privat, dan dapat diotomatisasi dengan skrip. + Angle Sudut + Animation effects Efek animasi + Annotations, form fill-in, and digital signatures Anotasi, pengisian formulir, dan tanda tangan digital + Any Apa pun + Any except extracting pages Apa pun kecuali ekstraksi halaman + Anyone opening the document will need this password. It's applied when you save. Siapa pun yang membuka dokumen ini akan memerlukan kata sandi ini. Berlaku saat Anda menyimpan. + Appear behind page Tampil di belakang halaman + Appear on top of page Tampil di atas halaman + Appearance mode Mode tampilan + Appearance settings… Pengaturan tampilan… + Applies to 1 page Berlaku untuk 1 halaman + Applies to {n} pages Berlaku untuk {n} halaman + Apply redactions Terapkan penyensoran + Apply scale Terapkan skala + Asks GitHub for the latest release. Nothing is downloaded or installed automatically. Meminta rilis terbaru dari GitHub. Tidak ada yang diunduh atau dipasang secara otomatis. + At most Paling banyak + Attachments Lampiran + Attachments Panel and Page Panel Lampiran dan Halaman + Audit space usage… Audit penggunaan ruang… + Author Penulis + Auto Otomatis + Auto follows the system's text size. Pages always render at the display's full resolution. Otomatis mengikuti ukuran teks sistem. Halaman selalu dirender pada resolusi penuh layar. + Auto portrait/landscape Potret/landscape otomatis + Auto-rotate pages Putar halaman otomatis + Auto-size text to fit redaction region Sesuaikan ukuran teks otomatis agar pas dengan area penyensoran + Available Tersedia + Back side only Hanya sisi belakang + Back to all tools Kembali ke semua alat + Back to the document Kembali ke dokumen + Before each selected page (select pages in Organize) Sebelum setiap halaman yang dipilih (pilih halaman di Atur) + Before the number Sebelum nomor + Bicubic downsampling to Downsampling bikubik hingga + Binding Pengikatan + Binding: Pengikatan: + Black and white Hitam dan putih + Bold Tebal + Booklet Buku kecil + Booklet subset: Subset buku kecil: + Bookmark options Opsi bookmark + Bookmarks Panel and Page Panel Bookmark dan Halaman + Border Color: Warna Garis Batas: + Borders and Colors Garis Batas dan Warna + Both sides Kedua sisi + Bottom Bawah + Bottom: Bawah: + Box Kotak + Browser's print dialog Dialog cetak browser + Butt Rata + Button is checked by default Tombol tercentang secara bawaan + Buttons with the same name and value are selected in unison Tombol dengan nama dan nilai yang sama dipilih bersama-sama + Bytes Byte + Calibrate from two points Kalibrasi dari dua titik + Can't be read: {e} Tidak dapat dibaca: {e} + Cancelling… Membatalkan… + Case-sensitive Pezonan huruf besar-kecil + Category: Kategori: + Center Tengah + Center window on screen Pusatkan jendela di layar + Centre Tengah + Certify Sertifikasi + Change settings… Ubah pengaturan… + Change the colour of line art as well as text Ubah warna gambar garis serta teks + Change {what} Ubah {what} + Changes allowed Perubahan yang diizinkan + Character limit 0 means no limit. A comb of characters needs a limit. Batas karakter 0 berarti tanpa batas. Susunan karakter memerlukan batas. + Character spacing Spasi karakter + Check Again Periksa Lagi + Check again Periksa lagi + Check box is checked by default Kotak centang tercentang secara bawaan + Check for updates Periksa pembaruan + Check spelling Periksa ejaan + Check the pages Periksa halaman + Check the pages of {name}: {why} Periksa halaman {name}: {why} + Checking Options ({on} of 32 in all categories) Memeriksa Opsi ({on} dari 32 di semua kategori) + Checking for a newer version… Mencari versi yang lebih baru… + Choose a PNG or JPEG image (up to 4 MiB). Transparency is preserved. Pilih gambar PNG atau JPEG (hingga 4 MiB). Transparansi dipertahankan. + Choose a folder for the exported files Pilih folder untuk file yang diekspor + Choose a folder for the extracted pages Pilih folder untuk halaman yang diekstrak + Choose a folder for the results Pilih folder untuk hasil + Choose a folder for the searchable files Pilih folder untuk file yang dapat dicari + Choose a layout: Pilih tata letak: + Choose a stamp, then click on the page to place it. Pilih stempel, lalu klik pada halaman untuk menempatkan. + Choose an image Pilih gambar + Choose images Pilih gambar + Choose image… Pilih gambar… + Choose photo… Pilih foto… + Choose the digital ID that you want to use for signing: Pilih ID digital yang ingin Anda gunakan untuk menandatangani: + Circle Lingkaran + Clean Up Bersihkan + Clean-up Pembersihan + Clear All Hapus Semua + Clear all Hapus semua + Clear selection / close find Hapus pilihan / tutup pencarian + Click on the page to add text; each click starts a new box, and ✓ finishes. Drag items to move them, drag a corner to resize, double-click text to edit it. Klik pada halaman untuk menambahkan teks; setiap klik memulai kotak baru, dan ✓ menyelesaikannya. Seret item untuk memindahkannya, seret sudut untuk mengubah ukurannya, klik dua kali teks untuk mengeditnya. + Click the first point to begin. Klik titik pertama untuk memulai. + Click to sort, drag to move the column. Drag its edge to resize it. Klik untuk mengurutkan, seret untuk memindahkan kolom. Seret tepinya untuk mengubah ukurannya. + Click vertices. Enter or double-click finishes a perimeter or area. Click the first point to close an area. Klik titik sudut. Enter atau klik dua kali menyelesaikan perimeter atau area. Klik titik pertama untuk menutup area. + Clockwise 90 degrees 90 derajat searah jarum jam + Close (Esc) Tutup (Esc) + Close Tab Tutup Tab + Close panel Tutup panel + Closed arrow Panah tertutup + Collapse Ciutkan + Collapse all Ciutkan semua + Collapse all bookmarks Ciutkan semua bookmark + Collapse tag Ciutkan tag + Collate Susun + Color: Warna: + Colour Warna + Colours are remapped while rendering; the document itself never changes. Warna dipetakan ulang saat merender; dokumen itu sendiri tidak pernah berubah. + Comb of Comb dari + Combine the rest Gabungkan sisanya + Combined {n} files Menggabungkan {n} file + Coming in milestone Segera hadir di milestone + Comment and form data Komentar dan data formulir + Commenting, filling in form fields, and signing existing signature fields Memberi komentar, mengisi kolom formulir, dan menandatangani kolom tanda tangan yang ada + Comments & Forms Komentar & Formulir + Comments only Hanya komentar + Commit selected value immediately Langsung terapkan nilai yang dipilih + Common Properties Properti Umum + Compare Files Bandingkan File + Compare this file with an older version: Compare files… in All tools. Bandingkan file ini dengan versi lama: Bandingkan file… di Semua alat. + Compatibility Kompatibilitas + Compress document structure (object streams) Kompres struktur dokumen (object streams) + Compression Kompresi + Configure New Digital ID Konfigurasi ID Digital Baru + Confirm Password Konfirmasi Kata Sandi + Conformance level: Tingkat kesesuaian: + Continue Lanjutkan + Copies, two-sided printing and colour are chosen in the browser's print dialog. Jumlah salinan, cetak dua sisi, dan warna dipilih dalam dialog cetak browser. + Copies: Salinan: + Copy selected text Salin teks yang dipilih + Copy text Salin teks + Couldn't check for updates: {e} Tidak dapat memeriksa pembaruan: {e} + Couldn't open the printer's preferences: {e} Tidak dapat membuka preferensi printer: {e} + Counterclockwise 90 degrees 90 derajat berlawanan arah jarum jam + Country/Region Negara/Wilayah + Create Custom Stamp Buat Stempel Kustom + Create Link Buat Tautan + Create PDF Comment Summary Buat Ringkasan Komentar PDF + Create PDF comment summary… Buat ringkasan komentar PDF… + Create PDF from images Buat PDF dari gambar + Create a new Digital ID (self-signed, saved to a password-protected file) Buat ID digital baru (ditandatangani sendiri, disimpan dalam file terlindungi kata sandi) + Create accessibility report Buat laporan aksesibilitas + Create custom stamp… Buat stempel kustom… + Create {what} Buat {what} + Created a PDF from {n} files Membuat PDF dari {n} file + Created a PDF from {n} files; left out: {names} Membuat PDF dari {n} file; tidak disertakan: {names} + Creates 1 file from {n} pages. Membuat 1 file dari {n} halaman. + Creates {f} files from {n} pages. Membuat {f} file dari {n} halaman. + Crop (% trimmed from each side) Potong (% dipangkas dari setiap sisi) + Currency symbol: Simbol mata uang: + Current page Halaman saat ini + Current page ({n}) Halaman saat ini ({n}) + Current page — type a page number or label (such as iv) and press Enter Halaman saat ini — ketik nomor atau label halaman (misalnya iv) lalu tekan Enter + Custom Kustom + Custom scale: Skala kustom: + Custom text: Teks kustom: + Custom: Kustom: + Cut and stack Potong dan tumpuk + Cut marks Tanda potong + DPI sets the printed page size without resampling the image. DPI mengatur ukuran halaman cetak tanpa mengambil ulang sampel gambar. + Dark theme Tema gelap + Date format Format tanggal + Decimal places: Tempat desimal: + Decimals Desimal + Declared conformance: {shown} Kesesuaian yang dinyatakan: {shown} + Decorative figure Gambar dekoratif + Default Bawaan + Default Value: Nilai Bawaan: + Default workspace mode Mode ruang kerja bawaan + Default: Bawaan: + Delete page {label} Hapus halaman {label} + Delete pages (Delete) Hapus halaman (Hapus) + Delete pages after extracting Hapus halaman setelah mengekstrak + Delete selected pages (Organize) Hapus halaman yang dipilih (Atur halaman) + Delete stamp Hapus stempel + Delete {o} Hapus {o} + Describe the figure Jelaskan gambarnya + Description Deskripsi + Description: Deskripsi: + Details Detail + Diamond Belah ketupat + Digital ID ID Digital + Digital ID password Kata sandi ID Digital + Direction: Arah: + Discard Buang + Discard Objects Buang Objek + Discard User Data Buang Data Pengguna + Discard alternate images Buang gambar alternatif + Discard document tags Buang tag dokumen + Discard embedded page thumbnails Buang thumbnail halaman yang tertanam + Discard embedded print settings Buang pengaturan cetak yang tertanam + Discard this text (Esc) Buang teks ini (Esc) + Dismiss Tutup + Distinguished name Nama distinguished + Distribute Distribusikan + Document Dokumen + Document Properties Properti Dokumen + Document Title Judul Dokumen + Document and markups Dokumen dan anotasi + Document and stamps Dokumen dan stempel + Document language Bahasa dokumen + Document properties ({key}) Properti dokumen ({key}) + Documents and view Dokumen dan tampilan + Done Selesai + Done adding text Selesai menambahkan teks + Download Unduh + Downsample to Turunkan sampel ke + Drag the selection to move it. Esc clears the selection. Seret pilihan untuk memindahkannya. Esc menghapus pilihan. + Drag to reorder Seret untuk mengurutkan ulang + Draw Gambar + Draw your {what} below. Gambar {what} Anda di bawah. + Drawing scale changes. Use Actual size for full-scale plans. Skala gambar berubah. Gunakan Ukuran sebenarnya untuk gambar berskala penuh. + Drop PDFs, images, text files or folders here, or choose them. Jatuhkan PDF, gambar, file teks, atau folder di sini, atau pilih dari komputer. + Duplicate "{name}" onto: Duplikasi "{name}" ke: + Duplicate Field Duplikasi Kolom + Duplicate… Duplikasi… + Dynamic Dinamis + Dynamic XFA form laid out from its template: {pages}, {fields}. Formulir XFA dinamis ditata dari templatenya: {pages}, {fields}. + Each file holds as many of the {n} pages as fit. Setiap file memuat sebanyak mungkin dari {n} halaman yang muat. + Each image is measured where pages draw it; an image is replaced only if the result is smaller. Setiap gambar diukur di tempat halaman menampilkannya; gambar hanya diganti jika hasilnya lebih kecil. + Each image once, named after the document and page. JPEG images are saved unchanged; others as PNG. Setiap gambar sekali, diberi nama sesuai dokumen dan halamannya. Gambar JPEG disimpan apa adanya; lainnya sebagai PNG. + Earlier in tab order Lebih awal dalam urutan tab + Edit Action Ubah Tindakan + Edit image Edit gambar + Edit text… Edit teks… + Edit… Edit… + Email Address Alamat Email + Enable Acrobat JavaScript Aktifkan Acrobat JavaScript + Enable copying of text, images, and other content Izinkan penyalinan teks, gambar, dan konten lainnya + Enable text access for screen reader devices for the visually impaired Aktifkan akses teks untuk pembaca layar bagi tuna netra + Encrypt Enkripsi + Endpoints Endpoint + Enhance page Tingkatkan halaman + Enter the password that opens it Masukkan kata sandi untuk membukanya + Enter the permissions password to allow combining Masukkan kata sandi izin untuk mengizinkan penggabungan + Entire page Seluruh halaman + Even Pages Only Hanya Halaman Genap + Even and Odd Pages Halaman Genap dan Ganjil + Even pages only Hanya halaman genap + Every PDF, image and text file in the folder Semua file PDF, gambar, dan teks di dalam folder + Every PDF, image and text file in the folder and the folders inside it Semua file PDF, gambar, dan teks di dalam folder beserta folder di dalamnya + Example: {sample} Contoh: {sample} + Exclude images smaller than Kecualikan gambar yang lebih kecil dari + Expand Perluas + Expand all Perluas semua + Expand all bookmarks Perluas semua bookmark + Expand tag Perluas tag + Expand top-level bookmarks Perluas bookmark tingkat atas + Explain Jelaskan + Export All Images Ekspor Semua Gambar + Export Value: {on} Nilai Ekspor: {on} + Export all to data file… Ekspor semua ke file data… + Export certificate… Ekspor sertifikat… + Export comments Ekspor komentar + Export form data Ekspor data formulir + Export stopped: {e} Ekspor dihentikan: {e} + Export to Image Ekspor ke Gambar + Export to Text Ekspor ke Teks + Exported 1 image Mengekspor 1 gambar + Exported the text of 1 page Mengekspor teks dari 1 halaman + Exported the text of {n} pages Mengekspor teks dari {n} halaman + Exported {n} images Mengekspor {n} gambar + Exporting… {d} of {t} Mengekspor… {d} dari {t} + Export… Ekspor… + Extract pages as separate files Ekstrak halaman sebagai file terpisah + Extract pages to a new document Ekstrak halaman ke dokumen baru + Extracted 1 page Mengekstrak 1 halaman + Extracted {n} pages Mengekstrak {n} halaman + Field is used for file selection Kolom ini digunakan untuk pemilihan file + Field names (comma-separated) Nama kolom (dipisahkan koma) + Field names with + - * / and parentheses; put \\ before spaces in names. Nama kolom dengan + - * / dan tanda kurung; letakkan \\ sebelum spasi dalam nama. + Field value is in range: Nilai kolom berada dalam rentang: + Field value is not validated Nilai kolom tidak divalidasi + Field: {field} on page {p} Kolom: {field} pada halaman {p} + Fields to reset (comma-separated; empty: all) Kolom yang akan direset (dipisahkan koma; kosong: semua) + Figure {i} of {n}{page} Gambar {i} dari {n}{page} + File (.p12, .pfx) File (.p12, .pfx) + File Name Nama File + File size Ukuran file + Files are combined from top to bottom. Leave Pages empty to take every page. File digabungkan dari atas ke bawah. Biarkan Halaman kosong untuk mengambil semua halaman. + Files are combined in the order shown. Drag them to change it. File digabungkan sesuai urutan yang ditampilkan. Seret untuk mengubah urutannya. + Files for {name} File untuk {name} + Files you open in PdfCraft appear here. Drop a PDF anywhere to open it. File yang Anda buka di PdfCraft akan muncul di sini. Jatuhkan PDF di mana saja untuk membukanya. + Fill & Sign dates Tanggal Isi & Tanda Tangani + Fill & Sign signature Tanda tangan Isi & Tanda Tangani + Fill Color: Warna Isian: + Fill colour Warna isian + Fill colour: none Warna isian: tidak ada + Filling in form fields and signing existing signature fields Mengisi kolom formulir dan menandatangani kolom tanda tangan yang ada + Filter comments Filter komentar + Find a tag Cari tag + Find options Opsi pencarian + Find text Cari teks + Find tools and commands Cari alat dan perintah + Finding document fonts… Mencari font dokumen… + Finish or discard the text being edited before selecting several objects. Selesaikan atau buang teks yang sedang diedit sebelum memilih beberapa objek. + First / last page Halaman pertama / terakhir + Fit Sesuaikan + Fit Height Sesuaikan Tinggi + Fit Page Sesuaikan Halaman + Fit Visible Sesuaikan Tampil + Fit Width Sesuaikan Lebar + Fit to height Sesuaikan tinggi + Fit to page Sesuaikan halaman + Fix Perbaiki + Fixed what could be fixed; 1 problem remains Memperbaiki yang bisa diperbaiki; 1 masalah tersisa + Fixed what could be fixed; {n} problems remain Memperbaiki yang bisa diperbaiki; {n} masalah tersisa + Flatten Fill & Sign when saving Ratakan Isi & Tanda Tangani saat menyimpan + Flip Horizontal Balik Horizontal + Flip Vertical Balik Vertikal + Flip horizontal Balik horizontal + Flip on long edge Balik pada sisi panjang + Flip on short edge Balik pada sisi pendek + Flip vertical Balik vertikal + Folders Folder + Font Size: Ukuran Font: + Font colour: Warna font: + Font size 0 uses automatic sizing. Ukuran font 0 menggunakan ukuran otomatis. + Font size: Ukuran font: + Font: Font: + Font: Helvetica Font: Helvetica + Fonts Font + For page sizes and margins. Untuk ukuran halaman dan margin. + Form data and PDF forms Data formulir dan formulir PDF + Form fields are flattened: their values stay visible. Saving rewrites the whole file. Kolom formulir diratakan: nilainya tetap terlihat. Menyimpan menulis ulang seluruh file. + Form fields only Hanya kolom formulir + Form fill-in and digital signatures Pengisian formulir dan tanda tangan digital + Format Format + Format text Format teks + Format: Format: + From Dari + From a PDF page or an image Dari halaman PDF atau gambar + From colour Dari warna + From {file} Dari {file} + From: Dari: + Front side only Hanya sisi depan + Get help, share feedback and follow development on Discord. Dapatkan bantuan, berikan masukan, dan ikuti pengembangan di Discord. + Go to a page view Ke tampilan halaman + Go to page {p} Ke halaman {p} + Go to the page Ke halaman tersebut + Go to this result Ke hasil ini + Graphic Grafis + Greyscale Skala abu-abu + Grid view Tampilan kisi + Hand (H) Tangan (H) + Has JavaScript actions (run in M6) Punya tindakan JavaScript (jalankan di M6) + Height: Tinggi: + Hide field highlights Sembunyikan sorotan kolom + Hide layer Sembunyikan lapisan + Hide menu bar Sembunyikan bilah menu + Hide password Sembunyikan kata sandi + Hide toolbars Sembunyikan bilah alat + Hide window controls Sembunyikan kontrol jendela + High Resolution Resolusi Tinggi + High resolution Resolusi tinggi + Highlight Style: Gaya Sorotan: + Highlight fields Sorot kolom + Home Beranda + Horizontal Horizontal + Horizontal reversed Horizontal terbalik + Horizontal scale Skala horizontal + Icon Ikon + Images and text Gambar dan teks + Images and text (converted to PDF) Gambar dan teks (dikonversi ke PDF) + Import list… Daftar impor… + Includes unsaved changes Termasuk perubahan yang belum disimpan + Indent Indentasi + Initial View Tampilan Awal + Ink sensitivity Sensitivitas tinta + Insert Date Sisipkan Tanggal + Insert Page Number Sisipkan Nomor Halaman + Insert a blank page after the selection Sisipkan halaman kosong setelah pilihan + Insert a file at the end Sisipkan file di akhir + Insert a file before page {label} Sisipkan file sebelum halaman {label} + Insert pages from a file… Sisipkan halaman dari file… + Inserting, deleting, and rotating pages Menyisipkan, menghapus, dan memutar halaman + Installed fonts… Font terpasang… + Intersections Irisan + Invisible Rectangle Persegi panjang tak terlihat + Issued by: Diterbitkan oleh: + Italic Miring + Item List Daftar Item + Item: Item: + Items marked Ready work today. Item yang ditandai Siap sudah berfungsi hari ini. + Its security settings don't allow copying pages Pengaturan keamanannya tidak mengizinkan penyalinan halaman + JavaScript Console Konsol JavaScript + JavaScript is turned off (Preferences ▸ JavaScript). JavaScript dimatikan (Preferensi > JavaScript). + JavaScript, e.g. getField("total").value JavaScript, misalnya getField("total").value + Join our Discord Gabung ke Discord kami + Join the ArtCraft community Gabung ke komunitas ArtCraft + Justify Ratakan kanan-kiri + Keep source fonts Pertahankan font sumber + Keep tool selected Pertahankan alat terpilih + Keep tool selected: on Pertahankan alat terpilih: aktif + Key Algorithm Algoritma kunci + Keychain · Gudang kunci · + Label Label + Labels Label + Labels: {preview}. Later pages keep their labels. Label: {preview}. Halaman berikutnya tetap memakai labelnya. + Landscape Landskap + Landscape Pages Halaman Landskap + Landscape and Portrait Pages Halaman Landskap dan Potret + Larger pages Halaman lebih besar + Later Nanti + Later in tab order Nanti dalam urutan tab + Layers Lapisan + Layers Panel and Page Panel Lapisan dan Halaman + Layout and Magnification Tata Letak dan Pembesaran + Leave out files that can't be read? Lewati file yang tidak dapat dibaca? + Left Kiri + Left Edge Tepi Kiri + Left out: {names} Dilewati: {names} + Left: Kiri: + Light theme Tema terang + Limit of Batas + Line Style: Gaya garis: + Line Thickness: Ketebalan garis: + Line ending Akhir baris + Line spacing Spasi baris + Line thickness Ketebalan garis + Link Action Tindakan Tautan + Link Appearance Tampilan Tautan + Link Properties Properti Tautan + Link Type: Jenis tautan: + List view Tampilan daftar + Load font… Muat font… + Locked Terkunci + Looking for PDFs… Mencari PDF… + Looking for printers… Mencari printer… + Low Resolution (150 dpi) Resolusi Rendah (150 dpi) + Low resolution Resolusi rendah + Magnification Pembesaran + Make Current Properties Default Jadikan Properti Saat Ini sebagai Bawaan + Margins Margin + Mark Page Range Tandai Rentang Halaman + Mark as comments Tandai sebagai komentar + Mark with checkmark Tandai dengan centang + Marked Ditandai + Mask: Masker: + Match page at 100% Samakan halaman pada 100% + Medium Sedang + Midpoints Titik tengah + Mixed Campuran + Modified Diubah + More options Opsi lainnya + More options: Opsi lainnya: + More ways to add files Cara lain untuk menambahkan file + Mouse wheel scroll speed Kecepatan gulir dengan roda mouse + Move down Pindahkan ke bawah + Move earlier Pindahkan lebih awal + Move later Pindahkan lebih nanti + Move up Pindahkan ke atas + Multi-line Multi-baris + Multiple Banyak + Multiple selection Pilihan ganda + Multiple words or phrases Banyak kata atau frasa + Name: Nama: + Navigation tab Tab navigasi + Needs manual check Perlu pemeriksaan manual + Negative number style: Gaya angka negatif: + New Action Tindakan Baru + New Action… Tindakan Baru… + New bookmark ({key}) Bookmark baru ({key}) + New file: File baru: + Next ({key}) Berikutnya ({key}) + Next / previous match Kecocokan berikutnya / sebelumnya + Next figure Gambar berikutnya + Next month Bulan berikutnya + Next page Halaman berikutnya + Next sheet Lembar berikutnya + Next view Tampilan berikutnya + No PDFs in this folder yet Belum ada PDF di folder ini + No actions Tidak ada tindakan + No changes allowed Perubahan tidak diizinkan + No changes to save Tidak ada perubahan untuk disimpan + No check has run yet. Pemeriksaan belum pernah dijalankan. + No color Tidak ada warna + No colour Tidak ada warna + No comments match. Tidak ada komentar yang cocok. + No comments yet. Belum ada komentar. + No differences in the text. Tidak ada perbedaan pada teks. + No digital IDs yet. Belum ada ID digital. + No documents are open Tidak ada dokumen yang terbuka + No file chosen Tidak ada file yang dipilih + No fill Tanpa isian + No fonts are referenced by the pages. Halaman tidak merujuk font apa pun. + No issues found Tidak ada masalah ditemukan + No limit Tanpa batas + No matches Tidak ada kecocokan + No matches. Tidak ada kecocokan. + No matching tools Tidak ada alat yang cocok + No openly licensed document fonts found. Load a font file. Tidak ditemukan font dokumen berlisensi terbuka. Muat sebuah file font. + No pages selected Tidak ada halaman yang dipilih + No photo chosen Tidak ada foto yang dipilih + No preview Tanpa pratinjau + No problems found: the document conforms to {level}. Tidak ada masalah ditemukan: dokumen memenuhi {level}. + No security Tanpa keamanan + No sheets Tidak ada lembar + No signature was found in the frame. Move the frame over the signature or raise the ink sensitivity. Tidak ada tanda tangan di dalam bingkai. Pindahkan bingkai ke atas tanda tangan atau naikkan sensitivitas tinta. + No status has been set. Status belum ditetapkan. + None (prefix only) Tidak ada (hanya awalan) + None found Tidak ditemukan + None — everything is allowed Tidak ada — semuanya diizinkan + Not allowed Tidak diizinkan + Not present Tidak ada + Nothing to redo Tidak ada yang perlu diulang + Nothing to undo Tidak ada yang perlu diurutkan + Number Nomor + Number of pages Jumlah halaman + Number pages Nomor halaman + Odd Pages Only Halaman Ganjil Saja + Odd pages only Hanya halaman ganjil + Offset from centre Offset dari titik tengah + Old file: File lama: + One word or phrase per line Satu kata atau frasa per baris + One {f} file per page, named after the document. Satu file {f} per halaman, diberi nama sesuai dokumen. + Only change the colour of black text or line art Ubah hanya warna teks hitam atau gambar garis + Only checked properties will change. Mixed means the selected fields have different values. Hanya properti yang dicentang yang akan berubah. Campuran berarti kolom yang dipilih memiliki nilai berbeda. + Only the page content changes: links, comments, form fields and bookmarks on the original pages stay. Hanya isi halaman yang berubah: tautan, komentar, kolom formulir dan bookmark pada halaman asli tetap. + Open Buka + Open a PDF ({key}) Buka PDF ({key}) + Open a PDF to measure it. Buka PDF untuk mengukurnya. + Open a document first Buka dokumen terlebih dahulu + Open a web page Buka halaman web + Open arrow Panah terbuka + Open email app Buka aplikasi email + Open in Full Screen mode Buka dalam mode Layar Penuh + Open in a new tab Buka di tab baru + Open link Buka tautan + Open the file as it was saved then Buka file seperti saat disimpan + Open the older version first Buka versi lama terlebih dahulu + Open this web page? Buka halaman web ini? + Open to page Buka ke halaman + Opened, but its security settings don't allow combining. Enter the permissions password. Terbuka, tetapi pengaturan keamanannya tidak mengizinkan penggabungan. Masukkan kata sandi izin. + Opens the printer driver's preferences. They are saved for every print from this computer; the copies, two-sided, grayscale and paper chosen here still apply. Membuka preferensi driver printer. Preferensi ini tersimpan untuk setiap cetak dari komputer ini; jumlah salinan, cetak dua sisi, skala abu-abu dan kertas yang dipilih di sini tetap berlaku. + Optimizing… cleaning up Mengoptimalkan… membersihkan + Optimizing… image {d} of {t} Mengoptimalkan… gambar {d} dari {t} + Optimizing… merging identical objects Mengoptimalkan… menggabungkan objek yang identik + Optimizing… removing user data Mengoptimalkan… menghapus data pengguna + Optimizing… writing the copy Mengoptimalkan… menulis salinan + Optional: needs an AI provider you configure Opsional: memerlukan penyedia AI yang Anda konfigurasi + Options… Opsi… + Organization Name Nama Organisasi + Organizational Unit Unit Organisasi + Orientation: Orientasi: + Original Asli + Original: replace pages Asli: ganti halaman + Other colour… Warna lain… + Outdent Kurangi indentasi + Output Keluaran + Output appears here. Keluaran akan muncul di sini. + Output intent: {list} Niat keluaran: {list} + Overlap: Tumpang tindih: + Owner password (no restrictions apply) Kata sandi pemilik (tidak ada pembatasan) + PDF Optimizer Pengoptimal PDF + PDF or image PDF atau gambar + PDF page: {size} Halaman PDF: {size} + PDF scale: {scale}% Skala PDF: {scale}% + PDF, images and text PDF, gambar dan teks + Page Only Halaman Saja + Page Range Options Opsi Rentang Halaman + Page Sizing & Handling Ukuran & Penanganan Halaman + Page background Latar halaman + Page display: {layout} Tampilan halaman: {layout} + Page layout Tata letak halaman + Page navigation Navigasi halaman + Page number Nomor halaman + Page order: Urutan halaman: + Page size Ukuran halaman + Page {label} Halaman {label} + Page {p} of {n} Halaman {p} dari {n} + Pages Panel and Page Panel Halaman dan Halaman + Pages from Halaman dari + Pages of {name} to combine, e.g. 1-3, 6 Halaman dari {name} yang akan digabung, misalnya 1-3, 6 + Pages per file Halaman per file + Pages per sheet: Halaman per lembar: + Pages to Print Halaman yang Dicetak + Pages: Halaman: + Pages: {k} of {n} Halaman: {k} dari {n} + Paper: Kertas: + Part of Bagian dari + Password Kata sandi + Password required Kata sandi diperlukan + Password security Keamanan kata sandi + Password-protected Dilindungi kata sandi + Paste after Tempel setelah + Paths Lokasi + Pattern Pola + Patterns Pola + Patterns (graphics objects) Pola (objek grafis) + PdfCraft didn't shut down normally. These documents had changes that were autosaved: PdfCraft tidak berhenti secara normal. Dokumen-dokumen ini memiliki perubahan yang disimpan otomatis: + PdfCraft works offline. No telemetry, no account, and no cloud processing unless you add a provider. PdfCraft bekerja secara luring. Tidak ada telemetri, tidak ada akun, dan tidak ada pemrosesan awan kecuali Anda menambahkan penyedia. + PdfCraft {c} is up to date. PdfCraft {c} sudah terbaru. + PdfCraft {v} is available. PdfCraft {v} tersedia. + Percentage Persentase + Permissions password Kata sandi izin + Permitted actions after certifying Tindakan yang diizinkan setelah disertifikasi + Photo Foto + Pick a tool in the quick bar, or type above. Pilih alat di bilah cepat, atau ketik di atas. + Pictures on those pages are recognized too; words already in the page's text are not added again Gambar di halaman-halaman itu juga dikenali; kata yang sudah ada dalam teks halaman tidak ditambahkan lagi + Pin a folder to Home Sematkan folder ke Beranda + Pin a folder to list its newest PDFs here, such as where your scanner or a synced cloud drive saves them. Sematkan folder untuk menampilkan PDF terbarunya di sini, misalnya tempat pemindai atau drive cloud tersinkron Anda menyimpannya. + Pin a folder… Sematkan folder… + Plain text in reading order; pages are separated by form feeds. Teks biasa dalam urutan baca; halaman dipisahkan oleh form feed. + Planned Direncanakan + Planned for milestone Direncanakan untuk tonggak + Points from the page's bottom-left corner. Titik diukur dari sudut kiri bawah halaman. + Portrait Potret + Portrait Pages Halaman Potret + Post Kirim + Poster Poster + Prefix Awalan + Preview Pratinjau + Preview unavailable: {e} Pratinjau tidak tersedia: {e} + Preview: page {p} of {n} Pratinjau: halaman {p} dari {n} + Previous ({key}) Sebelumnya ({key}) + Previous / next page Halaman sebelumnya / berikutnya + Previous figure Gambar sebelumnya + Previous month Bulan sebelumnya + Previous page Halaman sebelumnya + Previous sheet Lembar sebelumnya + Previous view Tampilan sebelumnya + Print ({key}) Cetak ({key}) + Print in grayscale Cetak dalam skala abu-abu + Print page border Cetak bingkai halaman + Print, NextPage, PrevPage, FirstPage or LastPage Print, NextPage, PrevPage, FirstPage atau LastPage + Printer paper and scaling may differ. Check driver settings. Kertas dan penskalaan printer bisa berbeda. Periksa pengaturan driver. + Printer properties Properti printer + Printer: Printer: + Printing allowed Pencetakan diizinkan + Privacy Privasi + Properties… Properti… + Protect Using Password Lindungi dengan Kata Sandi + Protected: the combined file won't keep its security settings Dilindungi: file gabungan tidak akan mempertahankan pengaturan keamanannya + Quality Kualitas + Read Only Hanya Baca + Reading colours Warna pembacaan + Ready Siap + Reason Alasan + Recent Terbaru + Recent colours Warna terbaru + Recognize Text Kenali Teks + Recognized 1 word 1 kata dikenali + Recognized {n} words {n} kata dikenali + Recognized {w} words in 1 file {w} kata dikenali dalam 1 file + Recognized {w} words in {n} files {w} kata dikenali dalam {n} file + Recognizing text… file {d} of {t} Mengenali teks… file {d} dari {t} + Recognizing text… page {d} of {t} Mengenali teks… halaman {d} dari {t} + Recommended tools Alat yang direkomendasikan + Recover Pulihkan + Recover unsaved documents? Pulihkan dokumen yang belum disimpan? + Redact all Sensor semua + Redacted area fill colour: Warna isi area bersensor: + Redaction Tool Properties Properti Alat Sensor + Redaction code: Kode sensor: + Reload Muat ulang + Reload documents when their files change on disk Muat ulang dokumen saat file-nya berubah di disk + Remove checkmark Hapus centang + Remove invalid links and bookmarks Hapus tautan dan bookmark yang tidak valid + Remove page Hapus halaman + Remove unreferenced named destinations Hapus tujuan bernama yang tidak dirujuk + Remove unused objects and merge identical ones Hapus objek yang tidak terpakai dan gabungkan yang identik + Remove {name} Hapus {name} + Remove {name} from Recent Hapus {name} dari Terbaru + Remove {n} files Hapus {n} file + Remove {n} pages Hapus {n} halaman + Reopen Closed Tab Buka Ulang Tab yang Ditutup + Reopen the files that were open when PdfCraft last closed Buka kembali file yang terbuka saat PdfCraft terakhir ditutup + Repair log Log perbaikan + Repeat overlay text Ulangi teks hamparan + Replace Image… Ganti Gambar… + Replace Pages Ganti Halaman + Replace document colours Ganti warna dokumen + Replace image Ganti gambar + Replacement text Teks pengganti + Replacement: pages of {name} Pengganti: halaman dari {name} + Replaces the existing one on those pages. Menggantikan yang ada di halaman-halaman itu. + Report Laporan + Report… Laporan… + Requires user to enter a password for: Memerlukan pengguna untuk memasukkan kata sandi untuk: + Reset columns Atur ulang kolom + Reset page size Atur ulang ukuran halaman + Reset to printer defaults Atur ulang ke bawaan printer + Resize window to initial page Ubah ukuran jendela ke halaman awal + Resolution Resolusi + Retain existing Pertahankan yang ada + Reveal in File Explorer Tampilkan di File Explorer + Reveal in Finder Tampilkan di Finder + Reverse closed arrow Balik panah tertutup + Reverse open arrow Balik panah terbuka + Reverse pages Balik halaman + Revert changes Kembalikan perubahan + Revert to the previously saved version of “{name}”? Changes since then can't be undone afterwards. Kembalikan ke versi “{name}” yang tersimpan sebelumnya? Perubahan setelahnya tidak dapat dibatalkan. + Review History Riwayat Tinjau + Revisions Revisi + Right Kanan + Right Edge Tepi Kanan + Rotate Clockwise Putar Searah Jarum Jam + Rotate Counterclockwise Putar Berlawanan Arah Jarum Jam + Rotate Pages Putar Halaman + Rotate clockwise Putar searah jarum jam + Rotate counterclockwise Putar berlawanan arah jarum jam + Rotate view Putar tampilan + Rotate view clockwise Putar tampilan searah jarum jam + Rotate view clockwise ({key}) Putar tampilan searah jarum jam ({key}) + Rotate view counterclockwise Putar tampilan berlawanan arah jarum jam + Rotate: Putar: + Rotation: Rotasi: + Running action… file {d} of {t} Menjalankan tindakan… file {d} dari {t} + Same as interface ({language}) Sama seperti antarmuka ({language}) + Sanitizing removes hidden information from the document: metadata, file attachments, comments, form fields (flattened), hidden text and layers, bookmarks, links, actions and scripts, and private application data. Pembersihan menghapus informasi tersembunyi dari dokumen: metadata, lampiran file, komentar, kolom formulir (diratakan), teks dan lapisan tersembunyi, bookmark, tautan, tindakan dan skrip, serta data aplikasi privat. + Save & Close Simpan & Tutup + Save ({key}) Simpan ({key}) + Save Image As… Simpan Gambar Sebagai… + Copy Image Salin Gambar + The image has been copied ({w} × {h} pixels) Gambar telah disalin ({w} × {h} piksel) + Couldn't copy the image: {e} Tidak dapat menyalin gambar: {e} + Copy Image in Original Format Salin Gambar dalam Format Asli + The image has been copied as a {ext} file Gambar telah disalin sebagai file {ext} + The page has changed; select the image again Halaman telah berubah; pilih gambar lagi + Save as PDF Simpan sebagai PDF + Save attachment… Simpan lampiran… + Save changes to “{name}” before closing? Simpan perubahan pada “{name}” sebelum menutup? + Save pages Simpan halaman + Save tag properties Simpan properti tag + Save the accessibility report Simpan laporan aksesibilitas + Save the document afterwards: saving rewrites the whole file so no trace of the removed content stays in it. Simpan dokumen setelahnya: penyimpanan menulis ulang seluruh file sehingga tidak ada jejak konten yang dihapus tertinggal di dalamnya. + Save the document afterwards; saving rewrites the whole file so nothing removed stays in it. Simpan dokumen setelahnya; penyimpanan menulis ulang seluruh file sehingga tidak ada yang dihapus tertinggal di dalamnya. + Save the spreadsheet Simpan lembar kerja + Save these pages as one PDF Simpan halaman ini sebagai satu PDF + Saved measurements Pengukuran tersimpan + Saved measurements. Pengukuran tersimpan. + Scale relative to target page Skala relatif terhadap halaman target + Scan Pindai + Script Name: Nama Skrip: + Script: Skrip: + Scripts run in a sandbox without file or network access. A script that asks to open a web page needs your permission first. With JavaScript off, Acrobat's standard format, validate and calculate functions still work. Skrip berjalan di sandbox tanpa akses file atau jaringan. Skrip yang meminta membuka halaman web memerlukan izin Anda terlebih dahulu. Dengan JavaScript nonaktif, fungsi format standar, validasi, dan hitung milik Acrobat tetap berfungsi. + Scroll long text Gulir teks panjang + Scroll tabs left Gulir tab ke kiri + Scroll tabs right Gulir tab ke kanan + Search comments Cari komentar + Search tools and commands… Cari alat dan perintah… + Searchable Image (Exact) Gambar yang Dapat Dicari (Tepat) + Searching… {s} of {p} pages Mencari… {s} dari {p} halaman + Searching… {s}/{p} Mencari… {s}/{p} + Security Keamanan + Security settings Pengaturan keamanan + Select (V) Pilih (V) + Select Action: Pilih Tindakan: + Select All Pilih Semua + Select Icon Pilih Ikon + Select Trigger: Pilih Pemicu: + Select a file first Pilih file terlebih dahulu + Select a file for the stamp Pilih file untuk stempel + Select a password-protected file first Pilih file terlindungi kata sandi terlebih dahulu + Select a word Pilih satu kata + Select all pages (Organize) Pilih semua halaman (Atur) + Select at most 1000 objects at a time. Pilih maksimal 1000 objek sekaligus. + Select data files to merge Pilih file data untuk digabung + Select format category: Pilih kategori format: + Select page {label} Pilih halaman {label} + Select pages Pilih halaman + Select the items to remove from this document. Pilih item yang akan dihapus dari dokumen ini. + Selected image files: {count} File gambar dipilih: {count} + Selected pages Halaman dipilih + Selection Pilihan + Sending to {printer}… Mengirim ke {printer}… + Sensitivity Sensitivitas + Sent to {printer} Dikirim ke {printer} + Sent to {printer}: {msg} Dikirim ke {printer}: {msg} + Separator style: Gaya pemisah: + Set Alternate Text Tetapkan Teks Alternatif + Set Fields to Same Size Samakan Ukuran Kolom + Set Page Boxes Tetapkan Kotak Halaman + Set layer visibility Atur visibilitas lapisan + Set status Tetapkan status + Set to current page ({n}) Samakan dengan halaman saat ini ({n}) + Set to zero Samakan dengan nol + Shared Field Properties Properti Kolom Bersama + Sheet {s} of {n} Lembar {s} dari {n} + Shift constrains to 45 degrees. Backspace removes a vertex. Escape cancels. Shift membatasi ke 45 derajat. Backspace menghapus simpul. Escape membatalkan. + Shift- or Ctrl/Command-click to select several fields. Klik Shift- atau Ctrl/Command untuk memilih beberapa kolom. + Shift-click to select several objects. Drag empty space to select an area. Klik Shift untuk memilih beberapa objek. Seret ruang kosong untuk memilih area. + Show Report Tampilkan Laporan + Show all Tampilkan semua + Show all comments Tampilkan semua komentar + Show certificate… Tampilkan sertifikat… + Show layer Tampilkan lapisan + Show less Tampilkan lebih sedikit + Show password Tampilkan kata sandi + Show the accessibility report Tampilkan laporan aksesibilitas + Show this dialog when the Checker starts Tampilkan dialog ini saat Pemeriksa dimulai + Show {n} more Tampilkan {n} lagi + Show: Tampilkan: + Shrink oversized pages Perkecil halaman yang terlalu besar + Sign Here Tanda Tangani Di Sini + Sign this field… Tanda tangani kolom ini… + Sign yourself Tanda tangani sendiri + Signature Details Detail Tanda Tangan + Signature is INVALID: Tanda tangan TIDAK VALID: + Signature is valid: Tanda tangan valid: + Signature panel Panel tanda tangan + Signature validity is UNKNOWN: Keabsahan tanda tangan TIDAK DIKETAHUI: + Signer's name Nama penanda tangan + Simplified field notation: Notasi kolom sederhana: + Single Page Halaman Tunggal + Single Page Continuous Halaman Tunggal Berurutan + Single word or phrase Satu kata atau frasa + Skip Rule Aturan Lewati + Skipped Dilewati + Slash Garis miring + Smaller pages Halaman lebih kecil + Snap to drawing Tempel ke gambar + Some bookmarks are not shown here: the panel lists a limited number, nested a limited depth. Sebagian bookmark tidak ditampilkan di sini: panel hanya menampilkan jumlah dan tingkat kedalaman yang terbatas. + Some page content couldn't be read; snapping uses the rest. Sebagian konten halaman tidak dapat dibaca; tempelan memakai bagian sisanya. + Sort by Urutkan menurut + Sort comments by: Urutkan komentar menurut: + Sort items Urutkan item + Source Sumber + Space Audit Audit Spasi + Special Khusus + Split document Pisah dokumen + Split into files… Pisah menjadi file… + Square Persegi + Standard Business Bisnis Standar + Start Mulai + Start Checking Mulai Pemeriksaan + Start page number Nomor halaman awal + Status Status + Steps Langkah + Strength: {s} Kekuatan: {s} + Style Gaya + Subject Subjek + Subset Subhimpunan + Summarize Options Ringkasan Opsi + Summary Ringkasan + Switch to List view to change the pages it takes. Beralih ke tampilan Daftar untuk mengubah halaman yang digunakannya. + Switch to two-page view first to show the cover page Beralih ke tampilan dua halaman terlebih dahulu untuk menampilkan halaman sampul + Tab order: move a field with its arrows. Urutan tab: pindahkan kolom dengan panahnya. + Tag type Tipe tag + Tags Tag + Text Color: Warna Teks: + Text alignment: Perataan teks: + Text in images isn't found; recognise text (OCR) first. Teks dalam gambar tidak ditemukan; lakukan pengenalan teks (OCR) terlebih dahulu. + Text is compared word by word; the differences are shown on the new file. Teks dibandingkan kata demi kata; perbedaan ditampilkan pada file baru. + Text recognition isn't installed: its model files are missing. Reinstall PdfCraft, or set PDFCRAFT_MODELS to the folder that holds them. Pengenalan teks belum terpasang: file modelnya hilang. Pasang ulang PdfCraft, atau atur PDFCRAFT_MODELS ke folder yang memuatnya. + Text to find Teks yang dicari + Text to insert Teks yang disisipkan + Text used as a clipping path cannot be moved with this selection. Teks yang dipakai sebagai jalur pemotongan tidak dapat dipindahkan dengan pilihan ini. + Text, marks and signatures become part of the page. Other comments stay editable. Teks, tanda, dan tanda tangan menjadi bagian dari halaman. Komentar lain tetap dapat diedit. + Thai and Arabic use regular fallback fonts when available. Bahasa Thai dan Arab memakai font cadangan biasa jika tersedia. + The PDF text fonts can't draw “{c}” ({code}). Choose supported text. Font teks PDF tidak dapat menggambar “{c}” ({code}). Pilih teks yang didukung. + The checker found 1 problem which may prevent the document from being fully accessible. Pemeriksa menemukan 1 masalah yang dapat menghambat dokumen agar sepenuhnya aksesibel. + The checker found no problems in this document. Pemeriksa tidak menemukan masalah pada dokumen ini. + The checker found {n} problems which may prevent the document from being fully accessible. Pemeriksa menemukan {n} masalah yang dapat menghambat dokumen agar sepenuhnya aksesibel. + The document now conforms to {level}; save it to keep the changes Dokumen sekarang sesuai dengan {level}; simpan untuk mempertahankan perubahan + The document opens without a password; this password is needed to change the restrictions. It's applied when you save. Dokumen terbuka tanpa kata sandi; kata sandi ini diperlukan untuk mengubah pembatasan. Ini berlaku saat Anda menyimpan. + The document's security settings don't allow copying text and images Pengaturan keamanan dokumen tidak mengizinkan penyalinan teks dan gambar + The document's security settings don't allow this change Pengaturan keamanan dokumen tidak mengizinkan perubahan ini + The existing action will be preserved. Tindakan yang ada akan dipertahankan. + The fonts PdfCraft writes with can't draw “{c}” ({code}), so it shows as ? in every PDF viewer. The text is saved. Font yang dipakai PdfCraft tidak dapat menggambar “{c}” ({code}), sehingga teks itu tampil sebagai ? di setiap penampil PDF. Teks tetap tersimpan. + The key is in the Windows certificate store, which may ask to allow PdfCraft to use it. Kunci berada di penyimpanan sertifikat Windows, yang mungkin meminta izin untuk memakai PdfCraft. + The key is in the macOS Keychain, which may ask to allow PdfCraft to use it. Kunci berada di Keychain macOS, yang mungkin meminta izin untuk memakai PdfCraft. + The newest {n} of {total} PDFs {n} PDF terbaru dari {total} + The password is only used to read the file; it isn't saved. Kata sandi hanya dipakai untuk membaca file; kata sandi tidak disimpan. + The printer driver's own settings for this print: paper tray, paper type, finishing and more. Pengaturan milik driver printer sendiri untuk cetakan ini: baki kertas, jenis kertas, finishing, dan lainnya. + The replacement file doesn't have that many pages. File pengganti tidak memiliki sebanyak itu halaman. + The same password is tried on each file. Kata sandi yang sama dicoba pada setiap file. + The signature will be invisible. Tanda tangan akan tidak terlihat. + The text is the same Teksnya sama + The value is shown as typed. Nilainya ditampilkan apa adanya. + There are no redaction marks (mark text, areas or pages first) Tidak ada tanda sensor (tandai teks, area, atau halaman terlebih dahulu) + These files can't be read, so they won't be in the combined PDF: File ini tidak dapat dibaca, jadi tidak akan ada dalam PDF gabungan: + These objects could not be moved. Select them again and try a smaller move. Objek ini tidak dapat dipindahkan. Pilih lagi dan coba perpindahan yang lebih kecil. + Thick Tebal + Thickness Ketebalan + Thin Tipis + This area has too many overlapping paths; intersection snapping is limited. Area ini memiliki terlalu banyak jalur yang bertumpuk; tempelan titik potong dibatasi. + This certificate is in your list of trusted certificates. Sertifikat ini ada dalam daftar sertifikat tepercaya Anda. + This certificate is not trusted. Signatures made with it show an unknown identity. Sertifikat ini tidak tepercaya. Tanda tangan yang dibuat dengannya menampilkan identitas yang tidak dikenal. + This certificate is trusted through a certificate above it in the chain. Sertifikat ini tepercaya melalui sertifikat di atasnya dalam rantai. + This comment's appearance can't be changed yet. Tampilan komentar ini belum dapat diubah. + This dialog shows the details of a certificate and its chain. Dialog ini menampilkan detail sebuah sertifikat dan rantainya. + This document contains {n} interactive form fields. Dokumen ini berisi {n} kolom formulir interaktif. + This document has no comments to flatten Dokumen ini tidak ada komentar untuk diratakan + This document has no document-level scripts. Dokumen ini tidak memiliki skrip tingkat dokumen. + This document has no editable structure tags. Dokumen ini tidak memiliki tag struktur yang dapat diedit. + This document has no form fields to flatten Dokumen ini tidak ada kolom formulir untuk diratakan + This document has no form fields you can fill in Dokumen ini tidak ada kolom formulir yang dapat Anda isi + This document has no pages. Dokumen ini tidak memiliki halaman. + This document has no restrictions to lift Dokumen ini tidak ada pembatasan untuk dilepas + This document has no signatures. Dokumen ini tidak memiliki tanda tangan. + This document has no tagged figures. Dokumen ini tidak memiliki gambar bertag. + This document has no {kind} to change Dokumen ini tidak ada {kind} untuk diubah + This document hasn't been checked yet. Dokumen ini belum diperiksa. + This document is secured. Some changes are restricted by its security settings. Dokumen ini diamankan. Beberapa perubahan dibatasi oleh pengaturan keamanannya. + This document isn't password-protected Dokumen ini tidak terlindungi kata sandi + This drawing exceeds the snapping limit; only the first paths are used. Gambar ini melampaui batas tempelan; hanya jalur pertama yang dipakai. + This field is locked. Unlock it to change its properties. Kolom ini terkunci. Buka kuncinya untuk mengubah propertinya. + This file changed on disk. Reload it to see the new version; your unsaved changes will be lost. File ini berubah di disk. Muat ulang untuk melihat versi baru; perubahan yang belum disimpan akan hilang. + This file was damaged and has been repaired. Saving keeps the repaired version. File ini rusak dan telah diperbaiki. Menyimpan mempertahankan versi yang sudah diperbaiki. + This folder isn't available right now. It may have moved, or its drive or cloud sync is offline. Folder ini sedang tidak tersedia. Folder mungkin telah berpindah, atau drive atau sinkronisasi cloud-nya sedang luring. + This form's scripts are turned off because one ran too long. Reopen the document to run them again. Skrip formulir ini dinonaktifkan karena salah satunya berjalan terlalu lama. Buka kembali dokumen untuk menjalankannya lagi. + This is a dynamic XFA form, which PdfCraft can't display yet. What you see is the file's placeholder page. Ini adalah formulir XFA dinamis, yang belum dapat ditampilkan oleh PdfCraft. Yang Anda lihat adalah halaman placeholder milik file tersebut. + This measurement needs at least {n} points. Pengukuran ini memerlukan minimal {n} titik. + This page contains objects that cannot be selected together. Halaman ini berisi objek yang tidak dapat dipilih bersama-sama. + This page couldn't be displayed.\n{e} Halaman ini tidak dapat ditampilkan.\n{e} + This printer offers no settings of its own. Printer ini tidak menyediakan pengaturan sendiri. + This printer's driver doesn't take two-sided settings from other programs, so its own setting applies. Change it in Properties… Driver printer ini tidak mengambil pengaturan cetak dua sisi dari program lain, jadi pengaturan miliknya yang berlaku. Ubah di Properti… + This web address mixes letters from different alphabets, a common way to imitate another site's name. Alamat web ini mencampur huruf dari beberapa abjad, cara umum untuk menyamar sebagai nama situs lain. + This web address uses letters from another alphabet, which can look like familiar ones. Alamat web ini memakai huruf dari abjad lain, yang bisa tampak seperti huruf yang familier. + Tile scale: Skala ubin: + Time Waktu + Title Judul + To change locked fields, also set Locked to No. Untuk mengubah kolom terkunci, tetapkan juga Terkunci ke Tidak. + To: Ke: + Today: {date} Hari ini: {date} + Toggle fit page / fit width Alihkan sesuaikan halaman / sesuaikan lebar + Tool Alat + Tools panel side Sisi panel alat + Tooltip: Tooltip: + Top Atas + Top-level bookmarks ({n}) Bookmark tingkat atas ({n}) + Total Total + Trust Percayai + Try the form as people filling it in will see it Coba formulir seperti yang akan dilihat oleh orang yang mengisinya + Two-Up (Cover Page) Dua-ke-Satu (Halaman Sampul) + Two-Up (Facing) Dua-ke-Satu (Bersebelahan) + Two-Up Continuous (Cover Page) Dua-ke-Satu Berurutan (Halaman Sampul) + Two-Up Continuous (Facing) Dua-ke-Satu Berurutan (Bersebelahan) + Two-sided: Dua sisi: + Type Tipe + Type text Ketik teks + Type the web address. Ketik alamat web. + Type your {what}. Ketik {what} Anda. + URL to submit to URL tujuan pengiriman + Unit Unit + Units Unit + Unknown author Penulis tidak dikenal + Unlock Buka kunci + Unlock {name} Buka kunci {name} + Unlock {n} files Buka kunci {n} file + Unlocked: the combined file won't be password-protected Tidak terkunci: file gabungan tidak akan terlindungi kata sandi + Unlock… Buka kunci… + Unpin Lepas sematan + Unpin {folder} Lepas sematan {folder} + Unplaced Belum ditempatkan + Unsupported measurements Pengukuran tidak didukung + Up Atas + Update Perbarui + Use 72 DPI (one point per pixel) Gunakan 72 DPI (satu titik per piksel) + Use Flate to encode streams that are not encoded Gunakan Flate untuk mengodekan stream yang belum dikodekan + Use a Digital ID from a file Gunakan ID Digital dari file + Use custom DPI Gunakan DPI kustom + Use each image's embedded DPI; use 72 DPI when it is absent. Gunakan DPI tertanam pada setiap gambar; gunakan 72 DPI jika tidak ada. + Use image resolution Gunakan resolusi gambar + Use now Gunakan sekarang + Use overlay text Gunakan teks overlay + Used when a PDF doesn't ask for a layout or zoom. Continuous scrolling never snaps between pages. Dipakai ketika PDF tidak meminta tata letak atau zoom. Gulir berurutan tidak pernah berhenti di antara halaman. + Used when opening PDFs. An explicit launch or control mode takes precedence for the session. Dipakai saat membuka PDF. Mode peluncuran atau mode kontrol eksplisit berlaku lebih dulu selama sesi. + User Interface Options Opsi Antarmuka Pengguna + User password Kata sandi pengguna + Valid for 5 years, for digital signatures. Self-signed IDs are usually not trusted by others. Berlaku selama 5 tahun, untuk tanda tangan digital. ID yang ditandatangani sendiri biasanya tidak tepercaya oleh orang lain. + Validate all Validasi semua + Value is not calculated Nilai belum dihitung + Value is the Nilainya adalah + Value: Nilai: + Verify Verifikasi + Verify to see what the document needs. Verifikasi untuk melihat apa yang dibutuhkan dokumen. + Version {v} Versi {v} + Vertical Vertikal + Vertical reversed Vertikal terbalik + Vertical text cannot be moved with this selection. Teks vertikal tidak dapat dipindahkan dengan pilihan ini. + View revision {n} Lihat revisi {n} + View signed version Lihat versi bertanda tangan + Viewport Area pandang + Viewport rectangle in page points (x, y, width, height) Persegi area pandang dalam titik halaman (x, y, lebar, tinggi) + Visible Rectangle Persegi Terlihat + Visual Visual + Warnings Peringatan + Welcome to PdfCraft Selamat datang di PdfCraft + What word or phrase would you like to search for? Kata atau frasa apa yang ingin Anda cari? + Whole words only Hanya kata utuh + Width: Lebar: + Window Options Opsi Jendela + Windows store · Windows store · + Write this email? Tulis email ini? + Wrong password Kata sandi salah + XFA form: its fields and its XFA data are kept in step, so other viewers show what you fill in. Formulir XFA: kolom dan data XFA-nya dijaga tetap sinkron, sehingga penampil lain menampilkan yang Anda isi. + You are about to apply 1 redaction mark. Text, images and drawings under the marks, and comments and form fields that overlap them, are removed permanently. Anda akan menerapkan 1 tanda sensor. Teks, gambar, dan gambar-gambar di bawah tanda tersebut, serta komentar dan kolom formulir yang bertumpang tindih dengannya, akan dihapus permanen. + You are about to apply {n} redaction marks. Text, images and drawings under the marks, and comments and form fields that overlap them, are removed permanently. Anda akan menerapkan {n} tanda sensor. Teks, gambar, dan gambar-gambar di bawah tanda tersebut, serta komentar dan kolom formulir yang bertumpang tindih dengannya, akan dihapus permanen. + You have version {c}. All releases are listed at {page}. Anda memiliki versi {c}. Semua rilis tercantum di {page}. + You have version {c}. Download the new version from its release page. Anda memiliki versi {c}. Unduh versi baru dari halaman rilisnya. + Your changes will be lost if you don't save them. Perubahan Anda akan hilang jika tidak Anda simpan. + ZIP ZIP + Zoom in Perbesar + Zoom in ({key}) Perbesar ({key}) + Zoom in / out (also pinch or {key}-scroll) Perbesar / perkecil (juga cubit atau gulir {key}) + Zoom out Perkecil + Zoom out ({key}) Perkecil ({key}) + already a PDF sudah berupa PDF + and {n} more dan {n} lagi + background latar belakang + characters karakter + e.g. My stamps mis. Stempel saya + e.g. en-US mis. en-US + for images above untuk gambar di atas + header or footer header atau footer + initials inisial + is available tersedia + is not available yet belum tersedia + just now baru saja + yesterday kemarin + needs an AI provider (off by default) membutuhkan penyedia AI (nonaktif secara bawaan) + no output folder was chosen tidak ada folder keluaran yang dipilih + no unused output name tidak ada nama keluaran yang belum terpakai + none tidak ada + of the following fields: dari kolom berikut: + AI assistant Asisten AI + Action Wizard Penyihir Tindakan + Action Wizard… Penyihir Tindakan… + Actions list Daftar tindakan + Add Bates numbering… Tambahkan penomoran Bates… + Add a button Tambahkan tombol + Add a callout Tambahkan kotak komentar + Add a checkbox Tambahkan kotak centang + Add a date field Tambahkan kolom tanggal + Add a digital signature field Tambahkan kolom tanda tangan digital + Add a drop-down list Tambahkan daftar tarik-turun + Add a list box Tambahkan kotak daftar + Add a radio button Tambahkan tombol radio + Add a stamp Tambahkan stempel + Add a sticky note Tambahkan catatan tempel + Add a text box Tambahkan kotak teks + Add a text field Tambahkan kolom teks + Add alternate text Tambahkan teks alternatif + Add alternate text… Tambahkan teks alternatif… + Add an image field Tambahkan kolom gambar + Add background… Tambahkan latar belakang… + Add comments Tambahkan komentar + Add content Tambahkan konten + Add files to combine Tambahkan file untuk digabung + Add form components Tambahkan komponen formulir + Add header & footer… Tambahkan header & footer… + Add image… Tambahkan gambar… + Add or edit links Tambahkan atau edit tautan + Add printer marks Tambahkan tanda cetak + Add search index Tambahkan indeks pencarian + Add text Tambahkan teks + Add watermark… Tambahkan tanda air… + Advanced optimization Optimasi lanjutan + Advanced options Opsi lanjutan + Apply PDF standards Terapkan standar PDF + Apply redactions… Terapkan penyensoran… + Archive documents Arsipkan dokumen + Area Luas + Arrow Panah + ArtCraft website Situs ArtCraft + Ask about this document Tanyakan tentang dokumen ini + Attach a file Lampirkan file + Attach file Lampirkan file + Audit space usage Periksa penggunaan ruang + Automatically tag PDF Tandai PDF secara otomatis + Background Latar belakang + Bates numbering Penomoran Bates + Blank page Halaman kosong + Bring your own model (off by default) Gunakan model Anda sendiri (nonaktif secara bawaan) + Button Tombol + Certificates Sertifikat + Certify (invisible signature) Sertifikasi (tanda tangan tak terlihat) + Certify (visible signature) Sertifikasi (tanda tangan terlihat) + Change initials Ubah inisial + Change reading options Ubah opsi baca + Change reading options… Ubah opsi baca… + Change signature Ubah tanda tangan + Check for accessibility Periksa aksesibilitas + Check for accessibility… Periksa aksesibilitas… + Checkbox Kotak centang + Checkmark Tanda centang + Clear form Kosongkan formulir + Clear redaction marks Hapus tanda penyensoran + Clipboard Papan klip + Cloud Awan + Column select Pilih kolom + Combine Gabung + Combine files Gabung file + Comment list Daftar komentar + Comments panel Panel komentar + Compare Bandingkan + Compare files Bandingkan file + Compare files… Bandingkan file… + Compress a PDF Kompres PDF + Console Konsol + Convert colors Konversi warna + Copy pages Salin halaman + Correct recognized text Koreksi teks hasil pengenalan + Create a PDF Buat PDF + Create from Buat dari + Create links from URLs Buat tautan dari URL + Crop pages Pangkas halaman + Cross Salib + Cut pages Potong halaman + Dark gray Abu-abu tua + Date Tanggal + Date field Kolom tanggal + Detect form fields Deteksi kolom formulir + Digital signature Tanda tangan digital + Digitally sign Tanda tangani secara digital + Distance Jarak + Document JavaScripts JavaScript dokumen + Document JavaScripts… JavaScript dokumen… + Document actions Tindakan dokumen + Dot Titik + Draw a cloud Gambar awan + Draw a line Gambar garis + Draw a polygon Gambar poligon + Draw a rectangle Gambar persegi panjang + Draw an arrow Gambar panah + Draw an oval Gambar oval + Draw connected lines Gambar garis terhubung + Draw freehand Gambar bebas + Drawing Gambar + Drawing scale Skala gambar + Drop-down list Daftar drop-down + Duplicate pages Duplikat halaman + Edit a PDF Edit PDF + Edit text & images Edit teks & gambar + Encrypt with certificate Enkripsi dengan sertifikat + Enhance camera image Perbaiki kualitas gambar kamera + Enhance scanned file Perbaiki hasil pindai file + Enter permissions password… Masukkan kata sandi izin… + Erase drawings Hapus gambar + Export a PDF Ekspor PDF + Export all comments to data file… Ekspor semua komentar ke file data… + Export all images Ekspor semua gambar + Export all images… Ekspor semua gambar… + Export data Ekspor data + Export form data… Ekspor data formulir… + Export measurements Ekspor hasil pengukuran + Export measurements as CSV Ekspor hasil pengukuran sebagai CSV + Export to Ekspor ke + Export to PowerPoint… Ekspor ke PowerPoint… + Extract Ekstrak + Extract pages Ekstrak halaman + Field list Daftar kolom + Field properties Properti kolom + Field properties… Properti kolom… + Fields Kolom + Fill Isi + Fill & Sign: add text Isi & Tanda Tangani: tambahkan teks + Fill & Sign: change initials Isi & Tanda Tangani: ubah inisial + Fill & Sign: change signature Isi & Tanda Tangani: ubah tanda tangan + Fill & Sign: checkmark Isi & Tanda Tangani: tanda centang + Fill & Sign: cross Isi & Tanda Tangani: salib + Fill & Sign: date Isi & Tanda Tangani: tanggal + Fill & Sign: dot Isi & Tanda Tangani: titik + Fill & Sign: initials Isi & Tanda Tangani: inisial + Fill & Sign: line Isi & Tanda Tangani: garis + Fill & Sign: remove saved initials Isi & Tanda Tangani: hapus inisial tersimpan + Fill & Sign: remove saved signature Isi & Tanda Tangani: hapus tanda tangan tersimpan + Fill & Sign: sign Isi & Tanda Tangani: tanda tangani + Find text and redact Cari teks dan sensor + Find text and redact… Cari teks dan sensor… + Fit to width scrolling Gulir sesuai lebar + Fit visible Sesuaikan yang terlihat + Fix hairlines Perbaiki garis rambut + Fix reading order Perbaiki urutan baca + Flatten comments Ratakan komentar + Flatten form fields Ratakan kolom formulir + Form fields panel Panel kolom formulir + Geospatial location Lokasi geospasial + Go to page… Ke halaman… + HTML web page Halaman web HTML + Header and footer Header dan footer + Hide all comments Sembunyikan semua komentar + Highlight text Sorot teks + Image Gambar + Image (PNG) Gambar (PNG) + Image field Kolom gambar + Images Gambar + Import comments… Impor komentar… + Import data Impor data + Import form data… Impor data formulir… + In multiple files Di beberapa file + In this file Di file ini + Index Indeks + Initials Inisial + Insert Sisipkan + Insert pages Sisipkan halaman + Insert text Sisipkan teks + JavaScript JavaScript + JavaScript console… Konsol JavaScript… + Join the ArtCraft Discord Gabung ke Discord ArtCraft + Light gray Abu-abu muda + Line Garis + Link Tautan + List box Kotak daftar + Make accessible Jadikan aksesibel + Manage embedded index Kelola indeks tersematam + Markup Anotasi + Marquee zoom Zoom area terpilih + Measure area Ukur luas + Measure distance Ukur jarak + Measure objects Ukur objek + Measure perimeter Ukur keliling + Measurement information Informasi pengukuran + Measurement snapping Snapping pengukuran + Merge data files into spreadsheet… Gabungkan file data ke spreadsheet… + Microsoft Word (.docx) Microsoft Word (.docx) + Modify page Ubah halaman + Multiple files Beberapa file + New bookmarks from structure Bookmark baru dari struktur + Open accessibility report Buka laporan aksesibilitas + Optimize scanned documents Optimalkan dokumen hasil pindai + Optimize scanned documents… Optimalkan dokumen hasil pindai… + Output preview Pratinjau keluaran + Oval Oval + PDF/A… PDF/A… + Page grid Kisi halaman + Page labels Label halaman + Page options Opsi halaman + Page transitions Transisi halaman + Paste pages Tempel halaman + PdfCraft on GitHub PdfCraft di GitHub + PdfCraft web page Halaman web PdfCraft + Perimeter Keliling + Pin folder to Home… Sematkan folder ke Beranda… + PostScript / EPS PostScript / EPS + Preflight Pemeriksaan pra-cetak + Prepare for accessibility Siapkan untuk aksesibilitas + Prepare for distribution Siapkan untuk distribusi + Prepare for distribution… Siapkan untuk distribusi… + Presentation (.pptx) Presentasi (.pptx) + Print production Produksi cetak + Protect a PDF Lindungi PDF + Protect with password Lindungi dengan kata sandi + Radio button Tombol radio + Recognize text Pengenalan teks + Recognize text in multiple files… Pengenalan teks di beberapa file… + Recognize text… Pengenalan teks… + Rectangle Persegi panjang + Redact a PDF Sensor PDF + Redact pages Sensori halaman + Redact pages… Sensori halaman… + Redact text and images Sensor teks dan gambar + Redaction properties… Properti penyensoran… + Reduce file size Perkecil ukuran file + Remove all links Hapus semua tautan + Remove background Hapus latar belakang + Remove header & footer Hapus header & footer + Remove hidden information Hapus informasi tersembunyi + Remove hidden information… Hapus informasi tersembunyi… + Remove watermark Hapus tanda air + Replace Ganti + Replace text Ganti teks + Reset panel layout Atur ulang tata letak panel + Review Tinjau + Rich Text Format (.rtf) Rich Text Format (.rtf) + Rotate Putar + Rotate pages Putar halaman + Rotate pages clockwise Putar halaman searah jarum jam + Rotate pages counterclockwise Putar halaman berlawanan arah jarum jam + Sanitize document Bersihkan dokumen + Sanitize document… Bersihkan dokumen… + Save as PDF/A Simpan sebagai PDF/A + Save as PDF/UA Simpan sebagai PDF/UA + Save as PDF/X Simpan sebagai PDF/X + Scan & OCR Pindai & OCR + Security properties Properti keamanan + Select files to compare Pilih file untuk dibandingkan + Separate PDFs Pisahkan PDF + Set measurement scale Atur skala pengukuran + Set page boxes Atur kotak halaman + Set page boxes… Atur kotak halaman… + Set properties Atur properti + Show cover page in two-page view Tampilkan halaman sampul dalam tampilan dua halaman + Signature Tanda tangan + Signatures panel Panel tanda tangan + Single file Satu file + Snapping Snapping + Split Pisah + Spreadsheet (.xlsx) Spreadsheet (.xlsx) + Squiggly underline Garis bawah bergelombang + Squiggly underline text Teks garis bawah bergelombang + Stamp Stempel + Stamp palette Palet stempel + Stamps Stempel + Standards Standar + Sticky note Catatan tempel + Strikethrough text Teks coret + Summarize Ringkas + Summarize comments Ringkas komentar + Switch light / dark theme Ganti tema terang / gelap + Tab order by columns Urutan tab menurut kolom + Tab order by rows Urutan tab menurut baris + Tab order: by columns Urutan tab: menurut kolom + Tab order: by document structure Urutan tab: menurut struktur dokumen + Tab order: by rows Urutan tab: menurut baris + Tags panel Panel tag + Text (plain) Teks (polos) + Text box Kotak teks + Text field Kolom teks + Timestamp Stempel waktu + Translate Terjemahkan + Underline text Teks bergaris bawah + Update background… Perbarui latar belakang… + Update header & footer… Perbarui header & footer… + Update watermark… Perbarui tanda air… + Use JavaScript Gunakan JavaScript + Use a certificate Gunakan sertifikat + Use guided actions Gunakan tindakan berpemandu + Use print production Gunakan produksi cetak + Use system setting Gunakan setelan sistem + Validate all signatures Validasi semua tanda tangan + Watermark Tanda air + Move object Pindahkan objek + Move objects Pindahkan objek + All tools Semua alat + Read Baca + E-Sign E-Sign + Tools Alat + Inspector Inspektur + on page {label} di halaman {label} + A font isn't embedded Font tidak tertanam + A {} action isn't allowed Tindakan {} tidak diizinkan + A {} annotation has additional actions Anotasi {} memiliki tindakan tambahan + A {} annotation has no appearance stream Anotasi {} tidak memiliki aliran tampilan + A {} annotation isn't set to print, or is hidden Anotasi {} tidak disetel untuk dicetak, atau disembunyikan + Accessibility Report Laporan Aksesibilitas + Add the PDFs to combine Tambahkan PDF untuk digabung + Added the first {n} PDFs in {folder} Menambahkan {n} PDF pertama di {folder} + CRL Signing Penandatanganan CRL + Certificate Signing Penandatanganan Sertifikat + Change Author Ubah Penulis + Change Keywords Ubah Kata Kunci + Change Subject Ubah Subjek + Change Title Ubah Judul + Choose a digital ID. Pilih ID digital. + Create links Buat tautan + Creator Pembuat + Cut and stack needs Two-sided: Off. Print single-sided sheets. Potong dan tumpuk memerlukan Dua sisi: Nonaktif. Cetak lembar satu sisi. + Data Encipherment Enkripsi Data + Decipher Only Hanya Dekripsi + Detailed Report Laporan Rinci + DeviceCMYK is used, but the PDF/A output intent isn't a CMYK profile DeviceCMYK digunakan, tetapi output intent PDF/A bukan profil CMYK + DeviceRGB is used, but the PDF/A output intent isn't an RGB profile DeviceRGB digunakan, tetapi output intent PDF/A bukan profil RGB + Digital Signature Tanda Tangan Digital + Document properties (⌘D) Properti dokumen (⌘D) + Drop PDFs or folders here, or choose them. Letakkan PDF atau folder di sini, atau pilih. + Encipher Only Hanya Enkripsi + English Inggris + Enter a URL Masukkan URL + Enter a name. Masukkan nama. + Enter a page number Masukkan nomor halaman + Enter the field names Masukkan nama kolom + Every PDF in the folder Semua PDF di folder + Every PDF in the folder and the folders inside it Semua PDF di folder dan folder di dalamnya + Field "{}" on page {p} has no description (tooltip) Kolom "{}" pada halaman {p} tidak memiliki deskripsi (tooltip) + Filename Nama file + Flatten Fill & Sign Ratakan Isi & Tanda Tangani + Font (unnamed) on page {p} doesn't map its characters to Unicode Font (tanpa nama) pada halaman {p} tidak memetakan karakternya ke Unicode + Font {} on page {p} doesn't map its characters to Unicode Font {} pada halaman {p} tidak memetakan karakternya ke Unicode + Form field on page {p} isn't tagged Kolom formulir pada halaman {p} tidak diberi tag + H{n} follows an H{d}; headings should not skip levels H{n} mengikuti H{d}; judul tidak boleh melompati level + Inserted text Teks yang disisipkan + Key Agreement Key Agreement + Key Encipherment Key Encipherment + Margins (in) Margin (in) + New bookmark (⌘B) Bookmark baru (⌘B) + Next (⌘G) Berikutnya (⌘G) + No PDFs found in {folder} Tidak ada PDF yang ditemukan di {folder} + No document language is set Bahasa dokumen belum diatur + No page has text: the document appears to be images of pages Tidak ada halaman yang memiliki teks: dokumen tampaknya berupa gambar halaman + Non-Repudiation Non-Repudiation + Only the document's owner can change its security (open it with the permissions password) Hanya pemilik dokumen yang dapat mengubah keamanannya (buka dengan kata sandi izin) + Open a PDF (⌘O) Buka PDF (⌘O) + Page {p} doesn't tab in structure order Halaman {p} tidak memiliki tab dalam urutan struktur + Page {p}: {n} untagged content item Halaman {p}: {n} item konten tanpa tag + Page {p}: {n} untagged content items Halaman {p}: {n} item konten tanpa tag + Page {} has additional actions Halaman {} memiliki tindakan tambahan + Panel layout could not be restored: {error} Tata letak panel tidak dapat dipulihkan: {error} + Panel move was not applied: {error} Pemindahan panel tidak diterapkan: {error} + PdfCraft can't check this signature yet: {}. PdfCraft belum dapat memeriksa tanda tangan ini: {}. + Previous (⇧⌘G) Sebelumnya (⇧⌘G) + Print (⌘P) Cetak (⌘P) + Producer Produsen + Redo {action} Ulangi {action} + Rendering… Merender… + Report created Laporan dibuat + Rev. {rev}: Certified by an unknown signer Rev. {rev}: Disertifikasi oleh penanda tangan yang tidak dikenal + Rev. {rev}: Certified by {name} Rev. {rev}: Disertifikasi oleh {name} + Rev. {rev}: Signed by an unknown signer Rev. {rev}: Ditandatangani oleh penanda tangan yang tidak dikenal + Rev. {rev}: Signed by {name} Rev. {rev}: Ditandatangani oleh {name} + Rotate view clockwise (⇧⌘+) Putar tampilan searah jarum jam (⇧⌘+) + Rule Name Nama Aturan + Save (M4) Simpan (M4) + Save as {level} Simpan sebagai {level} + Signature is invalid Tanda tangan tidak valid + Signature is valid Tanda tangan valid + Signature validity is unknown Keabsahan tanda tangan tidak diketahui + Signing time is from the clock on the signer's computer. Waktu penandatanganan berasal dari jam pada komputer penanda tangan. + Still rendering — this page is unusually complex… Masih merender — halaman ini sangat kompleks… + The ECDSA signature is not in canonical DER (trailing bytes, padding or a missing sign byte); it was read anyway. Tanda tangan ECDSA bukan DER kanonis (byte tambahan, padding, atau byte tanda yang hilang); tetapi tetap dibaca. + The ECDSA signature is the raw r and s values instead of a DER sequence; it was read anyway. Tanda tangan ECDSA berupa nilai r dan s mentah, bukan urutan DER; tetapi tetap dibaca. + The RSA signature value does not have the length of the key's modulus (leading zero bytes dropped or added); it was read anyway. Nilai tanda tangan RSA tidak memiliki panjang sebesar modulus kunci (nol di depan dihapus atau ditambahkan); tetapi tetap dibaca. + The RSA signature's DigestInfo has no NULL parameter (older signers write it so); it was read anyway. DigestInfo tanda tangan RSA tidak memiliki parameter NULL (penandatangan lama menulisnya demikian); tetapi tetap dibaca. + The certificate of {} does not allow this many CA certificates below it (path length), so it is not used to vouch for {}. Sertifikat {} tidak mengizinkan jumlah sertifikat CA sebesar itu di bawahnya (panjang jalur), sehingga tidak digunakan untuk menjamin {}. + The certificate of {} is not a CA certificate that may issue certificates, so it is not used to vouch for {}. Sertifikat {} bukan sertifikat CA yang dapat menerbitkan sertifikat, sehingga tidak digunakan untuk menjamin {}. + The certificate of {} was not valid at the time of signing, so it is not used to vouch for {}. Sertifikat {} tidak valid pada saat penandatanganan, sehingga tidak digunakan untuk menjamin {}. + The checker found problems which may prevent the document from being fully accessible. Pemeriksa menemukan masalah yang mungkin membuat dokumen tidak sepenuhnya dapat diakses. + The document has been altered or corrupted since the signature was applied. Dokumen telah diubah atau rusak sejak tanda tangan diterapkan. + The document has been altered or corrupted since the timestamp was applied. Dokumen telah diubah atau rusak sejak stempel waktu diterapkan. + The document has been altered since this signature was applied in ways it does not permit ({}). Dokumen telah diubah sejak tanda tangan ini diterapkan dengan cara yang tidak diizinkan ({}). + The document has been altered since this timestamp was applied in ways it does not permit ({}). Dokumen telah diubah sejak stempel waktu ini diterapkan dengan cara yang tidak diizinkan ({}). + The document has been modified since this signature was applied, but the changes are permitted ({}). Dokumen telah dimodifikasi sejak tanda tangan ini diterapkan, tetapi perubahannya diizinkan ({}). + The document has been modified since this timestamp was applied, but the changes are permitted ({}). Dokumen telah dimodifikasi sejak stempel waktu ini diterapkan, tetapi perubahannya diizinkan ({}). + The document has no tags (structure tree) Dokumen tidak memiliki tag (pohon struktur) + The document has no title Dokumen tidak memiliki judul + The document isn't marked as tagged (MarkInfo Marked) Dokumen tidak ditandai sebagai bertag (MarkInfo Marked) + The document isn't tagged, so none of its content is Dokumen tidak diberi tag, sehingga tidak ada isinya yang diberi tag + The document's embedded revocation information shows that the signer's certificate has not been revoked. Informasi pencabutan yang tertanam pada dokumen menunjukkan bahwa sertifikat penanda tangan belum dicabut. + The embedded timestamp token is valid and its authority is trusted; trusted time is {}. Token stempel waktu yang tertanam valid dan otoritasnya dipercaya; waktu yang dipercaya adalah {}. + The font {} isn't embedded Font {} tidak tertanam + The metadata doesn't identify the file as {} Metadata tidak mengidentifikasi file sebagai {} + The password is incorrect. Kata sandi salah. + The password must have at least 6 characters. Kata sandi harus memiliki minimal 6 karakter. + The passwords do not match. Kata sandi tidak cocok. + The security settings don't allow screen readers to read the text Pengaturan keamanan tidak mengizinkan pembaca layar untuk membaca teks + The signature algorithm and the SignerInfo's digest algorithm name different hashes; the signature was made with the SignerInfo's. Algoritma tanda tangan dan algoritma digest SignerInfo menunjuk hash yang berbeda; tanda tangan dibuat dengan milik SignerInfo. + The signature carries an unverified timestamp ({}): the timestamp authority is not in your list of trusted certificates, so the signing time claimed by the signer is used instead. Tanda tangan ini memuat stempel waktu yang belum diverifikasi ({}): otoritas stempel waktu tidak ada dalam daftar sertifikat tepercaya Anda, sehingga waktu penandatanganan yang diklaim oleh penanda tangan yang digunakan. + The signature contents are not hexadecimal. Isi tanda tangan bukan heksadesimal. + The signature could not be checked ({}). Tanda tangan tidak dapat diperiksa ({}). + The signature could not be read ({}). Tanda tangan tidak dapat dibaca ({}). + The signature could not be verified ({}). Tanda tangan tidak dapat diverifikasi ({}). + The signature has no valid byte range. Tanda tangan tidak memiliki rentang byte yang valid. + The signature includes an embedded timestamp. Tanda tangan menyertakan stempel waktu yang tertanam. + The signature is BER-encoded (indefinite lengths) rather than DER; it was read leniently. Tanda tangan dikodekan dengan BER (panjang tidak tetap), bukan DER; tetap dibaca secara toleran. + The signature uses the legacy adbe.x509.rsa_sha1 format. Tanda tangan menggunakan format lama adbe.x509.rsa_sha1. + The signature value does not match the signer's certificate: the signature is corrupt. Nilai tanda tangan tidak cocok dengan sertifikat penanda tangan: tanda tangan rusak. + The signature's byte range does not exclude exactly its contents. Rentang byte tanda tangan tidak mengecualikan tepat isi tanda tangan tersebut. + The signature's byte range does not match the file. Rentang byte tanda tangan tidak cocok dengan file. + The signature's timestamp token could not be verified ({}). Token stempel waktu tanda tangan tidak dapat diverifikasi ({}). + The signature's timestamp token does not cover the signature value. Token stempel waktu tanda tangan tidak mencakup nilai tanda tangan. + The signed content is a constructed (segmented) OCTET STRING, as BER allows; it was read anyway. Konten yang ditandatangani adalah OCTET STRING tersusun (bersegmen), sebagaimana diizinkan BER; tetap dibaca. + The signer's certificate does not allow digital signatures (its key usage has neither digital signature nor non-repudiation). Sertifikat penanda tangan tidak mengizinkan tanda tangan digital (penggunaan kuncinya tidak memuat digital signature maupun non-repudiation). + The signer's certificate has been revoked ({}). Sertifikat penanda tangan telah dicabut ({}). + The signer's certificate has critical extensions PdfCraft does not recognize ({}). Sertifikat penanda tangan memiliki ekstensi kritis yang tidak dikenali PdfCraft ({}). + The signer's certificate is not in the signature. Sertifikat penanda tangan tidak ada di dalam tanda tangan. + The signer's certificate is not issued for signing documents (its extended key usage has no document-signing purpose). Sertifikat penanda tangan tidak diterbitkan untuk menandatangani dokumen (penggunaan kunci ekstensifnya tidak memuat tujuan penandatanganan dokumen). + The signer's certificate was not valid at the time of signing. Sertifikat penanda tangan tidak valid pada saat penandatanganan. + The signer's identity is unknown because it has not been included in your list of trusted certificates and none of its parent certificates are trusted certificates. Identitas penanda tangan tidak diketahui karena tidak disertakan dalam daftar sertifikat tepercaya Anda dan tidak ada sertifikat induknya yang merupakan sertifikat tepercaya. + The signer's identity is valid. Identitas penanda tangan valid. + The timestamp authority's certificate was not valid at the time of timestamping. Sertifikat otoritas stempel waktu tidak valid pada saat pembuatan stempel waktu. + The timestamp contents are not hexadecimal. Isi stempel waktu bukan heksadesimal. + The timestamp has no valid byte range. Stempel waktu tidak memiliki rentang byte yang valid. + The timestamp token could not be read ({}). Token stempel waktu tidak dapat dibaca ({}). + The timestamp token is valid and its authority is trusted. Token stempel waktu valid dan otoritasnya dipercaya. + The timestamp token is valid, but the timestamp authority is not in your list of trusted certificates. Token stempel waktu valid, tetapi otoritas stempel waktu tidak ada dalam daftar sertifikat tepercaya Anda. + The timestamp's byte range does not exclude exactly its contents. Rentang byte stempel waktu tidak mengecualikan tepat isinya. + The timestamp's byte range does not match the file. Rentang byte stempel waktu tidak cocok dengan file. + The window shows the file name, not the title (Initial View > Show) Jendela menampilkan nama file, bukan judul (Tampilan Awal > Tampilkan) + There is no folder to save the digital ID in. Tidak ada folder untuk menyimpan ID digital. + This document has not been modified since this signature was applied. Dokumen ini belum dimodifikasi sejak tanda tangan ini diterapkan. + This document has not been modified since this timestamp was applied. Dokumen ini belum dimodifikasi sejak stempel waktu ini diterapkan. + This signature uses RIPEMD-160, a legacy 160-bit hash algorithm that is no longer recommended for signatures. It still validates, but it should not be relied on. Tanda tangan ini menggunakan RIPEMD-160, algoritme hash lama 160-bit yang tidak lagi direkomendasikan untuk tanda tangan. Tanda tangan ini tetap valid, tetapi tidak seharusnya diandalkan. + This signature uses SHA-1, a weak hash algorithm: collisions in it have been demonstrated. It still validates because many documents signed years ago use it, but it should not be relied on. Tanda tangan ini menggunakan SHA-1, algoritme hash yang lemah: tabrakan pada algoritme ini telah dibuktikan. Tanda tangan ini tetap valid karena banyak dokumen yang ditandatangani bertahun-tahun lalu memakainya, tetapi tidak seharusnya diandalkan. + Undo {action} Urungkan {action} + Unsigned signature field Kolom tanda tangan yang belum ditandatangani + Unsigned signature field: {name} Kolom tanda tangan yang belum ditandatangani: {name} + Zoom in (⌘+) Perbesar (⌘+) + Zoom in / out (also pinch or ⌘-scroll) Perbesar / perkecil (juga cubit atau ⌘-gulir) + Zoom out (⌘−) Perkecil (⌘−) + alternate text hides an annotation inside it teks alternatif menyembunyikan anotasi di dalamnya + alternate text on an element with no page content teks alternatif pada elemen tanpa konten halaman + comments komentar + document security store penyimpanan keamanan dokumen + document structure struktur dokumen + form fill pengisian formulir + its alternate text is inside another element's and will never be read teks alternatifnya berada di dalam elemen lain dan tidak akan pernah dibaca + links tautan + metadata metadata + no alternate text tanpa teks alternatif + no header cells (TH) tanpa sel header (TH) + no summary tanpa ringkasan + not in a TR bukan di dalam TR + not in a Table, THead, TBody or TFoot bukan di dalam Table, THead, TBody, atau TFoot + not in an L (list) bukan di dalam L (daftar) + not in an LI (list item) bukan di dalam LI (item daftar) + other changes perubahan lain + page content konten halaman + page {n} is out of range (1–{count}) halaman {n} di luar rentang (1–{count}) + pages added or removed halaman ditambahkan atau dihapus + rows have between {min} and {max} columns baris memiliki antara {min} dan {max} kolom + the first heading is an H{n}; headings should not skip levels judul pertama adalah H{n}; judul tidak boleh melompati level + the signed version could not be read versi yang ditandatangani tidak dapat dibaca + {n} pages and no bookmarks {n} halaman dan tanpa bookmark + {page} is not a page number or label {page} bukan nomor halaman atau label + {ty} element on page {p}: {what} elemen {ty} pada halaman {p}: {what} + {ty} element: {what} elemen {ty}: {what} + {who}, certificate issued by an unknown issuer. {who}, sertifikat diterbitkan oleh penerbit yang tidak dikenal. + {who}, certificate issued by {issuer}. {who}, sertifikat diterbitkan oleh {issuer}. + {} annotation on page {p} isn't tagged anotasi {} pada halaman {p} tidak diberi tag + {} annotations aren't allowed anotasi {} tidak diizinkan + … and {n} more … dan {n} lagi +@plural Delete {n} field|Delete {n} fields Hapus {n} kolom +@plural {n} byte|{n} bytes {n} byte +@plural {n} image optimized|{n} images optimized {n} gambar dioptimalkan +@plural {n} item discarded|{n} items discarded {n} item dibuang +@plural {n} pixel|{n} pixels {n} piksel +action wizard Start Mulai +comment menu Edit Edit + A button Sebuah tombol + A diagonal CONFIDENTIAL watermark on every page. Watermark CONFIDENTIAL diagonal pada setiap halaman. + A document needs at least one page: copy instead Dokumen memerlukan minimal satu halaman: gunakan salinan + A form field has additional actions Sebuah kolom formulir memiliki tindakan tambahan + A link Sebuah tautan + A script Sebuah skrip + A selected field has no widget on any page, so the fields can't be edited together. Kolom yang dipilih tidak memiliki widget di halaman mana pun, sehingga kolom tidak dapat diedit bersama. + A stream refers to an external file Sebuah stream mengacu ke file eksternal + A stream uses LZW compression Sebuah stream menggunakan kompresi LZW + A summary describes the table's purpose and layout. Add a Summary attribute to each table. Ringkasan menjelaskan tujuan dan tata letak tabel. Tambahkan atribut Ringkasan ke setiap tabel. + About Tentang + Accepted Diterima + Accessibility permission flag Bendera izin aksesibilitas + Accessibility permission flag is set Bendera izin aksesibilitas diaktifkan + Add Page Numbers Tambahkan Nomor Halaman + Add arrow Tambahkan panah + Add background Tambahkan latar belakang + Add bookmark Tambahkan bookmark + Add callout Tambahkan kotak komentar + Add checkmark Tambahkan tanda centang + Add cloud Tambahkan awan + Add connected lines Tambahkan garis terhubung + Add cross Tambahkan silang + Add dot Tambahkan titik + Add drawing Tambahkan gambar + Add field Tambahkan kolom + Add file attachment Tambahkan lampiran file + Add footer Tambahkan footer + Add header Tambahkan header + Add header & footer Tambahkan header & footer + Add highlight Tambahkan sorotan + Add image Tambahkan gambar + Add inserted text Tambahkan teks yang disisipkan + Add line Tambahkan garis + Add link Tambahkan tautan + Add oval Tambahkan oval + Add polygon Tambahkan poligon + Add rectangle Tambahkan persegi panjang + Add redaction mark Tambahkan tanda sensor + Add signature Tambahkan tanda tangan + Add squiggly underline Tambahkan garis bawah bergelombang + Add stamp Tambahkan stempel + Add sticky note Tambahkan catatan tempel + Add strikethrough Tambahkan coretan + Add text box Tambahkan kotak teks + Add underline Tambahkan garis bawah + Add watermark Tambahkan tanda air + Add {what} Tambahkan {what} + Added the first {n} files in {folder} Menambahkan {n} file pertama di {folder} + Adding images arrives on the web with file pickers for images Menambahkan gambar hadir di web bersama pemilih file untuk gambar + Algorithm Algoritma + Align fields Sejajarkan kolom + All annotations are tagged Semua anotasi diberi tag + All form fields are tagged Semua kolom formulir diberi tag + All form fields have description Semua kolom formulir memiliki deskripsi + All multimedia objects are tagged Semua objek multimedia diberi tag + All page content is tagged Semua konten halaman diberi tag + Allowed Diizinkan + Alternate Text Teks Alternatif + Alternate text inside an element that already has alternate text is never read. Remove the inner alternate text. Teks alternatif di dalam elemen yang sudah memiliki teks alternatif tidak akan pernah dibaca. Hapus teks alternatif di bagian dalam. + Alternate text must be associated with some content Teks alternatif harus terkait dengan konten tertentu + Alternate text on an element that contains a link or field hides that annotation from assistive technology. Move the alternate text. Teks alternatif pada elemen yang memuat tautan atau kolom menyembunyikan anotasi tersebut dari teknologi bantu. Pindahkan teks alternatif. + Alternate text on an element without page content is never reached. Remove it or attach the element to content. Teks alternatif pada elemen tanpa konten halaman tidak akan pernah dijangkau. Hapus atau pasang elemen tersebut ke konten. + Alternate text should not hide annotation Teks alternatif tidak boleh menyembunyikan anotasi + Alternate text that will never be read Teks alternatif yang tidak akan pernah dibaca + An action is already running Sebuah tindakan sedang berjalan + An embedded file has no AFRelationship File tertanam tidak memiliki AFRelationship + An image asks to be interpolated Sebuah gambar meminta untuk diinterpolasi + An image has alternates or OPI information Sebuah gambar memiliki gambar alternatif atau informasi OPI + Animation that flashes can cause seizures. Check scripts and media for flicker. Animasi yang berkedip dapat menyebabkan kejang. Periksa skrip dan media untuk kedipan. + Another file dialog is still open. Finish with it first. Dialog file lain masih terbuka. Selesaikan terlebih dahulu. + Application Aplikasi + Applied 1 redaction mark. Save to remove the content from the file. 1 tanda sensor diterapkan. Simpan untuk menghapus konten dari file. + Applied {n} redaction marks. Save to remove the content from the file. {n} tanda sensor diterapkan. Simpan untuk menghapus konten dari file. + Appropriate nesting Penumpukan yang sesuai + Arbitrary Mask Masker sembarang + Associated with content terkait dengan konten + At least one signature has problems. Setidaknya satu tanda tangan bermasalah. + At least one signature is invalid. Setidaknya satu tanda tangan tidak valid. + Attachment Lampiran + Basic constraints Batasan dasar + Beveled Miring + Black Hitam + Black on white Hitam di atas putih + Blue Biru + Bookmarks are present in large documents Bookmark ada pada dokumen besar + Both Keduanya + Button Properties Properti Tombol + Button Style: Gaya Tombol: + Calculate Hitung + Callout Kotak komentar + Cancelled Dibatalkan + Center Footer Text Pusatkan Teks Footer + Center Header Text Pusatkan Teks Header + Center horizontally Pusatkan secara horizontal + Center vertically Pusatkan secara vertikal + Certificate Viewer Penampil Sertifikat + Certified by {by} Disertifikasi oleh {by} + Change comment properties Ubah properti komentar + Change document properties Ubah properti dokumen + Change field properties Ubah properti kolom + Change initial view Ubah tampilan awal + Change link properties Ubah properti tautan + Change tag properties Ubah properti tag + Change {key} Ubah {key} + Changing the document Mengubah dokumen + Character encoding Pengodean karakter + Character limit: Batas karakter: + Check Periksa + Check Box Properties Properti Kotak Centang + Check Box Style: Gaya Kotak Centang: + Check that the tags read in the order a sighted reader would. Use the Reading Order tool or the Tags panel to correct it. Pastikan tag dibaca dalam urutan seperti yang akan dibaca pembaca yang melihat. Gunakan alat Urutan Baca atau panel Tag untuk memperbaikinya. + CheckBox CheckBox + Checked Dicentang + Choose a folder for the split files Pilih folder untuk file hasil pisah + Choose a folder on this computer to pin Pilih folder di komputer ini untuk disematkan + Click on the page to add a {tool}, or drag to set its size Klik pada halaman untuk menambahkan {tool}, atau seret untuk mengatur ukurannya + Click text or an image to edit it Klik teks atau gambar untuk mengeditnya + Color Images Gambar berwarna + Color Spaces Ruang warna + Color contrast Kontras warna + Comb of characters Sisir karakter + Combo Kombo + Coming in milestone {m}. Items marked Ready work today. Hadir di milestone {m}. Item bertanda Ready sudah dapat digunakan. + Command Perintah + Commenting Komentar + Comments and markups Komentar dan anotasi + Comments, links and fields must be in the tag tree to be announced. Tag the annotations. Komentar, tautan, dan kolom harus berada di pohon tag agar dapat diumumkan. Beri tag pada anotasi. + Completed Selesai + Configure a Digital ID for Signing Konfigurasikan ID Digital untuk Penandatanganan + Connected lines Garis terhubung + Content Streams Content Streams + Content copying Penyalinan konten + Content copying for accessibility Penyalinan konten untuk aksesibilitas + Contributors Kontributor + Copied {what} {what} disalin + Copy or cut pages first Salin atau potong halaman terlebih dahulu + Could not save: {e} Tidak dapat menyimpan: {e} + Couldn't add {name}: {e} Tidak dapat menambahkan {name}: {e} + Couldn't combine files: {e} Tidak dapat menggabungkan file: {e} + Couldn't create a PDF: {e} Tidak dapat membuat PDF: {e} + Couldn't download {name}: {e} Tidak dapat mengunduh {name}: {e} + Couldn't extract pages: {e} Tidak dapat mengekstrak halaman: {e} + Couldn't fit the visible content: {e} Tidak dapat menyesuaikan konten yang terlihat: {e} + Couldn't follow linked PDF: {reason} Tidak dapat mengikuti PDF tertaut: {reason} + Couldn't import the signature image: {e} Tidak dapat mengimpor gambar tanda tangan: {e} + Couldn't open revision {n}: {e} Tidak dapat membuka revisi {n}: {e} + Couldn't open the result: {e} Tidak dapat membuka hasil: {e} + Couldn't open the signed version: {e} Tidak dapat membuka versi yang ditandatangani: {e} + Couldn't open {name}: {e} Tidak dapat membuka {name}: {e} + Couldn't optimize the file Tidak dapat mengoptimalkan file + Couldn't optimize the file: {e} Tidak dapat mengoptimalkan file: {e} + Couldn't print from the browser ({e}); downloaded {name} to print instead Tidak dapat mencetak dari peramban ({e}); mengunduh {name} sebagai gantinya + Couldn't read {name}: {e} Tidak dapat membaca {name}: {e} + Couldn't recover {name}: {e} Tidak dapat memulihkan {name}: {e} + Couldn't reload {name}: {e} Tidak dapat memuat ulang {name}: {e} + Couldn't save the image: {e} Tidak dapat menyimpan gambar: {e} + Couldn't save {name}: {e} Tidak dapat menyimpan {name}: {e} + Couldn't save: {e} Tidak dapat menyimpan: {e} + Couldn't show the file picker. Please try again. Tidak dapat menampilkan pemilih file. Silakan coba lagi. + Couldn't split: {e} Tidak dapat memisah: {e} + Couldn't summarize comments: {e} Tidak dapat meringkas komentar: {e} + Couldn't take the snapshot: {e} Tidak dapat mengambil snapshot: {e} + Couldn't unlock {name}: {e} Tidak dapat membuka kunci {name}: {e} + Couldn't use the photo: {e} Tidak dapat menggunakan foto: {e} + Couldn't use {name}: {e} Tidak dapat menggunakan {name}: {e} + Couldn't write {name}: {e} Tidak dapat menulis {name}: {e} + Couldn't write {path}: {e} Tidak dapat menulis {path}: {e} + Create link Buat tautan + Created 1 link 1 tautan dibuat + Created a PDF from the first {n} files PDF dibuat dari {n} file pertama + Created a comment summary Ringkasan komentar dibuat + Created {n} links {n} tautan dibuat + Credit Cards Kartu Kredit + Crop page Potong halaman + Custom font Font kustom + Custom stamps arrive on the web with file pickers for images Stempel kustom hadir di versi web dengan pemilih file untuk gambar + Cut {what} Potong {what} + Dark gray theme Tema abu-abu gelap + Dashed Putus-putus + Dates Tanggal + Delete bookmark Hapus bookmark + Delete content Hapus konten + Delete document JavaScript Hapus JavaScript dokumen + Delete field Hapus kolom + Delete image Hapus gambar + Delete link Hapus tautan + Delete page Hapus halaman + Delete selected fields Hapus kolom yang dipilih + Deleted Dihapus + Detected 1 form field 1 kolom formulir terdeteksi + Detected {n} form fields {n} kolom formulir terdeteksi + Device colour is used, but there is no PDF/A output intent Warna perangkat digunakan, tetapi tidak ada output intent PDF/A + DeviceCMYK is used: it needs a CMYK output intent (not added automatically) DeviceCMYK digunakan: diperlukan output intent CMYK (tidak ditambahkan otomatis) + Diagnostic details Detail diagnostik + Digital Signature Properties Properti Tanda Tangan Digital + Discard all comments, forms and multimedia Buang semua komentar, formulir dan multimedia + Discard all links, actions and JavaScript Buang semua tautan, aksi dan JavaScript + Discard all object data (file attachments) Buang semua data objek (lampiran file) + Discard bookmarks Buang bookmark + Discard document information and metadata Buang informasi dokumen dan metadata + Discard hidden layer content Buang konten lapisan tersembunyi + Discard hidden text Buang teks tersembunyi + Discard private data of other applications Buang data pribadi aplikasi lain + Distribute fields Distribusikan kolom + Document Overhead Beban dokumen + Document assembly Penyusunan dokumen + Document has appropriate color contrast Dokumen memiliki kontras warna yang sesuai + Document is not image-only PDF Dokumen ini bukan PDF gambar saja + Document is tagged PDF Dokumen ini PDF bertanda + Document sanitized. Save to finish: saving rewrites the whole file. Dokumen dibersihkan. Simpan untuk menyelesaikan: penyimpanan menulis ulang seluruh file. + Document structure provides a logical reading order Struktur dokumen menyediakan urutan baca logis + Document title is showing in title bar Judul dokumen tampil di bilah judul + Documents of more than 20 pages need bookmarks for navigation. Add bookmarks for the main sections. Dokumen dengan lebih dari 20 halaman memerlukan bookmark untuk navigasi. Tambahkan bookmark untuk bagian utama. + Double-click Klik dua kali + Downloaded {name} {name} diunduh + Downloading attachments on the web arrives with M3.10 ({n} bytes ready) Mengunduh lampiran di versi web hadir dengan M3.10 ({n} byte siap) + Drag a rectangle around the area to copy Seret sebuah persegi panjang di sekitar area yang akan disalin + Drag a rectangle on a page to crop it; double-click a page for Set Page Boxes Seret persegi panjang pada halaman untuk memotongnya; klik dua kali halaman untuk Kotak Halaman + Drag a rectangle to create a link; double-click a link to edit it Seret persegi panjang untuk membuat tautan; klik dua kali tautan untuk mengeditnya + Drag the corners onto the document's edges, then choose Enhance page. Seret sudutnya ke tepi dokumen, lalu pilih Peningkatan halaman. + Drag to draw the area where the signature should appear. Seret untuk menggambar area tempat tanda tangan akan ditampilkan. + Dropdown Properties Properti Dropdown + Duplicate field Duplikat kolom + Duplicate page Duplikat halaman + Each field needs a tooltip that says what to enter. Add one in Field Properties > General > Tooltip. Setiap kolom memerlukan tooltip yang menjelaskan apa yang harus diisi. Tambahkan di Properti Kolom > Umum > Tooltip. + Edit comment Edit komentar + Edit content Edit konten + Edit document JavaScript Edit JavaScript dokumen + Edit fields Edit kolom + Edit script of {name} Edit skrip {name} + Edit text Edit teks + Editing Mengedit + Email Addresses Alamat Email + Embedded Files File Tersemat + Embedded files must be PDF/A files themselves (use PDF/A-3 for others) File tersemat harus berupa file PDF/A (gunakan PDF/A-3 untuk yang lain) + Encryption Enkripsi + Endpoint Endpoint + Erase Hapus + Eraser Penghapus + Even pages Halaman genap + Everything on a page must be tagged or marked as an artifact (decoration, headers, footers). Tag the untagged content. Semua yang ada di halaman harus bertanda atau ditandai sebagai artefak (dekorasi, header, footer). Tandai konten yang belum bertanda. + Execute a menu item Jalankan item menu + Export certificate Ekspor sertifikat + Exported to {path} Diekspor ke {path} + Extended Graphics States Status Grafik Diperluas + Field Kolom + Field descriptions Deskripsi kolom + Figures alternate text Teks alternatif gambar + Figures require alternate text Gambar memerlukan teks alternatif + File attachments Lampiran file + Files are combined in this order. Leave Pages empty to take every page. File digabungkan dalam urutan ini. Biarkan Halaman kosong untuk mengambil semua halaman. + Fill in {name} Isi {name} + Filling of form fields Pengisian kolom formulir + Flatten Ratakan + Flip image Balik gambar + Fonts must map their characters to Unicode so text can be read and copied. Fix the fonts or recreate the PDF. Font harus memetakan karakternya ke Unicode agar teks dapat dibaca dan disalin. Perbaiki font atau buat ulang PDF. + Form fields must be in the tag tree (Form tags) to be announced. Tag the form fields. Kolom formulir harus berada di pohon tag (tag Formulir) agar diumumkan. Tandai kolom formulir. + Formulas and similar non-text elements need alternate text. Add alternate text to them. Rumus dan elemen non-teks serupa memerlukan teks alternatif. Tambahkan teks alternatif ke elemen tersebut. + Gray Abu-abu + Grayscale Images Gambar Skala Abu-abu + Green Hijau + Green on black Hijau di atas hitam + H / Space (hold) H / Space (tahan) + Header cells (TH) tell listeners what each column or row holds. Mark the header cells. Sel header (TH) memberi tahu pendengar isi setiap kolom atau baris. Tandai sel header. + Headers Header + Heading levels shouldn't skip (an H1 followed by an H3). Retag the headings. Tingkat judul tidak boleh melompat (H1 diikuti H3). Ubah lagi tag judul. + Headings Judul + Hidden layers Lapisan tersembunyi + Hidden text Teks tersembunyi + Hide a field Sembunyikan kolom + Hides annotation Menyembunyikan anotasi + High Tinggi + Home / End Home / End + Horizontally Horizontal + Image-only PDF PDF gambar saja + Import {name} Impor {name} + Importing data arrives on the web with file pickers for data files Mengimpor data hadir di versi web dengan pemilih file untuk file data + Incorrect password. Try again. Kata sandi salah. Coba lagi. + Insert pages from {name} Sisipkan halaman dari {name} + Insert pages from {name} — 1 field renamed Sisipkan halaman dari {name} — 1 kolom diganti namanya + Insert pages from {name} — fields renamed Sisipkan halaman dari {name} — kolom diganti namanya + Inserted Disisipkan + Inset Inset + Intended usage Penggunaan yang dimaksud + Intersection Irisan + Invert Balik + Irregular tables confuse cell navigation. Give every row the same number of cells (counting spans). Tabel yang tidak rapi membingungkan navigasi sel. Berikan setiap baris jumlah sel yang sama (termasuk sel yang digabungkan). + Issued by Diterbitkan oleh + Issued to Diterbitkan kepada + Issuer Penerbit + Key usage Penggunaan kunci + Keywords Kata kunci + LI must be a child of L LI harus menjadi anak dari L + Landscape pages Halaman lanskap + Lbl and LBody Lbl dan LBody + Lbl and LBody must be children of LI Lbl dan LBody harus menjadi anak dari LI + Left Footer Text Teks Footer Kiri + Left Header Text Teks Header Kiri + Light blue Biru muda + Links, actions and JavaScripts Tautan, aksi dan JavaScript + List Daftar + List Box Properties Properti Kotak Daftar + List items Item daftar + List items belong in a list. Fix the list's tags. Item daftar harus berada dalam daftar. Perbaiki tag daftar. + List labels and bodies belong in a list item. Fix the list's tags. Label dan badan daftar harus berada dalam item daftar. Perbaiki tag daftar. + Lists Daftar + Load document font Muat font dokumen + Local cross-PDF links require the desktop app Tautan antar-PDF lokal memerlukan aplikasi desktop + Lock comment Kunci komentar + Logical Reading Order Urutan Baca Logis + Low Rendah + Make scans searchable, then make them smaller. Buat hasil pindai dapat dicari, lalu perkecil ukurannya. + Mark all Tandai semua + Mark as Confidential Tandai sebagai Rahasia + Mark differences Tandai perbedaan + Mark figure as decorative Tandai gambar sebagai dekoratif + Mark for redaction Tandai untuk disensor + Mark pages for redaction Tandai halaman untuk disensor + Match field sizes Samakan ukuran kolom + Maximum Maksimum + Measuring tool Alat pengukur + Merged 1 file into {path} 1 file digabungkan ke {path} + Merged {n} files into {path} {n} file digabungkan ke {path} + Merging data files needs the desktop app Menggabungkan file data memerlukan aplikasi desktop + Metadata Metadata + Midpoint Titik tengah + Minimum Minimum + Models Model + Mouse Down Tetikus Turun + Mouse Enter Tetikus Masuk + Mouse Exit Tetikus Keluar + Mouse Up Tetikus Naik + Move bookmark Pindahkan bookmark + Move comment Pindahkan komentar + Move image Pindahkan gambar + Move page Pindahkan halaman + Move pages Pindahkan halaman + Named Destinations Tujuan Bernama + Navigation links Tautan navigasi + Navigation links are not repetitive Tautan navigasi tidak berulang + Nested alternate text Teks alternatif bersarang + New {tool} comments will look like this one Komentar {tool} baru akan terlihat seperti yang ini + No PDFs, images or text files found in {folder} Tidak ditemukan PDF, gambar atau file teks di {folder} + No form fields were detected Tidak ada kolom formulir yang terdeteksi + No inaccessible scripts Tidak ada skrip yang tidak dapat diakses + No links to remove Tidak ada tautan untuk dihapus + No pages match those choices Tidak ada halaman yang cocok dengan pilihan tersebut + No unlinked web addresses were found in the text Tidak ditemukan alamat web tanpa tautan dalam teks + None of those files can be made into a PDF; use PDFs, images or .txt files Tidak ada file tersebut yang dapat dijadikan PDF; gunakan file PDF, gambar atau .txt + Note Catatan + Number every page in the footer. Beri nomor setiap halaman di footer. + Odd pages Halaman ganjil + On Blur Saat Kehilangan Fokus + On Focus Saat Fokus + On the web, open or drop an image to convert it Di versi web, buka atau seret gambar untuk mengonversinya + Open a web link Buka tautan web + Opened with Dibuka dengan + Opening the browser's print dialog… Membuka dialog cetak browser… + Optimization cancelled Optimalkan dibatalkan + Optimization is already running Optimalkan sudah berjalan + Optimize Scanned Documents Optimalkan Dokumen Hasil Pindai + Options Opsi + Orange Oranye + Other elements alternate text Teks alternatif elemen lainnya + Other elements that require alternate text Elemen lain yang memerlukan teks alternatif + Outline Kerangka + PDF producer Produsen PDF + PDF version Versi PDF + Page Content Konten Halaman + Page Range Rentang Halaman + Page does not require timed responses Halaman tidak memerlukan respons berjadwal + Page thumbnails Miniatur halaman + Page will not cause screen flicker Halaman tidak menyebabkan kedipan layar + Pages that are only pictures of text can't be read aloud or searched. Recognize text (OCR) to add a text layer. Halaman yang hanya berisi gambar teks tidak dapat dibaca dengan suara atau dicari. Gunakan Pengenalan teks (OCR) untuk menambahkan lapisan teks. + Pages with links, comments or fields should tab in structure order. The fix sets each page's tab order to Use Document Structure. Halaman dengan tautan, komentar atau kolom harus dapat di-tab dalam urutan struktur. Perbaikan mengatur urutan tab setiap halaman ke Gunakan Struktur Dokumen. + Passed Lulus + Password protection will be applied when you save Perlindungan kata sandi akan diterapkan saat Anda menyimpan + Path Jalur + PdfCraft is drawing without a graphics processor, so it may be slow. Updating the graphics driver may help. PdfCraft sedang menggambar tanpa akselerator grafis, jadi mungkin lambat. Memperbarui driver grafis mungkin membantu. + People may need more time to respond. Check that nothing has a time limit. Orang mungkin membutuhkan lebih banyak waktu untuk merespons. Pastikan tidak ada yang memiliki batas waktu. + Phone Number Nomor Telepon + Phone Numbers Nomor Telepon + Pictures need alternate text that describes them, or must be marked decorative. Add alternate text to each figure. Gambar memerlukan teks alternatif yang menjelaskannya, atau harus ditandai sebagai dekoratif. Tambahkan teks alternatif ke setiap gambar. + Pink Merah muda + Pinned folders need the desktop app Folder yang disematkan memerlukan aplikasi desktop + Pinned {folder} to Home {folder} disematkan ke Beranda + Place saved {what} Tempatkan {what} yang tersimpan + Planned for milestone {m} — open to see what it will include Direncanakan untuk milestone {m} — buka untuk melihat apa yang akan disertakan + Planned · {m} Direncanakan · {m} + Polygon Poligon + Polyline Polyline + Portable mode is off: {folder} can't be written ({error}). Settings are kept in your user folder instead. Mode portabel mati: {folder} tidak dapat ditulis ({error}). Pengaturan akan disimpan di folder pengguna Anda sebagai gantinya. + Portrait pages Halaman potret + Position Posisi + PostScript XObjects aren't allowed XObjects PostScript tidak diizinkan + Prepare for Distribution Siapkan untuk Distribusi + Preparing sheet {done} of {total} for printing… Menyiapkan lembar {done} dari {total} untuk pencetakan… + Preparing {n} sheets for printing… Menyiapkan {n} lembar untuk pencetakan… + Primary language Bahasa utama + Printing Mencetak + Private data of other applications Data pribadi aplikasi lain + Public key Kunci publik + Purple Ungu + PushButton PushButton + Radio Radio + Radio Button Properties Properti Tombol Radio + Re-type Password Ketik Ulang Kata Sandi + Red Merah + Redid {label} Mengulangi {label} + Regularity Keteraturan + Rejected Ditolak + Reliable character encoding is provided Pengodean karakter yang andal disediakan + Remove hidden information and flatten comments and form fields, so recipients see only the pages. Hapus informasi tersembunyi dan ratakan komentar serta kolom formulir agar penerima hanya melihat halaman. + Remove hidden information, metadata, scripts and embedded content, and rewrite the files. Hapus informasi tersembunyi, metadata, skrip dan konten tersemat, lalu tulis ulang file. + Remove redaction marks Hapus tanda sensor + Remove saved {what} Hapus {what} yang tersimpan + Removed 1 hidden item. Save to remove them from the file. 1 item tersembunyi dihapus. Simpan untuk menghapusnya dari file. + Removed 1 link 1 tautan dihapus + Removed {n} hidden items. Save to remove them from the file. {n} item tersembunyi dihapus. Simpan untuk menghapusnya dari file. + Removed {n} links {n} tautan dihapus + Rename bookmark Ganti nama bookmark + Rendering: hayro (bootstrap) · UI: egui · Icons: Lucide (ISC) · Fonts: Inter, JetBrains Mono, Dancing Script (OFL) Render: hayro (bootstrap) · UI: egui · Ikon: Lucide (ISC) · Font: Inter, JetBrains Mono, Dancing Script (OFL) + Repairs Perbaikan + Repeated navigation links should be skippable. Check links that appear on every page. Tautan navigasi yang berulang harus dapat dilewati. Periksa tautan yang muncul di setiap halaman. + Replace page Ganti halaman + Replace pages Ganti halaman + Replaced Diganti + Replacing images arrives on the web with image file pickers Mengganti gambar hadir di versi web dengan pemilih file gambar + Replacing images on page {p} arrives on the web with image pickers ({i}) Mengganti gambar di halaman {p} hadir di versi web dengan pemilih gambar ({i}) + Report Options Opsi Laporan + Reset a form Atur ulang formulir + Resize comment Ubah ukuran komentar + Restrictions Pembatasan + Restrictions lifted Pembatasan dihapus + Reverted to the last saved version Dikembalikan ke versi tersimpan terakhir + Right Footer Text Teks Footer Kanan + Right Header Text Teks Header Kanan + Rotate image Putar gambar + Rotate page Putar halaman + Rotate page {label} clockwise Putar halaman {label} searah jarum jam + Rotate page {label} counterclockwise Putar halaman {label} berlawanan arah jarum jam + Rows Baris + Run Jalankan + Run JavaScript Jalankan JavaScript + Run a JavaScript Jalankan sebuah JavaScript + Run form script Jalankan skrip formulir + SHA-1 digest Digest SHA-1 + SHA-256 digest Digest SHA-256 + Sanitize Bersihkan + Sanitize Documents Bersihkan Dokumen + Save as PDF/A-1b Simpan sebagai PDF/A-1b + Save as PDF/A-2b Simpan sebagai PDF/A-2b + Save as PDF/A-3b Simpan sebagai PDF/A-3b + Save image Simpan gambar + Save or revert changes before selecting another tag. Simpan atau kembalikan perubahan sebelum memilih tag lain. + Saved the print-ready PDF to {path} PDF siap cetak disimpan ke {path} + Saved {name} {name} disimpan + Saved {place}: {before} → {after} (not smaller){detail} Disimpan {place}: {before} → {after} (tidak lebih kecil){detail} + Saved {place}: {before} → {after} ({pct}% smaller){detail} Disimpan {place}: {before} → {after} ({pct}% lebih kecil){detail} + Saved, but reopening failed: {e} Tersimpan, tetapi membuka kembali gagal: {e} + Screen flicker Kedipan layar + Screen readers choose their voice from the document's language. Set it in Document Properties > Advanced > Language. Pembaca layar memilih suaranya dari bahasa dokumen. Atur di Properti dokumen > Lanjutan > Bahasa. + Scripted content must be usable with a keyboard and assistive technology. Check the document's scripts. Konten berskrip harus dapat digunakan dengan keyboard dan teknologi bantu. Periksa skrip dokumen. + Scripts Skrip + Scripts run in a sandbox without file or network access. With JavaScript off, Acrobat's standard format, validate and calculate functions still work. Skrip berjalan di sandbox tanpa akses file atau jaringan. Dengan JavaScript nonaktif, fungsi format, validasi dan hitung bawaan Acrobat tetap berfungsi. + Security method Metode keamanan + Security settings must allow assistive technology to read the content ("Enable text access for screen reader devices"). Change the document's security to allow it. Pengaturan keamanan harus mengizinkan teknologi bantu membaca konten ("Aktifkan akses teks untuk perangkat pembaca layar"). Ubah keamanan dokumen untuk mengizinkannya. + Security will be removed when you save Keamanan akan dihapus saat Anda menyimpan + Self-signed Ditandatangani sendiri + Serial number Nomor seri + Set alternate text Atur teks alternatif + Set bookmark destination Atur tujuan bookmark + Set document title Atur judul dokumen + Set status Accepted Atur status Diterima + Set status Cancelled Atur status Dibatalkan + Set status Completed Atur status Selesai + Set status None Atur status Tidak ada + Set status Rejected Atur status Ditolak + Set status Unmarked Atur status Belum ditandai + Set tab order Atur urutan tab + Set the image of {name} Atur gambar untuk {name} + Shadings Pembayangan + Show a field Tampilkan kolom + Sign with a Digital ID Tanda tangani dengan ID Digital + Signed and all signatures are valid. Ditandatangani dan semua tanda tangan valid. + Signed and saved to {path} Ditandatangani dan disimpan ke {path} + Signer Penanda tangan + Signing time Waktu penandatanganan + Social Security Number Nomor Jaminan Sosial + Social Security Numbers Nomor Jaminan Sosial + Solid Padat + Squiggly Bergelombang + Star Bintang + Strong Kuat + Structure Info Info struktur + Submit a form Kirim formulir + TH and TD TH dan TD + TH and TD must be children of TR TH dan TD harus menjadi anak dari TR + TR must be a child of Table, THead, TBody, or TFoot TR harus menjadi anak dari Table, THead, TBody, atau TFoot + Tab order Urutan tab + Tab order is consistent with structure order Urutan tab sesuai dengan urutan struktur + Table cells belong in a row. Fix the table's tags. Sel tabel harus berada dalam satu baris. Perbaiki tag tabel. + Table rows belong directly in a table or its head, body or foot. Fix the table's tags. Baris tabel harus berada langsung dalam tabel atau header, body, atau footer-nya. Perbaiki tag tabel. + Tables Tabel + Tables must contain the same number of columns in each row and rows in each column Tabel harus memiliki jumlah kolom yang sama di setiap baris dan jumlah baris yang sama di setiap kolom + Tables must have a summary Tabel harus memiliki ringkasan + Tables should have headers Tabel sebaiknya memiliki header + Tagged PDF PDF bertag + Tagged annotations Anotasi bertag + Tagged content Konten bertag + Tagged form fields Kolom formulir bertag + Tagged multimedia Multimedia bertag + Tags give the document a logical structure that assistive technology follows. Tag the document (Automatically tag PDF). Tag memberi struktur logis pada dokumen yang diikuti teknologi bantu. Beri tag pada dokumen (Beri tag PDF secara otomatis). + Text Field Properties Properti Kolom Teks + Text language is specified Bahasa teks sudah ditentukan + Text must contrast enough with its background for people with low vision. Check the colours by eye or with a contrast tool. Teks harus kontras cukup dengan latar belakangnya untuk orang dengan penglihatan rendah. Periksa warnanya dengan mata atau dengan alat kontras. + Text recognition is already running Pengenalan teks sudah berjalan + Text recognition isn't installed: its models are missing (run `cargo xtask models`, or set PDFCRAFT_MODELS). Pengenalan teks belum terpasang: modelnya tidak ada (jalankan `cargo xtask models`, atau atur PDFCRAFT_MODELS). + That didn't work: an internal error stopped it ({m}). Itu tidak berhasil: kesalahan internal menghentikannya ({m}). + That didn't work: an internal error stopped it ({m}). Your documents are unchanged. itu tidak berhasil: kesalahan internal menghentikannya ({m}). Dokumen Anda tidak berubah. + The Keychain's digital IDs couldn't be listed: {e} ID digital Keychain tidak dapat ditampilkan: {e} + The Windows store's digital IDs couldn't be listed: {e} ID digital di penyimpanan Windows tidak dapat ditampilkan: {e} + The clipboard has no image or text Papan klip tidak berisi gambar atau teks + The document changed while you were choosing a file, so nothing was changed. Dokumen berubah saat Anda memilih file, jadi tidak ada yang diubah. + The document changed while you were editing field properties. Dokumen berubah saat Anda mengedit properti kolom. + The document has additional actions (/AA) Dokumen memiliki tindakan tambahan (/AA) + The document has document-level JavaScript Dokumen memiliki JavaScript tingkat dokumen + The document has no XMP metadata Dokumen tidak memiliki metadata XMP + The document is encrypted Dokumen terenkripsi + The document is no longer open. Dokumen tidak lagi terbuka. + The document was closed before it could be saved. Dokumen ditutup sebelum dapat disimpan. + The document's security settings don't allow filling in form fields Pengaturan keamanan dokumen tidak mengizinkan pengisian kolom formulir + The field properties could not be changed. Properti kolom tidak dapat diubah. + The field properties dialog is no longer open. Dialog properti kolom tidak lagi terbuka. + The form asks to be submitted to {u}; PdfCraft doesn't send form data. Save the document to keep your entries. Formulir diminta untuk dikirim ke {u}; PdfCraft tidak mengirim data formulir. Simpan dokumen untuk mempertahankan isi Anda. + The form asks viewers to make appearances (NeedAppearances) Formulir meminta penampil untuk membuat tampilan (NeedAppearances) + The linked PDF opened, but its named destination was not applied. PDF tertaut terbuka, tetapi tujuan bernama tidak diterapkan. + The linked PDF opened, but its page destination was out of range. PDF tertaut terbuka, tetapi tujuan halamannya di luar rentang. + The operation failed. Operasi gagal. + The pages were extracted but not deleted, because the document changed while you were choosing a folder. Halaman diekstrak tetapi tidak dihapus, karena dokumen berubah saat Anda memilih folder. + The passwords don't match. Kata sandi tidak cocok. + The selected area has been copied ({w} × {h} pixels) Area yang dipilih telah disalin ({w} × {h} piksel) + The selected fields could not be found. Select them again. Kolom yang dipilih tidak ditemukan. Pilih lagi. + The standard fonts can't draw “{c}” ({code}). Only Western European characters can be added as text for now. Font standar tidak dapat menggambar “{c}” ({code}). Untuk saat ini hanya karakter Western European yang dapat ditambahkan sebagai teks. + The title in the metadata and the document information differ Judul dalam metadata dan informasi dokumen berbeda + The window should show a meaningful title rather than the file name. Set a title and Initial View > Show: Document Title. Jendela harus menampilkan judul yang bermakna, bukan nama file. Atur judul dan Tampilan Awal > Tampilkan: Judul Dokumen. + There are no redaction marks to apply Tidak ada tanda penyensoran untuk diterapkan + This PDF uses the unsupported {s} action. PDF ini menggunakan tindakan {s} yang tidak didukung. + This compatibility level supports only plain ASCII passwords. Tingkat kompatibilitas ini hanya mendukung kata sandi ASCII biasa. + This document can't be checked: it couldn't be read for editing Dokumen ini tidak dapat diperiksa: tidak dapat dibaca untuk diedit + This document has no attachments. Dokumen ini tidak memiliki lampiran. + This document has no bookmarks. Dokumen ini tidak memiliki bookmark. + This document has no form fields. Dokumen ini tidak memiliki kolom formulir. + This document has no layers. Dokumen ini tidak memiliki lapisan. + This file is already as small as it can be made ({size}). No copy was saved. File ini sudah sekecil mungkin ({size}). Tidak ada salinan yang disimpan. + This form also contains XFA data, which PdfCraft doesn't read yet. You can fill its fields, but Acrobat may show the XFA values instead. Formulir ini juga berisi data XFA, yang belum dibaca PdfCraft. Anda dapat mengisi kolomnya, tetapi Acrobat mungkin menampilkan nilai XFA sebagai gantinya. + Thumbnails Thumbnail + Timed responses Respons berjadwal + Type Password Ketik Kata Sandi + Type a password. Ketik kata sandi. + Typewriter Mesin ketik + Unchecked Tidak dicentang + Undid {label} Membatalkan {label} + Unlock comment Buka kunci komentar + Unlocked {n} of {m} files Membuka kunci {n} dari {m} file + Update background Perbarui latar belakang + Update header & footer Perbarui header & footer + Update watermark Perbarui tanda air + Use {what} Gunakan {what} + Valid Valid + Valid from Valid mulai + Valid to Valid sampai + Validate Validasi + Validity ends Validitas berakhir + Validity starts Validitas dimulai + Vertically Vertikal + Video, sound and rich media must be tagged to be announced. Tag the multimedia annotations. Video, suara, dan media kaya harus diberi tag agar dapat diumumkan. Beri tag pada anotasi multimedia. + Viewing Melihat + Weak Lemah + White on black Putih di atas hitam + Wrote 1 file to {dir} Menulis 1 file ke {dir} + Wrote {n} files to {dir} Menulis {n} file ke {dir} + X Object Forms Formulir Objek X + Yellow Kuning + Yellow on black Kuning di atas hitam + You can pin up to {n} folders. Unpin one first. Anda dapat menyematkan hingga {n} folder. Lepas sematan satu terlebih dahulu. + Your name Nama Anda + Zip Code Kode Pos + Zip Code + 4 Kode Pos + 4 + `{command}` {when} `{command}` {when} + a bookmark cannot be moved inside itself bookmark tidak dapat dipindahkan ke dalam dirinya sendiri + a document must keep at least one page dokumen harus mempertahankan setidaknya satu halaman + average rata-rata + maximum maksimum + minimum minimum + no such document tidak ada dokumen tersebut + nothing in the file matches this document tidak ada yang di dalam file ini cocok dengan dokumen ini + nothing to redo tidak ada yang perlu diulang + nothing to undo tidak ada yang perlu dibatalkan + pages halaman + product (x) perkalian (x) + sum (+) penjumlahan (+) + the document has no form fields dokumen tidak memiliki kolom formulir + the document has no page tree dokumen tidak memiliki pohon halaman + the document has no tags dokumen tidak memiliki tag + the document is protected by a password dokumen dilindungi kata sandi + the image is empty gambarnya kosong + the password is incorrect kata sandinya salah + the text recognition models are not installed (reinstall PdfCraft, or set PDFCRAFT_MODELS to the folder that holds them) model pengenalan teks belum terpasang (pasang ulang PdfCraft, atau atur PDFCRAFT_MODELS ke folder yang memuatnya) + the title must not be empty judul tidak boleh kosong + there are no pages to print tidak ada halaman untuk dicetak + there are no redaction marks to apply tidak ada tanda penyensoran untuk diterapkan + this document is signed: rewriting it would invalidate its signatures (save it incrementally instead) dokumen ini ditandatangani: menulis ulang akan membatalkan tanda tangannya (simpan secara bertahap sebagai gantinya) + this file isn't XFDF, FDF, XML or text form data file ini bukan XFDF, FDF, XML, atau data formulir teks + {0}: {1} {0}: {1} + {field}: {e} {field}: {e} + {file} is too large for a stamp (at most {n} MB) {file} terlalu besar untuk stempel (maksimal {n} MB) + {folder} is already pinned to Home {folder} sudah disematkan ke Beranda + {label} failed: {e} {label} gagal: {e} + {name} has no action {name} tidak memiliki tindakan + {name} is too large for a word list (at most 1 MB). {name} terlalu besar untuk daftar kata (maksimal 1 MB). + {name} submits the form to {url}; PdfCraft doesn't send form data. Save the document to keep your entries. {name} mengirim formulir ke {url}; PdfCraft tidak mengirim data formulir. Simpan dokumen untuk mempertahankan isi Anda. + {name}: choosing images arrives on the web with file pickers for images {name}: memilih gambar Herrera ke situs web dengan pemilih file untuk gambar + {name}: the {other} action isn't supported yet {name}: tindakan {other} belum didukung + {who} in this document tried to open an address PdfCraft won't open: {e}. {who} dalam dokumen ini mencoba membuka alamat yang tidak akan dibuka PdfCraft: {e}. + {who} in this document tried to open an address PdfCraft won't open: {e}. Only web (http, https) and email (mailto) links open from documents. {who} dalam dokumen ini mencoba membuka alamat yang tidak akan dibuka PdfCraft: {e}. Hanya tautan web (http, https) dan email (mailto) yang terbuka dari dokumen. +animation effects Off Nonaktif +animation effects On Aktif + View more Lihat lebih banyak + View less Lihat lebih sedikit + Only continue if you trust this document. An address can carry information from the document, such as what you typed into its form. Lanjutkan hanya jika Anda memercayai dokumen ini. Alamat dapat membawa informasi dari dokumen, seperti yang Anda ketik ke formulirnya. + Print single-sided. Keep the sheets in order, cut at the marks, then stack the piles left to right, top to bottom. Cetak satu sisi. Pertahankan urutan lembarnya, potong pada tanda, lalu tumpuk tumpukan dari kiri ke kanan, dari atas ke bawah. + Sign a sheet of white paper and take a photo of it in bright, even light (use the flash). Choose the photo or drop it here: PdfCraft finds the signature and removes the paper. Tandatangani selembar kertas putih dan ambil fotonya dengan cahaya terang dan merata (gunakan blitz). Pilih foto atau jatuhkan di sini: PdfCraft menemukan tanda tangan dan menghapus kertasnya. + This field's font can't draw “{c}” ({code}), so PdfCraft shows ? in its place. The value is saved, and other PDF viewers redraw the field from it. Font kolom ini tidak dapat menggambar “{c}” ({code}), jadi PdfCraft menampilkan ? sebagai gantinya. Nilainya disimpan, dan penampil PDF lain menggambar ulang kolom dari nilai itu. + {chars} can't be written into the PDF yet: Fill & Sign text is Western European only. Pick a numeric format such as dd.mm.yyyy. {chars} belum dapat ditulis ke PDF: teks Isi & Tanda Tangani hanya untuk Western European. Pilih format angka seperti dd.mm.yyyy. + January Januari + February Februari + March Maret + April April + May Mei + June Juni + July Juli + August Agustus + September September + October Oktober + November November + December Desember +calendar date January Januari +calendar date February Februari +calendar date March Maret +calendar date April April +calendar date May Mei +calendar date June Juni +calendar date July Juli +calendar date August Agustus +calendar date September September +calendar date October Oktober +calendar date November November +calendar date December Desember +calendar weekday Su Su +calendar weekday Mo Sen +calendar weekday Tu Sel +calendar weekday We Rab +calendar weekday Th Kam +calendar weekday Fr Jum +calendar weekday Sa Sab +signature pad Type Ketik +scroll speed Slow Lambat +scroll speed Normal Normal +scroll speed Fast Cepat +certificate Subject Subjek +certificate Issued to Diterbitkan untuk +certificate Issued by Diterbitkan oleh +certificate Valid from Valid mulai +certificate Valid to Valid sampai +certificate Intended usage Kegunaan yang dimaksud +certificate Version Versi +certificate Serial number Nomor seri +certificate Issuer Penerbit +certificate Validity starts Validitas dimulai +certificate Validity ends Validitas berakhir +certificate Public key Kunci publik +certificate Basic constraints Batasan dasar +certificate Key usage Penggunaan kunci +certificate Self-signed Ditandatangani sendiri +certificate SHA-1 digest Ringkasan SHA-1 +certificate SHA-256 digest Ringkasan SHA-256 + Certificate authority Otoritas sertifikat + End entity Entitas akhir + Float panel Jadikan panel mengambang + Move to group Pindahkan ke grup + Panels Panel + Resize panel window Ubah ukuran jendela panel + Resize panels Ubah ukuran panel + Grab bag Lain-lain + No contributor data was built into this copy. Data kontributor tidak disertakan dalam salinan ini. + No model credits were built into this copy. Kredit model tidak disertakan dalam salinan ini. + Reverse the order Balik urutan + Show Tampilkan + Sort Urutkan + Table Tabel + The field {name} no longer exists. Kolom {name} tidak lagi ada. + {n} contributors · {c} commits {n} kontributor · {c} commit + Username Nama pengguna + Display name Nama tampilan + Real name Nama asli + Name (A–Z) Nama (A–Z) + Merged PRs PR yang digabung + PRs PR + Commits Commit + Lines added Baris ditambahkan + +LOC +LOC + Lines deleted Baris dihapus + −LOC −LOC + Line delta Perubahan baris + ΔLOC ΔLOC + Binary assets added Aset biner ditambahkan + +Bin +Bin + Binary assets removed Aset biner dihapus + −Bin −Bin + First commit Commit pertama + First Pertama + Last commit Commit terakhir + Last Terakhir + Company Perusahaan + Model Model + Version Versi + % of all commits % dari semua commit + Lines +/− Baris +/− + @{login}: {prs} PRs, {commits} commits, +{added} / −{deleted} lines (Δ {delta}), +{bin_added} / −{bin_deleted} binary assets, {first} – {last} @{login}: {prs} PR, {commits} commit, +{added} / −{deleted} baris (Δ {delta}), +{bin_added} / −{bin_deleted} aset biner, {first} – {last} + of {name} dari {name} + of {pages} dari {pages} + on page {label} di halaman {label} + open to see what it will include buka untuk melihat apa yang akan disertakan + ships in milestone {m} rilis di milestone {m} + signature tanda tangan + sorted ascending terurut naik + sorted descending terurut menurun + to hingga + to {n} hingga {n} + watermark tanda air + yyyy or yy year · m or mm month · mmm or mmmm month name · d or dd day · ddd or dddd weekday. H, h, M, s and t are time letters and can't be used on their own: put {escape} before a letter to show it as is. yyyy atau yy tahun · m atau mm bulan · mmm atau mmmm nama bulan · d atau dd hari · ddd atau dddd nama hari. H, h, M, s, dan t adalah huruf waktu dan tidak dapat digunakan sendiri: letakkan {escape} sebelum huruf untuk menampilkannya apa adanya. + {c} of {n}{more} {c} dari {n}{more} + {dpi} pixels/inch {dpi} piksel/inci + {kind} Properties Properti {kind} + {kind} field kolom {kind} + {kind} · page {p} {kind} · halaman {p} + {kind} — click to show it on the page {kind} — klik untuk menampilkannya di halaman + {k} of {n} {k} dari {n} + {label} (1 issue) {label} (1 masalah) + {label} ({n} issues) {label} ({n} masalah) + {month} {day}, {y} {month} {day}, {y} + {month} {y} {month} {y} + {msg} to {dir} {msg} ke {dir} + {name} (default) {name} (bawaan) + {name} can't be combined: {why} {name} tidak dapat digabungkan: {why} + {name} is read-only {name} hanya baca + {name} — unsaved changes {name} — perubahan belum disimpan + {n} days ago {n} hari lalu + {n} differences found {n} perbedaan ditemukan + {n} fields selected {n} kolom dipilih + {n} files {n} file + {n} files done {n} file selesai + {n} files need attention {n} file perlu perhatian + {n} h ago {n} jam lalu + {n} instances {n} instans + {n} issues {n} masalah + {n} marks {n} tanda + {n} match(es) marked for redaction. {n} kecocokan ditandai untuk disensor. + {n} measurements use an unsupported format and are left out. {n} pengukuran menggunakan format yang tidak didukung dan dikecualikan. + {n} min ago {n} mnt lalu + {n} pages {n} halaman + {n} pages selected. {n} halaman dipilih. + {n} selected {n} dipilih + {n} tags {n} tag + {n} word(s) or phrase(s) {n} kata atau frasa + {n} {kind} {n} {kind} + {rule} - {status} {rule} - {status} + {s} action tindakan {s} + {verb} Background {verb} Latar Belakang + {verb} Header and Footer {verb} Header dan Footer + {verb} Watermark {verb} Tanda Air + {verb} as "{name}" {verb} sebagai "{name}" + {who} in this document wants to open this address in your browser: {who} dalam dokumen ini ingin membuka alamat ini di browser Anda: + {who} in this document wants to open your email app with this address: {who} dalam dokumen ini ingin membuka aplikasi email Anda dengan alamat ini: + {words} on {pages} {words} di {pages} + — (protection is applied when you save) — (perlindungan diterapkan saat Anda menyimpan) + “{name}” has security restrictions. Enter its permissions password to lift them. “{name}” memiliki pembatasan keamanan. Masukkan kata sandi izinnya untuk mencabut pembatasan tersebut. + “{name}” is protected. Enter a password to open it. “{name}” dilindungi. Masukkan kata sandi untuk membukanya. +@plural {n} page|{n} pages {n} halaman +@plural {n} file|{n} files {n} file +@plural {n} field|{n} fields {n} kolom +@plural {n} comment|{n} comments {n} komentar +@plural {n} result|{n} results {n} hasil +@plural {n} field name collides with earlier files and will be renamed: {list}|{n} field names collide with earlier files and will be renamed: {list} {n} nama kolom bertabrakan dengan file sebelumnya dan akan diganti nama: {list} +@plural {n} object selected|{n} objects selected {n} objek dipilih +@plural Downloaded {n} PDF|Downloaded {n} PDFs {n} PDF diunduh +key Ctrl Ctrl +key Shift Shift +key Delete Delete +key Esc Esc +key Home Home +key End End +key Space Space diff --git a/crates/ui-egui/src/i18n/mod.rs b/crates/ui-egui/src/i18n/mod.rs index 18a0fc54b..a92a73289 100644 --- a/crates/ui-egui/src/i18n/mod.rs +++ b/crates/ui-egui/src/i18n/mod.rs @@ -147,7 +147,7 @@ fn plural_sl(n: u64) -> usize { } /// The registry. English first: it is the fallback and the source language. -pub static LANGUAGES: [LangInfo; 22] = [ +pub static LANGUAGES: [LangInfo; 24] = [ LangInfo { code: "en", name: "English", source: "", plural: plural_one_other, rtl: false, catalog: OnceLock::new() }, LangInfo { code: "ja", name: "日本語", source: include_str!("ja.tsv"), plural: plural_none, rtl: false, catalog: OnceLock::new() }, // Simplified Chinese; `zh`, `zh-CN`, `zh-SG` and `zh-Hans-*` locales resolve here (see `candidates`). @@ -207,6 +207,12 @@ pub static LANGUAGES: [LangInfo; 22] = [ LangInfo { code: "tr", name: "Türkçe", source: include_str!("tr.tsv"), plural: plural_none, rtl: false, catalog: OnceLock::new() }, // Lithuanian; every `lt-*` locale (`lt-LT`, `lt_LT.UTF-8`) resolves here. Three plural forms (one, few, other). LangInfo { code: "lt", name: "Lietuvių", source: include_str!("lt.tsv"), plural: plural_lithuanian, rtl: false, catalog: OnceLock::new() }, + // Indonesian; every `id-*` locale (`id-ID`, `id_ID.UTF-8`) resolves here. CLDR `id` counts have + // one form ("other"), so `@plural` entries list a single form. + LangInfo { code: "id", name: "Bahasa Indonesia", source: include_str!("id.tsv"), plural: plural_none, rtl: false, catalog: OnceLock::new() }, + // Vietnamese; every `vi-*` locale (`vi-VN`, `vi_VN.UTF-8`) resolves here. CLDR `vi` counts have + // one form ("other"), so `@plural` entries list a single form. + LangInfo { code: "vi", name: "Tiếng Việt", source: include_str!("vi.tsv"), plural: plural_none, rtl: false, catalog: OnceLock::new() }, ]; impl LangInfo { @@ -2378,6 +2384,125 @@ mod tests { assert!(missing.is_empty(), "untranslated Slovene UI literals: {missing:#?}"); } + #[test] + fn indonesian_and_vietnamese_are_registered_and_persist() { + let id = Lang::from_code("id").expect("id registered"); + let vi = Lang::from_code("vi").expect("vi registered"); + assert_eq!(id.name(), "Bahasa Indonesia"); + assert_eq!(vi.name(), "Tiếng Việt"); + assert_eq!(normalize_pref("ID"), Some("id")); + assert_eq!(normalize_pref("Vi"), Some("vi")); + for tag in ["id", "id-ID", "id_ID.UTF-8", "ID-id"] { + assert_eq!(lang_from_tag(tag), Some(id), "{tag}"); + } + for tag in ["vi", "vi-VN", "vi_VN.UTF-8", "VI-vn"] { + assert_eq!(lang_from_tag(tag), Some(vi), "{tag}"); + } + assert_eq!(first_supported("id-ID\r\nen-US"), Some(id)); + assert_eq!(first_supported("vi-VN\r\nen-US"), Some(vi)); + assert_eq!(tr(id, "Save"), "Simpan"); + assert_eq!(tr(id, "Save as…"), "Simpan sebagai…"); + assert_eq!(tr(id, "Bookmarks"), "Bookmark"); + assert_eq!(tr(id, "Fill & Sign"), "Isi & Tanda Tangani"); + assert_eq!(tr(vi, "Save"), "Lưu"); + assert_eq!(tr(vi, "Save as…"), "Lưu thành…"); + assert_eq!(tr(vi, "Bookmarks"), "Dấu trang"); + assert_eq!(tr(vi, "Fill & Sign"), "Điền & Ký"); + assert_eq!(tr(vi, "Interface language"), "Ngôn ngữ giao diện"); + assert_eq!(tr(id, "Interface language"), "Bahasa antarmuka"); + // One CLDR plural form (CLDR `id`, `vi`): the message reads the same for every count. + assert_eq!((0..=3).map(|n| (id.0.plural)(n)).collect::>(), [0, 0, 0, 0]); + assert_eq!((0..=3).map(|n| (vi.0.plural)(n)).collect::>(), [0, 0, 0, 0]); + for n in [0, 1, 2, 5] { + assert_eq!(trn(id, n, "{n} page", "{n} pages"), format!("{n} halaman")); + assert_eq!(trn(vi, n, "{n} page", "{n} pages"), format!("{n} trang")); + assert_eq!(trn(id, n, "{n} field", "{n} fields"), format!("{n} kolom")); + assert_eq!(trn(vi, n, "{n} field", "{n} fields"), format!("{n} ô")); + } + let mut app = crate::PdfCraftApp::default(); + app.set_option("language", "ID").unwrap(); + assert_eq!(app.language, "id"); + let mut restored = crate::PdfCraftApp::default(); + restored.restore(&app.persist()); + assert_eq!(restored.language, "id"); + let mut app = crate::PdfCraftApp::default(); + app.set_option("language", "vi").unwrap(); + assert_eq!(app.language, "vi"); + let mut restored = crate::PdfCraftApp::default(); + restored.restore(&app.persist()); + assert_eq!(restored.language, "vi"); + assert!(restored.set_option("language", "xx").is_err()); + assert_eq!(restored.language, "vi"); + } + + /// Indonesian and Vietnamese translate every registered command and every All tools group, + /// section and item. + #[test] + fn indonesian_and_vietnamese_cover_commands_and_catalogue() { + for lang in [Lang::from_code("id").expect("id registered"), Lang::from_code("vi").expect("vi registered")] { + for command in pdfcraft_engine::commands::COMMANDS { + assert!(has(lang, command.label), "{} missing command: {}", lang.code(), command.label); + if let Some(menu) = command.menu { + assert!(has(lang, menu), "{} missing menu: {menu}", lang.code()); + } + } + for group in pdfcraft_engine::catalog::TOOL_GROUPS { + assert!(has(lang, group.label), "{} missing group: {}", lang.code(), group.label); + for section in group.sections { + assert!(has(lang, section.title), "{} missing section: {}", lang.code(), section.title); + for item in section.items { + assert!(has(lang, item.label), "{} missing item: {}", lang.code(), item.label); + } + } + } + } + } + + /// Every `tl!("…")` literal in the UI source is translated in Indonesian and Vietnamese, so a + /// new label cannot silently fall back to English in either. + #[test] + fn indonesian_and_vietnamese_cover_ui_literals() { + let mut stack = vec![std::path::Path::new(env!("CARGO_MANIFEST_DIR")).join("src")]; + let mut literals = std::collections::BTreeSet::new(); + while let Some(dir) = stack.pop() { + for entry in std::fs::read_dir(dir).expect("UI source directory") { + let path = entry.expect("UI source entry").path(); + if path.is_dir() { + if path.file_name().is_some_and(|name| name != "i18n") { + stack.push(path); + } + } else if path.extension().is_some_and(|ext| ext == "rs") { + let source = std::fs::read_to_string(path).expect("UI source file").replace("\r\n", "\n"); + let mut rest = source.split("#[cfg(test)]\nmod ").next().unwrap_or_default(); + while let Some((_, after)) = rest.split_once("tl!(\"") { + let mut escaped = false; + let end = after + .char_indices() + .find_map(|(i, c)| { + if c == '"' && !escaped { + return Some(i); + } + escaped = c == '\\' && !escaped; + None + }) + .expect("closed tl! literal"); + let (raw, tail) = after.split_at(end); + if tail.starts_with("\")") { + let label: String = serde_json::from_str(&format!("\"{raw}\"")).expect("UI literal escapes"); + literals.insert(label); + } + rest = tail.strip_prefix('"').expect("closing quote"); + } + } + } + } + assert!(literals.len() > 900, "source scan found only {} literals", literals.len()); + for lang in [Lang::from_code("id").expect("id registered"), Lang::from_code("vi").expect("vi registered")] { + let missing: Vec<_> = literals.iter().filter(|label| !has(lang, label)).collect(); + assert!(missing.is_empty(), "untranslated {} UI literals: {missing:#?}", lang.code()); + } + } + #[test] fn bulgarian_is_registered() { let bg = Lang::from_code("bg").expect("bg registered"); diff --git a/crates/ui-egui/src/i18n/ru.tsv b/crates/ui-egui/src/i18n/ru.tsv index 7f628088d..0658b5a14 100644 --- a/crates/ui-egui/src/i18n/ru.tsv +++ b/crates/ui-egui/src/i18n/ru.tsv @@ -7,10 +7,20 @@ # (Acrobat's included) was consulted or copied; add entries the same way. # Product and technology names (PdfCraft, PDF, Acrobat JavaScript ...) are not translated; # the trailing "…" of dialog commands is kept. - +# Document font selection +# Shared field properties (Prepare a form). +# Multi-object selection and movement (#844) +# Keyboard key names, distinct from command labels. +# Shared panel docking +# Architectural print controls (follow-up to #599). +# Accessibility structure tags. +# PDF tab context menu (#1233) + Delete Удалить + Home Главная Menu Меню File Файл Edit Редактирование + Off Выключено Pages Страницы View Просмотр Help Справка @@ -24,9 +34,6 @@ Name on new comments Имя в новых комментариях Open… Открыть… Open Recent Открыть недавние - Clear Recent Files Очистить недавние файлы - Remove from Recent Убрать из недавних - Remove {name} from Recent Убрать {name} из недавних Pin folder to Home… Закрепить папку на главной… Folders Папки Pin a folder… Закрепить папку… @@ -83,8 +90,6 @@ Display theme Тема оформления Side panels Боковые панели Enable Acrobat JavaScript Включить Acrobat JavaScript - Flatten Fill & Sign when saving Расплющить «Заполнить и подписать» при сохранении - Text, marks and signatures become part of the page. Other comments stay editable. Текст, пометки и подписи становятся частью страницы. Остальные комментарии можно по-прежнему править. OK OK Join our Discord Присоединяйтесь к нашему Discord Close Закрыть @@ -99,7 +104,7 @@ Previous / next page Предыдущая / следующая страница Delete selected pages (Organize) Удалить выделенные страницы (Организация) Select all pages (Organize) Выделить все страницы (Организация) - Home Главная +key Home Home Open Открыть Open a PDF ({key}) Открыть PDF ({key}) Dark gray theme Тёмно-серая тема @@ -354,7 +359,7 @@ Page options Параметры страниц Page grid Сетка страниц Rotate Повернуть - Delete Удалить +key Delete Delete Extract Извлечь Insert Вставить Replace Заменить @@ -615,7 +620,6 @@ Bottom: Снизу: Width: Ширина: Height: Высота: - Rotation: Поворот: Points from the page's bottom-left corner. Точки от левого нижнего угла страницы. Alignment: Выравнивание: Default Value: Значение по умолчанию: @@ -697,14 +701,11 @@ of the following fields: из следующих полей: Simplified field notation: Упрощённая запись полей: Field names with + - * / and parentheses; put \\ before spaces in names. Имена полей с + - * / и скобками; ставьте \\ перед пробелами в именах. - -# Document font selection Finding document fonts… Поиск шрифтов для документа… Installed fonts… Установленные шрифты… Keep source fonts Сохранить исходные шрифты Load font… Загрузить шрифт… No openly licensed document fonts found. Load a font file. Шрифты с открытой лицензией не найдены. Загрузите файл шрифта. - Format text Форматировать текст Bold Полужирный Italic Курсив @@ -789,7 +790,7 @@ {verb} Header and Footer {verb} колонтитулы {verb} Watermark {verb} водяной знак {verb} Background {verb} фон - Margins Поля + Margins (in) Поля (дюймы) Left Header Text Текст левого колонтитула Center Header Text Текст центрального колонтитула Right Header Text Текст правого колонтитула @@ -955,13 +956,6 @@ This comment's appearance can't be changed yet. Внешний вид этого комментария пока нельзя изменить. Icon Значок Thickness Толщина - Line ending Окончание линии - Open arrow Открытая стрелка - Closed arrow Закрытая стрелка - Butt Торец - Reverse open arrow Обратная открытая стрелка - Reverse closed arrow Обратная закрытая стрелка - Slash Косая черта Modified Изменено No status has been set. Статус не установлен. Compare Files Сравнить файлы @@ -1174,7 +1168,7 @@ Collate Собирать в тетради Print in grayscale Печать в оттенках серого Two-sided: Двусторонняя: - Off Выкл +animation effects Off Выкл Flip on long edge Переворот по длинной стороне Flip on short edge Переворот по короткой стороне Paper: Бумага: @@ -2048,14 +2042,8 @@ Default page display Отображение страниц по умолчанию Default zoom Масштаб по умолчанию Used when a PDF doesn't ask for a layout or zoom. Continuous scrolling never snaps between pages. Используется, когда PDF не запрашивает макет или масштаб. Непрерывная прокрутка никогда не привязывается между страницами. - Reopen the files that were open when PdfCraft last closed Повторно открывать файлы, которые были открыты при последнем закрытии PdfCraft - Reload documents when their files change on disk Перезагружать документы при изменении их файлов на диске - This file changed on disk. Reload it to see the new version; your unsaved changes will be lost. Этот файл был изменён на диске. Перезагрузите его, чтобы увидеть новую версию; несохранённые изменения будут потеряны. - Reload Перезагрузить - Couldn't reload {name}: {e} Не удалось перезагрузить {name}: {e} Choose a PNG or JPEG image (up to 4 MiB). Transparency is preserved. Выберите изображение PNG или JPEG (до 4 МиБ). Прозрачность сохраняется. Couldn't import the signature image: {e} Не удалось импортировать изображение подписи: {e} - @plural {n} page|{n} pages {n} страница|{n} страницы|{n} страниц @plural {n} field|{n} fields {n} поле|{n} поля|{n} полей @plural {n} field name collides with earlier files and will be renamed: {list}|{n} field names collide with earlier files and will be renamed: {list} Имя {n} поля конфликтует с предыдущими файлами и будет переименовано: {list}|Названия {n} полей конфликтуют с предыдущими файлами и будут переименованы: {list}|Названия {n} полей конфликтуют с предыдущими файлами и будут переименованы: {list} @@ -2077,7 +2065,101 @@ Created a PDF from {n} files; left out: {names} PDF создан из файлов: {n}; пропущены: {names} Created a PDF from the first {n} files PDF создан из первых файлов: {n} Go to page… Перейти на страницу… - For page sizes and margins. Для размеров страниц и полей. + Optimization is already running Оптимизация уже выполняется + Optimization cancelled Оптимизация отменена + Couldn't optimize the file Не удалось оптимизировать файл + Files are combined in this order. Leave Pages empty to take every page. Файлы объединяются в этом порядке. Оставьте «Страницы» пустым, чтобы взять все страницы. + Portable mode is off: {folder} can't be written ({error}). Settings are kept in your user folder instead. Портативный режим выключен: невозможно записать в {folder} ({error}). Настройки хранятся в вашей пользовательской папке. + PdfCraft is drawing without a graphics processor, so it may be slow. Updating the graphics driver may help. PdfCraft работает без графического процессора, поэтому может быть медленным. Обновление графического драйвера может помочь. + Show Показывать + Sort Сортировать + Reverse the order Обратный порядок + Grab bag Разное + Table Таблица + Username Имя пользователя + Display name Отображаемое имя + Real name Настоящее имя + Name (A–Z) Имя (А–Я) + Merged PRs Принятые PR + PRs PR + Commits Коммиты + Lines added Добавлено строк + +LOC +LOC + Lines deleted Удалено строк + −LOC −LOC + Line delta Изменение количества строк + ΔLOC ΔLOC + Binary assets added Добавлено бинарных ресурсов + +Bin +Bin + Binary assets removed Удалено бинарных ресурсов + −Bin −Bin + First commit Первый коммит + First Первый + Last commit Последний коммит + Last Последний + No contributor data was built into this copy. В эту копию не встроены данные об участниках. + No model credits were built into this copy. В эту копию не встроены сведения о моделях. + {n} contributors · {c} commits Участников: {n} · Коммитов: {c} + Company Организация + Model Модель + % of all commits % всех коммитов + Lines +/− Строк +/− + @{login}: {prs} PRs, {commits} commits, +{added} / −{deleted} lines (Δ {delta}), +{bin_added} / −{bin_deleted} binary assets, {first} – {last} @{login}: PR: {prs}, коммитов: {commits}, +{added} / −{deleted} строк (Δ {delta}), +{bin_added} / −{bin_deleted} бинарных ресурсов, {first} – {last} + None of those files can be made into a PDF; use PDFs, images or .txt files Ни один из этих файлов нельзя преобразовать в PDF; используйте PDF, изображения или файлы .txt + About О программе + Contributors Участники + Models Модели + Only continue if you trust this document. An address can carry information from the document, such as what you typed into its form. Продолжайте только если доверяете этому документу. Адрес может содержать информацию из документа, например данные, введённые в форму. + Print single-sided. Keep the sheets in order, cut at the marks, then stack the piles left to right, top to bottom. Печатайте с одной стороны. Сохраняйте порядок листов, разрежьте по меткам, затем сложите стопки слева направо, сверху вниз. + Undo {action} Отменить {action} + Redo {action} Повторить {action} + Reopen the files that were open when PdfCraft last closed Повторно открывать файлы, которые были открыты при последнем закрытии PdfCraft + Clear Recent Files Очистить недавние файлы + Remove from Recent Убрать из недавних + Remove {name} from Recent Убрать {name} из недавних + Inserted text Вставленный текст + Add {what} Добавить: {what} + Use {what} Использовать: {what} + Place saved {what} Разместить сохранённое: {what} + Remove saved {what} Удалить сохранённое: {what} + A link Ссылка + A button Кнопка + A script Сценарий + {who} in this document tried to open an address PdfCraft won't open: {e}. {who} в этом документе пытается открыть адрес, который PdfCraft не открывает: {e}. + {who} in this document tried to open an address PdfCraft won't open: {e}. Only web (http, https) and email (mailto) links open from documents. {who} в этом документе пытается открыть адрес, который PdfCraft не открывает: {e}. Из документов открываются только веб-ссылки (http, https) и ссылки на электронную почту (mailto). + Another file dialog is still open. Finish with it first. Ещё открыто другое окно выбора файла. Сначала завершите работу с ним. + Couldn't show the file picker. Please try again. Не удалось показать окно выбора файла. Попробуйте ещё раз. + The document changed while you were choosing a file, so nothing was changed. Документ изменился, пока вы выбирали файл, поэтому ничего не изменено. + The document was closed before it could be saved. Документ был закрыт до того, как его удалось сохранить. + The pages were extracted but not deleted, because the document changed while you were choosing a folder. Страницы извлечены, но не удалены, потому что документ изменился, пока вы выбирали папку. + That didn't work: an internal error stopped it ({m}). Не удалось: действие остановила внутренняя ошибка ({m}). + The Windows store's digital IDs couldn't be listed: {e} Не удалось получить список цифровых удостоверений из хранилища Windows: {e} + Align fields Выровнять поля + Distribute fields Распределить поля + Match field sizes Задать одинаковые размеры полей + Mark for redaction Пометить для удаления содержимого + Mark pages for redaction Пометить страницы для удаления содержимого + Change document properties Изменить свойства документа + Mark differences Пометить различия + Run form script Выполнить сценарий формы + Scripted content must be usable with a keyboard and assistive technology. Check the document's scripts. Содержимое со сценариями должно быть доступно для управления с помощью клавиатуры и вспомогательных технологий. Проверьте сценарии документа. + Table rows belong directly in a table or its head, body or foot. Fix the table's tags. Строки таблицы должны принадлежать непосредственно таблице или её заголовочной, основной или нижней части. Исправьте теги таблицы. + Basic constraints Основные ограничения + Certificate authority Центр сертификации + End entity Конечный субъект + SHA-1 digest Отпечаток SHA-1 + SHA-256 digest Отпечаток SHA-256 + Squiggly Волнистое + Home / End Home / End + H / Space (hold) H / Пробел (удерживать) + Rotation: Поворот: + Line ending Окончание линии + Open arrow Открытая стрелка + Closed arrow Закрытая стрелка + Butt Торец + Reverse open arrow Обратная открытая стрелка + Reverse closed arrow Обратная закрытая стрелка + Slash Косая черта The PDF text fonts can't draw “{c}” ({code}). Choose supported text. Шрифты текста PDF не могут отобразить «{c}» ({code}). Выберите поддерживаемый текст. The standard fonts can't draw “{c}” ({code}). Only Western European characters can be added as text for now. Стандартные шрифты не могут отобразить «{c}» ({code}). Пока в виде текста можно добавлять только западноевропейские символы. This field's font can't draw “{c}” ({code}), so PdfCraft shows ? in its place. The value is saved, and other PDF viewers redraw the field from it. Шрифт этого поля не может отобразить «{c}» ({code}), поэтому PdfCraft показывает на его месте ?. Значение сохранено, и другие программы просмотра PDF перерисуют поле по нему. @@ -2085,6 +2167,8 @@ Larger pages Крупнее страницы Smaller pages Мельче страницы Reset page size Сбросить размер страниц + Flatten Fill & Sign when saving Расплющить «Заполнить и подписать» при сохранении + Text, marks and signatures become part of the page. Other comments stay editable. Текст, пометки и подписи становятся частью страницы. Остальные комментарии можно по-прежнему править. Date format Формат даты Fill & Sign dates Даты для «Заполнить и подписать» Pattern Шаблон @@ -2098,10 +2182,10 @@ Printer properties Свойства принтера Reset to printer defaults Вернуть параметры принтера по умолчанию This printer offers no settings of its own. У этого принтера нет собственных параметров. + Margins Поля + For page sizes and margins. Для размеров страниц и полей. Scroll tabs left Прокрутить вкладки влево Scroll tabs right Прокрутить вкладки вправо - -# Shared field properties (Prepare a form). Shared Field Properties Общие свойства полей {n} fields selected Выбрано полей: {n} Mixed Разные значения @@ -2121,8 +2205,6 @@ The field {name} no longer exists. Поле {name} больше не существует. A selected field has no widget on any page, so the fields can't be edited together. У одного из выбранных полей нет виджета ни на одной странице, поэтому поля нельзя изменить вместе. ({n} at {dpi} dpi, the largest size they can be drawn at) ({n} — с разрешением {dpi} dpi, максимальным, с каким их можно отрисовать) - -# Multi-object selection and movement (#844) @plural {n} object selected|{n} objects selected Выделен {n} объект|Выделено {n} объекта|Выделено {n} объектов Drag the selection to move it. Esc clears the selection. Перетащите выделение, чтобы переместить его. Esc снимает выделение. Shift-click to select several objects. Drag empty space to select an area. Щёлкните с Shift, чтобы выбрать несколько объектов. Протяните рамку на пустом месте, чтобы выделить область. @@ -2137,13 +2219,9 @@ Fill colour Цвет заливки No fill Без заливки Fill colour: none Цвет заливки: нет - -# Keyboard key names, distinct from command labels. key Ctrl Ctrl key Shift Shift -key Delete Delete key Esc Esc -key Home Home key End End key Space Пробел Grid view Вид сеткой @@ -2157,23 +2235,21 @@ key Space Пробел Collapse all Свернуть все Remove page Удалить страницу Remove {n} pages Удалить страницы: {n} - -# Shared panel docking Reset panel layout Сбросить расположение панелей Float panel Сделать панель плавающей Move to group Переместить в группу Panels Панели Resize panels Изменить размеры панелей Resize panel window Изменить размер окна панели - Tools Инструменты - Inspector Инспектор - -# Architectural print controls (follow-up to #599). PDF page: {size} Страница PDF: {size} Match page at 100% Подобрать бумагу, масштаб 100% PDF scale: {scale}% Масштаб PDF: {scale}% Printer paper and scaling may differ. Check driver settings. Бумага и масштаб принтера могут отличаться. Проверьте настройки драйвера. Drawing scale changes. Use Actual size for full-scale plans. Масштаб чертежа изменяется. Для печати в исходном масштабе выберите Фактический размер. + Reload documents when their files change on disk Перезагружать документы при изменении их файлов на диске + This file changed on disk. Reload it to see the new version; your unsaved changes will be lost. Этот файл был изменён на диске. Перезагрузите его, чтобы увидеть новую версию; несохранённые изменения будут потеряны. + Reload Перезагрузить + Couldn't reload {name}: {e} Не удалось перезагрузить {name}: {e} Select page {label} Выбрать страницу {label} Rotate page {label} counterclockwise Повернуть страницу {label} против часовой стрелки Rotate page {label} clockwise Повернуть страницу {label} по часовой стрелке @@ -2184,7 +2260,6 @@ scroll speed Normal Обычная scroll speed Fast Высокая Animation effects Эффекты анимации animation effects On Вкл -animation effects Off Выкл Enhance camera image Улучшить снимок с камеры Drag the corners onto the document's edges, then choose Enhance page. Перетащите углы к краям документа, затем выберите «Улучшить страницу». Enhance page Улучшить страницу @@ -2214,7 +2289,6 @@ animation effects Off Выкл Tools panel side Сторона панели инструментов Add comment Добавить комментарий Change tag properties Изменить свойства тега -# Accessibility structure tags. Tags panel Панель тегов Tags Теги Tag type Тип тега @@ -2240,8 +2314,6 @@ animation effects Off Выкл Ink sensitivity Чувствительность к чернилам No signature was found in the frame. Move the frame over the signature or raise the ink sensitivity. В рамке не найдена подпись. Наведите рамку на подпись или увеличьте чувствительность к чернилам. Couldn't use the photo: {e} Не удалось использовать фото: {e} - -# PDF tab context menu (#1233) Close Tab Закрыть вкладку Reopen Closed Tab Открыть закрытую вкладку Reveal in Finder Показать в Finder diff --git a/crates/ui-egui/src/i18n/vi.tsv b/crates/ui-egui/src/i18n/vi.tsv new file mode 100644 index 000000000..6699c414f --- /dev/null +++ b/crates/ui-egui/src/i18n/vi.tsv @@ -0,0 +1,2583 @@ +# Vietnamese (vi) catalog. Columns, separated by a TAB: context source translation +# +# Clean-room translations of PdfCraft's English UI labels. Use standard Vietnamese computing +# terms; keep product and format names (PdfCraft, PDF, PDF/A, OCR, XFA, Word...) unchanged. +# Vietnamese does not inflect nouns for number, so @plural entries list one form. + Menu Trình đơn + Edit Chỉnh sửa + Pages Trang + View Xem + Help Trợ giúp + Zoom Thu phóng + Actual size Kích thước thực + Zoom to page level Thu phóng đến cỡ trang + Fit to width Vừa chiều rộng + Display theme Chủ đề hiển thị + Side panels Bảng bên + Preferences Tùy chọn + Preferences… Tùy chọn… + Interface language Ngôn ngữ giao diện + Interface size Cỡ giao diện + Auto ({percent}%) Tự động ({percent}%) + Identity Danh tính + Name on new comments Tên trong bình luận mới + Open… Mở… + Open Recent Đã mở gần đây + Clear Recent Files Xóa tệp đã mở gần đây + Remove from Recent Gỡ bỏ khỏi danh sách mở gần đây + No recent files Không có tệp mở gần đây + New blank PDF PDF trắng mới + Create PDF from file… Tạo PDF từ tệp… + Create PDF from images… Tạo PDF từ hình ảnh… + Create PDF from multiple files… Tạo PDF từ nhiều tệp… + Create separate PDFs… Tạo các PDF riêng… + Create PDF from clipboard Tạo PDF từ bộ nhớ tạm + Combine files… Kết hợp tệp… + Save Lưu + Save as… Lưu thành… + Close file Đóng tệp + Close all Đóng tất cả + Revert Hoàn nguyên + Print… In… + Document properties… Thuộc tính tài liệu… + Find… Tìm… + Advanced search… Tìm kiếm nâng cao… + Copy Sao chép + Cut Cắt + Paste Dán + Delete Xóa + Select all Chọn tất cả + Cancel Hủy + OK OK + Apply Áp dụng + Close Đóng + Back Quay lại + Next Tiếp theo + Previous Trước + Name Tên + File name Tên tệp + Location Vị trí + Browse… Duyệt… + Choose… Chọn… + Search Tìm + Clear Xóa hết + Refresh Làm mới + Loading… Đang tải… + Save changes? Lưu thay đổi? + Don't save Không lưu + Page Trang + Page {n} Trang {n} + of / + Fit one full page Vừa một trang đầy đủ + Single page Một trang + Two-page view Xem hai trang + Continuous scrolling Cuộn liên tục + Page display Hiển thị trang + Default page display Hiển thị trang mặc định + Default zoom Thu phóng mặc định + Full screen mode Chế độ toàn màn hình + Read mode Chế độ đọc + Comments Bình luận + Comment Bình luận + Add comment Thêm bình luận + Delete comment Xóa bình luận + Reply Trả lời + Highlight Tô sáng + Underline Gạch chân + Strikethrough Gạch ngang + Text Văn bản + Font Phông chữ + Size Kích thước + Color Màu + Opacity Độ mờ + Width Chiều rộng + Height Chiều cao + Rotation Xoay + More Thêm + Settings Cài đặt + General Chung + Language Ngôn ngữ + Appearance Giao diện hiển thị + Theme Chủ đề + Light Sáng + Dark Tối + System Hệ thống + Open file Mở tệp + Save file Lưu tệp + Export Xuất + Import Nhập + Export to image… Xuất ra hình ảnh… + Export to text… Xuất ra văn bản… + Export to Word… Xuất ra Word… + Export to HTML… Xuất ra HTML… + Export to RTF… Xuất ra RTF… + Reduce file size… Giảm kích thước tệp… + Optimize PDF… Tối ưu PDF… + Protect using password… Bảo vệ bằng mật khẩu… + Remove security Gỡ bỏ bảo mật + Security properties… Thuộc tính bảo mật… + Organize pages Sắp xếp trang + Rotate pages… Xoay trang… + Delete pages Xóa trang + Insert blank page Chèn trang trắng + Insert pages from file… Chèn trang từ tệp… + Replace pages… Thay thế trang… + Extract pages… Trích xuất trang… + Split document… Tách tài liệu… + Number pages… Đánh số trang… + Bookmarks Dấu trang + New bookmark Dấu trang mới + Forms Biểu mẫu + Form fields Ô biểu mẫu + Signatures Chữ ký + Sign Ký + Fill & Sign Điền & Ký + Accessibility Trợ năng + Help… Trợ giúp… + Check for updates… Kiểm tra cập nhật… + About PdfCraft Giới thiệu PdfCraft + Automatically Tự động + Never Không bao giờ + Always Luôn + Yes Có + No Không + On Bật + Off Tắt + Enabled Đã bật + Disabled Đã tắt + Required Bắt buộc + Optional Tùy chọn + None Không có + Unknown Không xác định + Error Lỗi + Warning Cảnh báo + Information Thông tin + Success Thành công + Failed Thất bại + File Tệp + Folder Thư mục + Choose a file… Chọn một tệp… + Choose a folder… Chọn một thư mục… + Open folder Mở thư mục + Create folder Tạo thư mục + Remove Gỡ bỏ + Rename Đổi tên + Duplicate Nhân bản + Move Di chuyển + Copy to clipboard Sao chép vào bộ nhớ tạm + Copied to clipboard Đã sao chép vào bộ nhớ tạm + Undo Hoàn tác + Redo Làm lại + Keyboard shortcuts Phím tắt + Find tools and commands… Tìm công cụ và lệnh… + Take a snapshot Chụp ảnh màn hình + Organize Sắp xếp + Comment and review Bình luận và xem lại + Prepare a form Chuẩn bị biểu mẫu + Protect Bảo vệ + Print In + Create Tạo + Convert Chuyển đổi + Optimize Tối ưu + Measure Đo + Redact Loại bỏ nội dung + Search results Kết quả tìm kiếm + No results Không có kết quả + Page {n} of {total} Trang {n} / {total} + {n} pages selected {n} trang đã chọn + · not fixable here · không thể sửa tại đây + (page {p}) (trang {p}) + (searching… {s} of {p} pages) (đang tìm… {s} trên {p} trang) + ({n} at {dpi} dpi, the largest size they can be drawn at) ({n} ở {dpi} dpi, kích thước lớn nhất có thể vẽ ra) + ({s} not exported: {first}) ({s} chưa xuất: {first}) + on page {p} trên trang {p} + · password-protected · được bảo vệ bằng mật khẩu + (none) (không có) + , Expires: , Hết hạn: + 1 difference found Tìm thấy 1 khác biệt + 1 file 1 tệp + 1 file done Đã xong 1 tệp + 1 file needs attention 1 tệp cần được xử lý + 1 instance 1 phiên bản + 1 issue 1 vấn đề + 1 mark 1 dấu + 1 page 1 trang + 1 page selected Đã chọn 1 trang + 1 page selected. Đã chọn 1 trang. + 180 degrees 180 độ + 9 digit, A letter, O letter or digit, X any character 9 chữ số, A chữ cái, O chữ cái hoặc chữ số, X ký tự bất kỳ + ; 1 page already had text ; 1 trang đã có văn bản + ; failed: {list} ; thất bại: {list} + ; {n} pages already had text ; {n} trang đã có văn bản + ? of {n} ? / {n} + A clean-room, open-source PDF application written in Rust. MIT OR Apache-2.0. Ứng dụng PDF mã nguồn mở phát triển theo nguyên tắc clean-room, viết bằng Rust. MIT OR Apache-2.0. + Accessibility Checker Trình kiểm tra trợ năng + Accessibility Checker Options Tùy chọn trình kiểm tra trợ năng + Acrobat 3.0 and later (40-bit RC4) Acrobat 3.0 trở lên (RC4 40-bit) + Acrobat 5.0 and later (128-bit RC4) Acrobat 5.0 trở lên (RC4 128-bit) + Acrobat 7.0 and later (128-bit AES) Acrobat 7.0 trở lên (AES 128-bit) + Acrobat X and later (256-bit AES) Acrobat X trở lên (AES 256-bit) + Action name: Tên hành động: + Actions Hành động + Active Đang hoạt động + Actual Size Kích thước thực + Actual text Văn bản thực tế + Add Thêm + Add Step Thêm bước + Add a comment Thêm một bình luận + Add a reply Thêm một trả lời + Add a sticky note here Thêm ghi chú dính tại đây + Add an Action Thêm một hành động + Add at least two files Thêm ít nhất hai tệp + Add files… Thêm tệp… + Add folder Thêm thư mục + Add folder and subfolders Thêm thư mục và thư mục con + Add folder and subfolders… Thêm thư mục và thư mục con… + Add folder… Thêm thư mục… + Add open documents Thêm tài liệu đang mở + Add the choices people pick from. Thêm các lựa chọn mà người dùng chọn. + Add the files to combine Thêm các tệp cần kết hợp + Add the steps this action runs, in order. Thêm các bước mà hành động này chạy, theo thứ tự. + Add to Trusted Certificates Thêm vào chứng thư tin cậy + Add to trusted certificates Thêm vào chứng thư tin cậy + Added 1 comment Đã thêm 1 bình luận + Added more than once Đã thêm nhiều lần + Added {n} comments Đã thêm {n} bình luận + Adds invisible text over each word; the page image is not changed Thêm văn bản vô hình đè lên từng từ; hình ảnh trang không thay đổi + Advanced Nâng cao + Advanced Options {chevron} Tùy chọn nâng cao {chevron} + Align Căn + Align left Căn trái + Align right Căn phải + Alignment: Căn chỉnh: + All Tất cả + All document contents Toàn bộ nội dung tài liệu + All document contents except metadata Toàn bộ nội dung tài liệu trừ siêu dữ liệu + All open documents Tất cả tài liệu đang mở + All pages Tất cả trang + All pages in document Tất cả trang trong tài liệu + All pages in range Tất cả trang trong phạm vi + Allow Rich Text Formatting Cho phép định dạng văn bản phong phú + Allow user to enter custom text Cho phép người dùng nhập văn bản tùy chỉnh + Also recognize pages that already have text Cũng nhận dạng các trang đã có văn bản + Alternate text Văn bản thay thế + An action with this name already exists. Đã có một hành động với tên này. + An open-source PDF workbench — local, private, and scriptable. Bàn làm việc PDF mã nguồn mở — cục bộ, riêng tư và có thể viết kịch bản. + Angle Góc + Animation effects Hiệu ứng chuyển động + Annotations, form fill-in, and digital signatures Chú thích, điền biểu mẫu và chữ ký số + Any Bất kỳ + Any except extracting pages Bất kỳ trừ trích xuất trang + Anyone opening the document will need this password. It's applied when you save. Bất kỳ ai mở tài liệu đều cần mật khẩu này. Mật khẩu được áp dụng khi bạn lưu. + Appear behind page Hiển thị sau trang + Appear on top of page Hiển thị đè lên trang + Appearance mode Chế độ hiển thị + Appearance settings… Cài đặt hiển thị… + Applies to 1 page Áp dụng cho 1 trang + Applies to {n} pages Áp dụng cho {n} trang + Apply redactions Áp dụng loại bỏ nội dung + Apply scale Áp dụng tỉ lệ + Asks GitHub for the latest release. Nothing is downloaded or installed automatically. Hỏi GitHub về bản phát hành mới nhất. Không có gì được tải xuống hoặc cài đặt tự động. + At most Tối đa + Attachments Tệp đính kèm + Attachments Panel and Page Bảng tệp đính kèm và trang + Audit space usage… Kiểm tra dung lượng đã dùng… + Author Tác giả + Auto Tự động + Auto follows the system's text size. Pages always render at the display's full resolution. Tự động đi theo cỡ chữ của hệ thống. Các trang luôn được hiển thị ở độ phân giải đầy đủ của màn hình. + Auto portrait/landscape Tự động dọc/ngang + Auto-rotate pages Tự động xoay trang + Auto-size text to fit redaction region Tự động cỡ chữ vừa vùng loại bỏ nội dung + Available Khả dụng + Back side only Chỉ mặt sau + Back to all tools Quay lại tất cả công cụ + Back to the document Quay lại tài liệu + Before each selected page (select pages in Organize) Trước mỗi trang đã chọn (chọn trang trong Sắp xếp trang) + Before the number Trước số + Bicubic downsampling to Lấy mẫu lại bicubic xuống + Binding Ràng buộc + Binding: Ràng buộc: + Black and white Đen trắng + Bold Đậm + Booklet Tập vở + Booklet subset: Tập vở được chọn: + Bookmark options Tùy chọn dấu trang + Bookmarks Panel and Page Bảng dấu trang và trang + Border Color: Màu viền: + Borders and Colors Viền và màu + Both sides Cả hai mặt + Bottom Dưới + Bottom: Dưới: + Box Hộp + Browser's print dialog Hộp thoại in của trình duyệt + Butt Phẳng + Button is checked by default Nút được chọn mặc định + Buttons with the same name and value are selected in unison Các nút có cùng tên và cùng giá trị được chọn đồng thời + Bytes Byte + Calibrate from two points Hiệu chuẩn từ hai điểm + Can't be read: {e} Không đọc được: {e} + Cancelling… Đang hủy… + Case-sensitive Phân biệt chữ hoa chữ thường + Category: Danh mục: + Center Giữa + Center window on screen Căn cửa sổ vào giữa màn hình + Centre Giữa + Certify Chứng nhận + Change settings… Thay đổi cài đặt… + Change the colour of line art as well as text Thay đổi màu của hình vẽ nét cũng như văn bản + Change {what} Thay đổi {what} + Changes allowed Thay đổi được phép + Character limit 0 means no limit. A comb of characters needs a limit. Giới hạn ký tự 0 nghĩa là không giới hạn. Ô kẹo ký tự cần phải có giới hạn. + Character spacing Khoảng cách ký tự + Check Again Kiểm tra lại + Check again Kiểm tra lại + Check box is checked by default Ô kiểm tra được chọn mặc định + Check for updates Kiểm tra cập nhật + Check spelling Kiểm tra chính tả + Check the pages Kiểm tra các trang + Check the pages of {name}: {why} Kiểm tra các trang của {name}: {why} + Checking Options ({on} of 32 in all categories) Đang kiểm tra Tùy chọn ({on} trên 32 trong tất cả danh mục) + Checking for a newer version… Đang kiểm tra phiên bản mới hơn… + Choose a PNG or JPEG image (up to 4 MiB). Transparency is preserved. Chọn hình ảnh PNG hoặc JPEG (tối đa 4 MiB). Độ trong suốt được giữ nguyên. + Choose a folder for the exported files Chọn thư mục cho các tệp đã xuất + Choose a folder for the extracted pages Chọn thư mục cho các trang đã trích xuất + Choose a folder for the results Chọn thư mục cho kết quả + Choose a folder for the searchable files Chọn thư mục cho các tệp có thể tìm kiếm + Choose a layout: Chọn bố cục: + Choose a stamp, then click on the page to place it. Chọn một con dấu, rồi nhấp vào trang để đặt nó. + Choose an image Chọn một hình ảnh + Choose images Chọn hình ảnh + Choose image… Chọn hình ảnh… + Choose photo… Chọn ảnh chụp… + Choose the digital ID that you want to use for signing: Chọn Digital ID mà bạn muốn dùng để ký: + Circle Hình tròn + Clean Up Dọn dẹp + Clean-up Dọn dẹp + Clear All Xóa tất cả + Clear all Xóa tất cả + Clear selection / close find Xóa lựa chọn / đóng thanh tìm kiếm + Click on the page to add text; each click starts a new box, and ✓ finishes. Drag items to move them, drag a corner to resize, double-click text to edit it. Nhấp vào trang để thêm văn bản; mỗi lần nhấp bắt đầu một hộp mới, và ✓ kết thúc. Kéo các mục để di chuyển, kéo một góc để đổi kích thước, nhấp đúp vào văn bản để chỉnh sửa. + Click the first point to begin. Nhấp vào điểm đầu tiên để bắt đầu. + Click to sort, drag to move the column. Drag its edge to resize it. Nhấp để sắp xếp, kéo để di chuyển cột. Kéo cạnh của nó để đổi kích thước. + Click vertices. Enter or double-click finishes a perimeter or area. Click the first point to close an area. Nhấp vào các đỉnh. Nhấn Enter hoặc nhấp đúp để hoàn tất một chu vi hoặc một vùng. Nhấp vào điểm đầu tiên để đóng một vùng. + Clockwise 90 degrees Theo chiều kim đồng hồ 90 độ + Close (Esc) Đóng (Esc) + Close Tab Đóng thẻ + Close panel Đóng bảng bên + Closed arrow Mũi tên khép kín + Collapse Thu gọn + Collapse all Thu gọn tất cả + Collapse all bookmarks Thu gọn tất cả dấu trang + Collapse tag Thu gọn thẻ + Collate Đối chiếu + Color: Màu: + Colour Màu + Colours are remapped while rendering; the document itself never changes. Màu được ánh xạ lại khi kết xuất; bản thân tài liệu không bao giờ thay đổi. + Comb of Ô kẹo của + Combine the rest Kết hợp phần còn lại + Combined {n} files Đã kết hợp {n} tệp + Coming in milestone Sẽ có trong phiên bản tiếp theo + Comment and form data Dữ liệu bình luận và biểu mẫu + Commenting, filling in form fields, and signing existing signature fields Bình luận, điền vào các ô biểu mẫu và ký các ô chữ ký hiện có + Comments & Forms Bình luận & Biểu mẫu + Comments only Chỉ bình luận + Commit selected value immediately Áp dụng ngay giá trị đã chọn + Common Properties Thuộc tính chung + Compare Files So sánh tệp + Compare this file with an older version: Compare files… in All tools. So sánh tệp này với một phiên bản cũ hơn: So sánh tệp… trong Tất cả công cụ. + Compatibility Tương thích + Compress document structure (object streams) Nén cấu trúc tài liệu (object streams) + Compression Nén + Configure New Digital ID Cấu hình Digital ID mới + Confirm Password Xác nhận mật khẩu + Conformance level: Mức tuân thủ: + Continue Tiếp tục + Copies, two-sided printing and colour are chosen in the browser's print dialog. Số bản in, in hai mặt và màu được chọn trong hộp thoại in của trình duyệt. + Copies: Số bản in: + Copy selected text Sao chép văn bản đã chọn + Copy text Sao chép văn bản + Couldn't check for updates: {e} Không thể kiểm tra cập nhật: {e} + Couldn't open the printer's preferences: {e} Không thể mở tùy chọn máy in: {e} + Counterclockwise 90 degrees Ngược chiều kim đồng hồ 90 độ + Country/Region Quốc gia/Khu vực + Create Custom Stamp Tạo con dấu tùy chỉnh + Create Link Tạo liên kết + Create PDF Comment Summary Tạo bản tóm tắt bình luận PDF + Create PDF comment summary… Tạo bản tóm tắt bình luận PDF… + Create PDF from images Tạo PDF từ hình ảnh + Create a new Digital ID (self-signed, saved to a password-protected file) Tạo Digital ID mới (tự ký, lưu vào tệp được bảo vệ bằng mật khẩu) + Create accessibility report Tạo báo cáo trợ năng + Create custom stamp… Tạo con dấu tùy chỉnh… + Create {what} Tạo {what} + Created a PDF from {n} files Đã tạo PDF từ {n} tệp + Created a PDF from {n} files; left out: {names} Đã tạo PDF từ {n} tệp; bỏ qua: {names} + Creates 1 file from {n} pages. Tạo 1 tệp từ {n} trang. + Creates {f} files from {n} pages. Tạo {f} tệp từ {n} trang. + Crop (% trimmed from each side) Cắt xén (% bị cắt ở mỗi cạnh) + Currency symbol: Ký hiệu tiền tệ: + Current page Trang hiện tại + Current page ({n}) Trang hiện tại ({n}) + Current page — type a page number or label (such as iv) and press Enter Trang hiện tại — nhập số trang hoặc nhãn (ví dụ iv) rồi nhấn Enter + Custom Tùy chỉnh + Custom scale: Tỷ lệ tùy chỉnh: + Custom text: Văn bản tùy chỉnh: + Custom: Tùy chỉnh: + Cut and stack Cắt và xếp chồng + Cut marks Dấu cắt + DPI sets the printed page size without resampling the image. DPI đặt kích thước trang in mà không lấy mẫu lại hình ảnh. + Dark theme Giao diện tối + Date format Định dạng ngày + Decimal places: Số chữ số thập phân: + Decimals Chữ số thập phân + Declared conformance: {shown} Mức tuân thủ khai báo: {shown} + Decorative figure Hình minh họa trang trí + Default Mặc định + Default Value: Giá trị mặc định: + Default workspace mode Chế độ không gian làm việc mặc định + Default: Mặc định: + Delete page {label} Xóa trang {label} + Delete pages (Delete) Xóa trang (Delete) + Delete pages after extracting Xóa trang sau khi trích xuất + Delete selected pages (Organize) Xóa các trang đã chọn (Sắp xếp trang) + Delete stamp Xóa con dấu + Delete {o} Xóa {o} + Describe the figure Mô tả hình minh họa + Description Mô tả + Description: Mô tả: + Details Chi tiết + Diamond Hình thoi + Digital ID Digital ID + Digital ID password Mật khẩu Digital ID + Direction: Hướng: + Discard Bỏ qua + Discard Objects Loại bỏ đối tượng + Discard User Data Loại bỏ dữ liệu người dùng + Discard alternate images Loại bỏ hình ảnh thay thế + Discard document tags Loại bỏ thẻ tài liệu + Discard embedded page thumbnails Loại bỏ ảnh thu nhỏ trang nhúng + Discard embedded print settings Loại bỏ cài đặt in nhúng + Discard this text (Esc) Bỏ văn bản này (Esc) + Dismiss Đóng + Distinguished name Tên phân biệt + Distribute Phân phối + Document Tài liệu + Document Properties Thuộc tính tài liệu + Document Title Tiêu đề tài liệu + Document and markups Tài liệu và chú thích + Document and stamps Tài liệu và con dấu + Document language Ngôn ngữ tài liệu + Document properties ({key}) Thuộc tính tài liệu ({key}) + Documents and view Tài liệu và chế độ xem + Done Xong + Done adding text Đã xong thêm văn bản + Download Tải xuống + Downsample to Giảm mẫu xuống + Drag the selection to move it. Esc clears the selection. Kéo vùng chọn để di chuyển. Esc xóa vùng chọn. + Drag to reorder Kéo để sắp xếp lại + Draw Vẽ + Draw your {what} below. Vẽ {what} của bạn bên dưới. + Drawing scale changes. Use Actual size for full-scale plans. Tỷ lệ bản vẽ thay đổi. Dùng Kích thước thực cho bản vẽ tỷ lệ 1:1. + Drop PDFs, images, text files or folders here, or choose them. Kéo thả PDF, hình ảnh, tệp văn bản hoặc thư mục vào đây, hoặc chọn chúng. + Duplicate "{name}" onto: Nhân bản "{name}" sang: + Duplicate Field Nhân bản ô + Duplicate… Nhân bản… + Dynamic Động + Dynamic XFA form laid out from its template: {pages}, {fields}. Biểu mẫu XFA động được bố trí từ mẫu của nó: {pages}, {fields}. + Each file holds as many of the {n} pages as fit. Mỗi tệp chứa càng nhiều trang trong {n} trang càng vừa. + Each image is measured where pages draw it; an image is replaced only if the result is smaller. Mỗi hình ảnh được đo tại nơi các trang vẽ nó; hình ảnh chỉ được thay thế nếu kết quả nhỏ hơn. + Each image once, named after the document and page. JPEG images are saved unchanged; others as PNG. Mỗi hình ảnh một lần, được đặt tên theo tài liệu và trang. Ảnh JPEG được lưu nguyên vẹn; ảnh khác dưới dạng PNG. + Earlier in tab order Sớm hơn trong thứ tự thẻ + Edit Action Chỉnh sửa hành động + Edit image Chỉnh sửa hình ảnh + Edit text… Chỉnh sửa văn bản… + Edit… Chỉnh sửa… + Email Address Địa chỉ email + Enable Acrobat JavaScript Bật JavaScript của Acrobat + Enable copying of text, images, and other content Cho phép sao chép văn bản, hình ảnh và nội dung khác + Enable text access for screen reader devices for the visually impaired Bật truy cập văn bản cho thiết bị đọc màn hình dành cho người khiếm thị + Encrypt Mã hóa + Endpoints Điểm cuối + Enhance page Tăng cường trang + Enter the password that opens it Nhập mật khẩu mở tệp đó + Enter the permissions password to allow combining Nhập mật khẩu quyền để cho phép kết hợp + Entire page Toàn bộ trang + Even Pages Only Chỉ trang chẵn + Even and Odd Pages Trang chẵn và lẻ + Even pages only Chỉ trang chẵn + Every PDF, image and text file in the folder Mọi tệp PDF, hình ảnh và văn bản trong thư mục + Every PDF, image and text file in the folder and the folders inside it Mọi tệp PDF, hình ảnh và văn bản trong thư mục và các thư mục bên trong + Example: {sample} Ví dụ: {sample} + Exclude images smaller than Loại trừ hình ảnh nhỏ hơn + Expand Mở rộng + Expand all Mở rộng tất cả + Expand all bookmarks Mở rộng tất cả dấu trang + Expand tag Mở rộng thẻ + Expand top-level bookmarks Mở rộng dấu trang cấp cao nhất + Explain Giải thích + Export All Images Xuất tất cả hình ảnh + Export Value: {on} Giá trị xuất: {on} + Export all to data file… Xuất tất cả sang tệp dữ liệu… + Export certificate… Xuất chứng thư… + Export comments Xuất bình luận + Export form data Xuất dữ liệu biểu mẫu + Export stopped: {e} Đã dừng xuất: {e} + Export to Image Xuất sang hình ảnh + Export to Text Xuất sang văn bản + Exported 1 image Đã xuất 1 hình ảnh + Exported the text of 1 page Đã xuất văn bản của 1 trang + Exported the text of {n} pages Đã xuất văn bản của {n} trang + Exported {n} images Đã xuất {n} hình ảnh + Exporting… {d} of {t} Đang xuất… {d} / {t} + Export… Xuất… + Extract pages as separate files Trích xuất trang thành các tệp riêng + Extract pages to a new document Trích xuất trang sang tài liệu mới + Extracted 1 page Đã trích xuất 1 trang + Extracted {n} pages Đã trích xuất {n} trang + Field is used for file selection Ô này được dùng để chọn tệp + Field names (comma-separated) Tên ô (phân tách bằng dấu phẩy) + Field names with + - * / and parentheses; put \\ before spaces in names. Tên ô với + - * / và dấu ngoặc; đặt \\ trước khoảng trắng trong tên. + Field value is in range: Giá trị ô nằm trong phạm vi: + Field value is not validated Giá trị ô không được kiểm tra + Field: {field} on page {p} Ô: {field} ở trang {p} + Fields to reset (comma-separated; empty: all) Các ô cần đặt lại (phân tách bằng dấu phẩy; trống: tất cả) + Figure {i} of {n}{page} Hình {i} / {n}{page} + File (.p12, .pfx) Tệp (.p12, .pfx) + File Name Tên tệp + File size Kích thước tệp + Files are combined from top to bottom. Leave Pages empty to take every page. Các tệp được kết hợp từ trên xuống dưới. Để trống Trang để lấy mọi trang. + Files are combined in the order shown. Drag them to change it. Các tệp được kết hợp theo thứ tự hiển thị. Kéo chúng để thay đổi thứ tự. + Files for {name} Các tệp cho {name} + Files you open in PdfCraft appear here. Drop a PDF anywhere to open it. Các tệp bạn mở trong PdfCraft sẽ xuất hiện ở đây. Kéo thả PDF vào bất kỳ đâu để mở. + Fill & Sign dates Ngày điền & ký + Fill & Sign signature Chữ ký điền & ký + Fill Color: Màu tô: + Fill colour Màu tô + Fill colour: none Màu tô: không có + Filling in form fields and signing existing signature fields Điền vào các ô biểu mẫu và ký các ô chữ ký hiện có + Filter comments Lọc bình luận + Find a tag Tìm một thẻ + Find options Tùy chọn tìm kiếm + Find text Tìm văn bản + Find tools and commands Tìm công cụ và lệnh + Finding document fonts… Đang tìm phông chữ của tài liệu… + Finish or discard the text being edited before selecting several objects. Hoàn tất hoặc bỏ văn bản đang chỉnh sửa trước khi chọn nhiều đối tượng. + First / last page Trang đầu / trang cuối + Fit Vừa + Fit Height Vừa chiều cao + Fit Page Vừa trang + Fit Visible Vừa vùng hiển thị + Fit Width Vừa chiều rộng + Fit to height Vừa chiều cao + Fit to page Vừa trang + Fix Sửa + Fixed what could be fixed; 1 problem remains Đã sửa những gì có thể sửa; còn lại 1 vấn đề + Fixed what could be fixed; {n} problems remain Đã sửa những gì có thể sửa; còn lại {n} vấn đề + Flatten Fill & Sign when saving Làm phẳng Điền & Ký khi lưu + Flip Horizontal Lật ngang + Flip Vertical Lật dọc + Flip horizontal Lật ngang + Flip on long edge Lật theo cạnh dài + Flip on short edge Lật theo cạnh ngắn + Flip vertical Lật dọc + Folders Thư mục + Font Size: Cỡ phông chữ: + Font colour: Màu phông chữ: + Font size 0 uses automatic sizing. Cỡ phông chữ 0 dùng kích thước tự động. + Font size: Cỡ phông chữ: + Font: Phông chữ: + Font: Helvetica Phông chữ: Helvetica + Fonts Phông chữ + For page sizes and margins. Dành cho kích thước trang và lề. + Form data and PDF forms Dữ liệu biểu mẫu và biểu mẫu PDF + Form fields are flattened: their values stay visible. Saving rewrites the whole file. Các ô biểu mẫu được làm phẳng: giá trị của chúng vẫn hiển thị. Việc lưu sẽ ghi lại toàn bộ tệp. + Form fields only Chỉ ô biểu mẫu + Form fill-in and digital signatures Điền biểu mẫu và chữ ký số + Format Định dạng + Format text Định dạng văn bản + Format: Định dạng: + From Từ + From a PDF page or an image Từ một trang PDF hoặc một hình ảnh + From colour Từ màu + From {file} Từ {file} + From: Từ: + Front side only Chỉ mặt trước + Get help, share feedback and follow development on Discord. Nhận trợ giúp, gửi phản hồi và theo dõi quá trình phát triển trên Discord. + Go to a page view Chuyển đến chế độ xem trang + Go to page {p} Đến trang {p} + Go to the page Đến trang đó + Go to this result Đến kết quả này + Graphic Đồ họa + Greyscale Thang xám + Grid view Chế độ lưới + Hand (H) Tay (H) + Has JavaScript actions (run in M6) Có hành động JavaScript (chạy ở M6) + Height: Chiều cao: + Hide field highlights Ẩn đánh dấu ô + Hide layer Ẩn lớp + Hide menu bar Ẩn thanh trình đơn + Hide password Ẩn mật khẩu + Hide toolbars Ẩn thanh công cụ + Hide window controls Ẩn nút điều khiển cửa sổ + High Resolution Độ phân giải cao + High resolution Độ phân giải cao + Highlight Style: Kiểu làm nổi bật: + Highlight fields Làm nổi bật ô + Home Trang chủ + Horizontal Ngang + Horizontal reversed Đảo ngang + Horizontal scale Tỷ lệ ngang + Icon Biểu tượng + Images and text Hình ảnh và văn bản + Images and text (converted to PDF) Hình ảnh và văn bản (chuyển đổi sang PDF) + Import list… Nhập danh sách… + Includes unsaved changes Bao gồm thay đổi chưa lưu + Indent Thụt lề + Initial View Chế độ xem ban đầu + Ink sensitivity Độ nhạy mực + Insert Date Chèn ngày + Insert Page Number Chèn số trang + Insert a blank page after the selection Chèn một trang trắng sau vùng chọn + Insert a file at the end Chèn một tệp vào cuối + Insert a file before page {label} Chèn một tệp trước trang {label} + Insert pages from a file… Chèn trang từ một tệp… + Inserting, deleting, and rotating pages Chèn, xóa và xoay trang + Installed fonts… Phông chữ đã cài đặt… + Intersections Giao điểm + Invisible Rectangle Hình chữ nhật vô hình + Issued by: Cấp bởi: + Italic Nghiêng + Item List Danh sách mục + Item: Mục: + Items marked Ready work today. Các mục được đánh dấu Đã sẵn sàng đều hoạt động ngay. + Its security settings don't allow copying pages Cài đặt bảo mật của tệp này không cho phép sao chép các trang + JavaScript Console Bảng điều khiển JavaScript + JavaScript is turned off (Preferences ▸ JavaScript). JavaScript đã bị tắt (Tùy chọn > JavaScript). + JavaScript, e.g. getField("total").value JavaScript, ví dụ getField("total").value + Join our Discord Tham gia Discord của chúng tôi + Join the ArtCraft community Tham gia cộng đồng ArtCraft + Justify Căn đều + Keep source fonts Giữ phông chữ gốc + Keep tool selected Giữ công cụ được chọn + Keep tool selected: on Giữ công cụ được chọn: Bật + Key Algorithm Thuật toán khóa + Keychain · Keychain · + Label Nhãn + Labels Nhãn + Labels: {preview}. Later pages keep their labels. Nhãn: {preview}. Các trang sau giữ nguyên nhãn của chúng. + Landscape Ngang + Landscape Pages Trang nằm ngang + Landscape and Portrait Pages Trang nằm ngang và nằm dọc + Larger pages Trang lớn hơn + Later Sau + Later in tab order Sau trong thứ tự tab + Layers Lớp + Layers Panel and Page Bảng Lớp và Trang + Layout and Magnification Bố cục và Độ phóng đại + Leave out files that can't be read? Bỏ qua các tệp không thể đọc? + Left Trái + Left Edge Cạnh trái + Left out: {names} Bỏ qua: {names} + Left: Còn lại: + Light theme Giao diện sáng + Limit of Giới hạn + Line Style: Kiểu đường: + Line Thickness: Độ dày đường: + Line ending Kết thúc dòng + Line spacing Giãn dòng + Line thickness Độ dày đường + Link Action Hành động liên kết + Link Appearance Giao diện hiển thị của liên kết + Link Properties Thuộc tính liên kết + Link Type: Loại liên kết: + List view Dạng danh sách + Load font… Tải phông chữ… + Locked Đã khóa + Looking for PDFs… Đang tìm PDF… + Looking for printers… Đang tìm máy in… + Low Resolution (150 dpi) Độ phân giải thấp (150 dpi) + Low resolution Độ phân giải thấp + Magnification Độ phóng đại + Make Current Properties Default Đặt thuộc tính hiện tại làm mặc định + Margins Lề + Mark Page Range Đánh dấu phạm vi trang + Mark as comments Đánh dấu là bình luận + Mark with checkmark Đánh dấu bằng dấu kiểm + Marked Đã đánh dấu + Mask: Mặt nạ: + Match page at 100% Khớp trang ở 100% + Medium Trung bình + Midpoints Điểm giữa + Mixed Hỗn hợp + Modified Đã sửa đổi + More options Tùy chọn khác + More options: Tùy chọn khác: + More ways to add files Thêm cách khác để thêm tệp + Mouse wheel scroll speed Tốc độ cuộn bằng lăn chuột + Move down Di chuyển xuống + Move earlier Di chuyển lên trước + Move later Di chuyển xuống sau + Move up Di chuyển lên + Multi-line Nhiều dòng + Multiple Nhiều + Multiple selection Chọn nhiều + Multiple words or phrases Nhiều từ hoặc cụm từ + Name: Tên: + Navigation tab Tab điều hướng + Needs manual check Cần kiểm tra thủ công + Negative number style: Kiểu số âm: + New Action Hành động mới + New Action… Hành động mới… + New bookmark ({key}) Dấu trang mới ({key}) + New file: Tệp mới: + Next ({key}) Tiếp theo ({key}) + Next / previous match Kết quả khớp tiếp theo / trước đó + Next figure Hình tiếp theo + Next month Tháng sau + Next page Trang tiếp theo + Next sheet Tờ tiếp theo + Next view Chế độ xem tiếp theo + No PDFs in this folder yet Chưa có PDF nào trong thư mục này + No actions Không có hành động nào + No changes allowed Không cho phép thay đổi + No changes to save Không có thay đổi nào để lưu + No check has run yet. Chưa chạy kiểm tra nào. + No color Không màu + No colour Không màu + No comments match. Không có bình luận nào khớp. + No comments yet. Chưa có bình luận nào. + No differences in the text. Không có khác biệt trong văn bản. + No digital IDs yet. Chưa có danh tính số nào. + No documents are open Không có tài liệu nào đang mở + No file chosen Chưa chọn tệp + No fill Không tô + No fonts are referenced by the pages. Các trang không tham chiếu phông chữ nào. + No issues found Không tìm thấy vấn đề nào + No limit Không giới hạn + No matches Không có kết quả khớp + No matches. Không có kết quả khớp. + No matching tools Không có công cụ phù hợp + No openly licensed document fonts found. Load a font file. Không tìm thấy phông chữ tài liệu nào có giấy phép mở. Hãy tải một tệp phông chữ. + No pages selected Chưa chọn trang nào + No photo chosen Chưa chọn ảnh + No preview Không có bản xem trước + No problems found: the document conforms to {level}. Không tìm thấy vấn đề nào: tài liệu tuân thủ {level}. + No security Không bảo mật + No sheets Không có tờ nào + No signature was found in the frame. Move the frame over the signature or raise the ink sensitivity. Không tìm thấy chữ ký nào trong khung. Di chuyển khung qua chữ ký hoặc tăng độ nhạy mực. + No status has been set. Chưa đặt trạng thái nào. + None (prefix only) Không có (chỉ tiền tố) + None found Không tìm thấy mục nào + None — everything is allowed Không có — cho phép tất cả + Not allowed Không cho phép + Not present Không có + Nothing to redo Không có gì để làm lại + Nothing to undo Không có gì để hoàn tác + Number Số + Number of pages Số trang + Number pages Đánh số trang + Odd Pages Only Chỉ trang lẻ + Odd pages only Chỉ trang lẻ + Offset from centre Lệch từ tâm + Old file: Tệp cũ: + One word or phrase per line Mỗi dòng một từ hoặc cụm từ + One {f} file per page, named after the document. Mỗi trang một tệp {f}, đặt tên theo tài liệu. + Only change the colour of black text or line art Chỉ thay đổi màu của văn bản đen hoặc hình vẽ nét + Only checked properties will change. Mixed means the selected fields have different values. Chỉ các thuộc tính được chọn mới thay đổi. Hỗn hợp nghĩa là các ô đã chọn có giá trị khác nhau. + Only the page content changes: links, comments, form fields and bookmarks on the original pages stay. Chỉ nội dung trang thay đổi: liên kết, bình luận, ô biểu mẫu và dấu trang trên các trang gốc vẫn giữ nguyên. + Open Mở + Open a PDF ({key}) Mở một PDF ({key}) + Open a PDF to measure it. Mở một PDF để đo. + Open a document first Hãy mở một tài liệu trước + Open a web page Mở một trang web + Open arrow Mũi tên mở + Open email app Mở ứng dụng email + Open in Full Screen mode Mở ở chế độ Toàn màn hình + Open in a new tab Mở trong tab mới + Open link Mở liên kết + Open the file as it was saved then Mở tệp ở trạng thái đã lưu khi đó + Open the older version first Hãy mở phiên bản cũ hơn trước + Open this web page? Mở trang web này? + Open to page Mở tại trang + Opened, but its security settings don't allow combining. Enter the permissions password. Đã mở, nhưng cài đặt bảo mật của tệp không cho phép kết hợp. Hãy nhập mật khẩu quyền. + Opens the printer driver's preferences. They are saved for every print from this computer; the copies, two-sided, grayscale and paper chosen here still apply. Mở tùy chọn của trình điều khiển máy in. Chúng được lưu cho mọi lần in từ máy tính này; số bản in, in hai mặt, thang xám và loại giấy chọn ở đây vẫn được áp dụng. + Optimizing… cleaning up Đang tối ưu… dọn dẹp + Optimizing… image {d} of {t} Đang tối ưu… ảnh {d} trên {t} + Optimizing… merging identical objects Đang tối ưu… hợp nhất các đối tượng giống nhau + Optimizing… removing user data Đang tối ưu… xóa dữ liệu người dùng + Optimizing… writing the copy Đang tối ưu… ghi bản sao + Optional: needs an AI provider you configure Tùy chọn: cần một nhà cung cấp AI mà bạn tự cấu hình + Options… Tùy chọn… + Organization Name Tên tổ chức + Organizational Unit Đơn vị tổ chức + Orientation: Hướng: + Original Gốc + Original: replace pages Bản gốc: thay thế trang + Other colour… Màu khác… + Outdent Giảm thụt lề + Output Đầu ra + Output appears here. Kết quả sẽ hiển thị ở đây. + Output intent: {list} Mục đích đầu ra: {list} + Overlap: Chồng lấn: + Owner password (no restrictions apply) Mật khẩu chủ sở hữu (không áp dụng hạn chế nào) + PDF Optimizer Trình tối ưu PDF + PDF or image PDF hoặc hình ảnh + PDF page: {size} Trang PDF: {size} + PDF scale: {scale}% Tỉ lệ PDF: {scale}% + PDF, images and text PDF, hình ảnh và văn bản + Page Only Chỉ trang + Page Range Options Tùy chọn phạm vi trang + Page Sizing & Handling Kích thước & xử lý trang + Page background Nền trang + Page display: {layout} Hiển thị trang: {layout} + Page layout Bố cục trang + Page navigation Điều hướng trang + Page number Số trang + Page order: Thứ tự trang: + Page size Kích thước trang + Page {label} Trang {label} + Page {p} of {n} Trang {p} / {n} + Pages Panel and Page Bảng Trang và Trang + Pages from Các trang từ + Pages of {name} to combine, e.g. 1-3, 6 Các trang của {name} cần kết hợp, ví dụ 1-3, 6 + Pages per file Số trang mỗi tệp + Pages per sheet: Số trang mỗi tờ: + Pages to Print Các trang cần in + Pages: Các trang: + Pages: {k} of {n} Trang: {k} / {n} + Paper: Giấy: + Part of Một phần của + Password Mật khẩu + Password required Yêu cầu mật khẩu + Password security Bảo mật bằng mật khẩu + Password-protected Được bảo vệ bằng mật khẩu + Paste after Dán sau + Paths Đường dẫn + Pattern Mẫu + Patterns Mẫu + Patterns (graphics objects) Mẫu (đối tượng đồ họa) + PdfCraft didn't shut down normally. These documents had changes that were autosaved: PdfCraft đã không tắt bình thường. Những tài liệu sau có thay đổi đã được lưu tự động: + PdfCraft works offline. No telemetry, no account, and no cloud processing unless you add a provider. PdfCraft hoạt động ngoại tuyến. Không theo dõi, không tài khoản và không xử lý trên đám mây trừ khi bạn thêm nhà cung cấp. + PdfCraft {c} is up to date. PdfCraft {c} đã là bản mới nhất. + PdfCraft {v} is available. Đã có PdfCraft {v}. + Percentage Phần trăm + Permissions password Mật khẩu quyền + Permitted actions after certifying Hành động được phép sau khi chứng nhận + Photo Ảnh + Pick a tool in the quick bar, or type above. Chọn một công cụ trong thanh nhanh, hoặc nhập ở trên. + Pictures on those pages are recognized too; words already in the page's text are not added again Hình ảnh trên các trang đó cũng được nhận dạng; các từ đã có trong văn bản trang sẽ không được thêm lại + Pin a folder to Home Ghim một thư mục vào Trang chủ + Pin a folder to list its newest PDFs here, such as where your scanner or a synced cloud drive saves them. Ghim một thư mục để liệt kê các PDF mới nhất ở đây, chẳng hạn nơi máy quét hoặc ổ đám mây đồng bộ lưu chúng. + Pin a folder… Ghim một thư mục… + Plain text in reading order; pages are separated by form feeds. Văn bản thuần theo thứ tự đọc; các trang được phân tách bằng ký tự điều khiển trang. + Planned Đã lên kế hoạch + Planned for milestone Dự kiến cho cột mốc + Points from the page's bottom-left corner. Điểm tính từ góc dưới bên trái của trang. + Portrait Dọc + Portrait Pages Trang nằm dọc + Post Đăng + Poster Áp phích + Prefix Tiền tố + Preview Xem trước + Preview unavailable: {e} Không xem trước được: {e} + Preview: page {p} of {n} Xem trước: trang {p} / {n} + Previous ({key}) Trước ({key}) + Previous / next page Trang trước / sau + Previous figure Hình trước + Previous month Tháng trước + Previous page Trang trước + Previous sheet Tờ trước + Previous view Chế độ xem trước + Print ({key}) In ({key}) + Print in grayscale In thang xám + Print page border In viền trang + Print, NextPage, PrevPage, FirstPage or LastPage Print, NextPage, PrevPage, FirstPage hoặc LastPage + Printer paper and scaling may differ. Check driver settings. Giấy và tỉ lệ của máy in có thể khác. Hãy kiểm tra cài đặt trình điều khiển. + Printer properties Thuộc tính máy in + Printer: Máy in: + Printing allowed Cho phép in + Privacy Quyền riêng tư + Properties… Thuộc tính… + Protect Using Password Bảo vệ bằng mật khẩu + Protected: the combined file won't keep its security settings Được bảo vệ: tệp sau khi kết hợp sẽ không giữ cài đặt bảo mật của nó + Quality Chất lượng + Read Only Chỉ đọc + Reading colours Màu sắc khi đọc + Ready Sẵn sàng + Reason Lý do + Recent Gần đây + Recent colours Màu gần đây + Recognize Text Nhận dạng văn bản + Recognized 1 word Đã nhận dạng 1 từ + Recognized {n} words Đã nhận dạng {n} từ + Recognized {w} words in 1 file Đã nhận dạng {w} từ trong 1 tệp + Recognized {w} words in {n} files Đã nhận dạng {w} từ trong {n} tệp + Recognizing text… file {d} of {t} Đang nhận dạng văn bản… tệp {d} trên {t} + Recognizing text… page {d} of {t} Đang nhận dạng văn bản… trang {d} trên {t} + Recommended tools Công cụ đề xuất + Recover Khôi phục + Recover unsaved documents? Khôi phục các tài liệu chưa lưu? + Redact all Loại bỏ toàn bộ nội dung + Redacted area fill colour: Màu tô vùng đã loại bỏ nội dung: + Redaction Tool Properties Thuộc tính công cụ loại bỏ nội dung + Redaction code: Mã loại bỏ nội dung: + Reload Tải lại + Reload documents when their files change on disk Tải lại tài liệu khi tệp của chúng thay đổi trên ổ đĩa + Remove checkmark Bỏ dấu kiểm + Remove invalid links and bookmarks Gỡ bỏ liên kết và dấu trang không hợp lệ + Remove page Gỡ bỏ trang + Remove unreferenced named destinations Gỡ bỏ các đích đến có tên không được tham chiếu + Remove unused objects and merge identical ones Gỡ bỏ các đối tượng không dùng và hợp nhất những đối tượng giống nhau + Remove {name} Gỡ bỏ {name} + Remove {name} from Recent Gỡ bỏ {name} khỏi Gần đây + Remove {n} files Gỡ bỏ {n} tệp + Remove {n} pages Gỡ bỏ {n} trang + Reopen Closed Tab Mở lại tab đã đóng + Reopen the files that were open when PdfCraft last closed Mở lại các tệp đang mở khi PdfCraft đóng lần trước + Repair log Nhật ký sửa chữa + Repeat overlay text Lặp lại văn bản phủ lên + Replace Image… Thay thế hình ảnh… + Replace Pages Thay thế trang + Replace document colours Thay thế màu của tài liệu + Replace image Thay thế hình ảnh + Replacement text Văn bản thay thế + Replacement: pages of {name} Thay thế: các trang của {name} + Replaces the existing one on those pages. Thay thế mục hiện có trên các trang đó. + Report Báo cáo + Report… Báo cáo… + Requires user to enter a password for: Yêu cầu người dùng nhập mật khẩu cho: + Reset columns Đặt lại số cột + Reset page size Đặt lại kích thước trang + Reset to printer defaults Đặt lại về mặc định của máy in + Resize window to initial page Đổi kích thước cửa sổ theo trang ban đầu + Resolution Độ phân giải + Retain existing Giữ nguyên hiện có + Reveal in File Explorer Hiển thị trong File Explorer + Reveal in Finder Hiển thị trong Finder + Reverse closed arrow Đảo hướng mũi tên đã đóng + Reverse open arrow Đảo hướng mũi tên đang mở + Reverse pages Đảo thứ tự trang + Revert changes Hoàn tác thay đổi + Revert to the previously saved version of “{name}”? Changes since then can't be undone afterwards. Quay lại phiên bản đã lưu trước đó của “{name}”? Những thay đổi từ đó trở đi sẽ không thể hoàn tác sau này. + Review History Lịch sử xem lại + Revisions Bản chỉnh sửa + Right Phải + Right Edge Cạnh phải + Rotate Clockwise Xoay theo chiều kim đồng hồ + Rotate Counterclockwise Xoay ngược chiều kim đồng hồ + Rotate Pages Xoay trang + Rotate clockwise Xoay theo chiều kim đồng hồ + Rotate counterclockwise Xoay ngược chiều kim đồng hồ + Rotate view Xoay chế độ xem + Rotate view clockwise Xoay chế độ xem theo chiều kim đồng hồ + Rotate view clockwise ({key}) Xoay chế độ xem theo chiều kim đồng hồ ({key}) + Rotate view counterclockwise Xoay chế độ xem ngược chiều kim đồng hồ + Rotate: Xoay: + Rotation: Xoay: + Running action… file {d} of {t} Đang chạy hành động… tệp {d} trong {t} + Same as interface ({language}) Giống giao diện ({language}) + Sanitizing removes hidden information from the document: metadata, file attachments, comments, form fields (flattened), hidden text and layers, bookmarks, links, actions and scripts, and private application data. Làm sạch sẽ loại bỏ thông tin ẩn khỏi tài liệu: siêu dữ liệu, tệp đính kèm, bình luận, ô biểu mẫu (được dàn phẳng), văn bản và lớp ẩn, dấu trang, liên kết, hành động và tập lệnh, cùng dữ liệu riêng của ứng dụng. + Save & Close Lưu & Đóng + Save ({key}) Lưu ({key}) + Save Image As… Lưu hình ảnh thành… + Copy Image Sao chép hình ảnh + The image has been copied ({w} × {h} pixels) Đã sao chép hình ảnh ({w} × {h} điểm ảnh) + Couldn't copy the image: {e} Không thể sao chép hình ảnh: {e} + Copy Image in Original Format Sao chép hình ảnh ở định dạng gốc + The image has been copied as a {ext} file Đã sao chép hình ảnh thành tệp {ext} + The page has changed; select the image again Trang đã thay đổi; hãy chọn lại hình ảnh + Save as PDF Lưu thành PDF + Save attachment… Lưu tệp đính kèm… + Save changes to “{name}” before closing? Lưu thay đổi vào “{name}” trước khi đóng? + Save pages Lưu các trang + Save tag properties Lưu thuộc tính thẻ + Save the accessibility report Lưu báo cáo trợ năng + Save the document afterwards: saving rewrites the whole file so no trace of the removed content stays in it. Lưu tài liệu sau đó: việc lưu sẽ ghi lại toàn bộ tệp nên không còn dấu vết của nội dung đã loại bỏ. + Save the document afterwards; saving rewrites the whole file so nothing removed stays in it. Lưu tài liệu sau đó; việc lưu sẽ ghi lại toàn bộ tệp nên không còn gì đã bị loại bỏ. + Save the spreadsheet Lưu bảng tính + Save these pages as one PDF Lưu các trang này thành một tệp PDF + Saved measurements Số đo đã lưu + Saved measurements. Đã lưu số đo. + Scale relative to target page Tỉ lệ so với trang đích + Scan Quét + Script Name: Tên tập lệnh: + Script: Tập lệnh: + Scripts run in a sandbox without file or network access. A script that asks to open a web page needs your permission first. With JavaScript off, Acrobat's standard format, validate and calculate functions still work. Tập lệnh chạy trong hộp cát, không có quyền truy cập tệp hay mạng. Một tập lệnh yêu cầu mở trang web sẽ cần bạn cho phép trước. Khi tắt JavaScript, các hàm định dạng, xác nhận và tính toán tiêu chuẩn của Acrobat vẫn hoạt động. + Scroll long text Cuộn văn bản dài + Scroll tabs left Cuộn thẻ sang trái + Scroll tabs right Cuộn thẻ sang phải + Search comments Tìm trong bình luận + Search tools and commands… Tìm công cụ và lệnh… + Searchable Image (Exact) Hình ảnh có thể tìm kiếm (Chính xác) + Searching… {s} of {p} pages Đang tìm… {s} trong {p} trang + Searching… {s}/{p} Đang tìm… {s}/{p} + Security Bảo mật + Security settings Cài đặt bảo mật + Select (V) Chọn (V) + Select Action: Chọn hành động: + Select All Chọn tất cả + Select Icon Chọn biểu tượng + Select Trigger: Chọn trình kích hoạt: + Select a file first Hãy chọn tệp trước + Select a file for the stamp Chọn một tệp cho con dấu + Select a password-protected file first Hãy chọn tệp được bảo vệ bằng mật khẩu trước + Select a word Chọn một từ + Select all pages (Organize) Chọn tất cả trang (Sắp xếp trang) + Select at most 1000 objects at a time. Chọn tối đa 1000 đối tượng mỗi lần. + Select data files to merge Chọn các tệp dữ liệu để hợp nhất + Select format category: Chọn danh mục định dạng: + Select page {label} Chọn trang {label} + Select pages Chọn trang + Select the items to remove from this document. Chọn các mục cần loại bỏ khỏi tài liệu này. + Selected image files: {count} Các tệp hình ảnh đã chọn: {count} + Selected pages Các trang đã chọn + Selection Lựa chọn + Sending to {printer}… Đang gửi tới {printer}… + Sensitivity Độ nhạy + Sent to {printer} Đã gửi tới {printer} + Sent to {printer}: {msg} Đã gửi tới {printer}: {msg} + Separator style: Kiểu dấu phân cách: + Set Alternate Text Đặt văn bản thay thế + Set Fields to Same Size Đặt các ô cùng kích thước + Set Page Boxes Đặt hộp trang + Set layer visibility Đặt khả năng hiển thị của lớp + Set status Đặt trạng thái + Set to current page ({n}) Đặt về trang hiện tại ({n}) + Set to zero Đặt về 0 + Shared Field Properties Thuộc tính ô dùng chung + Sheet {s} of {n} Trang tính {s} trên {n} + Shift constrains to 45 degrees. Backspace removes a vertex. Escape cancels. Shift giới hạn ở góc 45 độ. Backspace xóa một đỉnh. Escape hủy thao tác. + Shift- or Ctrl/Command-click to select several fields. Nhấn Shift- hoặc Ctrl/Command-click để chọn nhiều ô. + Shift-click to select several objects. Drag empty space to select an area. Nhấn Shift-click để chọn nhiều đối tượng. Kéo vùng trống để chọn một khu vực. + Show Report Hiện báo cáo + Show all Hiện tất cả + Show all comments Hiện tất cả bình luận + Show certificate… Hiện chứng thư… + Show layer Hiện lớp + Show less Hiện ít hơn + Show password Hiện mật khẩu + Show the accessibility report Hiện báo cáo trợ năng + Show this dialog when the Checker starts Hiện hộp thoại này khi Trình kiểm tra bắt đầu + Show {n} more Hiện thêm {n} + Show: Hiện: + Shrink oversized pages Thu nhỏ các trang quá khổ + Sign Here Ký tại đây + Sign this field… Ký ô này… + Sign yourself Tự ký + Signature Details Chi tiết chữ ký + Signature is INVALID: Chữ ký KHÔNG HỢP LỆ: + Signature is valid: Chữ ký hợp lệ: + Signature panel Bảng chữ ký + Signature validity is UNKNOWN: Tính hợp lệ của chữ ký KHÔNG RÕ: + Signer's name Tên người ký + Simplified field notation: Ký hiệu ô rút gọn: + Single Page Trang đơn + Single Page Continuous Trang đơn liên tục + Single word or phrase Một từ hoặc cụm từ + Skip Rule Bỏ qua quy tắc + Skipped Đã bỏ qua + Slash Dấu gạch chéo + Smaller pages Các trang nhỏ hơn + Snap to drawing Bám theo nét vẽ + Some bookmarks are not shown here: the panel lists a limited number, nested a limited depth. Một số dấu trang không hiển thị ở đây: bảng chỉ liệt kê số lượng có giới hạn, với độ sâu lồng nhau có giới hạn. + Some page content couldn't be read; snapping uses the rest. Không thể đọc một phần nội dung trang; việc bám sử dụng phần còn lại. + Sort by Sắp xếp theo + Sort comments by: Sắp xếp bình luận theo: + Sort items Sắp xếp các mục + Source Nguồn + Space Audit Kiểm tra khoảng trắng + Special Đặc biệt + Split document Tách tài liệu + Split into files… Tách thành các tệp… + Square Vuông + Standard Business Standard Business + Start Bắt đầu + Start Checking Bắt đầu kiểm tra + Start page number Số trang bắt đầu + Status Trạng thái + Steps Các bước + Strength: {s} Độ mạnh: {s} + Style Kiểu + Subject Chủ thể + Subset Tập con + Summarize Options Tùy chọn tóm tắt + Summary Tóm tắt + Switch to List view to change the pages it takes. Chuyển sang chế độ xem Danh sách để thay đổi các trang mà nó dùng. + Switch to two-page view first to show the cover page Hãy chuyển sang chế độ xem hai trang trước để hiện trang bìa + Tab order: move a field with its arrows. Thứ tự tab: di chuyển một ô bằng các mũi tên của nó. + Tag type Loại thẻ + Tags Các thẻ + Text Color: Màu văn bản: + Text alignment: Căn chỉnh văn bản: + Text in images isn't found; recognise text (OCR) first. Không tìm thấy văn bản trong hình ảnh; hãy nhận dạng văn bản (OCR) trước. + Text is compared word by word; the differences are shown on the new file. Văn bản được so sánh từng từ; những khác biệt được hiển thị trên tệp mới. + Text recognition isn't installed: its model files are missing. Reinstall PdfCraft, or set PDFCRAFT_MODELS to the folder that holds them. Nhận dạng văn bản chưa được cài đặt: các tệp mô hình của nó đã thiếu. Hãy cài lại PdfCraft, hoặc đặt PDFCRAFT_MODELS trỏ tới thư mục chứa chúng. + Text to find Văn bản cần tìm + Text to insert Văn bản cần chèn + Text used as a clipping path cannot be moved with this selection. Văn bản dùng làm đường cắt không thể di chuyển với lựa chọn này. + Text, marks and signatures become part of the page. Other comments stay editable. Văn bản, dấu đánh dấu và chữ ký trở thành một phần của trang. Các bình luận khác vẫn có thể chỉnh sửa. + Thai and Arabic use regular fallback fonts when available. Tiếng Thái và tiếng Ả Rập dùng phông chữ dự phòng thông thường khi có sẵn. + The PDF text fonts can't draw “{c}” ({code}). Choose supported text. Các phông chữ văn bản của PDF không vẽ được “{c}” ({code}). Hãy chọn văn bản được hỗ trợ. + The checker found 1 problem which may prevent the document from being fully accessible. Trình kiểm tra tìm thấy 1 vấn đề có thể khiến tài liệu không hoàn toàn trợ năng. + The checker found no problems in this document. Trình kiểm tra không tìm thấy vấn đề nào trong tài liệu này. + The checker found {n} problems which may prevent the document from being fully accessible. Trình kiểm tra tìm thấy {n} vấn đề có thể khiến tài liệu không hoàn toàn trợ năng. + The document now conforms to {level}; save it to keep the changes Tài liệu hiện đã tuân thủ {level}; hãy lưu để giữ các thay đổi + The document opens without a password; this password is needed to change the restrictions. It's applied when you save. Tài liệu mở không cần mật khẩu; mật khẩu này cần thiết để thay đổi các hạn chế. Nó được áp dụng khi bạn lưu. + The document's security settings don't allow copying text and images Cài đặt bảo mật của tài liệu không cho phép sao chép văn bản và hình ảnh + The document's security settings don't allow this change Cài đặt bảo mật của tài liệu không cho phép thay đổi này + The existing action will be preserved. Hành động hiện có sẽ được giữ nguyên. + The fonts PdfCraft writes with can't draw “{c}” ({code}), so it shows as ? in every PDF viewer. The text is saved. Các phông chữ mà PdfCraft dùng để ghi không vẽ được “{c}” ({code}), nên nó hiện thành ? trong mọi trình xem PDF. Văn bản vẫn được lưu. + The key is in the Windows certificate store, which may ask to allow PdfCraft to use it. Khóa nằm trong kho chứng thư của Windows, có thể yêu cầu cho phép PdfCraft sử dụng nó. + The key is in the macOS Keychain, which may ask to allow PdfCraft to use it. Khóa nằm trong Keychain của macOS, có thể yêu cầu cho phép PdfCraft sử dụng nó. + The newest {n} of {total} PDFs {n} PDF mới nhất trong {total} + The password is only used to read the file; it isn't saved. Mật khẩu chỉ được dùng để đọc tệp; nó không được lưu. + The printer driver's own settings for this print: paper tray, paper type, finishing and more. Cài đặt riêng của trình điều khiển máy in cho lần in này: khay giấy, loại giấy, hoàn thiện và hơn thế nữa. + The replacement file doesn't have that many pages. Tệp thay thế không có nhiều trang như vậy. + The same password is tried on each file. Cùng một mật khẩu được thử trên từng tệp. + The signature will be invisible. Chữ ký sẽ không nhìn thấy được. + The text is the same Văn bản giống nhau + The value is shown as typed. Giá trị được hiển thị đúng như đã nhập. + There are no redaction marks (mark text, areas or pages first) Không có dấu loại bỏ nội dung nào (hãy đánh dấu văn bản, vùng hoặc trang trước) + These files can't be read, so they won't be in the combined PDF: Không thể đọc các tệp này, nên chúng sẽ không có trong PDF hợp nhất: + These objects could not be moved. Select them again and try a smaller move. Không thể di chuyển các đối tượng này. Hãy chọn lại chúng và thử di chuyển một khoảng nhỏ hơn. + Thick Đậm + Thickness Độ dày + Thin Mỏng + This area has too many overlapping paths; intersection snapping is limited. Khu vực này có quá nhiều đường dẫn chồng lấn; việc bám tại giao điểm bị giới hạn. + This certificate is in your list of trusted certificates. Chứng thư này nằm trong danh sách chứng thư tin cậy của bạn. + This certificate is not trusted. Signatures made with it show an unknown identity. Chứng thư này không được tin cậy. Các chữ ký tạo bằng nó hiển thị danh tính không xác định. + This certificate is trusted through a certificate above it in the chain. Chứng thư này được tin cậy thông qua một chứng thư ở trên nó trong chuỗi. + This comment's appearance can't be changed yet. Chưa thể thay đổi giao diện hiển thị của bình luận này. + This dialog shows the details of a certificate and its chain. Hộp thoại này hiển thị chi tiết của một chứng thư và chuỗi của nó. + This document contains {n} interactive form fields. Tài liệu này chứa {n} ô biểu mẫu tương tác. + This document has no comments to flatten Tài liệu này không có bình luận nào để dàn phẳng + This document has no document-level scripts. Tài liệu này không có tập lệnh ở cấp tài liệu. + This document has no editable structure tags. Tài liệu này không có thẻ cấu trúc nào để chỉnh sửa. + This document has no form fields to flatten Tài liệu này không có ô biểu mẫu nào để dàn phẳng + This document has no form fields you can fill in Tài liệu này không có ô biểu mẫu nào để điền + This document has no pages. Tài liệu này không có trang nào. + This document has no restrictions to lift Tài liệu này không có hạn chế nào để gỡ bỏ + This document has no signatures. Tài liệu này không có chữ ký nào. + This document has no tagged figures. Tài liệu này không có hình vẽ nào được gắn thẻ. + This document has no {kind} to change Tài liệu này không có {kind} nào để thay đổi + This document hasn't been checked yet. Tài liệu này chưa được kiểm tra. + This document is secured. Some changes are restricted by its security settings. Tài liệu này đã được bảo vệ. Một số thay đổi bị hạn chế bởi cài đặt bảo mật của nó. + This document isn't password-protected Tài liệu này không được bảo vệ bằng mật khẩu + This drawing exceeds the snapping limit; only the first paths are used. Nét vẽ này vượt quá giới hạn bám; chỉ những đường dẫn đầu tiên được dùng. + This field is locked. Unlock it to change its properties. Ô này đã bị khóa. Hãy mở khóa để thay đổi thuộc tính của nó. + This file changed on disk. Reload it to see the new version; your unsaved changes will be lost. Tệp này đã thay đổi trên đĩa. Hãy tải lại để xem phiên bản mới; các thay đổi chưa lưu của bạn sẽ bị mất. + This file was damaged and has been repaired. Saving keeps the repaired version. Tệp này bị hỏng và đã được sửa. Việc lưu sẽ giữ phiên bản đã sửa. + This folder isn't available right now. It may have moved, or its drive or cloud sync is offline. Thư mục này hiện không khả dụng. Có thể nó đã được di chuyển, hoặc ổ đĩa hay đồng bộ đám mây của nó đang ngoại tuyến. + This form's scripts are turned off because one ran too long. Reopen the document to run them again. Các tập lệnh của biểu mẫu này đã bị tắt vì một tập lệnh chạy quá lâu. Hãy mở lại tài liệu để chạy lại chúng. + This is a dynamic XFA form, which PdfCraft can't display yet. What you see is the file's placeholder page. Đây là biểu mẫu XFA động, PdfCraft chưa thể hiển thị được. Bạn đang thấy trang giữ chỗ của tệp. + This measurement needs at least {n} points. Số đo này cần ít nhất {n} điểm. + This page contains objects that cannot be selected together. Trang này chứa các đối tượng không thể chọn cùng lúc. + This page couldn't be displayed.\n{e} Không thể hiển thị trang này.\n{e} + This printer offers no settings of its own. Máy in này không có cài đặt riêng nào. + This printer's driver doesn't take two-sided settings from other programs, so its own setting applies. Change it in Properties… Trình điều khiển của máy in này không nhận cài đặt in hai mặt từ các chương trình khác, nên cài đặt riêng của nó sẽ được áp dụng. Hãy thay đổi trong Thuộc tính… + This web address mixes letters from different alphabets, a common way to imitate another site's name. Địa chỉ web này trộn lẫn chữ cái từ nhiều bảng chữ cái khác nhau, một cách phổ biến để bắt chước tên của trang web khác. + This web address uses letters from another alphabet, which can look like familiar ones. Địa chỉ web này dùng chữ cái từ một bảng chữ cái khác, có thể trông giống chữ quen thuộc. + Tile scale: Tỉ lệ xếp ô: + Time Thời gian + Title Tiêu đề + To change locked fields, also set Locked to No. Để thay đổi các ô đã bị khóa, hãy đặt Khóa thành Không. + To: Đến: + Today: {date} Hôm nay: {date} + Toggle fit page / fit width Chuyển đổi vừa trang / vừa chiều rộng + Tool Công cụ + Tools panel side Vị trí bảng công cụ + Tooltip: Chú giải: + Top Trên cùng + Top-level bookmarks ({n}) Dấu trang cấp cao nhất ({n}) + Total Tổng + Trust Tin cậy + Try the form as people filling it in will see it Xem trước biểu mẫu như người điền sẽ thấy + Two-Up (Cover Page) Hai trang (Trang bìa) + Two-Up (Facing) Hai trang (Đối diện) + Two-Up Continuous (Cover Page) Hai trang liên tục (Trang bìa) + Two-Up Continuous (Facing) Hai trang liên tục (Đối diện) + Two-sided: In hai mặt: + Type Loại + Type text Nhập văn bản + Type the web address. Nhập địa chỉ web. + Type your {what}. Nhập {what} của bạn. + URL to submit to URL để gửi tới + Unit Đơn vị + Units Đơn vị + Unknown author Tác giả không xác định + Unlock Mở khóa + Unlock {name} Mở khóa {name} + Unlock {n} files Mở khóa {n} tệp + Unlocked: the combined file won't be password-protected Đã mở khóa: tệp hợp nhất sẽ không được bảo vệ bằng mật khẩu + Unlock… Mở khóa… + Unpin Bỏ ghim + Unpin {folder} Bỏ ghim {folder} + Unplaced Chưa đặt + Unsupported measurements Số đo không được hỗ trợ + Up Lên + Update Cập nhật + Use 72 DPI (one point per pixel) Dùng 72 DPI (một điểm mỗi pixel) + Use Flate to encode streams that are not encoded Dùng Flate để mã hóa các luồng chưa được mã hóa + Use a Digital ID from a file Dùng Digital ID từ một tệp + Use custom DPI Dùng DPI tùy chỉnh + Use each image's embedded DPI; use 72 DPI when it is absent. Dùng DPI nhúng của từng hình ảnh; dùng 72 DPI khi không có. + Use image resolution Dùng độ phân giải hình ảnh + Use now Dùng ngay + Use overlay text Dùng văn bản phủ + Used when a PDF doesn't ask for a layout or zoom. Continuous scrolling never snaps between pages. Dùng khi PDF không yêu cầu bố cục hoặc mức thu phóng. Cuộn liên tục không bao giờ bám giữa các trang. + Used when opening PDFs. An explicit launch or control mode takes precedence for the session. Dùng khi mở PDF. Chế độ khởi chạy hoặc chế độ điều khiển tường minh sẽ được ưu tiên cho phiên làm việc này. + User Interface Options Tùy chọn giao diện người dùng + User password Mật khẩu người dùng + Valid for 5 years, for digital signatures. Self-signed IDs are usually not trusted by others. Có hiệu lực 5 năm, dành cho chữ ký số. Digital ID tự ký thường không được người khác tin cậy. + Validate all Xác nhận tất cả + Value is not calculated Giá trị không được tính toán + Value is the Giá trị là + Value: Giá trị: + Verify Xác minh + Verify to see what the document needs. Xác minh để xem tài liệu cần gì. + Version {v} Phiên bản {v} + Vertical Dọc + Vertical reversed Dọc đảo ngược + Vertical text cannot be moved with this selection. Văn bản dọc không thể di chuyển với lựa chọn này. + View revision {n} Xem bản sửa đổi {n} + View signed version Xem phiên bản đã ký + Viewport Khung xem + Viewport rectangle in page points (x, y, width, height) Hình chữ nhật khung xem theo điểm trang (x, y, chiều rộng, chiều cao) + Visible Rectangle Hình chữ nhật hiển thị + Visual Trực quan + Warnings Cảnh báo + Welcome to PdfCraft Chào mừng đến với PdfCraft + What word or phrase would you like to search for? Bạn muốn tìm từ hoặc cụm từ nào? + Whole words only Chỉ từ đầy đủ + Width: Chiều rộng: + Window Options Tùy chọn cửa sổ + Windows store · Cửa hàng Windows · + Write this email? Viết email này? + Wrong password Sai mật khẩu + XFA form: its fields and its XFA data are kept in step, so other viewers show what you fill in. Biểu mẫu XFA: các ô của nó và dữ liệu XFA được đồng bộ với nhau, nên các trình xem khác hiển thị đúng những gì bạn điền. + You are about to apply 1 redaction mark. Text, images and drawings under the marks, and comments and form fields that overlap them, are removed permanently. Bạn sắp áp dụng 1 dấu loại bỏ nội dung. Văn bản, hình ảnh và nét vẽ nằm dưới các dấu, cùng bình luận và ô biểu mẫu chồng lấn chúng, sẽ bị xóa vĩnh viễn. + You are about to apply {n} redaction marks. Text, images and drawings under the marks, and comments and form fields that overlap them, are removed permanently. Bạn sắp áp dụng {n} dấu loại bỏ nội dung. Văn bản, hình ảnh và nét vẽ nằm dưới các dấu, cùng bình luận và ô biểu mẫu chồng lấn chúng, sẽ bị xóa vĩnh viễn. + You have version {c}. All releases are listed at {page}. Bạn đang có phiên bản {c}. Tất cả các bản phát hành được liệt kê tại {page}. + You have version {c}. Download the new version from its release page. Bạn đang có phiên bản {c}. Hãy tải phiên bản mới từ trang phát hành của nó. + Your changes will be lost if you don't save them. Các thay đổi của bạn sẽ bị mất nếu bạn không lưu. + ZIP ZIP + Zoom in Phóng to + Zoom in ({key}) Phóng to ({key}) + Zoom in / out (also pinch or {key}-scroll) Phóng to / thu nhỏ (cũng có thể dùng hai ngón tay vuốt hoặc cuộn bằng {key}) + Zoom out Thu nhỏ + Zoom out ({key}) Thu nhỏ ({key}) + already a PDF đã là PDF + and {n} more và {n} nữa + background nền + characters ký tự + e.g. My stamps ví dụ: Con dấu của tôi + e.g. en-US ví dụ: en-US + for images above cho các hình ảnh phía trên + header or footer đầu trang hoặc chân trang + initials chữ viết tắt + is available khả dụng + is not available yet chưa khả dụng + just now vừa xong + yesterday hôm qua + needs an AI provider (off by default) cần một nhà cung cấp AI (tắt theo mặc định) + no output folder was chosen chưa chọn thư mục đầu ra + no unused output name không có tên đầu ra nào chưa dùng + none không có + of the following fields: trong số các ô sau: + AI assistant AI Assistant + Action Wizard Trình hướng dẫn hành động + Action Wizard… Trình hướng dẫn hành động… + Actions list Danh sách hành động + Add Bates numbering… Thêm đánh số Bates… + Add a button Thêm một nút + Add a callout Thêm một hộp thoại chú thích + Add a checkbox Thêm một ô kiểm tra + Add a date field Thêm một ô ngày + Add a digital signature field Thêm một ô chữ ký số + Add a drop-down list Thêm một danh sách thả xuống + Add a list box Thêm một hộp danh sách + Add a radio button Thêm nút chọn + Add a stamp Thêm con dấu + Add a sticky note Thêm ghi chú dính + Add a text box Thêm hộp văn bản + Add a text field Thêm ô văn bản + Add alternate text Thêm văn bản thay thế + Add alternate text… Thêm văn bản thay thế… + Add an image field Thêm ô hình ảnh + Add background… Thêm nền… + Add comments Thêm bình luận + Add content Thêm nội dung + Add files to combine Thêm tệp để kết hợp + Add form components Thêm thành phần biểu mẫu + Add header & footer… Thêm đầu trang & chân trang… + Add image… Thêm hình ảnh… + Add or edit links Thêm hoặc chỉnh sửa liên kết + Add printer marks Thêm dấu in + Add search index Thêm chỉ mục tìm kiếm + Add text Thêm văn bản + Add watermark… Thêm hình mờ… + Advanced optimization Tối ưu nâng cao + Advanced options Tùy chọn nâng cao + Apply PDF standards Áp dụng tiêu chuẩn PDF + Apply redactions… Áp dụng loại bỏ nội dung… + Archive documents Lưu trữ tài liệu + Area Diện tích + Arrow Mũi tên + ArtCraft website Trang web ArtCraft + Ask about this document Hỏi về tài liệu này + Attach a file Đính kèm một tệp + Attach file Đính kèm tệp + Audit space usage Kiểm tra mức sử dụng dung lượng + Automatically tag PDF Tự động gắn thẻ PDF + Background Nền + Bates numbering Đánh số Bates + Blank page Trang trắng + Bring your own model (off by default) Dùng mô hình của riêng bạn (mặc định tắt) + Button Nút + Certificates Chứng thư + Certify (invisible signature) Chứng nhận (chữ ký vô hình) + Certify (visible signature) Chứng nhận (chữ ký nhìn thấy được) + Change initials Đổi chữ viết tắt + Change reading options Đổi tùy chọn đọc + Change reading options… Đổi tùy chọn đọc… + Change signature Đổi chữ ký + Check for accessibility Kiểm tra trợ năng + Check for accessibility… Kiểm tra trợ năng… + Checkbox Ô tích + Checkmark Dấu tích + Clear form Xóa biểu mẫu + Clear redaction marks Xóa dấu loại bỏ nội dung + Clipboard Bảng tạm + Cloud Đám mây + Column select Chọn theo cột + Combine Kết hợp + Combine files Kết hợp tệp + Comment list Danh sách bình luận + Comments panel Bảng bình luận + Compare So sánh + Compare files So sánh tệp + Compare files… So sánh tệp… + Compress a PDF Nén một PDF + Console Bảng điều khiển + Convert colors Chuyển đổi màu + Copy pages Sao chép trang + Correct recognized text Sửa văn bản đã nhận dạng + Create a PDF Tạo một PDF + Create from Tạo từ + Create links from URLs Tạo liên kết từ URL + Crop pages Cắt lề trang + Cross Dấu chéo + Cut pages Cắt trang + Dark gray Xám đậm + Date Ngày + Date field Ô ngày + Detect form fields Phát hiện ô biểu mẫu + Digital signature Chữ ký số + Digitally sign Ký số + Distance Khoảng cách + Document JavaScripts JavaScripts của tài liệu + Document JavaScripts… JavaScripts của tài liệu… + Document actions Hành động của tài liệu + Dot Dấu chấm + Draw a cloud Vẽ đám mây + Draw a line Vẽ đường thẳng + Draw a polygon Vẽ đa giác + Draw a rectangle Vẽ hình chữ nhật + Draw an arrow Vẽ mũi tên + Draw an oval Vẽ hình bầu dục + Draw connected lines Vẽ các đường thẳng nối tiếp + Draw freehand Vẽ tự do + Drawing Vẽ tay + Drawing scale Tỉ lệ vẽ + 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 + Edit text & images Chỉnh sửa văn bản & hình ảnh + Encrypt with certificate Mã hóa bằng chứng thư + Enhance camera image Cải thiện hình ảnh máy ảnh + Enhance scanned file Cải thiện tệp đã quét + Enter permissions password… Nhập mật khẩu quyền… + Erase drawings Xóa nét vẽ + Export a PDF Xuất một PDF + Export all comments to data file… Xuất tất cả bình luận ra tệp dữ liệu… + Export all images Xuất tất cả hình ảnh + Export all images… Xuất tất cả hình ảnh… + Export data Xuất dữ liệu + Export form data… Xuất dữ liệu biểu mẫu… + Export measurements Xuất kết quả đo + Export measurements as CSV Xuất kết quả đo dưới dạng CSV + Export to Xuất vào + Export to PowerPoint… Xuất sang PowerPoint… + Extract Trích xuất + Extract pages Trích xuất trang + Field list Danh sách ô + Field properties Thuộc tính ô + Field properties… Thuộc tính ô… + Fields Các ô + Fill Điền + Fill & Sign: add text Điền & Ký: thêm văn bản + Fill & Sign: change initials Điền & Ký: đổi chữ viết tắt + Fill & Sign: change signature Điền & Ký: đổi chữ ký + Fill & Sign: checkmark Điền & Ký: dấu tích + Fill & Sign: cross Điền & Ký: dấu chéo + Fill & Sign: date Điền & Ký: ngày + Fill & Sign: dot Điền & Ký: dấu chấm + Fill & Sign: initials Điền & Ký: chữ viết tắt + Fill & Sign: line Điền & Ký: đường thẳng + Fill & Sign: remove saved initials Điền & Ký: gỡ bỏ chữ viết tắt đã lưu + Fill & Sign: remove saved signature Điền & Ký: gỡ bỏ chữ ký đã lưu + Fill & Sign: sign Điền & Ký: ký + Find text and redact Tìm văn bản và loại bỏ nội dung + Find text and redact… Tìm văn bản và loại bỏ nội dung… + Fit to width scrolling Cuộn vừa chiều rộng + Fit visible Vừa vùng nhìn thấy + Fix hairlines Sửa đường viền mảnh + Fix reading order Sửa thứ tự đọc + Flatten comments Làm phẳng bình luận + Flatten form fields Làm phẳng ô biểu mẫu + Form fields panel Bảng ô biểu mẫu + Geospatial location Vị trí địa lý + Go to page… Đến trang… + HTML web page Trang web HTML + Header and footer Đầu trang và chân trang + Hide all comments Ẩn tất cả bình luận + Highlight text Tô sáng văn bản + Image Hình ảnh + Image (PNG) Hình ảnh (PNG) + Image field Ô hình ảnh + Images Hình ảnh + Import comments… Nhập bình luận… + Import data Nhập dữ liệu + Import form data… Nhập dữ liệu biểu mẫu… + In multiple files Trong nhiều tệp + In this file Trong tệp này + Index Chỉ mục + Initials Chữ viết tắt + Insert Chèn + Insert pages Chèn trang + Insert text Chèn văn bản + JavaScript JavaScript + JavaScript console… Bảng điều khiển JavaScript… + Join the ArtCraft Discord Tham gia Discord của ArtCraft + Light gray Xám nhạt + Line Đường thẳng + Link Liên kết + List box Hộp danh sách + Make accessible Làm cho dễ tiếp cận + Manage embedded index Quản lý chỉ mục nhúng + Markup Chú thích + Marquee zoom Thu phóng vùng chọn + Measure area Đo diện tích + Measure distance Đo khoảng cách + Measure objects Đo đối tượng + Measure perimeter Đo chu vi + Measurement information Thông tin phép đo + Measurement snapping Bám phép đo + Merge data files into spreadsheet… Gộp các tệp dữ liệu vào bảng tính… + Microsoft Word (.docx) Microsoft Word (.docx) + Modify page Sửa đổi trang + Multiple files Nhiều tệp + New bookmarks from structure Tạo dấu trang mới từ cấu trúc + Open accessibility report Mở báo cáo trợ năng + Optimize scanned documents Tối ưu tài liệu đã quét + Optimize scanned documents… Tối ưu tài liệu đã quét… + Output preview Xem trước kết quả + Oval Hình bầu dục + PDF/A… PDF/A… + Page grid Lưới trang + Page labels Nhãn trang + Page options Tùy chọn trang + Page transitions Hiệu ứng chuyển trang + Paste pages Dán trang + PdfCraft on GitHub PdfCraft trên GitHub + PdfCraft web page Trang web PdfCraft + Perimeter Chu vi + Pin folder to Home… Ghim thư mục vào Trang chủ… + PostScript / EPS PostScript / EPS + Preflight Kiểm tra trước khi in + Prepare for accessibility Chuẩn bị cho trợ năng + Prepare for distribution Chuẩn bị để phân phối + Prepare for distribution… Chuẩn bị để phân phối… + Presentation (.pptx) Trình bày (.pptx) + Print production Dàn trang in + Protect a PDF Bảo vệ một PDF + Protect with password Bảo vệ bằng mật khẩu + Radio button Nút chọn + Recognize text Nhận dạng văn bản + Recognize text in multiple files… Nhận dạng văn bản trong nhiều tệp… + Recognize text… Nhận dạng văn bản… + Rectangle Hình chữ nhật + Redact a PDF Loại bỏ nội dung một PDF + Redact pages Loại bỏ nội dung trang + Redact pages… Loại bỏ nội dung trang… + Redact text and images Loại bỏ nội dung văn bản và hình ảnh + Redaction properties… Thuộc tính loại bỏ nội dung… + Reduce file size Giảm kích thước tệp + Remove all links Gỡ bỏ tất cả liên kết + Remove background Gỡ bỏ nền + Remove header & footer Gỡ bỏ đầu trang & chân trang + Remove hidden information Gỡ bỏ thông tin ẩn + Remove hidden information… Gỡ bỏ thông tin ẩn… + Remove watermark Gỡ bỏ hình mờ + Replace Thay thế + Replace text Thay thế văn bản + Reset panel layout Đặt lại bố cục bảng + Review Xem lại + Rich Text Format (.rtf) Rich Text Format (.rtf) + Rotate Xoay + Rotate pages Xoay trang + Rotate pages clockwise Xoay trang theo chiều kim đồng hồ + Rotate pages counterclockwise Xoay trang ngược chiều kim đồng hồ + Sanitize document Làm sạch tài liệu + Sanitize document… Làm sạch tài liệu… + Save as PDF/A Lưu dạng PDF/A + Save as PDF/UA Lưu dạng PDF/UA + Save as PDF/X Lưu dạng PDF/X + Scan & OCR Quét & OCR + Security properties Thuộc tính bảo mật + Select files to compare Chọn tệp để so sánh + Separate PDFs Tách PDF + Set measurement scale Đặt tỉ lệ đo + Set page boxes Đặt khung trang + Set page boxes… Đặt khung trang… + Set properties Đặt thuộc tính + Show cover page in two-page view Hiện trang bìa ở chế độ xem hai trang + Signature Chữ ký + Signatures panel Bảng chữ ký + Single file Một tệp + Snapping Bám + Split Tách + Spreadsheet (.xlsx) Bảng tính (.xlsx) + Squiggly underline Gạch chân gợn sóng + Squiggly underline text Gạch chân gợn sóng văn bản + Stamp Con dấu + Stamp palette Bảng màu con dấu + Stamps Con dấu + Standards Tiêu chuẩn + Sticky note Ghi chú dính + Strikethrough text Gạch ngang văn bản + Summarize Tóm tắt + Summarize comments Tóm tắt bình luận + Switch light / dark theme Chuyển giao diện sáng / tối + Tab order by columns Thứ tự Tab theo cột + Tab order by rows Thứ tự Tab theo hàng + Tab order: by columns Thứ tự Tab: theo cột + Tab order: by document structure Thứ tự Tab: theo cấu trúc tài liệu + Tab order: by rows Thứ tự Tab: theo hàng + Tags panel Bảng thẻ + Text (plain) Văn bản (thuần) + Text box Hộp văn bản + Text field Ô văn bản + Timestamp Dấu thời gian + Translate Dịch + Underline text Gạch chân văn bản + Update background… Cập nhật nền… + Update header & footer… Cập nhật đầu trang & chân trang… + Update watermark… Cập nhật hình mờ… + Use JavaScript Dùng JavaScript + Use a certificate Dùng một chứng thư + Use guided actions Dùng hành động có hướng dẫn + Use print production Dùng dàn trang in + Use system setting Dùng cài đặt hệ thống + Validate all signatures Xác thực tất cả chữ ký + Watermark Hình mờ + Move object Di chuyển đối tượng + Move objects Di chuyển các đối tượng + All tools Tất cả công cụ + Read Đọc + E-Sign Ký điện tử + Tools Công cụ + Inspector Trình kiểm tra + on page {label} trên trang {label} + A font isn't embedded Phông chữ chưa được nhúng + A {} action isn't allowed Hành động {} không được phép + A {} annotation has additional actions Chú thích {} có hành động bổ sung + A {} annotation has no appearance stream Chú thích {} không có luồng giao diện hiển thị + A {} annotation isn't set to print, or is hidden Chú thích {} không được đặt để in hoặc đang bị ẩn + Accessibility Report Báo cáo Trợ năng + Add the PDFs to combine Thêm các PDF để kết hợp + Added the first {n} PDFs in {folder} Đã thêm {n} PDF đầu tiên trong {folder} + CRL Signing Ký bằng CRL + Certificate Signing Ký bằng chứng thư + Change Author Đổi Tác giả + Change Keywords Đổi Từ khóa + Change Subject Đổi Chủ đề + Change Title Đổi Tiêu đề + Choose a digital ID. Chọn một danh tính số. + Create links Tạo liên kết + Creator Người tạo + Cut and stack needs Two-sided: Off. Print single-sided sheets. Cắt và xếp chồng cần có In hai mặt: Tắt. Hãy in các tờ in một mặt. + Data Encipherment Mã hóa dữ liệu + Decipher Only Chỉ giải mã + Detailed Report Báo cáo chi tiết + DeviceCMYK is used, but the PDF/A output intent isn't a CMYK profile Đang dùng DeviceCMYK, nhưng ý định đầu ra PDF/A không phải là hồ sơ CMYK + DeviceRGB is used, but the PDF/A output intent isn't an RGB profile Đang dùng DeviceRGB, nhưng ý định đầu ra PDF/A không phải là hồ sơ RGB + Digital Signature Chữ ký số + Document properties (⌘D) Thuộc tính tài liệu (⌘D) + Drop PDFs or folders here, or choose them. Kéo tệp PDF hoặc thư mục vào đây, hoặc chọn chúng. + Encipher Only Chỉ mã hóa + English Tiếng Anh + Enter a URL Nhập một URL + Enter a name. Nhập một tên. + Enter a page number Nhập số trang + Enter the field names Nhập tên các ô + Every PDF in the folder Mọi tệp PDF trong thư mục + Every PDF in the folder and the folders inside it Mọi tệp PDF trong thư mục và các thư mục bên trong + Field "{}" on page {p} has no description (tooltip) Ô "{}" trên trang {p} không có mô tả (chú thích) + Filename Tên tệp + Flatten Fill & Sign Dàn phẳng Điền & Ký + Font (unnamed) on page {p} doesn't map its characters to Unicode Phông chữ (không tên) trên trang {p} không ánh xạ các ký tự của nó sang Unicode + Font {} on page {p} doesn't map its characters to Unicode Phông chữ {} trên trang {p} không ánh xạ các ký tự của nó sang Unicode + Form field on page {p} isn't tagged Ô biểu mẫu trên trang {p} chưa được gắn thẻ + H{n} follows an H{d}; headings should not skip levels H{n} đứng sau một H{d}; các tiêu đề không nên bỏ qua cấp độ + Inserted text Văn bản đã chèn + Key Agreement Thỏa thuận khóa + Key Encipherment Mã hóa khóa + Margins (in) Lề (inch) + New bookmark (⌘B) Dấu trang mới (⌘B) + Next (⌘G) Tiếp theo (⌘G) + No PDFs found in {folder} Không tìm thấy tệp PDF nào trong {folder} + No document language is set Chưa đặt ngôn ngữ cho tài liệu + No page has text: the document appears to be images of pages Không trang nào có văn bản: tài liệu có vẻ chỉ là hình ảnh của các trang + Non-Repudiation Chống thoái chối + Only the document's owner can change its security (open it with the permissions password) Chỉ chủ sở hữu của tài liệu mới có thể thay đổi bảo mật của nó (mở bằng mật khẩu quyền) + Open a PDF (⌘O) Mở một tệp PDF (⌘O) + Page {p} doesn't tab in structure order Trang {p} không theo thứ tự tab trong cấu trúc + Page {p}: {n} untagged content item Trang {p}: {n} mục nội dung chưa gắn thẻ + Page {p}: {n} untagged content items Trang {p}: {n} mục nội dung chưa gắn thẻ + Page {} has additional actions Trang {} có hành động bổ sung + Panel layout could not be restored: {error} Không thể khôi phục bố cục bảng bên: {error} + Panel move was not applied: {error} Việc di chuyển bảng bên không được áp dụng: {error} + PdfCraft can't check this signature yet: {}. PdfCraft chưa thể kiểm tra chữ ký này: {}. + Previous (⇧⌘G) Trước (⇧⌘G) + Print (⌘P) In (⌘P) + Producer Nhà sản xuất + Redo {action} Làm lại {action} + Rendering… Đang kết xuất… + Report created Đã tạo báo cáo + Rev. {rev}: Certified by an unknown signer Bản {rev}: Được chứng nhận bởi người ký không xác định + Rev. {rev}: Certified by {name} Bản {rev}: Được chứng nhận bởi {name} + Rev. {rev}: Signed by an unknown signer Bản {rev}: Được ký bởi người ký không xác định + Rev. {rev}: Signed by {name} Bản {rev}: Được ký bởi {name} + Rotate view clockwise (⇧⌘+) Xoay giao diện theo chiều kim đồng hồ (⇧⌘+) + Rule Name Tên quy tắc + Save (M4) Lưu (M4) + Save as {level} Lưu thành {level} + Signature is invalid Chữ ký không hợp lệ + Signature is valid Chữ ký hợp lệ + Signature validity is unknown Không rõ tính hợp lệ của chữ ký + Signing time is from the clock on the signer's computer. Thời điểm ký lấy từ đồng hồ trên máy tính của người ký. + Still rendering — this page is unusually complex… Vẫn đang kết xuất — trang này phức tạp bất thường… + The ECDSA signature is not in canonical DER (trailing bytes, padding or a missing sign byte); it was read anyway. Chữ ký ECDSA không ở dạng DER chuẩn (byte thừa, phần đệm hoặc thiếu byte dấu); nó vẫn được đọc. + The ECDSA signature is the raw r and s values instead of a DER sequence; it was read anyway. Chữ ký ECDSA là giá trị r và s thô thay vì một chuỗi DER; nó vẫn được đọc. + The RSA signature value does not have the length of the key's modulus (leading zero bytes dropped or added); it was read anyway. Giá trị chữ ký RSA không có độ dài bằng modulus của khóa (byte 0 ở đầu bị bỏ hoặc thêm vào); nó vẫn được đọc. + The RSA signature's DigestInfo has no NULL parameter (older signers write it so); it was read anyway. DigestInfo của chữ ký RSA không có tham số NULL (các bộ ký cũ ghi như vậy); nó vẫn được đọc. + The certificate of {} does not allow this many CA certificates below it (path length), so it is not used to vouch for {}. Chứng thư của {} không cho phép có nhiều chứng thư CA như vậy bên dưới nó (độ dài đường dẫn), vì vậy nó không được dùng để bảo chứng cho {}. + The certificate of {} is not a CA certificate that may issue certificates, so it is not used to vouch for {}. Chứng thư của {} không phải là chứng thư CA có thể cấp chứng thư, vì vậy nó không được dùng để bảo chứng cho {}. + The certificate of {} was not valid at the time of signing, so it is not used to vouch for {}. Chứng thư của {} không hợp lệ tại thời điểm ký, vì vậy nó không được dùng để bảo chứng cho {}. + The checker found problems which may prevent the document from being fully accessible. Bộ kiểm tra phát hiện vấn đề có thể khiến tài liệu không hoàn toàn trợ năng. + The document has been altered or corrupted since the signature was applied. Tài liệu đã bị thay đổi hoặc hỏng kể từ khi chữ ký được áp dụng. + The document has been altered or corrupted since the timestamp was applied. Tài liệu đã bị thay đổi hoặc hỏng kể từ khi dấu thời gian được áp dụng. + The document has been altered since this signature was applied in ways it does not permit ({}). Tài liệu đã bị thay đổi theo những cách mà chữ ký này không cho phép ({}). + The document has been altered since this timestamp was applied in ways it does not permit ({}). Tài liệu đã bị thay đổi theo những cách mà dấu thời gian này không cho phép ({}). + The document has been modified since this signature was applied, but the changes are permitted ({}). Tài liệu đã được sửa đổi kể từ khi chữ ký này được áp dụng, nhưng các thay đổi đó được phép ({}). + The document has been modified since this timestamp was applied, but the changes are permitted ({}). Tài liệu đã được sửa đổi kể từ khi dấu thời gian này được áp dụng, nhưng các thay đổi đó được phép ({}). + The document has no tags (structure tree) Tài liệu không có thẻ nào (cây cấu trúc) + The document has no title Tài liệu không có tiêu đề + The document isn't marked as tagged (MarkInfo Marked) Tài liệu không được đánh dấu là đã gắn thẻ (MarkInfo Marked) + The document isn't tagged, so none of its content is Tài liệu chưa được gắn thẻ, vì vậy không có nội dung nào của nó được gắn thẻ + The document's embedded revocation information shows that the signer's certificate has not been revoked. Thông tin thu hồi nhúng trong tài liệu cho thấy chứng thư của người ký chưa bị thu hồi. + The embedded timestamp token is valid and its authority is trusted; trusted time is {}. Mã thông báo dấu thời gian nhúng hợp lệ và cơ quan của nó được tin cậy; thời gian tin cậy là {}. + The font {} isn't embedded Phông chữ {} không được nhúng + The metadata doesn't identify the file as {} Siêu dữ liệu không nhận diện tệp là {} + The password is incorrect. Mật khẩu không đúng. + The password must have at least 6 characters. Mật khẩu phải có ít nhất 6 ký tự. + The passwords do not match. Hai mật khẩu không khớp. + The security settings don't allow screen readers to read the text Cài đặt bảo mật không cho phép trình đọc màn hình đọc văn bản + The signature algorithm and the SignerInfo's digest algorithm name different hashes; the signature was made with the SignerInfo's. Thuật toán chữ ký và thuật toán băm trong SignerInfo chỉ định các hàm băm khác nhau; chữ ký được tạo bằng thuật toán của SignerInfo. + The signature carries an unverified timestamp ({}): the timestamp authority is not in your list of trusted certificates, so the signing time claimed by the signer is used instead. Chữ ký mang dấu thời gian chưa được xác minh ({}): cơ quan dấu thời gian không có trong danh sách chứng thư tin cậy của bạn, nên thời điểm ký mà người ký tuyên bố sẽ được dùng thay thế. + The signature contents are not hexadecimal. Nội dung chữ ký không phải là mã thập lục phân. + The signature could not be checked ({}). Không thể kiểm tra chữ ký ({}). + The signature could not be read ({}). Không thể đọc chữ ký ({}). + The signature could not be verified ({}). Không thể xác minh chữ ký ({}). + The signature has no valid byte range. Chữ ký không có phạm vi byte hợp lệ. + The signature includes an embedded timestamp. Chữ ký có chứa dấu thời gian nhúng. + The signature is BER-encoded (indefinite lengths) rather than DER; it was read leniently. Chữ ký được mã hóa theo BER (độ dài không xác định) thay vì DER; nó được đọc theo cách dễ dãi hơn. + The signature uses the legacy adbe.x509.rsa_sha1 format. Chữ ký dùng định dạng cũ adbe.x509.rsa_sha1. + The signature value does not match the signer's certificate: the signature is corrupt. Giá trị chữ ký không khớp với chứng thư của người ký: chữ ký bị hỏng. + The signature's byte range does not exclude exactly its contents. Phạm vi byte của chữ ký không loại trừ chính xác nội dung của nó. + The signature's byte range does not match the file. Phạm vi byte của chữ ký không khớp với tệp. + The signature's timestamp token could not be verified ({}). Không thể xác minh mã thông báo dấu thời gian của chữ ký ({}). + The signature's timestamp token does not cover the signature value. Mã thông báo dấu thời gian của chữ ký không bao phủ giá trị chữ ký. + The signed content is a constructed (segmented) OCTET STRING, as BER allows; it was read anyway. Nội dung được ký là một OCTET STRING dựng thành (phân đoạn), như BER cho phép; nó vẫn được đọc. + The signer's certificate does not allow digital signatures (its key usage has neither digital signature nor non-repudiation). Chứng thư của người ký không cho phép chữ ký số (mục đích sử dụng khóa của nó không có chữ ký số cũng không có chống thoái chối). + The signer's certificate has been revoked ({}). Chứng thư của người ký đã bị thu hồi ({}). + The signer's certificate has critical extensions PdfCraft does not recognize ({}). Chứng thư của người ký có các phần mở rộng quan trọng mà PdfCraft không nhận ra ({}). + The signer's certificate is not in the signature. Chứng thư của người ký không có trong chữ ký. + The signer's certificate is not issued for signing documents (its extended key usage has no document-signing purpose). Chứng thư của người ký không được cấp để ký tài liệu (mục đích sử dụng khóa mở rộng của nó không có mục đích ký tài liệu). + The signer's certificate was not valid at the time of signing. Chứng thư của người ký không hợp lệ tại thời điểm ký. + The signer's identity is unknown because it has not been included in your list of trusted certificates and none of its parent certificates are trusted certificates. Danh tính của người ký không xác định vì nó không có trong danh sách chứng thư tin cậy của bạn và không chứng thư cha nào của nó là chứng thư tin cậy. + The signer's identity is valid. Danh tính của người ký hợp lệ. + The timestamp authority's certificate was not valid at the time of timestamping. Chứng thư của cơ quan dấu thời gian không hợp lệ tại thời điểm đóng dấu thời gian. + The timestamp contents are not hexadecimal. Nội dung dấu thời gian không phải là mã thập lục phân. + The timestamp has no valid byte range. Dấu thời gian không có phạm vi byte hợp lệ. + The timestamp token could not be read ({}). Không thể đọc mã thông báo dấu thời gian ({}). + The timestamp token is valid and its authority is trusted. Mã thông báo dấu thời gian hợp lệ và cơ quan của nó được tin cậy. + The timestamp token is valid, but the timestamp authority is not in your list of trusted certificates. Mã thông báo dấu thời gian hợp lệ, nhưng cơ quan dấu thời gian không có trong danh sách chứng thư tin cậy của bạn. + The timestamp's byte range does not exclude exactly its contents. Phạm vi byte của dấu thời gian không loại trừ chính xác nội dung của nó. + The timestamp's byte range does not match the file. Phạm vi byte của dấu thời gian không khớp với tệp. + The window shows the file name, not the title (Initial View > Show) Cửa sổ hiển thị tên tệp chứ không phải tiêu đề (Initial View > Show) + There is no folder to save the digital ID in. Không có thư mục nào để lưu ID số. + This document has not been modified since this signature was applied. Tài liệu này chưa bị sửa đổi kể từ khi chữ ký này được áp dụng. + This document has not been modified since this timestamp was applied. Tài liệu này chưa bị sửa đổi kể từ khi dấu thời gian này được áp dụng. + This signature uses RIPEMD-160, a legacy 160-bit hash algorithm that is no longer recommended for signatures. It still validates, but it should not be relied on. Chữ ký này dùng RIPEMD-160, thuật toán băm 160 bit cũ không còn được khuyến nghị cho chữ ký. Nó vẫn hợp lệ, nhưng không nên tin dựa vào nó. + This signature uses SHA-1, a weak hash algorithm: collisions in it have been demonstrated. It still validates because many documents signed years ago use it, but it should not be relied on. Chữ ký này dùng SHA-1, một thuật toán băm yếu: đã chứng minh được sự trùng lặp trong đó. Nó vẫn hợp lệ vì nhiều tài liệu ký từ nhiều năm trước dùng nó, nhưng không nên tin dựa vào nó. + Undo {action} Hoàn tác {action} + Unsigned signature field Ô chữ ký chưa ký + Unsigned signature field: {name} Ô chữ ký chưa ký: {name} + Zoom in (⌘+) Thu phóng vào (⌘+) + Zoom in / out (also pinch or ⌘-scroll) Thu phóng vào / ra (cũng có thể dùng hai ngón tay vuốt hoặc cuộn bằng ⌘) + Zoom out (⌘−) Thu phóng ra (⌘−) + alternate text hides an annotation inside it văn bản thay thế che khuất một chú thích bên trong + alternate text on an element with no page content văn bản thay thế trên một phần tử không có nội dung trang + comments bình luận + document security store kho bảo mật của tài liệu + document structure cấu trúc tài liệu + form fill điền biểu mẫu + its alternate text is inside another element's and will never be read văn bản thay thế của nó nằm bên trong văn bản thay thế của phần tử khác và sẽ không bao giờ được đọc + links liên kết + metadata siêu dữ liệu + no alternate text không có văn bản thay thế + no header cells (TH) không có ô tiêu đề (TH) + no summary không có tóm tắt + not in a TR không nằm trong TR + not in a Table, THead, TBody or TFoot không nằm trong Table, THead, TBody hoặc TFoot + not in an L (list) không nằm trong L (danh sách) + not in an LI (list item) không nằm trong LI (mục danh sách) + other changes thay đổi khác + page content nội dung trang + page {n} is out of range (1–{count}) trang {n} nằm ngoài phạm vi (1–{count}) + pages added or removed trang được thêm hoặc bị xóa + rows have between {min} and {max} columns các hàng có từ {min} đến {max} cột + the first heading is an H{n}; headings should not skip levels tiêu đề đầu tiên là một H{n}; các tiêu đề không nên bỏ qua cấp độ + the signed version could not be read không thể đọc phiên bản đã ký + {n} pages and no bookmarks {n} trang và không có dấu trang + {page} is not a page number or label {page} không phải là số trang hoặc nhãn trang + {ty} element on page {p}: {what} phần tử {ty} trên trang {p}: {what} + {ty} element: {what} phần tử {ty}: {what} + {who}, certificate issued by an unknown issuer. {who}, chứng thư do một cơ quan cấp không xác định. + {who}, certificate issued by {issuer}. {who}, chứng thư do {issuer} cấp. + {} annotation on page {p} isn't tagged chú thích {} trên trang {p} chưa được gắn thẻ + {} annotations aren't allowed không cho phép chú thích {} + … and {n} more … và {n} nữa +@plural Delete {n} field|Delete {n} fields Xóa {n} ô +@plural {n} byte|{n} bytes {n} byte +@plural {n} image optimized|{n} images optimized Đã tối ưu {n} hình ảnh +@plural {n} item discarded|{n} items discarded Đã loại bỏ {n} mục +@plural {n} pixel|{n} pixels {n} pixel +action wizard Start Bắt đầu +comment menu Edit Chỉnh sửa + A button Một nút + A diagonal CONFIDENTIAL watermark on every page. Hình mờ chéo CONFIDENTIAL trên mọi trang. + A document needs at least one page: copy instead Một tài liệu cần có ít nhất một trang: hãy sao chép + A form field has additional actions Một ô biểu mẫu có hành động bổ sung + A link Một liên kết + A script Một kịch bản + A selected field has no widget on any page, so the fields can't be edited together. Ô đã chọn không có điều khiển trên bất kỳ trang nào, vì vậy không thể chỉnh sửa các ô cùng lúc. + A stream refers to an external file Một luồng tham chiếu đến một tệp bên ngoài + A stream uses LZW compression Một luồng dùng nén LZW + A summary describes the table's purpose and layout. Add a Summary attribute to each table. Phần tóm tắt mô tả mục đích và bố cục của bảng. Hãy thêm thuộc tính Summary cho mỗi bảng. + About Giới thiệu + Accepted Đã chấp nhận + Accessibility permission flag Cờ quyền trợ năng + Accessibility permission flag is set Cờ quyền trợ năng đã được đặt + Add Page Numbers Thêm số trang + Add arrow Thêm mũi tên + Add background Thêm nền + Add bookmark Thêm dấu trang + Add callout Thêm hộp thoại chú thích + Add checkmark Thêm dấu kiểm + Add cloud Thêm đám mây + Add connected lines Thêm đường nối + Add cross Thêm chữ thập + Add dot Thêm chấm + Add drawing Thêm hình vẽ + Add field Thêm ô + Add file attachment Thêm tệp đính kèm + Add footer Thêm chân trang + Add header Thêm đầu trang + Add header & footer Thêm đầu trang & chân trang + Add highlight Thêm tô sáng + Add image Thêm hình ảnh + Add inserted text Thêm văn bản đã chèn + Add line Thêm đường thẳng + Add link Thêm liên kết + Add oval Thêm hình bầu dục + Add polygon Thêm đa giác + Add rectangle Thêm hình chữ nhật + Add redaction mark Thêm dấu loại bỏ nội dung + Add signature Thêm chữ ký + Add squiggly underline Thêm gạch chân gợn sóng + Add stamp Thêm con dấu + Add sticky note Thêm ghi chú dính + Add strikethrough Thêm gạch ngang + Add text box Thêm hộp văn bản + Add underline Thêm gạch chân + Add watermark Thêm hình mờ + Add {what} Thêm {what} + Added the first {n} files in {folder} Đã thêm {n} tệp đầu tiên trong {folder} + Adding images arrives on the web with file pickers for images Thêm hình ảnh sẽ có trên web cùng với bộ chọn tệp cho hình ảnh + Algorithm Thuật toán + Align fields Căn các ô + All annotations are tagged Tất cả chú thích đều được gắn thẻ + All form fields are tagged Tất cả ô biểu mẫu đều được gắn thẻ + All form fields have description Tất cả ô biểu mẫu đều có mô tả + All multimedia objects are tagged Tất cả đối tượng đa phương tiện đều được gắn thẻ + All page content is tagged Tất cả nội dung trang đều được gắn thẻ + Allowed Được phép + Alternate Text Văn bản thay thế + Alternate text inside an element that already has alternate text is never read. Remove the inner alternate text. Văn bản thay thế bên trong một phần tử đã có văn bản thay thế sẽ không bao giờ được đọc. Hãy xóa văn bản thay thế bên trong. + Alternate text must be associated with some content Văn bản thay thế phải được liên kết với nội dung nào đó + Alternate text on an element that contains a link or field hides that annotation from assistive technology. Move the alternate text. Văn bản thay thế trên một phần tử chứa liên kết hoặc ô sẽ che khuất chú thích đó khỏi công nghệ trợ giúp. Hãy chuyển văn bản thay thế. + Alternate text on an element without page content is never reached. Remove it or attach the element to content. Văn bản thay thế trên một phần tử không có nội dung trang sẽ không bao giờ được tiếp cận. Hãy xóa nó hoặc gắn phần tử vào nội dung. + Alternate text should not hide annotation Văn bản thay thế không nên che khuất chú thích + Alternate text that will never be read Văn bản thay thế sẽ không bao giờ được đọc + An action is already running Một hành động đang chạy + An embedded file has no AFRelationship Một tệp nhúng không có AFRelationship + An image asks to be interpolated Một hình ảnh yêu cầu nội suy + An image has alternates or OPI information Một hình ảnh có thông tin thay thế hoặc OPI + Animation that flashes can cause seizures. Check scripts and media for flicker. Hoạt hình nhấp nháy có thể gây co giật. Hãy kiểm tra kịch bản và nội dung đa phương tiện xem có nhấp nháy không. + Another file dialog is still open. Finish with it first. Hộp thoại tệp khác vẫn đang mở. Hãy hoàn tất nó trước. + Application Ứng dụng + Applied 1 redaction mark. Save to remove the content from the file. Đã áp dụng 1 dấu loại bỏ nội dung. Hãy lưu để xóa nội dung khỏi tệp. + Applied {n} redaction marks. Save to remove the content from the file. Đã áp dụng {n} dấu loại bỏ nội dung. Hãy lưu để xóa nội dung khỏi tệp. + Appropriate nesting Lồng nhau phù hợp + Arbitrary Mask Mặt nạ tùy ý + Associated with content Được liên kết với nội dung + At least one signature has problems. Có ít nhất một chữ ký gặp vấn đề. + At least one signature is invalid. Có ít nhất một chữ ký không hợp lệ. + Attachment Tệp đính kèm + Basic constraints Ràng buộc cơ bản + Beveled Vát cạnh + Black Đen + Black on white Đen trên nền trắng + Blue Xanh dương + Bookmarks are present in large documents Có dấu trang trong tài liệu lớn + Both Cả hai + Button Properties Thuộc tính nút + Button Style: Kiểu nút: + Calculate Tính toán + Callout Hộp thoại chú thích + Cancelled Đã hủy + Center Footer Text Căn giữa văn bản chân trang + Center Header Text Căn giữa văn bản đầu trang + Center horizontally Căn giữa theo chiều ngang + Center vertically Căn giữa theo chiều dọc + Certificate Viewer Trình xem chứng thư + Certified by {by} Được chứng nhận bởi {by} + Change comment properties Thay đổi thuộc tính bình luận + Change document properties Thay đổi thuộc tính tài liệu + Change field properties Thay đổi thuộc tính ô + Change initial view Thay đổi chế độ xem ban đầu + Change link properties Thay đổi thuộc tính liên kết + Change tag properties Thay đổi thuộc tính thẻ + Change {key} Thay đổi {key} + Changing the document Đang thay đổi tài liệu + Character encoding Bảng mã ký tự + Character limit: Giới hạn ký tự: + Check Kiểm tra + Check Box Properties Thuộc tính ô chọn + Check Box Style: Kiểu ô chọn: + Check that the tags read in the order a sighted reader would. Use the Reading Order tool or the Tags panel to correct it. Kiểm tra xem các thẻ có được đọc theo thứ tự mà người đọc bình thường sẽ đọc không. Hãy dùng công cụ Thứ tự đọc hoặc bảng Thẻ để sửa lại. + CheckBox CheckBox + Checked Đã chọn + Choose a folder for the split files Chọn thư mục cho các tệp đã tách + Choose a folder on this computer to pin Chọn một thư mục trên máy tính này để ghim + Click on the page to add a {tool}, or drag to set its size Nhấp vào trang để thêm {tool}, hoặc kéo để đặt kích thước + Click text or an image to edit it Nhấp vào văn bản hoặc hình ảnh để chỉnh sửa + Color Images Ảnh màu + Color Spaces Không gian màu + Color contrast Độ tương phản màu + Comb of characters Lược răng cưa ký tự + Combo Combo + Coming in milestone {m}. Items marked Ready work today. Sẽ có trong mốc {m}. Các mục được đánh dấu Ready đã hoạt động. + Command Lệnh + Commenting Bình luận + Comments and markups Bình luận và chú thích + Comments, links and fields must be in the tag tree to be announced. Tag the annotations. Bình luận, liên kết và ô phải nằm trong cây thẻ thì mới được thông báo. Hãy gắn thẻ cho các chú thích. + Completed Đã hoàn thành + Configure a Digital ID for Signing Cấu hình ID số để ký + Connected lines Đường nối + Content Streams Luồng nội dung + Content copying Sao chép nội dung + Content copying for accessibility Sao chép nội dung cho trợ năng + Contributors Người đóng góp + Copied {what} Đã sao chép {what} + Copy or cut pages first Hãy sao chép hoặc cắt trang trước + Could not save: {e} Không thể lưu: {e} + Couldn't add {name}: {e} Không thể thêm {name}: {e} + Couldn't combine files: {e} Không thể kết hợp tệp: {e} + Couldn't create a PDF: {e} Không thể tạo tệp PDF: {e} + Couldn't download {name}: {e} Không thể tải xuống {name}: {e} + Couldn't extract pages: {e} Không thể trích xuất trang: {e} + Couldn't fit the visible content: {e} Không thể vừa với nội dung hiển thị: {e} + Couldn't follow linked PDF: {reason} Không thể mở tệp PDF được liên kết: {reason} + Couldn't import the signature image: {e} Không thể nhập hình ảnh chữ ký: {e} + Couldn't open revision {n}: {e} Không thể mở bản sửa đổi {n}: {e} + Couldn't open the result: {e} Không thể mở kết quả: {e} + Couldn't open the signed version: {e} Không thể mở phiên bản đã ký: {e} + Couldn't open {name}: {e} Không thể mở {name}: {e} + Couldn't optimize the file Không thể tối ưu tệp + Couldn't optimize the file: {e} Không thể tối ưu tệp: {e} + Couldn't print from the browser ({e}); downloaded {name} to print instead Không thể in từ trình duyệt ({e}); đã tải xuống {name} để in thay thế + Couldn't read {name}: {e} Không thể đọc {name}: {e} + Couldn't recover {name}: {e} Không thể khôi phục {name}: {e} + Couldn't reload {name}: {e} Không thể tải lại {name}: {e} + Couldn't save the image: {e} Không thể lưu hình ảnh: {e} + Couldn't save {name}: {e} Không thể lưu {name}: {e} + Couldn't save: {e} Không thể lưu: {e} + Couldn't show the file picker. Please try again. Không thể hiển thị bộ chọn tệp. Vui lòng thử lại. + Couldn't split: {e} Không thể tách: {e} + Couldn't summarize comments: {e} Không thể tóm tắt bình luận: {e} + Couldn't take the snapshot: {e} Không thể chụp ảnh chụp màn hình: {e} + Couldn't unlock {name}: {e} Không thể mở khóa {name}: {e} + Couldn't use the photo: {e} Không thể dùng ảnh: {e} + Couldn't use {name}: {e} Không thể dùng {name}: {e} + Couldn't write {name}: {e} Không thể ghi {name}: {e} + Couldn't write {path}: {e} Không thể ghi {path}: {e} + Create link Tạo liên kết + Created 1 link Đã tạo 1 liên kết + Created a PDF from the first {n} files Đã tạo PDF từ {n} tệp đầu tiên + Created a comment summary Đã tạo bản tóm tắt bình luận + Created {n} links Đã tạo {n} liên kết + Credit Cards Thẻ tín dụng + Crop page Cắt trang + Custom font Phông chữ tùy chỉnh + Custom stamps arrive on the web with file pickers for images Con dấu tùy chỉnh sẽ có trên web kèm bộ chọn tệp cho hình ảnh + Cut {what} Cắt {what} + Dark gray theme Giao diện màu xám đậm + Dashed Nét đứt + Dates Ngày tháng + Delete bookmark Xóa dấu trang + Delete content Xóa nội dung + Delete document JavaScript Xóa JavaScript của tài liệu + Delete field Xóa ô + Delete image Xóa hình ảnh + Delete link Xóa liên kết + Delete page Xóa trang + Delete selected fields Xóa các ô đã chọn + Deleted Đã xóa + Detected 1 form field Đã phát hiện 1 ô biểu mẫu + Detected {n} form fields Đã phát hiện {n} ô biểu mẫu + Device colour is used, but there is no PDF/A output intent Đang dùng màu thiết bị, nhưng không có ý định đầu ra PDF/A + DeviceCMYK is used: it needs a CMYK output intent (not added automatically) Đang dùng DeviceCMYK: cần có ý định đầu ra CMYK (không được thêm tự động) + Diagnostic details Chi tiết chẩn đoán + Digital Signature Properties Thuộc tính chữ ký số + Discard all comments, forms and multimedia Loại bỏ mọi bình luận, biểu mẫu và đa phương tiện + Discard all links, actions and JavaScript Loại bỏ mọi liên kết, hành động và JavaScript + Discard all object data (file attachments) Loại bỏ mọi dữ liệu đối tượng (tệp đính kèm) + Discard bookmarks Loại bỏ dấu trang + Discard document information and metadata Loại bỏ thông tin tài liệu và siêu dữ liệu + Discard hidden layer content Loại bỏ nội dung lớp ẩn + Discard hidden text Loại bỏ văn bản ẩn + Discard private data of other applications Loại bỏ dữ liệu riêng tư của ứng dụng khác + Distribute fields Phân bố các ô + Document Overhead Dung lượng tăng thêm + Document assembly Ghép tài liệu + Document has appropriate color contrast Tài liệu có độ tương phản màu phù hợp + Document is not image-only PDF Tài liệu không phải là PDF chỉ gồm hình ảnh + Document is tagged PDF Tài liệu là PDF đã gắn thẻ + Document sanitized. Save to finish: saving rewrites the whole file. Đã làm sạch tài liệu. Hãy Lưu để hoàn tất: việc lưu sẽ ghi lại toàn bộ tệp. + Document structure provides a logical reading order Cấu trúc tài liệu cung cấp thứ tự đọc hợp lý + Document title is showing in title bar Tiêu đề tài liệu đang hiển thị trên thanh tiêu đề + Documents of more than 20 pages need bookmarks for navigation. Add bookmarks for the main sections. Tài liệu trên 20 trang cần dấu trang để điều hướng. Hãy thêm dấu trang cho các phần chính. + Double-click Nhấp đúp + Downloaded {name} Đã tải xuống {name} + Downloading attachments on the web arrives with M3.10 ({n} bytes ready) Tải xuống tệp đính kèm trên web sẽ có trên web kèm M3.10 ({n} byte đã sẵn sàng) + Drag a rectangle around the area to copy Kéo một hình chữ nhật bao quanh vùng cần sao chép + Drag a rectangle on a page to crop it; double-click a page for Set Page Boxes Kéo một hình chữ nhật trên trang để cắt; nhấp đúp vào một trang để đặt Hộp trang + Drag a rectangle to create a link; double-click a link to edit it Kéo một hình chữ nhật để tạo liên kết; nhấp đúp vào một liên kết để chỉnh sửa + Drag the corners onto the document's edges, then choose Enhance page. Kéo các góc vào mép của tài liệu, rồi chọn Cải thiện trang. + Drag to draw the area where the signature should appear. Kéo để vẽ vùng nơi chữ ký sẽ xuất hiện. + Dropdown Properties Thuộc tính danh sách thả xuống + Duplicate field Nhân bản ô + Duplicate page Nhân bản trang + Each field needs a tooltip that says what to enter. Add one in Field Properties > General > Tooltip. Mỗi ô cần một chú thích cho biết cần nhập gì. Hãy thêm một chú thích trong Thuộc tính ô > Chung > Chú thích. + Edit comment Chỉnh sửa bình luận + Edit content Chỉnh sửa nội dung + Edit document JavaScript Chỉnh sửa JavaScript của tài liệu + Edit fields Chỉnh sửa các ô + Edit script of {name} Chỉnh sửa script của {name} + Edit text Chỉnh sửa văn bản + Editing Đang chỉnh sửa + Email Addresses Địa chỉ email + Embedded Files Tệp nhúng + Embedded files must be PDF/A files themselves (use PDF/A-3 for others) Tệp nhúng phải là tệp PDF/A (dùng PDF/A-3 cho các tệp khác) + Encryption Mã hóa + Endpoint Điểm cuối + Erase Xóa + Eraser Tẩy + Even pages Trang chẵn + Everything on a page must be tagged or marked as an artifact (decoration, headers, footers). Tag the untagged content. Mọi thứ trên một trang phải được gắn thẻ hoặc đánh dấu là artifact (họa tiết, đầu trang, chân trang). Hãy gắn thẻ cho nội dung chưa gắn thẻ. + Execute a menu item Chạy một mục trình đơn + Export certificate Xuất chứng thư + Exported to {path} Đã xuất tới {path} + Extended Graphics States Trạng thái đồ họa mở rộng + Field Ô + Field descriptions Mô tả ô + Figures alternate text Văn bản thay thế cho hình + Figures require alternate text Hình cần văn bản thay thế + File attachments Tệp đính kèm + Files are combined in this order. Leave Pages empty to take every page. Các tệp được kết hợp theo thứ tự này. Hãy để trống Trang để lấy mọi trang. + Fill in {name} Điền vào {name} + Filling of form fields Điền các ô biểu mẫu + Flatten Làm phẳng + Flip image Lật hình ảnh + Fonts must map their characters to Unicode so text can be read and copied. Fix the fonts or recreate the PDF. Phông chữ phải ánh xạ ký tự của mình sang Unicode để văn bản có thể được đọc và sao chép. Hãy sửa phông chữ hoặc tạo lại PDF. + Form fields must be in the tag tree (Form tags) to be announced. Tag the form fields. Các ô biểu mẫu phải nằm trong cây thẻ (thẻ biểu mẫu) để được thông báo. Hãy gắn thẻ cho các ô biểu mẫu. + Formulas and similar non-text elements need alternate text. Add alternate text to them. Công thức và các phần tử không phải văn bản tương tự cần có văn bản thay thế. Hãy thêm văn bản thay thế cho chúng. + Gray Xám + Grayscale Images Ảnh xám + Green Xanh lá + Green on black Xanh lá trên nền đen + H / Space (hold) H / Space (giữ) + Header cells (TH) tell listeners what each column or row holds. Mark the header cells. Ô tiêu đề (TH) cho trình đọc biết mỗi cột hoặc hàng chứa gì. Hãy đánh dấu các ô tiêu đề. + Headers Đầu trang + Heading levels shouldn't skip (an H1 followed by an H3). Retag the headings. Cấp đề mục không nên bị bỏ qua (H1 sau đó là H3). Hãy gắn thẻ lại các đề mục. + Headings Đề mục + Hidden layers Các lớp ẩn + Hidden text Văn bản ẩn + Hide a field Ẩn một ô + Hides annotation Ẩn chú thích + High Cao + Home / End Home / End + Horizontally Theo chiều ngang + Image-only PDF PDF chỉ gồm hình ảnh + Import {name} Nhập {name} + Importing data arrives on the web with file pickers for data files Nhập dữ liệu sẽ có trên web kèm bộ chọn tệp cho tệp dữ liệu + Incorrect password. Try again. Mật khẩu không đúng. Hãy thử lại. + Insert pages from {name} Chèn trang từ {name} + Insert pages from {name} — 1 field renamed Chèn trang từ {name} — đã đổi tên 1 ô + Insert pages from {name} — fields renamed Chèn trang từ {name} — đã đổi tên các ô + Inserted Đã chèn + Inset Thu vào trong + Intended usage Mục đích sử dụng + Intersection Giao + Invert Đảo ngược + Irregular tables confuse cell navigation. Give every row the same number of cells (counting spans). Bảng không đều gây khó điều hướng giữa các ô. Hãy cho mỗi hàng cùng số ô (tính cả các ô đã gộp). + Issued by Cấp bởi + Issued to Cấp cho + Issuer Bên cấp + Key usage Mục đích sử dụng khóa + Keywords Từ khóa + LI must be a child of L LI phải là phần tử con của L + Landscape pages Trang ngang + Lbl and LBody Lbl và LBody + Lbl and LBody must be children of LI Lbl và LBody phải là phần tử con của LI + Left Footer Text Văn bản chân trang trái + Left Header Text Văn bản đầu trang trái + Light blue Xanh nhạt + Links, actions and JavaScripts Liên kết, hành động và JavaScript + List Danh sách + List Box Properties Thuộc tính hộp danh sách + List items Mục danh sách + List items belong in a list. Fix the list's tags. Các mục danh sách phải thuộc một danh sách. Hãy sửa lại thẻ của danh sách. + List labels and bodies belong in a list item. Fix the list's tags. Nhãn và phần thân của danh sách phải thuộc một mục danh sách. Hãy sửa lại thẻ của danh sách. + Lists Danh sách + Load document font Tải phông chữ của tài liệu + Local cross-PDF links require the desktop app Liên kết cục bộ giữa các PDF cần có ứng dụng máy tính + Lock comment Khóa bình luận + Logical Reading Order Thứ tự đọc hợp lý + Low Thấp + Make scans searchable, then make them smaller. Làm cho bản quét có thể tìm kiếm, rồi làm cho chúng nhỏ hơn. + Mark all Đánh dấu tất cả + Mark as Confidential Đánh dấu là Mật + Mark differences Đánh dấu khác biệt + Mark figure as decorative Đánh dấu hình là trang trí + Mark for redaction Đánh dấu để loại bỏ nội dung + Mark pages for redaction Đánh dấu trang để loại bỏ nội dung + Match field sizes Khớp kích thước ô + Maximum Tối đa + Measuring tool Công cụ đo + Merged 1 file into {path} Đã hợp nhất 1 tệp vào {path} + Merged {n} files into {path} Đã hợp nhất {n} tệp vào {path} + Merging data files needs the desktop app Hợp nhất tệp dữ liệu cần có ứng dụng máy tính + Metadata Siêu dữ liệu + Midpoint Điểm giữa + Minimum Tối thiểu + Models Mô hình + Mouse Down Nhấn chuột xuống + Mouse Enter Chuột đi vào + Mouse Exit Chuột đi ra + Mouse Up Nhả chuột + Move bookmark Di chuyển dấu trang + Move comment Di chuyển bình luận + Move image Di chuyển hình ảnh + Move page Di chuyển trang + Move pages Di chuyển các trang + Named Destinations Đích đến có tên + Navigation links Liên kết điều hướng + Navigation links are not repetitive Liên kết điều hướng không bị lặp lại + Nested alternate text Văn bản thay thế lồng nhau + New {tool} comments will look like this one Các bình luận {tool} mới sẽ trông giống như bình luận này + No PDFs, images or text files found in {folder} Không tìm thấy PDF, hình ảnh hoặc tệp văn bản nào trong {folder} + No form fields were detected Không phát hiện ô biểu mẫu nào + No inaccessible scripts Không có script không thể truy cập + No links to remove Không có liên kết nào để gỡ bỏ + No pages match those choices Không có trang nào khớp với những lựa chọn đó + No unlinked web addresses were found in the text Không tìm thấy địa chỉ web chưa liên kết nào trong văn bản + None of those files can be made into a PDF; use PDFs, images or .txt files Không tệp nào trong số đó có thể tạo thành PDF; hãy dùng PDF, hình ảnh hoặc tệp .txt + Note Ghi chú + Number every page in the footer. Đánh số mọi trang trong chân trang. + Odd pages Trang lẻ + On Blur Khi mất tiêu điểm + On Focus Khi nhận tiêu điểm + On the web, open or drop an image to convert it Trên web, hãy mở hoặc thả một hình ảnh để chuyển đổi + Open a web link Mở một liên kết web + Opened with Được mở bằng + Opening the browser's print dialog… Đang mở hộp thoại in của trình duyệt… + Optimization cancelled Đã hủy tối ưu + Optimization is already running Tối ưu đang chạy + Optimize Scanned Documents Tối ưu tài liệu đã quét + Options Tùy chọn + Orange Cam + Other elements alternate text Văn bản thay thế cho phần tử khác + Other elements that require alternate text Phần tử khác cần văn bản thay thế + Outline Đề mục + PDF producer Trình tạo PDF + PDF version Phiên bản PDF + Page Content Nội dung trang + Page Range Phạm vi trang + Page does not require timed responses Trang không yêu cầu phản hồi có thời hạn + Page thumbnails Hình thu nhỏ của trang + Page will not cause screen flicker Trang sẽ không gây nhấp nháy màn hình + Pages that are only pictures of text can't be read aloud or searched. Recognize text (OCR) to add a text layer. Các trang chỉ là hình ảnh của chữ sẽ không thể đọc thành tiếng hoặc tìm kiếm. Hãy nhận dạng văn bản (OCR) để thêm một lớp văn bản. + Pages with links, comments or fields should tab in structure order. The fix sets each page's tab order to Use Document Structure. Các trang có liên kết, bình luận hoặc ô nên đi theo thứ tự cấu trúc khi dùng phím Tab. Cách sửa sẽ đặt thứ tự Tab của từng trang thành Dùng cấu trúc tài liệu. + Passed Đạt + Password protection will be applied when you save Bảo vệ bằng mật khẩu sẽ được áp dụng khi bạn lưu + Path Đường dẫn + PdfCraft is drawing without a graphics processor, so it may be slow. Updating the graphics driver may help. PdfCraft đang vẽ mà không có bộ xử lý đồ họa nên có thể sẽ chậm. Cập nhật trình điều khiển đồ họa có thể hữu ích. + People may need more time to respond. Check that nothing has a time limit. Mọi người có thể cần thêm thời gian để phản hồi. Hãy kiểm tra xem có gì đang giới hạn thời gian không. + Phone Number Số điện thoại + Phone Numbers Số điện thoại + Pictures need alternate text that describes them, or must be marked decorative. Add alternate text to each figure. Hình ảnh cần có văn bản thay thế mô tả chúng, hoặc phải được đánh dấu là trang trí. Hãy thêm văn bản thay thế cho từng hình. + Pink Hồng + Pinned folders need the desktop app Các thư mục đã ghim cần có ứng dụng máy tính + Pinned {folder} to Home Đã ghim {folder} vào Trang chủ + Place saved {what} Vị trí đã lưu {what} + Planned for milestone {m} — open to see what it will include Dự kiến cho cột mốc {m} — mở để xem nó sẽ bao gồm gì + Planned · {m} Dự kiến · {m} + Polygon Đa giác + Polyline Đường gấp khúc + Portable mode is off: {folder} can't be written ({error}). Settings are kept in your user folder instead. Chế độ di động đang tắt: không thể ghi vào {folder} ({error}). Cài đặt được giữ trong thư mục người dùng của bạn. + Portrait pages Trang dọc + Position Vị trí + PostScript XObjects aren't allowed Không cho phép XObject PostScript + Prepare for Distribution Chuẩn bị phát hành + Preparing sheet {done} of {total} for printing… Đang chuẩn bị tờ {done} trên {total} để in… + Preparing {n} sheets for printing… Đang chuẩn bị {n} tờ để in… + Primary language Ngôn ngữ chính + Printing In + Private data of other applications Dữ liệu riêng tư của ứng dụng khác + Public key Khóa công khai + Purple Tím + PushButton PushButton + Radio Radio + Radio Button Properties Thuộc tính nút radio + Re-type Password Nhập lại mật khẩu + Red Đỏ + Redid {label} Đã làm lại {label} + Regularity Đều đặn + Rejected Bị từ chối + Reliable character encoding is provided Có mã hóa ký tự đáng tin cậy + Remove hidden information and flatten comments and form fields, so recipients see only the pages. Loại bỏ thông tin ẩn và làm phẳng bình luận cùng các ô biểu mẫu, để người nhận chỉ thấy các trang. + Remove hidden information, metadata, scripts and embedded content, and rewrite the files. Loại bỏ thông tin ẩn, siêu dữ liệu, script và nội dung nhúng, rồi ghi lại các tệp. + Remove redaction marks Gỡ bỏ dấu đánh dấu loại bỏ nội dung + Remove saved {what} Gỡ bỏ {what} đã lưu + Removed 1 hidden item. Save to remove them from the file. Đã gỡ bỏ 1 mục ẩn. Hãy Lưu để xóa chúng khỏi tệp. + Removed 1 link Đã gỡ bỏ 1 liên kết + Removed {n} hidden items. Save to remove them from the file. Đã gỡ bỏ {n} mục ẩn. Hãy Lưu để xóa chúng khỏi tệp. + Removed {n} links Đã gỡ bỏ {n} liên kết + Rename bookmark Đổi tên dấu trang + Rendering: hayro (bootstrap) · UI: egui · Icons: Lucide (ISC) · Fonts: Inter, JetBrains Mono, Dancing Script (OFL) Kết xuất: hayro (bootstrap) · Giao diện: egui · Biểu tượng: Lucide (ISC) · Phông chữ: Inter, JetBrains Mono, Dancing Script (OFL) + Repairs Sửa chữa + Repeated navigation links should be skippable. Check links that appear on every page. Các liên kết điều hướng lặp lại nên có thể bỏ qua. Hãy kiểm tra các liên kết xuất hiện trên mọi trang. + Replace page Thay trang + Replace pages Thay các trang + Replaced Đã thay thế + Replacing images arrives on the web with image file pickers Thay hình ảnh sẽ có trên web kèm bộ chọn tệp hình ảnh + Replacing images on page {p} arrives on the web with image pickers ({i}) Thay hình ảnh trên trang {p} sẽ có trên web kèm bộ chọn hình ảnh ({i}) + Report Options Tùy chọn báo cáo + Reset a form Đặt lại biểu mẫu + Resize comment Đổi kích thước bình luận + Restrictions Hạn chế + Restrictions lifted Đã gỡ bỏ hạn chế + Reverted to the last saved version Đã hoàn nguyên về phiên bản đã lưu gần nhất + Right Footer Text Văn bản chân trang phải + Right Header Text Văn bản đầu trang phải + Rotate image Xoay hình ảnh + Rotate page Xoay trang + Rotate page {label} clockwise Xoay trang {label} theo chiều kim đồng hồ + Rotate page {label} counterclockwise Xoay trang {label} ngược chiều kim đồng hồ + Rows Các hàng + Run Chạy + Run JavaScript Chạy JavaScript + Run a JavaScript Chạy một JavaScript + Run form script Chạy script của biểu mẫu + SHA-1 digest Giá trị băm SHA-1 + SHA-256 digest Giá trị băm SHA-256 + Sanitize Làm sạch + Sanitize Documents Làm sạch tài liệu + Save as PDF/A-1b Lưu thành PDF/A-1b + Save as PDF/A-2b Lưu thành PDF/A-2b + Save as PDF/A-3b Lưu thành PDF/A-3b + Save image Lưu hình ảnh + Save or revert changes before selecting another tag. Hãy lưu hoặc hoàn nguyên thay đổi trước khi chọn thẻ khác. + Saved the print-ready PDF to {path} Đã lưu PDF sẵn sàng in vào {path} + Saved {name} Đã lưu {name} + Saved {place}: {before} → {after} (not smaller){detail} Đã lưu {place}: {before} → {after} (không nhỏ hơn){detail} + Saved {place}: {before} → {after} ({pct}% smaller){detail} Đã lưu {place}: {before} → {after} (nhỏ hơn {pct}%){detail} + Saved, but reopening failed: {e} Đã lưu, nhưng mở lại không thành công: {e} + Screen flicker Nhấp nháy màn hình + Screen readers choose their voice from the document's language. Set it in Document Properties > Advanced > Language. Trình đọc màn hình chọn giọng đọc theo ngôn ngữ của tài liệu. Hãy đặt trong Thuộc tính tài liệu > Nâng cao > Ngôn ngữ. + Scripted content must be usable with a keyboard and assistive technology. Check the document's scripts. Nội dung có script phải dùng được với bàn phím và công nghệ trợ giúp. Hãy kiểm tra các script của tài liệu. + Scripts Script + Scripts run in a sandbox without file or network access. With JavaScript off, Acrobat's standard format, validate and calculate functions still work. Script chạy trong hộp cát không có quyền truy cập tệp hay mạng. Khi tắt JavaScript, các hàm format, validate và calculate tiêu chuẩn của Acrobat vẫn hoạt động. + Security method Phương thức bảo mật + Security settings must allow assistive technology to read the content ("Enable text access for screen reader devices"). Change the document's security to allow it. Cài đặt bảo mật phải cho phép công nghệ trợ giúp đọc nội dung ("Bật truy cập văn bản cho thiết bị trình đọc màn hình"). Hãy thay đổi bảo mật của tài liệu để cho phép điều đó. + Security will be removed when you save Bảo mật sẽ được gỡ bỏ khi bạn lưu + Self-signed Tự ký + Serial number Số sê-ri + Set alternate text Đặt văn bản thay thế + Set bookmark destination Đặt đích đến dấu trang + Set document title Đặt tiêu đề tài liệu + Set status Accepted Đặt trạng thái Đã chấp nhận + Set status Cancelled Đặt trạng thái Đã hủy + Set status Completed Đặt trạng thái Đã hoàn thành + Set status None Đặt trạng thái Không có + Set status Rejected Đặt trạng thái Bị từ chối + Set status Unmarked Đặt trạng thái Chưa đánh dấu + Set tab order Đặt thứ tự Tab + Set the image of {name} Đặt hình ảnh cho {name} + Shadings Màu tô + Show a field Hiện một ô + Sign with a Digital ID Ký bằng Danh tính kỹ thuật số + Signed and all signatures are valid. Đã ký và mọi chữ ký đều hợp lệ. + Signed and saved to {path} Đã ký và lưu vào {path} + Signer Người ký + Signing time Thời điểm ký + Social Security Number Số an sinh xã hội + Social Security Numbers Số an sinh xã hội + Solid Nét liền + Squiggly Nét gợn sóng + Star Hình sao + Strong Đậm + Structure Info Thông tin cấu trúc + Submit a form Gửi biểu mẫu + TH and TD TH và TD + TH and TD must be children of TR TH và TD phải là phần tử con của TR + TR must be a child of Table, THead, TBody, or TFoot TR phải là phần tử con của Table, THead, TBody hoặc TFoot + Tab order Thứ tự Tab + Tab order is consistent with structure order Thứ tự Tab nhất quán với thứ tự cấu trúc + Table cells belong in a row. Fix the table's tags. Ô bảng phải nằm trong một hàng. Hãy sửa các thẻ của bảng. + Table rows belong directly in a table or its head, body or foot. Fix the table's tags. Hàng bảng phải nằm trực tiếp trong bảng hoặc phần đầu, thân hoặc chân của bảng. Hãy sửa các thẻ của bảng. + Tables Bảng + Tables must contain the same number of columns in each row and rows in each column Mỗi hàng của bảng phải có cùng số cột và mỗi cột phải có cùng số hàng + Tables must have a summary Bảng phải có phần tóm tắt + Tables should have headers Bảng nên có hàng tiêu đề + Tagged PDF PDF có gắn thẻ + Tagged annotations Chú thích có gắn thẻ + Tagged content Nội dung có gắn thẻ + Tagged form fields Ô biểu mẫu có gắn thẻ + Tagged multimedia Nội dung đa phương tiện có gắn thẻ + Tags give the document a logical structure that assistive technology follows. Tag the document (Automatically tag PDF). Các thẻ giúp tài liệu có cấu trúc logic mà công nghệ trợ giúp có thể tuân theo. Hãy gắn thẻ cho tài liệu (Tự động gắn thẻ PDF). + Text Field Properties Thuộc tính ô văn bản + Text language is specified Đã chỉ định ngôn ngữ văn bản + Text must contrast enough with its background for people with low vision. Check the colours by eye or with a contrast tool. Văn bản phải tương phản đủ với nền của nó đối với người khiếm thị. Hãy kiểm tra màu bằng mắt hoặc bằng công cụ đo tương phản. + Text recognition is already running Nhận dạng văn bản đang chạy + Text recognition isn't installed: its models are missing (run `cargo xtask models`, or set PDFCRAFT_MODELS). Nhận dạng văn bản chưa được cài đặt: thiếu mô hình của nó (chạy `cargo xtask models`, hoặc đặt PDFCRAFT_MODELS). + That didn't work: an internal error stopped it ({m}). Không thực hiện được: một lỗi nội bộ đã dừng nó ({m}). + That didn't work: an internal error stopped it ({m}). Your documents are unchanged. Không thực hiện được: một lỗi nội bộ đã dừng nó ({m}). Tài liệu của bạn không thay đổi. + The Keychain's digital IDs couldn't be listed: {e} Không thể liệt kê các định danh số của Keychain: {e} + The Windows store's digital IDs couldn't be listed: {e} Không thể liệt kê các định danh số của kho Windows: {e} + The clipboard has no image or text Bảng nhớ tạm không có hình ảnh hay văn bản + The document changed while you were choosing a file, so nothing was changed. Tài liệu đã thay đổi trong khi bạn đang chọn tệp, nên không có gì được thay đổi. + The document changed while you were editing field properties. Tài liệu đã thay đổi trong khi bạn đang chỉnh sửa thuộc tính ô. + The document has additional actions (/AA) Tài liệu có các hành động bổ sung (/AA) + The document has document-level JavaScript Tài liệu có JavaScript ở cấp tài liệu + The document has no XMP metadata Tài liệu không có siêu dữ liệu XMP + The document is encrypted Tài liệu đã được mã hóa + The document is no longer open. Tài liệu không còn được mở. + The document was closed before it could be saved. Tài liệu đã đóng trước khi có thể lưu. + The document's security settings don't allow filling in form fields Cài đặt bảo mật của tài liệu không cho phép điền vào các ô biểu mẫu + The field properties could not be changed. Không thể thay đổi thuộc tính ô. + The field properties dialog is no longer open. Hộp thoại thuộc tính ô không còn mở. + The form asks to be submitted to {u}; PdfCraft doesn't send form data. Save the document to keep your entries. Biểu mẫu yêu cầu gửi đến {u}; PdfCraft không gửi dữ liệu biểu mẫu. Hãy lưu tài liệu để giữ lại những gì bạn đã nhập. + The form asks viewers to make appearances (NeedAppearances) Biểu mẫu yêu cầu trình xem tạo giao diện hiển thị (NeedAppearances) + The linked PDF opened, but its named destination was not applied. PDF liên kết đã mở, nhưng đích đến theo tên của nó không được áp dụng. + The linked PDF opened, but its page destination was out of range. PDF liên kết đã mở, nhưng đích đến trang của nó nằm ngoài phạm vi. + The operation failed. Thao tác không thành công. + The pages were extracted but not deleted, because the document changed while you were choosing a folder. Các trang đã được trích xuất nhưng không bị xóa, vì tài liệu đã thay đổi trong khi bạn đang chọn thư mục. + The passwords don't match. Mật khẩu không khớp. + The selected area has been copied ({w} × {h} pixels) Vùng đã chọn đã được sao chép ({w} × {h} điểm ảnh) + The selected fields could not be found. Select them again. Không tìm thấy các ô đã chọn. Hãy chọn lại. + The standard fonts can't draw “{c}” ({code}). Only Western European characters can be added as text for now. Các phông chữ tiêu chuẩn không thể vẽ “{c}” ({code}). Hiện chỉ có thể thêm ký tự Tây Âu dưới dạng văn bản. + The title in the metadata and the document information differ Tiêu đề trong siêu dữ liệu và trong thông tin tài liệu khác nhau + The window should show a meaningful title rather than the file name. Set a title and Initial View > Show: Document Title. Cửa sổ nên hiển thị một tiêu đề có ý nghĩa thay vì tên tệp. Hãy đặt tiêu đề rồi chọn Initial View > Show: Document Title. + There are no redaction marks to apply Không có dấu loại bỏ nội dung nào để áp dụng + This PDF uses the unsupported {s} action. PDF này dùng hành động {s} không được hỗ trợ. + This compatibility level supports only plain ASCII passwords. Mức tương thích này chỉ hỗ trợ mật khẩu ASCII thuần. + This document can't be checked: it couldn't be read for editing Không thể kiểm tra tài liệu này: không đọc được để chỉnh sửa + This document has no attachments. Tài liệu này không có tệp đính kèm. + This document has no bookmarks. Tài liệu này không có dấu trang. + This document has no form fields. Tài liệu này không có ô biểu mẫu. + This document has no layers. Tài liệu này không có lớp. + This file is already as small as it can be made ({size}). No copy was saved. Tệp này đã nhỏ đến mức nhỏ nhất có thể ({size}). Không có bản sao nào được lưu. + This form also contains XFA data, which PdfCraft doesn't read yet. You can fill its fields, but Acrobat may show the XFA values instead. Biểu mẫu này cũng chứa dữ liệu XFA, mà PdfCraft chưa đọc được. Bạn có thể điền các ô của nó, nhưng Acrobat có thể hiển thị các giá trị XFA thay thế. + Thumbnails Hình thu nhỏ + Timed responses Câu trả lời có thời gian + Type Password Nhập mật khẩu + Type a password. Nhập mật khẩu. + Typewriter Máy đánh chữ + Unchecked Chưa đánh dấu + Undid {label} Đã hoàn tác {label} + Unlock comment Mở khóa bình luận + Unlocked {n} of {m} files Đã mở khóa {n} trong {m} tệp + Update background Cập nhật nền + Update header & footer Cập nhật đầu trang & chân trang + Update watermark Cập nhật hình mờ + Use {what} Dùng {what} + Valid Hợp lệ + Valid from Hiệu lực từ + Valid to Hiệu lực đến + Validate Xác thực + Validity ends Hiệu lực kết thúc + Validity starts Hiệu lực bắt đầu + Vertically Theo chiều dọc + Video, sound and rich media must be tagged to be announced. Tag the multimedia annotations. Video, âm thanh và nội dung đa phương tiện phải được gắn thẻ để được thông báo. Hãy gắn thẻ cho các chú thích đa phương tiện. + Viewing Xem + Weak Mờ + White on black Trắng trên nền đen + Wrote 1 file to {dir} Đã ghi 1 tệp vào {dir} + Wrote {n} files to {dir} Đã ghi {n} tệp vào {dir} + X Object Forms Biểu mẫu X Object + Yellow Vàng + Yellow on black Vàng trên nền đen + You can pin up to {n} folders. Unpin one first. Bạn có thể ghim tối đa {n} thư mục. Hãy bỏ ghim một thư mục trước. + Your name Tên của bạn + Zip Code Mã bưu chính + Zip Code + 4 Mã bưu chính + 4 + `{command}` {when} `{command}` {when} + a bookmark cannot be moved inside itself không thể di chuyển một dấu trang vào chính nó + a document must keep at least one page tài liệu phải giữ ít nhất một trang + average trung bình + maximum tối đa + minimum tối thiểu + no such document không có tài liệu như vậy + nothing in the file matches this document không có gì trong tệp khớp với tài liệu này + nothing to redo không có gì để làm lại + nothing to undo không có gì để hoàn tác + pages trang + product (x) nhân (x) + sum (+) cộng (+) + the document has no form fields tài liệu không có ô biểu mẫu + the document has no page tree tài liệu không có cây trang + the document has no tags tài liệu không có thẻ + the document is protected by a password tài liệu được bảo vệ bằng mật khẩu + the image is empty hình ảnh rỗng + the password is incorrect mật khẩu không đúng + the text recognition models are not installed (reinstall PdfCraft, or set PDFCRAFT_MODELS to the folder that holds them) mô hình nhận dạng văn bản chưa được cài đặt (cài lại PdfCraft, hoặc đặt PDFCRAFT_MODELS thành thư mục chứa chúng) + the title must not be empty tiêu đề không được để trống + there are no pages to print không có trang nào để in + there are no redaction marks to apply không có dấu loại bỏ nội dung nào để áp dụng + this document is signed: rewriting it would invalidate its signatures (save it incrementally instead) tài liệu này đã được ký: viết lại nó sẽ làm mất hiệu lực của các chữ ký đó (hãy lưu tăng dần thay thế) + this file isn't XFDF, FDF, XML or text form data tệp này không phải dữ liệu biểu mẫu XFDF, FDF, XML hay văn bản + {0}: {1} {0}: {1} + {field}: {e} {field}: {e} + {file} is too large for a stamp (at most {n} MB) {file} quá lớn cho một con dấu (tối đa {n} MB) + {folder} is already pinned to Home {folder} đã được ghim vào Trang chủ + {label} failed: {e} {label} không thành công: {e} + {name} has no action {name} không có hành động nào + {name} is too large for a word list (at most 1 MB). {name} quá lớn cho một danh sách từ (tối đa 1 MB). + {name} submits the form to {url}; PdfCraft doesn't send form data. Save the document to keep your entries. {name} gửi biểu mẫu đến {url}; PdfCraft không gửi dữ liệu biểu mẫu. Hãy lưu tài liệu để giữ lại những gì bạn đã nhập. + {name}: choosing images arrives on the web with file pickers for images {name}: chọn hình ảnh sẽ mở trang web kèm bộ chọn tệp dành cho hình ảnh + {name}: the {other} action isn't supported yet {name}: hành động {other} chưa được hỗ trợ + {who} in this document tried to open an address PdfCraft won't open: {e}. {who} trong tài liệu này đã cố mở một địa chỉ mà PdfCraft sẽ không mở: {e}. + {who} in this document tried to open an address PdfCraft won't open: {e}. Only web (http, https) and email (mailto) links open from documents. {who} trong tài liệu này đã cố mở một địa chỉ mà PdfCraft sẽ không mở: {e}. Chỉ liên kết web (http, https) và email (mailto) mở được từ tài liệu. +animation effects Off Tắt +animation effects On Bật + View more Xem thêm + View less Xem ít hơn + Only continue if you trust this document. An address can carry information from the document, such as what you typed into its form. Chỉ tiếp tục nếu bạn tin tưởng tài liệu này. Một địa chỉ có thể mang theo thông tin từ tài liệu, chẳng hạn những gì bạn đã nhập vào biểu mẫu của nó. + Print single-sided. Keep the sheets in order, cut at the marks, then stack the piles left to right, top to bottom. In một mặt. Giữ đúng thứ tự các tờ, cắt theo vạch, rồi xếp từng chồng từ trái sang phải, từ trên xuống dưới. + Sign a sheet of white paper and take a photo of it in bright, even light (use the flash). Choose the photo or drop it here: PdfCraft finds the signature and removes the paper. Hãy ký một tờ giấy trắng và chụp ảnh nó trong ánh sáng đủ sáng và đều (dùng đèn flash). Chọn bức ảnh hoặc kéo thả vào đây: PdfCraft sẽ tìm chữ ký và gỡ bỏ tờ giấy. + This field's font can't draw “{c}” ({code}), so PdfCraft shows ? in its place. The value is saved, and other PDF viewers redraw the field from it. Phông chữ của ô này không thể vẽ “{c}” ({code}), nên PdfCraft hiển thị ? thay thế. Giá trị vẫn được lưu và các trình xem PDF khác sẽ vẽ lại ô từ giá trị đó. + {chars} can't be written into the PDF yet: Fill & Sign text is Western European only. Pick a numeric format such as dd.mm.yyyy. {chars} chưa thể được ghi vào PDF: văn bản Điền & Ký chỉ dành cho Tây Âu. Hãy chọn một định dạng số như dd.mm.yyyy. + January Tháng Một + February Tháng Hai + March Tháng Ba + April Tháng Tư + May Tháng Năm + June Tháng Sáu + July Tháng Bảy + August Tháng Tám + September Tháng Chín + October Tháng Mười + November Tháng Mười Một + December Tháng Mười Hai +calendar date January tháng Một +calendar date February tháng Hai +calendar date March tháng Ba +calendar date April tháng Tư +calendar date May tháng Năm +calendar date June tháng Sáu +calendar date July tháng Bảy +calendar date August tháng Tám +calendar date September tháng Chín +calendar date October tháng Mười +calendar date November tháng Mười Một +calendar date December tháng Mười Hai +calendar weekday Su CN +calendar weekday Mo T2 +calendar weekday Tu T3 +calendar weekday We T4 +calendar weekday Th T5 +calendar weekday Fr T6 +calendar weekday Sa T7 +signature pad Type Nhập +scroll speed Slow Chậm +scroll speed Normal Bình thường +scroll speed Fast Nhanh +certificate Subject Chủ thể +certificate Issued to Cấp cho +certificate Issued by Cấp bởi +certificate Valid from Hiệu lực từ +certificate Valid to Hiệu lực đến +certificate Intended usage Mục đích sử dụng +certificate Version Phiên bản +certificate Serial number Số sê-ri +certificate Issuer Bên cấp +certificate Validity starts Hiệu lực bắt đầu +certificate Validity ends Hiệu lực kết thúc +certificate Public key Khóa công khai +certificate Basic constraints Ràng buộc cơ bản +certificate Key usage Cách dùng khóa +certificate Self-signed Tự ký +certificate SHA-1 digest Tóm lược SHA-1 +certificate SHA-256 digest Tóm lược SHA-256 + Certificate authority Cơ quan cấp chứng thư + End entity Thực thể cuối + Float panel Bảng nổi + Move to group Di chuyển vào nhóm + Panels Bảng bên + Resize panel window Đổi kích thước cửa sổ bảng bên + Resize panels Đổi kích thước các bảng bên + Grab bag Túi đồ + No contributor data was built into this copy. Bản này không có dữ liệu người đóng góp. + No model credits were built into this copy. Bản này không có thông tin ghi công mô hình. + Reverse the order Đảo thứ tự + Show Hiện + Sort Sắp xếp + Table Bảng + The field {name} no longer exists. Ô {name} không còn tồn tại. + {n} contributors · {c} commits {n} người đóng góp · {c} commit + Username Tên người dùng + Display name Tên hiển thị + Real name Tên thật + Name (A–Z) Tên (A–Z) + Merged PRs PR đã hợp nhất + PRs PR + Commits Commit + Lines added Số dòng đã thêm + +LOC +LOC + Lines deleted Số dòng đã xóa + −LOC −LOC + Line delta Chênh lệch dòng + ΔLOC ΔLOC + Binary assets added Tài nguyên nhị phân đã thêm + +Bin +Bin + Binary assets removed Tài nguyên nhị phân đã gỡ bỏ + −Bin −Bin + First commit Commit đầu tiên + First Đầu tiên + Last commit Commit cuối cùng + Last Cuối cùng + Company Công ty + Model Mô hình + Version Phiên bản + % of all commits % trong tất cả commit + Lines +/− Dòng +/− + @{login}: {prs} PRs, {commits} commits, +{added} / −{deleted} lines (Δ {delta}), +{bin_added} / −{bin_deleted} binary assets, {first} – {last} @{login}: {prs} PR, {commits} commit, +{added} / −{deleted} dòng (Δ {delta}), +{bin_added} / −{bin_deleted} tài nguyên nhị phân, {first} – {last} + of {name} trong {name} + of {pages} trong {pages} + on page {label} trên trang {label} + open to see what it will include mở ra để xem nó sẽ bao gồm những gì + ships in milestone {m} được phát hành trong mốc {m} + signature chữ ký + sorted ascending sắp xếp tăng dần + sorted descending sắp xếp giảm dần + to đến + to {n} đến {n} + watermark hình mờ + yyyy or yy year · m or mm month · mmm or mmmm month name · d or dd day · ddd or dddd weekday. H, h, M, s and t are time letters and can't be used on their own: put {escape} before a letter to show it as is. năm yyyy hoặc yy · tháng m hoặc mm · tên tháng mmm hoặc mmmm · ngày d hoặc dd · thứ ddd hoặc dddd. H, h, M, s và t là chữ cái thời gian và không thể dùng độc lập: hãy đặt {escape} trước chữ cái để hiển thị nguyên văn. + {c} of {n}{more} {c} trên {n}{more} + {dpi} pixels/inch {dpi} điểm ảnh/inch + {kind} Properties Thuộc tính {kind} + {kind} field ô {kind} + {kind} · page {p} {kind} · trang {p} + {kind} — click to show it on the page {kind} — nhấp để hiện nó trên trang + {k} of {n} {k} trên {n} + {label} (1 issue) {label} (1 vấn đề) + {label} ({n} issues) {label} ({n} vấn đề) + {month} {day}, {y} {month} {day}, {y} + {month} {y} {month} {y} + {msg} to {dir} {msg} vào {dir} + {name} (default) {name} (mặc định) + {name} can't be combined: {why} không thể kết hợp {name}: {why} + {name} is read-only {name} chỉ đọc + {name} — unsaved changes {name} — thay đổi chưa lưu + {n} days ago {n} ngày trước + {n} differences found tìm thấy {n} khác biệt + {n} fields selected đã chọn {n} ô + {n} files {n} tệp + {n} files done đã xong {n} tệp + {n} files need attention {n} tệp cần xử lý + {n} h ago {n} giờ trước + {n} instances {n} bản + {n} issues {n} vấn đề + {n} marks {n} dấu + {n} match(es) marked for redaction. đã đánh dấu {n} kết quả khớp để loại bỏ nội dung. + {n} measurements use an unsupported format and are left out. {n} số đo dùng định dạng không được hỗ trợ và bị bỏ qua. + {n} min ago {n} phút trước + {n} pages {n} trang + {n} pages selected. đã chọn {n} trang. + {n} selected đã chọn {n} + {n} tags {n} thẻ + {n} word(s) or phrase(s) {n} từ hoặc cụm từ + {n} {kind} {n} {kind} + {rule} - {status} {rule} - {status} + {s} action hành động {s} + {verb} Background {verb} nền + {verb} Header and Footer {verb} đầu trang và chân trang + {verb} Watermark {verb} hình mờ + {verb} as "{name}" {verb} với tên "{name}" + {who} in this document wants to open this address in your browser: {who} trong tài liệu này muốn mở địa chỉ này trong trình duyệt của bạn: + {who} in this document wants to open your email app with this address: {who} trong tài liệu này muốn mở ứng dụng email của bạn bằng địa chỉ này: + {words} on {pages} {words} trên {pages} + — (protection is applied when you save) — (bảo vệ được áp dụng khi bạn lưu) + “{name}” has security restrictions. Enter its permissions password to lift them. “{name}” có các hạn chế bảo mật. Nhập mật khẩu quyền của nó để gỡ bỏ. + “{name}” is protected. Enter a password to open it. “{name}” đã được bảo vệ. Nhập mật khẩu để mở nó. +@plural {n} page|{n} pages {n} trang +@plural {n} file|{n} files {n} tệp +@plural {n} field|{n} fields {n} ô +@plural {n} comment|{n} comments {n} bình luận +@plural {n} result|{n} results {n} kết quả +@plural {n} field name collides with earlier files and will be renamed: {list}|{n} field names collide with earlier files and will be renamed: {list} {n} tên ô trùng với các tệp trước đó và sẽ được đổi tên: {list} +@plural {n} object selected|{n} objects selected đã chọn {n} đối tượng +@plural Downloaded {n} PDF|Downloaded {n} PDFs Đã tải xuống {n} PDF +key Ctrl Ctrl +key Shift Shift +key Delete Delete +key Esc Esc +key Home Home +key End End +key Space Space diff --git a/crates/ui-egui/src/theme.rs b/crates/ui-egui/src/theme.rs index 9f2bb9009..182b5b670 100644 --- a/crates/ui-egui/src/theme.rs +++ b/crates/ui-egui/src/theme.rs @@ -338,13 +338,14 @@ fn font_definitions_for_platform(prefer_hans: bool, platform: FontPolicyPlatform } } // Arabic-script faces (file names, document titles), Telugu faces (the Telugu interface, - // file names), Hebrew faces (file names, text being edited) and Thai faces after the CJK ones; the - // ranges don't overlap. + // file names), Hebrew faces (file names, text being edited), Thai faces and Devanagari faces + // (the Hindi interface) after the CJK ones; the ranges don't overlap. for face in pdfcraft_fonts::ui_arabic_fonts() .into_iter() .chain(pdfcraft_fonts::ui_telugu_fonts()) .chain(pdfcraft_fonts::ui_hebrew_fonts()) .chain(pdfcraft_fonts::ui_thai_fonts()) + .chain(pdfcraft_fonts::ui_devanagari_fonts()) { let name = face.name(); if !fonts.font_data.contains_key(&name) { diff --git a/crates/ui-egui/tests/fonts.rs b/crates/ui-egui/tests/fonts.rs index 63a31d4cf..369164a20 100644 --- a/crates/ui-egui/tests/fonts.rs +++ b/crates/ui-egui/tests/fonts.rs @@ -8,6 +8,7 @@ const JAPANESE: &str = "日本語の文字"; const CHINESE: &str = "简体中文欢迎"; const ARABIC: &str = "واحد اثنين"; const TELUGU: &str = "తెలుగు ఫైల్"; +const DEVANAGARI: &str = "हिंदी पाठ सम्पादन"; fn families() -> Vec { vec![FontId::proportional(13.0), FontId::monospace(13.0), theme::medium(13.0), theme::semibold(17.0)] @@ -163,7 +164,30 @@ fn system_fallback_covers_devanagari() { assert_eq!(stack.iter().filter(|n| *n == theme::SYSTEM_DEVANAGARI_FALLBACK).count(), 1, "{family:?}"); } let mut fonts = Fonts::new(TextOptions::default(), defs); - const DEVANAGARI: &str = "हिंदी पाठ सम्पादन"; + for id in families() { + assert!(fonts.has_glyphs(&id, DEVANAGARI), "{id:?} lacks {DEVANAGARI}"); + } + assert!(layout_widths(&mut fonts, DEVANAGARI).iter().all(|w| w.is_finite() && *w > 0.0)); +} + +/// Built with craft-fonts, Hindi text renders with real glyphs (no tofu) in every family: a +/// `Deva` face is a fallback after the app's own fonts. Without craft-fonts it is the installed +/// Devanagari fallback's job (see `system_fallback_covers_devanagari`), and the web build has +/// neither. +#[test] +fn devanagari_ui_text_uses_craft_fonts() { + if pdfcraft_fonts::ui_devanagari_fonts().is_empty() { + eprintln!("skipping devanagari_ui_text_uses_craft_fonts: built without craft-fonts (set CRAFT_FONTS_DIR to run it)"); + return; + } + let defs = theme::font_definitions(); + for family in [FontFamily::Proportional, FontFamily::Monospace] { + let stack = &defs.families[&family]; + let first = stack.iter().position(|n| pdfcraft_fonts::ui_devanagari_fonts().iter().any(|f| f.name() == *n)).expect("a Deva face is a fallback"); + let own = stack.iter().position(|n| n == "Inter" || n == "JetBrainsMono").expect("the app's own font"); + assert!(own < first, "{family:?}: {stack:?}"); + } + let mut fonts = Fonts::new(TextOptions::default(), defs); for id in families() { assert!(fonts.has_glyphs(&id, DEVANAGARI), "{id:?} lacks {DEVANAGARI}"); } @@ -264,7 +288,7 @@ fn ui_fonts_work_without_craft_fonts() { theme::install_fonts(&ctx); } -/// Latin- and Cyrillic-script catalogs (Czech, Brazilian Portuguese, German, Spanish, French, Russian, Bulgarian, Hungarian, Ukrainian, Italian, Slovene) are drawn entirely by the app's own faces +/// Latin- and Cyrillic-script catalogs (Czech, Brazilian Portuguese, German, Spanish, French, Russian, Bulgarian, Kazakh, Hungarian, Ukrainian, Italian, Slovene, Lithuanian, Greek, Turkish, Indonesian, Vietnamese) are drawn entirely by the app's own faces /// (Inter, JetBrains Mono): no letter falls through to egui's defaults or a CJK fallback. (egui's /// `has_glyphs` can't answer this: with only the primary face it is also the replacement face.) #[test] @@ -287,8 +311,14 @@ fn primary_ui_fonts_cover_latin_and_cyrillic_catalogs() { ("tr", include_str!("../src/i18n/tr.tsv")), ("sl", include_str!("../src/i18n/sl.tsv")), ("lt", include_str!("../src/i18n/lt.tsv")), + ("id", include_str!("../src/i18n/id.tsv")), + ("vi", include_str!("../src/i18n/vi.tsv")), ] { - let mut text = String::from("áčďéěíňóřšťúůýžÁČĎÉĚÍŇÓŘŠŤÚŮÝŽãõçâêôàÃÕÇÂÊÔÀñÑüÜäÄöÖőűß„“¿¡«»…ґҐєЄіІїЇәғқңөұүһӘҒҚҢӨҰҮҺ"); + // Vietnamese stacks its diacritics: the precomposed letters and the base letters they + // combine with, including `đ` and the tone marks `ạ ả ấ ầ ẩ ẫ ậ ắ ằ ẳ ẵ ặ ế ề ể ễ ệ`. + let mut text = String::from( + "áčďéěíňóřšťúůýžÁČĎÉĚÍŇÓŘŠŤÚŮÝŽãõçâêôàÃÕÇÂÊÔÀñÑüÜäÄöÖőűß„“¿¡«»…ґҐєЄіІїЇәғқңөұүһӘҒҚҢӨҰҮҺđĐạảấầẩẫậắằẳẵặếềểễệọỏốồổỗộớờởỡợụủứừửữựỳỵỷỹ", + ); for line in catalog.lines().filter(|l| !l.starts_with('#')) { if let Some(translation) = line.split('\t').nth(2) { text.extend(translation.chars().filter(|c| !c.is_whitespace())); diff --git a/docs/gaps.md b/docs/gaps.md index 4c235c174..dc98f77d5 100644 --- a/docs/gaps.md +++ b/docs/gaps.md @@ -38,7 +38,7 @@ update the numbers. | 11 | Accessibility: checker only, no tagging tools | feature | 40–70 | [target-app-parity.md](target-app-parity.md) | | 12 | No measured fidelity harness against Acrobat | quality | (in 2) | [target-app-parity.md](target-app-parity.md) | | 13 | Performance budgets and lazy loading of very large files | performance | 25–45 | this file | -| 14 | Arabic not mirrored; no Hindi, Indonesian, Korean, Vietnamese | localization | 30–50 | [localization-parity.md](localization-parity.md) | +| 14 | Arabic not mirrored; no Hindi, Korean | localization | 30–50 | [localization-parity.md](localization-parity.md) | | 15 | Forms: JavaScript object model, actions, submit, XFA depth | feature | 40–75 | [pdf-spec-parity.md](pdf-spec-parity.md) | | 16 | UI precision gaps (multi-select move, rulers, accelerators, windows) | UI/UX | 30–60 | [ui-parity.md](ui-parity.md) | | 17 | Certificate security and other protect gaps | feature, spec | 15–30 | [pdf-spec-parity.md](pdf-spec-parity.md) | @@ -236,14 +236,14 @@ update the numbers. to edit. - **Estimate:** 25–45 h. **Doc:** this file. -### 14. Arabic not mirrored; no Hindi, Indonesian, Korean, Vietnamese +### 14. Arabic not mirrored; no Hindi, Korean - **Missing:** a right-to-left layout (panels, menus, alignment), bidirectional text in the text - layout itself (wrapping, typed text); catalogs for Hindi, Indonesian, Korean and Vietnamese - (Acrobat ships Korean; it ships Arabic in its Middle East edition; it ships none of the other - three). + layout itself (wrapping, typed text); catalogs for Hindi and Korean, each with the script face it + needs (Acrobat ships Korean; it ships Arabic in its Middle East edition; it ships neither Hindi + nor Indonesian nor Vietnamese). Indonesian and Vietnamese ship as of 2026-10-13. - **Evidence:** [localization.md](localization.md) §Arabic; `misc.rtl-ui` planned. -- **Estimate:** 30–50 h (Arabic RTL 20–35, four catalogs 10–15 plus review). **Doc:** +- **Estimate:** 30–50 h (Arabic RTL 20–35, two catalogs 10–15 plus review). **Doc:** [localization-parity.md](localization-parity.md). ### 15. Forms: JavaScript object model, actions, submit, XFA depth diff --git a/docs/localization-parity.md b/docs/localization-parity.md index ccd5f88b9..7bc2d7807 100644 --- a/docs/localization-parity.md +++ b/docs/localization-parity.md @@ -1,6 +1,6 @@ # Localization parity -> **Last reviewed:** 2026-10-10 · **Last updated:** 2026-10-12 · **Change:** minor (list all registered interface languages; preserve the original coverage snapshot) · **Target:** Adobe Acrobat Pro (Acrobat DC, continuous track 26.002.21931, macOS) +> **Last reviewed:** 2026-10-10 · **Last updated:** 2026-10-13 · **Change:** minor (Indonesian and Vietnamese ship as full 2,578-key catalogs; the key union is now 2,578; the localization dimension re-measures at ≈ 76%) · **Target:** Adobe Acrobat Pro (Acrobat DC, continuous track 26.002.21931, macOS) Per-language status of PdfCraft's interface against Acrobat Pro's. How translations work and how to add a language: [localization.md](localization.md). Summary in [ROADMAP.md](../ROADMAP.md). @@ -9,8 +9,11 @@ add a language: [localization.md](localization.md). Summary in [ROADMAP.md](../R - **Strings translated** is measured: the catalogs in `crates/ui-egui/src/i18n/.tsv`, counted as distinct `(context, English)` keys with a non-empty translation. The denominator is the union - of keys across all catalogs, **2,143**. Cross-check: of the 1,151 distinct `tl!("…")` literals in - `crates/ui-egui/src`, every full catalog covers 96.5–99.4% (7 literals are in no catalog yet). + of keys across all catalogs, **2,578** (it was 2,143 until the Lithuanian catalog arrived; the + percentages in the table below for the languages measured on 2026-10-10 are that older + snapshot's). Cross-check: of the `tl!("…")` literals in `crates/ui-egui/src`, Indonesian and + Vietnamese translate every one of them (required by `indonesian_and_vietnamese_cover_ui_literals`), + and two literals are in no catalog yet. English is built in. - **Not counted:** error details from the engine and the operating system, which are shown in English inside a translated frame; there is no translated user documentation or help yet (Acrobat @@ -34,16 +37,17 @@ add a language: [localization.md](localization.md). Summary in [ROADMAP.md](../R | Arabic | `ar` | 2,143 (100%) | dialogs and tooltips; no help | Letters joined and lines reordered at load, but **layout not mirrored**, wrapped lines break at the wrong end, typed text runs left to right (`localization.md` §Arabic) | no | partial | yes (Middle East edition) | 25–45 | | French | `fr` | 2,128 (99.3%) | dialogs and tooltips; no help | Latin | no | partial | yes | 1–2 | | Portuguese (Brazil) | `pt-br` | 2,130 (99.4%) | dialogs and tooltips; no help | Latin | community (#288) | partial | yes | 1–2 | -| Indonesian | `id` | 0 | none | Latin | no | none | no | 3–5 | +| Indonesian | `id` | 2,578 (100%) | dialogs and tooltips through `tl!`; no help | Latin, drawn by the bundled Inter and JetBrains Mono (tested in `crates/ui-egui/tests/fonts.rs`) | no | partial | no | 1–2 | | Japanese | `ja` | 2,123 (99.1%) | dialogs and tooltips; no help | BIZ UDPGothic from craft-fonts; IME patched on macOS, Windows, X11, Wayland; vertical text renders but can't be edited | no | partial | yes | 4–8 | | German | `de` | 2,128 (99.3%) | dialogs and tooltips; no help | Latin | community, in progress (#828: terminology, clipping) | partial | yes | 2–4 | | Korean | `ko` | 0 | none | Hangul IME patched (Microsoft and Apple Korean, `vendor/README.md` winit 3, 6, 9, 10); no Hangul UI face in craft-fonts | no | none | yes | 6–10 | -| Vietnamese | `vi` | 0 | none | Latin with stacked diacritics; bundled Inter covers them (not tested) | no | none | no | 3–5 | +| Vietnamese | `vi` | 2,578 (100%) | dialogs and tooltips through `tl!`; no help | Latin with stacked diacritics; the bundled Inter covers them, tested in `crates/ui-egui/tests/fonts.rs` | no | partial | no | 1–2 | -**Localization dimension ≈ 59%**: the mean over the twelve, counting a catalog's percentage but only -60% for Chinese and Arabic until their script problems are fixed, and 0 for the four missing -languages. **≈ 60–115 h** to bring all twelve to `full`, of which ≈ 35–60 h is engineering (Hans -face, RTL layout, bidi text) and the rest catalogs and fixes; native-speaker review needs humans. +**Localization dimension ≈ 76%**: the mean over the twelve, counting a catalog's percentage but only +60% for Chinese and Arabic until their script problems are fixed, and 0 for the two languages still +missing (Hindi, Korean). **≈ 55–90 h** to bring all twelve to `full`, of which ≈ 35–60 h is +engineering (Hans face, RTL layout, bidi text) and the rest the two remaining catalogs and fixes; +native-speaker review needs humans. No language is `full` except English: every catalog leaves engine error details in English, and none has translated help. @@ -67,7 +71,7 @@ none has translated help. | Turkish | `tr` | 2,313 entries | partial | yes | | Lithuanian | `lt` | 2,578 entries | partial; community native-speaker review ([#1401](https://github.com/storytold/pdfcraft/pull/1401)) | no | -**14 other languages** ship (21 catalogs plus English, 22 interface languages in Preferences). +**14 other languages** ship (23 catalogs plus English, 24 interface languages in Preferences). The entry counts without percentages were measured on 2026-10-12; they are not percentages of the older 2,143-key snapshot above. Their presence does not imply a detailed linguistic or runtime review. Acrobat languages PdfCraft lacks: Danish, Dutch, Finnish, Norwegian, Swedish, Hebrew. @@ -75,5 +79,6 @@ Acrobat languages PdfCraft lacks: Danish, Dutch, Finnish, Norwegian, Swedish, He | Date | Change | Summary | |---|---|---| +| 2026-10-13 | minor | Indonesian and Vietnamese ship as full 2,578-key catalogs with month and weekday names; the key union is 2,578 and the dimension re-measures at ≈ 76% (Hindi and Korean are the two languages still missing) | | 2026-10-12 | minor | Added current counts for Kazakh, Polish, Slovenian, Greek, Turkish and Lithuanian; retained existing language assessments and the original percentage snapshot | | 2026-10-10 | major | Created. Catalog counts measured from `crates/ui-egui/src/i18n/*.tsv` against the 2,143-key union; Acrobat's localizations from its bundle's `.lproj` and Sequences folder names | diff --git a/docs/localization.md b/docs/localization.md index 05240cafb..10c979cb1 100644 --- a/docs/localization.md +++ b/docs/localization.md @@ -1,10 +1,11 @@ # Interface language -Choose **Menu > Edit > Preferences…** (Command-comma on macOS, Ctrl-comma elsewhere) **> Interface language** and select **Auto**, **English**, **日本語**, **简体中文**, **繁體中文**, **Čeština**, **Português (Brasil)**, **Deutsch**, **Español**, **Français**, **Русский**, **Қазақша**, **Български**, **తెలుగు**, **Magyar**, **Українська**, **Italiano**, **العربية**, **Polski**, **Slovenščina**, **Ελληνικά**, **Türkçe** or **Lietuvių**. The change applies immediately and persists between launches. Command ids, document contents and file names are unchanged. +Choose **Menu > Edit > Preferences…** (Command-comma on macOS, Ctrl-comma elsewhere) **> Interface language** and select **Auto**, **English**, **日本語**, **简体中文**, **繁體中文**, **Čeština**, **Português (Brasil)**, **Deutsch**, **Español**, **Français**, **Русский**, **Қазақша**, **Български**, **తెలుగు**, **Magyar**, **Українська**, **Italiano**, **العربية**, **Polski**, **Slovenščina**, **Ελληνικά**, **Türkçe**, **Lietuvių**, **Bahasa Indonesia** or **Tiếng Việt**. The change applies immediately and persists between launches. Command ids, document contents and file names are unchanged. Displayed keyboard shortcuts use the same active interface language. For example, German shows `Strg+K` and `Strg+Umschalt+S` in the toolbar, menus, command palette, tooltips and Keyboard shortcuts dialog; macOS keeps its modifier symbols (`⌘`, `⇧`, `⌃`). Key names have their own `key` catalog context, so the Delete key can read `Entf` while the command remains `Löschen`. A missing key-name entry falls back to the English key name. Actual bindings and machine-facing command ids remain stable. -**Auto** (the default) follows the system language: `LC_ALL`, `LC_MESSAGES` or `LANG`, then the preferred-languages list on macOS. Any Portuguese locale (`pt_BR`, `pt_PT`) uses the Brazilian catalog, any French locale (`fr`, `fr_FR`, `fr_CA`, `fr_BE`) the French one, any German locale (`de`, `de_DE`, `de_AT`, `de_CH`) the German one, and Chinese locales for Taiwan, Hong Kong and Macau (`zh_TW`, `zh_HK`, `zh_MO`, `zh-Hant`) the Traditional Chinese one; other Chinese locales (`zh`, `zh_CN`, `zh_SG`, `zh-Hans`) the Simplified Chinese one. Telugu locales (`te`, `te_IN`) use the Telugu catalog, Bulgarian locales (`bg`, `bg_BG`) the Bulgarian one, and Hungarian locales (`hu`, `hu_HU`) the Hungarian one, and Ukrainian locales (`uk`, `uk_UA`) the Ukrainian one, and Italian locales (`it`, `it_IT`, `it_CH`) the Italian one, and Arabic locales (`ar`, `ar_MA`, `ar_EG`, `ar_SA`, …) the Arabic one, and Turkish locales (`tr`, `tr_TR`) the Turkish one, and Slovenian locales (`sl`, `sl_SI`) the Slovenian one. A system language without a catalog shows English. On Windows, **Auto** uses the Windows display languages, in preference order, when no supported locale is selected by those environment variables. Neutral `C`/`POSIX` locale values (including `C.UTF-8`) inherited from a launcher do not override the Windows display language; explicitly named supported locales such as `fr_FR.UTF-8` still do. The query asks Windows directly (`GetUserPreferredUILanguages`, through the `sys-locale` crate) without starting a process, and is cached for the process. If detection fails or the display language has no catalog, PdfCraft shows English. +**Auto** (the default) follows the system language: `LC_ALL`, `LC_MESSAGES` or `LANG`, then the preferred-languages list on macOS. Any Portuguese locale (`pt_BR`, `pt_PT`) uses the Brazilian catalog, any French locale (`fr`, `fr_FR`, `fr_CA`, `fr_BE`) the French one, any German locale (`de`, `de_DE`, `de_AT`, `de_CH`) the German one, and Chinese locales for Taiwan, Hong Kong and Macau (`zh_TW`, `zh_HK`, `zh_MO`, `zh-Hant`) the Traditional Chinese one; other Chinese locales (`zh`, `zh_CN`, `zh_SG`, `zh-Hans`) the Simplified Chinese one. Telugu locales (`te`, `te_IN`) use the Telugu catalog, Bulgarian locales (`bg`, `bg_BG`) the Bulgarian one, and Hungarian locales (`hu`, `hu_HU`) the Hungarian one, and Ukrainian locales (`uk`, `uk_UA`) the Ukrainian one, and Italian locales (`it`, `it_IT`, `it_CH`) the Italian one, and Arabic locales (`ar`, `ar_MA`, `ar_EG`, `ar_SA`, …) the Arabic one, and Turkish locales (`tr`, `tr_TR`) the Turkish one, and Indonesian locales (`id`, `id_ID`) the Indonesian one, and Vietnamese locales (`vi`, `vi_VN`) the Vietnamese one. A system language without a catalog shows English. On Windows, **Auto** uses the Windows display languages, in preference order, when no supported locale is selected by those environment variables. Neutral `C`/`POSIX` locale values (including `C.UTF-8`) inherited from a launcher do not override the Windows display language; explicitly named supported locales such as `fr_FR.UTF-8` still do. The query asks Windows directly (`GetUserPreferredUILanguages`, through the `sys-locale` crate) without starting a process, and is cached for the process. If detection fails or the display language has no catalog, PdfCraft shows English. +**Auto** (the default) follows the system language: `LC_ALL`, `LC_MESSAGES` or `LANG`, then the preferred-languages list on macOS. Any Portuguese locale (`pt_BR`, `pt_PT`) uses the Brazilian catalog, any French locale (`fr`, `fr_FR`, `fr_CA`, `fr_BE`) the French one, any German locale (`de`, `de_DE`, `de_AT`, `de_CH`) the German one, and Chinese locales for Taiwan, Hong Kong and Macau (`zh_TW`, `zh_HK`, `zh_MO`, `zh-Hant`) the Traditional Chinese one; other Chinese locales (`zh`, `zh_CN`, `zh_SG`, `zh-Hans`) the Simplified Chinese one. Telugu locales (`te`, `te_IN`) use the Telugu catalog, Bulgarian locales (`bg`, `bg_BG`) the Bulgarian one, and Hungarian locales (`hu`, `hu_HU`) the Hungarian one, and Ukrainian locales (`uk`, `uk_UA`) the Ukrainian one, and Italian locales (`it`, `it_IT`, `it_CH`) the Italian one, and Arabic locales (`ar`, `ar_MA`, `ar_EG`, `ar_SA`, …) the Arabic one, and Slovenian locales (`sl`, `sl_SI`) the Slovenian one, and Indonesian locales (`id`, `id_ID`) the Indonesian one, and Vietnamese locales (`vi`, `vi_VN`) the Vietnamese one. A system language without a catalog shows English. On Windows, **Auto** uses the Windows display languages, in preference order, when no supported locale is selected by those environment variables. Neutral `C`/`POSIX` locale values (including `C.UTF-8`) inherited from a launcher do not override the Windows display language; explicitly named supported locales such as `fr_FR.UTF-8` still do. The query asks Windows directly (`GetUserPreferredUILanguages`, through the `sys-locale` crate) without starting a process, and is cached for the process. If detection fails or the display language has no catalog, PdfCraft shows English. The control channel exposes the setting through `ui.set`: @@ -12,10 +13,10 @@ The control channel exposes the setting through `ui.set`: {"method":"ui.set","params":{"key":"language","value":"ja"}} ``` -The value is `auto` or a language code (`en`, `ja`, `zh-hans`, `zh-hant`, `cs`, `pt-br`, `de`, `es`, `fr`, `ru`, `kk`, `bg`, `te`, `hu`, `uk`, `it`, `ar`, `pl`, `sl`, `el`, `tr`, `lt`), in any case. `ui.state` reports `language` as written in the preferences (`auto`, `en`, `ja`, `zh-hans`, `zh-hant`, `cs`, `pt-br`, `de`, `es`, `fr`, `ru`, `kk`, `bg`, `te`, `hu`, `uk`, `it`, `ar`, `pl`, `sl`, `el`, `tr` or `lt`). Unknown values return an error without changing the current setting. Preferences saved before this setting existed follow the system language. +The value is `auto` or a language code (`en`, `ja`, `zh-hans`, `zh-hant`, `cs`, `pt-br`, `de`, `es`, `fr`, `ru`, `kk`, `bg`, `te`, `hu`, `uk`, `it`, `ar`, `pl`, `sl`, `el`, `tr`, `lt`, `id`, `vi`), in any case. `ui.state` reports `language` as written in the preferences (`auto`, `en`, `ja`, `zh-hans`, `zh-hant`, `cs`, `pt-br`, `de`, `es`, `fr`, `ru`, `kk`, `bg`, `te`, `hu`, `uk`, `it`, `ar`, `pl`, `sl`, `el`, `tr`, `lt`, `id` or `vi`). Unknown values return an error without changing the current setting. Preferences saved before this setting existed follow the system language. -Dialogs, panels, menus, notices and history labels go through the catalog (`tl!`). Japanese, Traditional Chinese, Simplified Chinese, Russian, Bulgarian, German, Spanish, French, Telugu, Hungarian, Ukrainian, Italian, Brazilian Portuguese and Arabic translate them (about 2,000–2,140 entries each); Czech and Turkish cover the menus so far. Untranslated labels use English. Error details that come from the engine or the operating system are shown as they are, inside a translated frame ("操作「…」に失敗しました: …"). The command palette matches the translated label, the English label and the command id. Vertical Japanese PDF rendering is an existing viewer feature; this change does not add vertical text editing. Per-language coverage, script support and what each language still needs are in [localization-parity.md](localization-parity.md). -Dialogs, panels, menus, notices and history labels go through the catalog (`tl!`). Japanese, Traditional Chinese, Simplified Chinese, Russian, Bulgarian, German, Spanish, French, Telugu, Hungarian, Ukrainian, Italian, Brazilian Portuguese, Arabic and Slovenian translate them (about 2,000–2,190 entries each); Czech covers the menus so far. Untranslated labels use English. Error details that come from the engine or the operating system are shown as they are, inside a translated frame ("操作「…」に失敗しました: …"). The command palette matches the translated label, the English label and the command id. Vertical Japanese PDF rendering is an existing viewer feature; this change does not add vertical text editing. Per-language coverage, script support and what each language still needs are in [localization-parity.md](localization-parity.md). +Dialogs, panels, menus, notices and history labels go through the catalog (`tl!`). Japanese, Traditional Chinese, Simplified Chinese, Russian, Bulgarian, German, Spanish, French, Telugu, Hungarian, Ukrainian, Italian, Brazilian Portuguese and Arabic translate them (about 2,000–2,140 entries each); Czech and Turkish cover the menus so far. Indonesian and Vietnamese translate every key in the union (2,578 entries each, including every registered command, All tools label and `tl!` literal). Untranslated labels use English. Error details that come from the engine or the operating system are shown as they are, inside a translated frame ("操作「…」に失敗しました: …"). The command palette matches the translated label, the English label and the command id. Vertical Japanese PDF rendering is an existing viewer feature; this change does not add vertical text editing. Per-language coverage, script support and what each language still needs are in [localization-parity.md](localization-parity.md). +Dialogs, panels, menus, notices and history labels go through the catalog (`tl!`). Japanese, Traditional Chinese, Simplified Chinese, Russian, Bulgarian, German, Spanish, French, Telugu, Hungarian, Ukrainian, Italian, Brazilian Portuguese, Arabic and Slovenian translate them (about 2,000–2,190 entries each); Czech covers the menus so far. Indonesian and Vietnamese translate every key in the union (2,578 entries each). Untranslated labels use English. Error details that come from the engine or the operating system are shown as they are, inside a translated frame ("操作「…」に失敗しました: …"). The command palette matches the translated label, the English label and the command id. Vertical Japanese PDF rendering is an existing viewer feature; this change does not add vertical text editing. Per-language coverage, script support and what each language still needs are in [localization-parity.md](localization-parity.md). Whole sentences that the layers below word — what the accessibility checker found, what the PDF/A verifier reports, what a signature's details say, what is wrong with the pages to print, what an edit is called in the history — are translated too, because those layers hand the sentence over apart from the document's own words. See [Sentences the engine words](#sentences-the-engine-words). @@ -23,11 +24,13 @@ The Ukrainian catalog has 2,047 entries, written from the meaning of the English The Lithuanian catalog has 2,578 entries and three integer plural forms. Calendar headings use standalone month names; dates use genitive forms. Coverage tests check commands/tools, scanned literal and direct lookups, and source/context keys in the other bundled catalogs. Calendar, inspector and password-dialog UI regressions check dynamic labels and preserve document values. A native Lithuanian-speaking contributor has reviewed the translation. +The Indonesian and Vietnamese catalogs have 2,578 entries each: every `(context, English)` key the union of the bundled catalogs holds, written from the meaning of the English labels with Indonesian computing vocabulary and standard Vietnamese terms. Neither language inflects nouns for number ([CLDR](https://www.unicode.org/cldr/charts/48/supplemental/language_plural_rules.html) `id` and `vi` have one form, `other`), so their `@plural` entries list a single form that reads the same for every count. Catalog regressions require every registered command, every All tools group, section and item, and every `tl!` literal in both, and the font test requires the bundled Latin faces to cover both catalogs, stacked Vietnamese diacritics included. Month and weekday names for stamps are in the same two languages: Indonesian writes them as they stand, Vietnamese lower-cases `tháng` after a day number (`7 tháng Ba`) and keeps it capitalised standing alone (`Tháng Ba`). + Edit text reads Hebrew lines in typing order and writes them back in drawing order (`crates/edit/src/bidi.rs`); letters the page's own font lacks are drawn with the craft-fonts `Hebr` face (Noto Sans Hebrew) as Type 3 glyphs, and a build without one says so. Hebrew points (niqqud) can't be written yet. The craft-fonts revision pinned for CI and releases has no `Hebr` face yet, so until one is added releases report that error instead of drawing the missing letters. -Japanese interface text uses BIZ UDPGothic from [craft-fonts](https://github.com/storytold/craft-fonts), an optional build input that every release includes (`CRAFT_FONTS_DIR`; see the README). A build made without it has no Japanese face, so Japanese labels show replacement boxes. Chinese is drawn with the same craft-fonts CJK faces (in Simplified Chinese the `Hans` faces come first, so a line never mixes faces with different baselines), so a character none of them has shows a replacement box (and every Chinese character does in a build without craft-fonts). Russian, Bulgarian, Czech, Brazilian Portuguese, German, Spanish, French, Hungarian, Italian, Turkish and Lithuanian need only the bundled Latin faces (tested in `tests/fonts.rs`). Hungarian uses the same one/other plural rule as English: 1 is singular, and every other count — including 0 — is the other form. After a numeral the noun stays singular (`1 oldal`, `2 oldal`). Telugu is drawn with a craft-fonts `Telu` face (Noto Sans Telugu, kept in the web build too), whose conjuncts egui shapes; a build without one shows Telugu labels as replacement boxes, and the release-pinned craft-fonts input has no Telugu face yet. -Japanese interface text uses BIZ UDPGothic from [craft-fonts](https://github.com/storytold/craft-fonts), an optional build input that every release includes (`CRAFT_FONTS_DIR`; see the README). A build made without it has no Japanese face, so Japanese labels show replacement boxes. Chinese is drawn with the same craft-fonts CJK faces (in Simplified Chinese the `Hans` faces come first, so a line never mixes faces with different baselines), so a character none of them has shows a replacement box (and every Chinese character does in a build without craft-fonts). Russian, Bulgarian, Czech, Brazilian Portuguese, German, Spanish, French, Hungarian, Italian and Slovenian need only the bundled Latin faces (tested in `tests/fonts.rs`). Slovenian has four plural forms: one (1, 101, 201…), two (2, 102…), few (3, 4, 103…) and other (everything else, including 0, 5–20 and 21+), so `@plural` entries list four forms (`1 stran`, `2 strani`, `3 strani`, `5 strani`). Hungarian uses the same one/other plural rule as English: 1 is singular, and every other count — including 0 — is the other form. After a numeral the noun stays singular (`1 oldal`, `2 oldal`). Telugu is drawn with a craft-fonts `Telu` face (Noto Sans Telugu, kept in the web build too), whose conjuncts egui shapes; a build without one shows Telugu labels as replacement boxes, and the release-pinned craft-fonts input has no Telugu face yet. -Japanese interface text uses BIZ UDPGothic from [craft-fonts](https://github.com/storytold/craft-fonts), an optional build input that every release includes (`CRAFT_FONTS_DIR`; see the README). A build made without it has no Japanese face, so Japanese labels show replacement boxes. Chinese is drawn with the same craft-fonts CJK faces (in Simplified Chinese the `Hans` faces come first, so a line never mixes faces with different baselines), so a character none of them has shows a replacement box (and every Chinese character does in a build without craft-fonts). Until craft-fonts has an allowed `Hans` face, the desktop app draws a Chinese interface with a Chinese face already installed on the machine (Microsoft YaHei or JhengHei on Windows, PingFang, Hiragino Sans GB or STHeiti on macOS, WenQuanYi or Droid Sans Fallback on Linux; never Noto CJK or Source Han), placed before the Japanese faces so a line keeps one face (#826). The web build has no installed fonts to fall back on. Russian, Bulgarian, Czech, Brazilian Portuguese, German, Spanish, French, Hungarian and Italian need only the bundled Latin faces (tested in `tests/fonts.rs`). Hungarian uses the same one/other plural rule as English: 1 is singular, and every other count — including 0 — is the other form. After a numeral the noun stays singular (`1 oldal`, `2 oldal`). Telugu is drawn with a craft-fonts `Telu` face (Noto Sans Telugu, kept in the web build too), whose conjuncts egui shapes; a build without one shows Telugu labels as replacement boxes, and the release-pinned craft-fonts input has no Telugu face yet. +Japanese interface text uses BIZ UDPGothic from [craft-fonts](https://github.com/storytold/craft-fonts), an optional build input that every release includes (`CRAFT_FONTS_DIR`; see the README). A build made without it has no Japanese face, so Japanese labels show replacement boxes. Chinese is drawn with the same craft-fonts CJK faces (in Simplified Chinese the `Hans` faces come first, so a line never mixes faces with different baselines), so a character none of them has shows a replacement box (and every Chinese character does in a build without craft-fonts). Russian, Bulgarian, Czech, Brazilian Portuguese, German, Spanish, French, Hungarian, Italian, Turkish, Lithuanian, Indonesian and Vietnamese need only the bundled Latin faces (tested in `tests/fonts.rs`). Hungarian uses the same one/other plural rule as English: 1 is singular, and every other count — including 0 — is the other form. After a numeral the noun stays singular (`1 oldal`, `2 oldal`). Telugu is drawn with a craft-fonts `Telu` face (Noto Sans Telugu, kept in the web build too), whose conjuncts egui shapes; a build without one shows Telugu labels as replacement boxes, and the release-pinned craft-fonts input has no Telugu face yet. +Japanese interface text uses BIZ UDPGothic from [craft-fonts](https://github.com/storytold/craft-fonts), an optional build input that every release includes (`CRAFT_FONTS_DIR`; see the README). A build made without it has no Japanese face, so Japanese labels show replacement boxes. Chinese is drawn with the same craft-fonts CJK faces (in Simplified Chinese the `Hans` faces come first, so a line never mixes faces with different baselines), so a character none of them has shows a replacement box (and every Chinese character does in a build without craft-fonts). Russian, Bulgarian, Czech, Brazilian Portuguese, German, Spanish, French, Hungarian, Italian, Slovenian, Indonesian and Vietnamese need only the bundled Latin faces (tested in `tests/fonts.rs`). Slovenian has four plural forms: one (1, 101, 201…), two (2, 102…), few (3, 4, 103…) and other (everything else, including 0, 5–20 and 21+), so `@plural` entries list four forms (`1 stran`, `2 strani`, `3 strani`, `5 strani`). Hungarian uses the same one/other plural rule as English: 1 is singular, and every other count — including 0 — is the other form. After a numeral the noun stays singular (`1 oldal`, `2 oldal`). Telugu is drawn with a craft-fonts `Telu` face (Noto Sans Telugu, kept in the web build too), whose conjuncts egui shapes; a build without one shows Telugu labels as replacement boxes, and the release-pinned craft-fonts input has no Telugu face yet. +Japanese interface text uses BIZ UDPGothic from [craft-fonts](https://github.com/storytold/craft-fonts), an optional build input that every release includes (`CRAFT_FONTS_DIR`; see the README). A build made without it has no Japanese face, so Japanese labels show replacement boxes. Chinese is drawn with the same craft-fonts CJK faces (in Simplified Chinese the `Hans` faces come first, so a line never mixes faces with different baselines), so a character none of them has shows a replacement box (and every Chinese character does in a build without craft-fonts). Until craft-fonts has an allowed `Hans` face, the desktop app draws a Chinese interface with a Chinese face already installed on the machine (Microsoft YaHei or JhengHei on Windows, PingFang, Hiragino Sans GB or STHeiti on macOS, WenQuanYi or Droid Sans Fallback on Linux; never Noto CJK or Source Han), placed before the Japanese faces so a line keeps one face (#826). The web build has no installed fonts to fall back on. Russian, Bulgarian, Czech, Brazilian Portuguese, German, Spanish, French, Hungarian, Italian, Indonesian and Vietnamese need only the bundled Latin faces (tested in `tests/fonts.rs`). Hungarian uses the same one/other plural rule as English: 1 is singular, and every other count — including 0 — is the other form. After a numeral the noun stays singular (`1 oldal`, `2 oldal`). Telugu is drawn with a craft-fonts `Telu` face (Noto Sans Telugu, kept in the web build too), whose conjuncts egui shapes; a build without one shows Telugu labels as replacement boxes, and the release-pinned craft-fonts input has no Telugu face yet. The Brazilian Portuguese catalog has 2,000 entries: the ~1,826-entry gist André Cardoso posted in [#288](https://github.com/storytold/pdfcraft/issues/288), the labels added since, and a review of the existing wording. Portuguese, like French, treats 0 and 1 as singular (`1 página`, `2 páginas`). diff --git a/docs/roadmap.md b/docs/roadmap.md index fabb5e603..e54c8389f 100644 --- a/docs/roadmap.md +++ b/docs/roadmap.md @@ -116,9 +116,9 @@ total matches the parity estimate. | M13 | Automation (MCP, Action Wizard, CLI) + AI providers | 60–120 | 45% | 25–45 | Done: MCP resources (document info, text, page images); headless tool table (123 tools incl. signing, optimizing, initial view, links, stamps, data exchange, comment review, forms authoring and scripts, redaction, sanitize, print, add content), opt-in MCP server over stdio, CLI `run`/`tools` (closed stdout pipes exit cleanly), UI control channel with drag. Missing: Action Wizard, AI providers
Done since: CLI run and MCP reject missing, empty, repeated and option-valued --root arguments before any tool/script execution or MCP initialization. A single-hyphen directory name remains valid; synthetic CLI regressions preserve a would-be overwritten file. `text_find` also caps the per-page match ranges it materializes at the remaining result limit plus one continuation match. CLI robustness scans visit each directory once through overlapping roots and symlink aliases. | | M12 | Accessibility, compare, measure, search, XFA | 200–380 | 30% | 90–160 | Done: new `a11y` crate with the Accessibility Checker (all 32 rules, report, Fix/Skip/Explain, options dialog and results panel, agent tools). Locatable figure, annotation and form findings highlight their page bounds.
Done since: 2D distance, perimeter and area measurements with persistent viewport calibration, snapping, live information and CSV export; a bounded text-only auto-tag proposal tool; text-only Apply writes marked content, paragraph tags and a parent tree, then opens the Tags panel for review. Missing: mixed-content and field autotag, heading/list/table/figure classification, Order/Content panels, Reading Order tool, compare, geospatial/3D measurement, search index, XFA | | M13 | Automation (MCP, Action Wizard, CLI) + AI providers | 60–120 | 45% | 25–45 | Done: MCP resources (document info, text, page images); headless tool table (123 tools incl. signing, optimizing, initial view, links, stamps, data exchange, comment review, forms authoring and scripts, redaction, sanitize, print, add content), opt-in MCP server over stdio, CLI `run`/`tools` (closed stdout pipes exit cleanly), UI control channel with drag. Missing: Action Wizard, AI providers
Done since: CLI run and MCP reject missing, empty, repeated and option-valued --root arguments before any tool/script execution or MCP initialization. A single-hyphen directory name remains valid; synthetic CLI regressions preserve a would-be overwritten file. `text_find` also caps the per-page match ranges it materializes at the remaining result limit plus one continuation match. | -| M14 | 1.0 polish: performance, localization, installers | 120–250 | 15% | 80–150 | Done: PhotoCraft's translation system (`i18n/`: TSV catalogs, `tl!`, command-id and plural entries, system-language detection, strict catalog tests); every dialog, panel and notice goes through `tl!`. Catalogs of ≈ 2,000–2,140 entries for Japanese, Simplified and Traditional Chinese, Russian, Bulgarian, German, Spanish, French, Telugu, Hungarian, Ukrainian, Italian, Brazilian Portuguese and Arabic (logical-order catalog put into display order; layout not yet mirrored); Czech covers the menus. Signed and notarized macOS builds, signed Windows installers (x64, x86, ARM64), AppImage, deb, rpm, Flatpak and FreeBSD packages. #307 (bounded large-PDF memory): shared resource indexes and parser metadata, lazy inspection, bounded caches; a 9,156-page file inspects in ≈ 1.8 s at ≈ 500 MiB instead of exceeding 10 GiB. Edits let go of the previous working file before writing the next (a 1 GiB file peaks at two copies while editing, not three; gap 13). Shortcut display uses localized modifier/key names across menus, toolbar, palette, Help and tooltips (#496). Lithuanian adds a 2,578-entry catalog and date names, reviewed by a native-speaking contributor. Validated candidate (macOS raster probe; Windows runtime unverified): the Windows policy changes only embedded JetBrains Mono; horizontal alpha-edge energy per ink improves 2.78%, 3.87% and 1.59% at 100%, 125% and 150%, and is down 0.79% at 200%. Inter is pixel-identical; layout hashes, glyph coverage and the 8 MiB atlas are unchanged. Timing and RSS ranges overlap, with no improvement claimed. Estimates unchanged. Missing: a right-to-left layout, a Chinese UI face in releases, Hindi/Indonesian/Korean/Vietnamese, file-backed input and global memory budgets, performance budgets, keyboard-only operation | +| M14 | 1.0 polish: performance, localization, installers | 120–250 | 15% | 80–150 | Done: PhotoCraft's translation system (`i18n/`: TSV catalogs, `tl!`, command-id and plural entries, system-language detection, strict catalog tests); every dialog, panel and notice goes through `tl!`. Catalogs of ≈ 2,000–2,140 entries for Japanese, Simplified and Traditional Chinese, Russian, Bulgarian, German, Spanish, French, Telugu, Hungarian, Ukrainian, Italian, Brazilian Portuguese and Arabic (logical-order catalog put into display order; layout not yet mirrored); Czech covers the menus. Indonesian and Vietnamese add full 2,578-key catalogs (2026-10-13). Signed and notarized macOS builds, signed Windows installers (x64, x86, ARM64), AppImage, deb, rpm, Flatpak and FreeBSD packages. #307 (bounded large-PDF memory): shared resource indexes and parser metadata, lazy inspection, bounded caches; a 9,156-page file inspects in ≈ 1.8 s at ≈ 500 MiB instead of exceeding 10 GiB. Edits let go of the previous working file before writing the next (a 1 GiB file peaks at two copies while editing, not three; gap 13). Shortcut display uses localized modifier/key names across menus, toolbar, palette, Help and tooltips (#496). Lithuanian adds a 2,578-entry catalog and date names, reviewed by a native-speaking contributor. Validated candidate (macOS raster probe; Windows runtime unverified): the Windows policy changes only embedded JetBrains Mono; horizontal alpha-edge energy per ink improves 2.78%, 3.87% and 1.59% at 100%, 125% and 150%, and is down 0.79% at 200%. Inter is pixel-identical; layout hashes, glyph coverage and the 8 MiB atlas are unchanged. Timing and RSS ranges overlap, with no improvement claimed. Estimates unchanged. Missing: a right-to-left layout, a Chinese UI face in releases, Hindi/Korean catalogs and their Devanagari and Hangul faces, file-backed input and global memory budgets, performance budgets, keyboard-only operation | | M13 | Automation (MCP, Action Wizard, CLI) + AI providers | 60–120 | 45% | 25–45 | Done: MCP resources (document info, text, page images); headless tool table (123 tools incl. signing, optimizing, initial view, links, stamps, data exchange, comment review, forms authoring and scripts, redaction, sanitize, print, add content), opt-in MCP server over stdio, CLI `run`/`tools` (closed stdout pipes exit cleanly), UI control channel with drag. Missing: Action Wizard, AI providers | -| M14 | 1.0 polish: performance, localization, installers | 120–250 | 15% | 80–150 | Done: PhotoCraft's translation system (`i18n/`: TSV catalogs, `tl!`, command-id and plural entries, system-language detection, strict catalog tests); every dialog, panel and notice goes through `tl!`. Catalogs of ≈ 2,000–2,140 entries for Japanese, Simplified and Traditional Chinese, Russian, Bulgarian, German, Spanish, French, Telugu, Hungarian, Ukrainian, Italian, Brazilian Portuguese and Arabic (logical-order catalog put into display order; layout not yet mirrored); Czech covers the menus. Signed and notarized macOS builds, signed Windows installers (x64, x86, ARM64), AppImage, deb, rpm, Flatpak and FreeBSD packages. #307 (bounded large-PDF memory): shared resource indexes and parser metadata, lazy inspection, bounded caches; a 9,156-page file inspects in ≈ 1.8 s at ≈ 500 MiB instead of exceeding 10 GiB. Edits let go of the previous working file before writing the next (a 1 GiB file peaks at two copies while editing, not three; gap 13). Shortcut display uses localized modifier/key names across menus, toolbar, palette, Help and tooltips (#496). Traditional Chinese accessibility statuses, rule semantics and Taiwan form/table terms have catalog regressions. Missing: a right-to-left layout, a Chinese UI face in releases, Hindi/Indonesian/Korean/Vietnamese, file-backed input and global memory budgets, performance budgets, keyboard-only operation | +| M14 | 1.0 polish: performance, localization, installers | 120–250 | 15% | 80–150 | Done: PhotoCraft's translation system (`i18n/`: TSV catalogs, `tl!`, command-id and plural entries, system-language detection, strict catalog tests); every dialog, panel and notice goes through `tl!`. Catalogs of ≈ 2,000–2,140 entries for Japanese, Simplified and Traditional Chinese, Russian, Bulgarian, German, Spanish, French, Telugu, Hungarian, Ukrainian, Italian, Brazilian Portuguese and Arabic (logical-order catalog put into display order; layout not yet mirrored); Czech covers the menus. Indonesian and Vietnamese add full 2,578-key catalogs (2026-10-13). Signed and notarized macOS builds, signed Windows installers (x64, x86, ARM64), AppImage, deb, rpm, Flatpak and FreeBSD packages. #307 (bounded large-PDF memory): shared resource indexes and parser metadata, lazy inspection, bounded caches; a 9,156-page file inspects in ≈ 1.8 s at ≈ 500 MiB instead of exceeding 10 GiB. Edits let go of the previous working file before writing the next (a 1 GiB file peaks at two copies while editing, not three; gap 13). Shortcut display uses localized modifier/key names across menus, toolbar, palette, Help and tooltips (#496). Traditional Chinese accessibility statuses, rule semantics and Taiwan form/table terms have catalog regressions. Missing: a right-to-left layout, a Chinese UI face in releases, Hindi/Korean catalogs and their Devanagari and Hangul faces, file-backed input and global memory budgets, performance budgets, keyboard-only operation | | | **Total** | **2,085–3,840** | **≈ 49% ready** | **≈ 770–1,400** | Area view of the same work: [target-app-parity.md](target-app-parity.md#by-feature-area) | ## Upcoming milestones, ranked diff --git a/docs/target-app-parity.md b/docs/target-app-parity.md index 85d6f5a8b..ef2a10d2e 100644 --- a/docs/target-app-parity.md +++ b/docs/target-app-parity.md @@ -181,7 +181,7 @@ features total and are shown for orientation; the others add to it. | File formats and conversion | ≈ 40% | 12% | 120–220 | within features | PDF read/write strong, encrypted output included (#774 fixed); export Word is layout-poor (#773); no Excel/PowerPoint export, no Office/HTML/PostScript import | [file-format-parity.md](file-format-parity.md) | | PDF specification and standards | ≈ 60% | 8% | 150–260 | within features | ISO 32000 syntax, encryption, annotations and AcroForm strong; rendering and fonts borrowed from `hayro`; PDF 2.0 extras, linearization, public-key security absent; PDF/A partial, PDF/X/UA none | [pdf-spec-parity.md](pdf-spec-parity.md) | | Hardware | ≈ 35% | 4% | 25–50 | additional | Page raster is CPU only (Acrobat has GPU rendering); Windows CNG and macOS Keychain keys sign, no PKCS #11; no scanners; web printing goes through the browser's print dialog as pictures, not vectors | [hardware-parity.md](hardware-parity.md) | -| Localization | ≈ 59% over the 12 key languages | 5% | 35–60 | additional | 15 catalogs, 13 at 94–100%; Chinese UI shows tofu in releases (#826, #688); Arabic not mirrored; no Hindi, Indonesian, Korean, Vietnamese | [localization-parity.md](localization-parity.md) | +| Localization | ≈ 76% over the 12 key languages | 5% | 25–50 | additional | 17 catalogs; Chinese UI shows tofu in releases (#826, #688); Arabic not mirrored; no Hindi or Korean | [localization-parity.md](localization-parity.md) | | Performance | ≈ 40% | 6% | 25–45 | additional | 500-page smooth scrolling and large-file memory work (#307) done; no performance budgets (`misc.performance-budgets`), no lazy loading of GB files; blurry text at 1080p/1440p (#730) | [gaps.md](gaps.md) | | Stability | ≈ 50% | 8% | 45–80 | additional | Never-crash rules and nightly fuzzing; 245 open issues on 2026-10-10, many of them `fix(...)` reports of wrong results in shipped features (the #799–#821 batch is fixed) | [gaps.md](gaps.md) | | Platforms | ≈ 70% | 5% | 15–30 | additional | macOS (signed, notarized), Windows x64/x86/ARM64 (signed), Linux (AppImage, deb, rpm, Flatpak), FreeBSD, web (WASM). Acrobat has no Linux, FreeBSD or full web editor; we lack web OCR and web recovery | [hardware-parity.md](hardware-parity.md) | From 644348dd0ff0bee4dc1590176931bcc876889f45 Mon Sep 17 00:00:00 2001 From: sanches Date: Tue, 13 Oct 2026 04:20:39 +0300 Subject: [PATCH 014/498] i18n: add Hindi and Korean interfaces Two complete catalogs, hi and ko, 2,578 entries each (every (context, English) key the bundled catalogs hold), registered in LANGUAGES (24 -> 26) and in the date languages (hi, ko). Both use a single @plural form. Korean has no Hangul face in craft-fonts, so desktop builds draw it with one installed face (Malgun Gothic, Apple SD Gothic Neo, Nanum; never Noto CJK / Source Han), added after the embedded faces like the Devanagari fallback. PDFCRAFT_SYSTEM_FONTS=0 turns it off. Tests: catalog registration and persistence, command / All tools / tl!() literal coverage for both, date names, Hangul fallback and candidate list. cargo xtask assets, fmt and clippy are clean. Also refreshes the ru.tsv SHA-256 in ATTRIBUTION.toml and the docs. Co-Authored-By: Claude Sonnet 5.5 --- ATTRIBUTION.md | 7 +- ATTRIBUTION.toml | 76 +- ROADMAP.md | 4 +- crates/engine/src/dates.rs | 38 +- crates/ui-egui/src/i18n/hi.tsv | 2582 ++++++++++++++++++++++++++++ crates/ui-egui/src/i18n/ko.tsv | 2582 ++++++++++++++++++++++++++++ crates/ui-egui/src/i18n/mod.rs | 125 +- crates/ui-egui/src/system_fonts.rs | 112 +- crates/ui-egui/src/theme.rs | 26 +- crates/ui-egui/tests/fonts.rs | 25 +- docs/gaps.md | 13 +- docs/localization-parity.md | 22 +- docs/localization.md | 10 +- docs/target-app-parity.md | 2 +- 14 files changed, 5494 insertions(+), 130 deletions(-) create mode 100644 crates/ui-egui/src/i18n/hi.tsv create mode 100644 crates/ui-egui/src/i18n/ko.tsv diff --git a/ATTRIBUTION.md b/ATTRIBUTION.md index be77e718b..e0d0ede28 100644 --- a/ATTRIBUTION.md +++ b/ATTRIBUTION.md @@ -4,7 +4,7 @@ Every asset PdfCraft includes, bundles or uses to build its published material, with its author, source and licence. The policy is in [AGENTS.md](AGENTS.md) §1. The machine-readable list, with SHA-256 hashes, is [ATTRIBUTION.toml](ATTRIBUTION.toml). Licence texts are kept beside the assets and summarised in [NOTICE](NOTICE). -## In this repository (270) +## In this repository (273) | Asset | Title | Author | Licence | Source | Used for | |---|---|---|---|---|---| @@ -28,6 +28,10 @@ Every asset PdfCraft includes, bundles or uses to build its published material, | `crates/ui-egui/src/i18n/ar.tsv` | Arabic interface translation catalog | PdfCraft contributors | MIT OR Apache-2.0 | Contributor-original: clean-room translations of PdfCraft's English UI labels, no proprietary localisation resources | Arabic UI strings, compiled in by crates/ui-egui/src/i18n/mod.rs | | `crates/ui-egui/src/i18n/tr.tsv` | Turkish interface translation catalog | PdfCraft contributors | MIT OR Apache-2.0 | Contributor-original: clean-room translations of PdfCraft's English UI labels, no proprietary localisation resources | Turkish UI strings, compiled in by crates/ui-egui/src/i18n/mod.rs | | `crates/ui-egui/src/i18n/lt.tsv` | Lithuanian interface translation catalog | PdfCraft contributors | MIT OR Apache-2.0 | Contributor-original: clean-room translations of PdfCraft's English UI labels and user-facing messages; reviewed by a native Lithuanian-speaking contributor | Lithuanian UI strings, compiled in by crates/ui-egui/src/i18n/mod.rs | +| `crates/ui-egui/src/i18n/id.tsv` | Indonesian interface translation catalog | PdfCraft contributors | MIT OR Apache-2.0 | Contributor-original: clean-room translations of PdfCraft's English UI labels, no proprietary localisation resources | Indonesian UI strings, compiled in by crates/ui-egui/src/i18n/mod.rs | +| `crates/ui-egui/src/i18n/vi.tsv` | Vietnamese interface translation catalog | PdfCraft contributors | MIT OR Apache-2.0 | Contributor-original: clean-room translations of PdfCraft's English UI labels, no proprietary localisation resources | Vietnamese UI strings, compiled in by crates/ui-egui/src/i18n/mod.rs | +| `crates/ui-egui/src/i18n/hi.tsv` | Hindi interface translation catalog | PdfCraft contributors | MIT OR Apache-2.0 | Contributor-original: clean-room translations of PdfCraft's English UI labels, no proprietary localisation resources | Hindi UI strings, compiled in by crates/ui-egui/src/i18n/mod.rs | +| `crates/ui-egui/src/i18n/ko.tsv` | Korean interface translation catalog | PdfCraft contributors | MIT OR Apache-2.0 | Contributor-original: clean-room translations of PdfCraft's English UI labels, no proprietary localisation resources | Korean UI strings, compiled in by crates/ui-egui/src/i18n/mod.rs | | `assets/icons/accessibility.svg` | Lucide icon "accessibility" | Lucide Contributors (portions Cole Bemis, Feather) | ISC | https://github.com/lucide-icons/lucide (npm lucide-static 1.49.0, icons/accessibility.svg) | UI icon, embedded via crates/ui-egui/src/icon_data.rs | | `assets/icons/align-left.svg` | Lucide icon "align-left" | Lucide Contributors (portions Cole Bemis, Feather) | ISC | https://github.com/lucide-icons/lucide (npm lucide-static 1.49.0, icons/align-left.svg) | UI icon, embedded via crates/ui-egui/src/icon_data.rs | | `assets/icons/align-center.svg` | Lucide icon "align-center" | Lucide Contributors (portions Cole Bemis, Feather) | ISC | https://github.com/lucide-icons/lucide (npm lucide-static 1.49.0, icons/align-center.svg) | UI icon, embedded via crates/ui-egui/src/icon_data.rs | @@ -222,7 +226,6 @@ Every asset PdfCraft includes, bundles or uses to build its published material, | `vendor/hayro-interpret/assets/FoxitSerifItalic.pfb` | FoxitSerifItalic (standard-14 substitute font) | Foxit Software Inc. / PDFium Authors | BSD-3-Clause | https://pdfium.googlesource.com/pdfium (via hayro-interpret 0.7.0 assets/) | Renders non-embedded standard-14 fonts (vendored hayro-interpret) | | `vendor/hayro-interpret/assets/FoxitSymbol.pfb` | FoxitSymbol (standard-14 substitute font) | Foxit Software Inc. / PDFium Authors | BSD-3-Clause | https://pdfium.googlesource.com/pdfium (via hayro-interpret 0.7.0 assets/) | Renders non-embedded standard-14 fonts (vendored hayro-interpret) | | `vendor/hayro-interpret/assets/CGATS001Compat-v2-micro.icc` | CGATS001Compat v2 micro ICC profile | Clinton Ingram (saucecontrol/Compact-ICC-Profiles) | CC0-1.0 | https://github.com/saucecontrol/Compact-ICC-Profiles | Default CMYK colour conversion (vendored hayro-interpret) | -| `crates/fonts/src/std14.rs` | Standard-14 font advance widths and encodings (as Rust tables) | Adobe (Core14 AFM metrics, PDF specification encodings); tables generated by the PdfCraft contributors | MIT OR Apache-2.0 | ISO 32000-2 Annex D and the Adobe Core14 AFM metrics. Generated by joining the published WinAnsi, Symbol and ZapfDingbats encodings (code to glyph name) with the per-glyph advance widths, then spot-checked against the specification by hand in the tests of crates/fonts/src/std14.rs. | Advance widths for the fourteen standard fonts, which a PDF may name without embedding. Non-visual data, not a typeface: the item AGENTS.md 1.1 permits, held first-party so generated appearance streams and the renderer agree. | | `docs/brand/artcraft-logo-white.png` | ArtCraft brand: artcraft-logo-white | ArtCraft Team | LicenseRef-Storyteller-Trademark | ArtCraft Team brand assets (provided by the project owner, 2026-10-01; identical copies in storytold/photocraft) | ArtCraft branding next to the community links (About dialog, Help menu, home screen) and in docs. ArtCraft Team trademark, not open source; may be used only unmodified within PdfCraft; forks and modified versions must remove it. | | `docs/brand/artcraft-logo-white.svg` | ArtCraft brand: artcraft-logo-white | ArtCraft Team | LicenseRef-Storyteller-Trademark | ArtCraft Team brand assets (provided by the project owner, 2026-10-01; identical copies in storytold/photocraft) | ArtCraft branding next to the community links (About dialog, Help menu, home screen) and in docs. ArtCraft Team trademark, not open source; may be used only unmodified within PdfCraft; forks and modified versions must remove it. | | `docs/brand/artcraft-logo.png` | ArtCraft brand: artcraft-logo | ArtCraft Team | LicenseRef-Storyteller-Trademark | ArtCraft Team brand assets (provided by the project owner, 2026-10-01; identical copies in storytold/photocraft) | ArtCraft branding next to the community links (About dialog, Help menu, home screen) and in docs. ArtCraft Team trademark, not open source; may be used only unmodified within PdfCraft; forks and modified versions must remove it. | diff --git a/ATTRIBUTION.toml b/ATTRIBUTION.toml index 018b56e1e..3d999b60c 100644 --- a/ATTRIBUTION.toml +++ b/ATTRIBUTION.toml @@ -7,7 +7,7 @@ licence = "MIT OR Apache-2.0" licence_file = "LICENSE-MIT" kind = "translation" usage = "Greek UI strings, compiled in by crates/ui-egui/src/i18n/mod.rs" -sha256 = "d0a69a35403e70b94c3adfef88b41ec719f4f6ab700d351c8f82a78c53b63ef6" +sha256 = "e04ab5246125efae2bad439e62c150fc10649c4b6796b30565615f5bd7509ec6" # ATTRIBUTION.toml: one entry per asset (AGENTS.md §1). The source of truth for provenance and licences. # ATTRIBUTION.md is generated from this file: `cargo xtask assets --write`. Checked by `cargo xtask assets` (part of `xtask ci`). @@ -30,7 +30,7 @@ licence = "MIT OR Apache-2.0" licence_file = "LICENSE-MIT" kind = "translation" usage = "Simplified Chinese UI strings, compiled in by crates/ui-egui/src/i18n/mod.rs" -sha256 = "caa23201b7f25dba9f8dc579771e13435e5e8c72a7efb9770e917a2a33003a39" +sha256 = "7f600eaa47f23fac4f9f0fece1454e59756c8dc57c7c697502cb02ee21410ac0" [[asset]] path = "crates/ui-egui/src/i18n/zh-hant.tsv" @@ -41,7 +41,7 @@ licence = "MIT OR Apache-2.0" licence_file = "LICENSE-MIT" kind = "translation" usage = "Traditional Chinese UI strings, compiled in by crates/ui-egui/src/i18n/mod.rs" -sha256 = "5ead9fccdca17810a3a98de3fa499d8a2469a1ff015c3d0e11880ca629295ea1" +sha256 = "37733adc79d7d32a057811b4dc5eb31251ef8ec91f1dac430253c69faac1c33f" [[asset]] path = "crates/ui-egui/src/i18n/cs.tsv" @@ -52,7 +52,7 @@ licence = "MIT OR Apache-2.0" licence_file = "LICENSE-MIT" kind = "translation" usage = "Czech UI strings, compiled in by crates/ui-egui/src/i18n/mod.rs" -sha256 = "d48f9d68711850cae48af53f7691facee4209f7846e3eb2c064d97dad2ae2426" +sha256 = "285b689b5224a66079738ab39d5a27e5f9ba72e1ab42e148f263b7ea320c4729" [[asset]] path = "crates/ui-egui/src/i18n/pt-br.tsv" @@ -63,7 +63,7 @@ licence = "MIT OR Apache-2.0" licence_file = "LICENSE-MIT" kind = "translation" usage = "Brazilian Portuguese UI strings, compiled in by crates/ui-egui/src/i18n/mod.rs" -sha256 = "6bc2edec99534d0df9b5e4a1c2e18dc32ad84c32e404c74dd437d86119b1d6ea" +sha256 = "e8154a154129ca158396de84d2d432ce1c587477795a6a14985f7834db255744" [[asset]] path = "crates/ui-egui/src/i18n/es.tsv" @@ -74,7 +74,7 @@ licence = "MIT OR Apache-2.0" licence_file = "LICENSE-MIT" kind = "translation" usage = "Spanish UI strings, compiled in by crates/ui-egui/src/i18n/mod.rs" -sha256 = "cb6c04bd36ba6ce0ebc808da2e47b65797e14d59466e93802adec4d4f5056e3b" +sha256 = "50d4e66209e8b56707bcd148d4644eb0ad9f49dfc195287cfbd851ffbe5c3830" [[asset]] path = "crates/ui-egui/src/i18n/fr.tsv" @@ -85,7 +85,7 @@ licence = "MIT OR Apache-2.0" licence_file = "LICENSE-MIT" kind = "translation" usage = "French UI strings, compiled in by crates/ui-egui/src/i18n/mod.rs" -sha256 = "0368944155991c2ea304788418fb326f30e45649539a0cf49539194b026ca104" +sha256 = "13e677d44d5224e60af28fcc89d8f8af552368ca3c11f0a871498c60fefa7ee2" [[asset]] path = "crates/ui-egui/src/i18n/de.tsv" @@ -96,7 +96,7 @@ licence = "MIT OR Apache-2.0" licence_file = "LICENSE-MIT" kind = "translation" usage = "German UI strings, compiled in by crates/ui-egui/src/i18n/mod.rs" -sha256 = "f4969c353f1424c6b9b5b110820c69dc59907590d013221511eae3f86c29024e" +sha256 = "e81112d69acc2e1bbb44c5252f8f323b1d637059b5ac5f4c9fcd3eb985a53442" [[asset]] path = "crates/ui-egui/src/i18n/te.tsv" @@ -107,7 +107,7 @@ licence = "MIT OR Apache-2.0" licence_file = "LICENSE-MIT" kind = "translation" usage = "Telugu UI strings, compiled in by crates/ui-egui/src/i18n/mod.rs" -sha256 = "4bb6fa4f3b6e236a4a353df79acd0c5528ea8354058eeaeb66c28bc0f7e02939" +sha256 = "df3d3650af984251372bf22b859ba6aca47f26eeff790e834d57a5a4071a1b48" [[asset]] path = "crates/ui-egui/src/i18n/it.tsv" @@ -118,7 +118,7 @@ licence = "MIT OR Apache-2.0" licence_file = "LICENSE-MIT" kind = "translation" usage = "Italian UI strings, compiled in by crates/ui-egui/src/i18n/mod.rs" -sha256 = "adcbdfc683589b067e062a6200084bf9192935b297f5b616f8ed39db9c71db9b" +sha256 = "c9e453382d9d5c83f7b0f986befc6113a62b4736a6b94a6462805cead406753b" [[asset]] path = "crates/ui-egui/src/i18n/pl.tsv" @@ -129,7 +129,7 @@ licence = "MIT OR Apache-2.0" licence_file = "LICENSE-MIT" kind = "translation" usage = "Polish UI strings, compiled in by crates/ui-egui/src/i18n/mod.rs" -sha256 = "aebe63cd91df2d2f9d2bdc1da43b017823dbc8a32135e999b9ac7041277be0c8" +sha256 = "2a205868b13f719dbc91fdc50f1133f5f317aa2245143bfeaa048190bc9c7d8c" [[asset]] path = "crates/ui-egui/src/i18n/ru.tsv" @@ -140,7 +140,7 @@ licence = "MIT OR Apache-2.0" licence_file = "LICENSE-MIT" kind = "translation" usage = "Russian UI strings, compiled in by crates/ui-egui/src/i18n/mod.rs" -sha256 = "3c8e3a28a5b751c6d6384809d4fd81c14c2ff5f561aaee5b58d24fbfa2ca4dc1" +sha256 = "59ff8e2d10c825711e25af41e3b12366a24568be725ba07998f2c6be30e56187" [[asset]] path = "crates/ui-egui/src/i18n/hu.tsv" @@ -151,7 +151,7 @@ licence = "MIT OR Apache-2.0" licence_file = "LICENSE-MIT" kind = "translation" usage = "Hungarian UI strings, compiled in by crates/ui-egui/src/i18n/mod.rs" -sha256 = "637fcfdd0bf1898b413af7ccbc2eb4228bf656273de9f3ef9241bd128940aeab" +sha256 = "882b3937802bbbd5afe0087264ee4118161351e8828cb02b608488ccfe39bfe9" [[asset]] path = "crates/ui-egui/src/i18n/bg.tsv" @@ -162,7 +162,7 @@ licence = "MIT OR Apache-2.0" licence_file = "LICENSE-MIT" kind = "translation" usage = "Bulgarian UI strings, compiled in by crates/ui-egui/src/i18n/mod.rs" -sha256 = "5285f8987bd8c265f73ff443906c1832a0886037592d334974cf539b9f972a3f" +sha256 = "8cca054e167995ca6d95bc45fc0f75385a15a78852e4b173bd4c5b7b651c5a9d" [[asset]] path = "crates/ui-egui/src/i18n/kk.tsv" @@ -173,7 +173,7 @@ licence = "MIT OR Apache-2.0" licence_file = "LICENSE-MIT" kind = "translation" usage = "Kazakh UI strings, compiled in by crates/ui-egui/src/i18n/mod.rs" -sha256 = "23779abc08be40ddfb305fd638fe280c854ac33473b2822006ba8bad399c0cad" +sha256 = "2f4a6429c0c290a53268733dac08da221085992036a4d304d7663d7947d806d3" [[asset]] path = "crates/ui-egui/src/i18n/ja.tsv" @@ -184,7 +184,7 @@ licence = "MIT OR Apache-2.0" licence_file = "LICENSE-MIT" kind = "translation" usage = "Japanese UI strings, compiled in by crates/ui-egui/src/i18n/mod.rs" -sha256 = "c5129c40b202d8467d8d4cf0a189da8c2ba2af711998edb73f67e1b291289a04" +sha256 = "2792f38b1699269b5886fa99a17c7773c3934df95dc4e2db3ba6a475dd652ba0" [[asset]] path = "crates/ui-egui/src/i18n/uk.tsv" @@ -195,7 +195,7 @@ licence = "MIT OR Apache-2.0" licence_file = "LICENSE-MIT" kind = "translation" usage = "Ukrainian UI strings, compiled in by crates/ui-egui/src/i18n/mod.rs" -sha256 = "11ed2aa56dc5f8f6656eba717500c74bb8c8f931c08f9f9b210b5b33dd9c2d5a" +sha256 = "937ac7eac4230c9a1d26d6bd7ef4f08f8d8c9d391a091682e8758fba3ca9678e" [[asset]] path = "crates/ui-egui/src/i18n/ar.tsv" @@ -206,7 +206,7 @@ licence = "MIT OR Apache-2.0" licence_file = "LICENSE-MIT" kind = "translation" usage = "Arabic UI strings, compiled in by crates/ui-egui/src/i18n/mod.rs" -sha256 = "a3863e2fed5ef584a87f65083a6b9fedf26d18ecebd574efce22bd7a01e3281c" +sha256 = "7ced08c3485c5eddf92767e6deb009d72351d70cefe60be654cfdac441f40f4b" [[asset]] path = "crates/ui-egui/src/i18n/tr.tsv" @@ -217,7 +217,7 @@ licence = "MIT OR Apache-2.0" licence_file = "LICENSE-MIT" kind = "translation" usage = "Turkish UI strings, compiled in by crates/ui-egui/src/i18n/mod.rs" -sha256 = "cade94846289c2822b408a2ea23e6c8f8f321708f4f27fd563695a3c4fade6a1" +sha256 = "4e70c6db374db37bf70a17e251675b94128fb11b4d6d20ef669b36fd4ae14ff1" [[asset]] path = "crates/ui-egui/src/i18n/lt.tsv" @@ -228,7 +228,7 @@ licence = "MIT OR Apache-2.0" licence_file = "LICENSE-MIT" kind = "translation" usage = "Lithuanian UI strings, compiled in by crates/ui-egui/src/i18n/mod.rs" -sha256 = "35b6b03dae01b9a2e98f6d1f682d0699d77772e6efec7e28e1f26039c57b151f" +sha256 = "d2e6be7cf74525310a203bed7434e7f69d2288d337ee696de2882df8da31a746" [[asset]] path = "crates/ui-egui/src/i18n/id.tsv" @@ -252,6 +252,28 @@ kind = "translation" usage = "Vietnamese UI strings, compiled in by crates/ui-egui/src/i18n/mod.rs" sha256 = "21215a2a3489a03050d884b51a512e5c8b58b690dd36e182a4917ddd87b7b922" +[[asset]] +path = "crates/ui-egui/src/i18n/hi.tsv" +title = "Hindi interface translation catalog" +author = "PdfCraft contributors" +source = "Contributor-original: clean-room translations of PdfCraft's English UI labels, no proprietary localisation resources" +licence = "MIT OR Apache-2.0" +licence_file = "LICENSE-MIT" +kind = "translation" +usage = "Hindi UI strings, compiled in by crates/ui-egui/src/i18n/mod.rs" +sha256 = "0dff6ebbd918a71f3e1e4dab7f439088bedf91469fc6bf56c3e1a0e114e99149" + +[[asset]] +path = "crates/ui-egui/src/i18n/ko.tsv" +title = "Korean interface translation catalog" +author = "PdfCraft contributors" +source = "Contributor-original: clean-room translations of PdfCraft's English UI labels, no proprietary localisation resources" +licence = "MIT OR Apache-2.0" +licence_file = "LICENSE-MIT" +kind = "translation" +usage = "Korean UI strings, compiled in by crates/ui-egui/src/i18n/mod.rs" +sha256 = "0254b088b5ef93c88a2f9cfc0a27cdf12eaf38fcad6f0a619adb34a618175cc5" + [[asset]] path = "assets/icons/accessibility.svg" title = "Lucide icon \"accessibility\"" @@ -2386,18 +2408,6 @@ kind = "data" usage = "Default CMYK colour conversion (vendored hayro-interpret)" sha256 = "73e1ba37d2bad5bab2a964f40a9eed96209666efc067c3322626214bbef234a0" -[[asset]] -path = "crates/fonts/src/std14.rs" -title = "Standard-14 font advance widths and encodings (as Rust tables)" -author = "Adobe (Core14 AFM metrics, PDF specification encodings); tables generated by the PdfCraft contributors" -source = "ISO 32000-2 Annex D and the Adobe Core14 AFM metrics. Generated by joining the published WinAnsi, Symbol and ZapfDingbats encodings (code to glyph name) with the per-glyph advance widths, then spot-checked against the specification by hand in the tests of crates/fonts/src/std14.rs." -licence = "MIT OR Apache-2.0" -licence_file = "LICENSE-MIT" -kind = "data" -adobe_data = true -usage = "Advance widths for the fourteen standard fonts, which a PDF may name without embedding. Non-visual data, not a typeface: the item AGENTS.md 1.1 permits, held first-party so generated appearance streams and the renderer agree." -sha256 = "4ce47db7e65467d4ea1d1642ff76dfcaeb9669c1811a93819d7e00e63fa9fcf8" - [[bundled]] crate = "epaint_default_fonts" version = "0.36.2" @@ -3373,4 +3383,4 @@ licence = "MIT OR Apache-2.0" licence_file = "LICENSE-MIT" kind = "translation" usage = "Slovene UI strings, compiled in by crates/ui-egui/src/i18n/mod.rs" -sha256 = "2685fbb694cbdeb7632ecb5e7396e1209047c83319e28ceea032b3ec9fb2fc0e" +sha256 = "6c01a439220415b83acab79c014286e5871ba7946a9c3b9a4776be797d55a086" diff --git a/ROADMAP.md b/ROADMAP.md index cb9b13008..47da00971 100644 --- a/ROADMAP.md +++ b/ROADMAP.md @@ -119,14 +119,14 @@ Measured from `crates/ui-egui/src/i18n/*.tsv` (2,578 keys). Detail and script no | English | `en` | 100% | full | | Simplified Chinese | `zh-hans` | 97.4% | partial (no Hans UI face in releases, #826) | | Spanish | `es` | 95.5% | partial | -| Hindi | `hi` | 0% | none | +| Hindi | `hi` | 100% | partial | | Arabic | `ar` | 100% | partial (layout not mirrored) | | French | `fr` | 99.3% | partial | | Portuguese (Brazil) | `pt-br` | 99.4% | partial | | Indonesian | `id` | 100% | partial | | Japanese | `ja` | 99.1% | partial | | German | `de` | 99.3% | partial | -| Korean | `ko` | 0% | none | +| Korean | `ko` | 100% | partial (installed Hangul face; none in craft-fonts yet) | | Vietnamese | `vi` | 100% | partial | Also shipped: Traditional Chinese, Russian, Bulgarian, Telugu, Hungarian, Ukrainian, Italian diff --git a/crates/engine/src/dates.rs b/crates/engine/src/dates.rs index da1f5937e..a28f1e674 100644 --- a/crates/engine/src/dates.rs +++ b/crates/engine/src/dates.rs @@ -56,7 +56,7 @@ const AR_DAYS: [&str; 7] = ["الأحد", "الاثنين", "الثلاثاء", /// The languages month and weekday names can be written in (Preferences ▸ Date format ▸ Language): /// the interface languages, in the same order and with the same names. -pub static DATE_LANGUAGES: [DateLanguage; 24] = [ +pub static DATE_LANGUAGES: [DateLanguage; 26] = [ DateLanguage { code: "en", name: "English", @@ -408,6 +408,26 @@ pub static DATE_LANGUAGES: [DateLanguage; 24] = [ days: ["Chủ Nhật", "Thứ Hai", "Thứ Ba", "Thứ Tư", "Thứ Năm", "Thứ Sáu", "Thứ Bảy"], days_short: ["CN", "T2", "T3", "T4", "T5", "T6", "T7"], }, + // Hindi (Devanagari). Month and weekday names are the same with and after a day number. + DateLanguage { + code: "hi", + name: "हिन्दी", + months: ["जनवरी", "फ़रवरी", "मार्च", "अप्रैल", "मई", "जून", "जुलाई", "अगस्त", "सितंबर", "अक्तूबर", "नवंबर", "दिसंबर"], + months_with_day: None, + months_short: ["जन॰", "फ़र॰", "मार्च", "अप्रैल", "मई", "जून", "जुला॰", "अग॰", "सित॰", "अक्तू॰", "नव॰", "दिस॰"], + days: ["रविवार", "सोमवार", "मंगलवार", "बुधवार", "गुरुवार", "शुक्रवार", "शनिवार"], + days_short: ["रवि", "सोम", "मंगल", "बुध", "गुरु", "शुक्र", "शनि"], + }, + // Korean: months are numbered (`3월`) and weekdays end in 요일; no names change after a day. + DateLanguage { + code: "ko", + name: "한국어", + months: ["1월", "2월", "3월", "4월", "5월", "6월", "7월", "8월", "9월", "10월", "11월", "12월"], + months_with_day: None, + months_short: ["1월", "2월", "3월", "4월", "5월", "6월", "7월", "8월", "9월", "10월", "11월", "12월"], + days: ["일요일", "월요일", "화요일", "수요일", "목요일", "금요일", "토요일"], + days_short: ["일", "월", "화", "수", "목", "금", "토"], + }, ]; /// The date language for `code` (any case), or `None` when there's none. @@ -727,6 +747,22 @@ mod tests { assert_eq!(s.today_text_for_pdf(Some("d mmmm yyyy"), None).as_deref(), Ok("14 November 2023")); } + /// Hindi and Korean names are the same with and after a day number. Neither is Western + /// European, so the date-text path refuses them with what to use instead. + #[test] + fn hindi_and_korean_month_and_weekday_names() { + assert_eq!(in_lang("d mmmm yyyy", "hi"), "7 मार्च 2026"); + assert_eq!(in_lang("dddd, mmmm", "hi"), "शनिवार, मार्च"); + assert_eq!(in_lang("ddd, d mmm", "hi"), "शनि, 7 मार्च"); + assert_eq!(in_lang("yyyy\\년 mmmm d\\일 dddd", "ko"), "2026년 3월 7일 토요일"); + assert_eq!(in_lang("ddd", "ko"), "토"); + let mut s = Session::new().with_clock(|| 1_700_000_000); + for code in ["hi", "ko"] { + s.set_date_language(Some(code)).unwrap(); + assert!(s.today_text_for_pdf(Some("d mmmm yyyy"), None).unwrap_err().contains("dd.mm.yyyy"), "{code}"); + } + } + #[test] fn the_session_writes_names_in_its_date_language() { let mut s = Session::new().with_clock(|| 1_700_000_000); diff --git a/crates/ui-egui/src/i18n/hi.tsv b/crates/ui-egui/src/i18n/hi.tsv new file mode 100644 index 000000000..9610c9ffe --- /dev/null +++ b/crates/ui-egui/src/i18n/hi.tsv @@ -0,0 +1,2582 @@ +# Hindi (hi) interface catalog. Columns, separated by a TAB: +# context English source translation +# Clean-room translation written from the English source's meaning. +# License: MIT OR Apache-2.0. + Menu मेनू + File फ़ाइल + Edit संपादित करें + Pages पृष्ठ + View दृश्य + Help सहायता + Preferences प्राथमिकताएँ + Preferences… प्राथमिकताएँ… + Interface language इंटरफ़ेस भाषा + Interface size इंटरफ़ेस का आकार + Auto ({percent}%) स्वतः ({percent}%) + Auto follows the system's text size. Pages always render at the display's full resolution. स्वतः मोड सिस्टम की टेक्स्ट आकार सेटिंग का पालन करता है। पृष्ठ हमेशा डिस्प्ले की पूर्ण रिज़ॉल्यूशन पर रेंडर होते हैं। + Identity पहचान + Name on new comments नई टिप्पणियों में नाम + Open… खोलें… + Open Recent हाल ही में खोले गए + Pin folder to Home… होम पर फ़ोल्डर पिन करें… + Folders फ़ोल्डर + Pin a folder… फ़ोल्डर पिन करें… + Pin a folder to Home होम पर फ़ोल्डर पिन करें + Pin a folder to list its newest PDFs here, such as where your scanner or a synced cloud drive saves them. किसी फ़ोल्डर को पिन करें ताकि उसके नवीनतम पीडीएफ़ यहाँ सूची में दिखें, जैसे वह जगह जहाँ आपका स्कैनर या सिंक किया गया क्लाउड ड्राइव उन्हें सहेजता है। + Unpin अनपिन करें + Unpin {folder} {folder} अनपिन करें + Looking for PDFs… पीडीएफ़ खोजे जा रहे हैं… + This folder isn't available right now. It may have moved, or its drive or cloud sync is offline. यह फ़ोल्डर इस समय उपलब्ध नहीं है। हो सकता है कि इसे स्थानांतरित कर दिया गया हो, या इसका ड्राइव या क्लाउड सिंक ऑफ़लाइन हो। + No PDFs in this folder yet इस फ़ोल्डर में अभी तक कोई पीडीएफ़ नहीं है + Show less कम दिखाएँ + Show {n} more {n} और दिखाएँ + The newest {n} of {total} PDFs {total} पीडीएफ़ में से नवीनतम {n} + Pinned folders need the desktop app पिन किए गए फ़ोल्डरों के लिए डेस्कटॉप ऐप आवश्यक है + Choose a folder on this computer to pin पिन करने के लिए इस कंप्यूटर का कोई फ़ोल्डर चुनें + {folder} is already pinned to Home {folder} पहले से ही होम पर पिन है + You can pin up to {n} folders. Unpin one first. आप अधिकतम {n} फ़ोल्डर पिन कर सकते हैं। पहले किसी एक को अनपिन करें। + Pinned {folder} to Home {folder} को होम पर पिन किया गया + No recent files कोई हाल की फ़ाइल नहीं + New blank PDF नया खाली पीडीएफ़ + Create PDF from file… फ़ाइल से पीडीएफ़ बनाएँ… + Create PDF from images… छवियों से पीडीएफ़ बनाएँ… + Create PDF from clipboard क्लिपबोर्ड से पीडीएफ़ बनाएँ + Combine files… फ़ाइलें संयोजित करें… + Save सहेजें + Save as… इस रूप में सहेजें… + Close file फ़ाइल बंद करें + Close all सभी बंद करें + Revert सहेजे गए संस्करण पर लौटें + Print… प्रिंट करें… + Document properties… दस्तावेज़ गुण… + Undo पूर्ववत करें + Redo पुनः करें + Find… खोजें… + Advanced search… उन्नत खोज… + Copy pages पृष्ठ कॉपी करें + Cut pages पृष्ठ काटें + Paste pages पृष्ठ पेस्ट करें + Fit visible दृश्य भाग पर फ़िट करें + Marquee zoom चयनित क्षेत्र पर ज़ूम करें + Take a snapshot स्नैपशॉट लें + Column select कॉलम चयन + Full screen mode पूर्ण स्क्रीन मोड + Read mode पढ़ने का मोड + Switch light / dark theme हल्की / गहरी थीम पर स्विच करें + Comments panel टिप्पणी पैनल + Form fields panel फ़ॉर्म फ़ील्ड पैनल + Clear form फ़ॉर्म साफ़ करें + Find tools and commands… टूल और कमांड खोजें… + Zoom ज़ूम + Actual size वास्तविक आकार + Zoom to page level पृष्ठ स्तर पर ज़ूम करें + Fit to width चौड़ाई के अनुसार फ़िट करें + Display theme प्रदर्शन थीम + Side panels साइड पैनल + Enable Acrobat JavaScript Acrobat JavaScript सक्षम करें + OK ठीक है + Join our Discord हमारे Discord से जुड़ें + Close बंद करें + Next / previous match अगला / पिछला मिलान + Copy selected text चयनित टेक्स्ट कॉपी करें + Double-click डबल-क्लिक + Select a word शब्द चुनें + Clear selection / close find चयन हटाएँ / खोज बंद करें + Zoom in / out (also pinch or {key}-scroll) ज़ूम इन / आउट करें (पिंच या {key}-स्क्रॉल से भी) + Rotate view दृश्य घुमाएँ + First / last page पहला / अंतिम पृष्ठ + Previous / next page पिछला / अगला पृष्ठ + Delete selected pages (Organize) चयनित पृष्ठ हटाएँ (व्यवस्था) + Select all pages (Organize) सभी पृष्ठ चुनें (व्यवस्था) + Home होम + Open खोलें + Open a PDF ({key}) पीडीएफ़ खोलें ({key}) + Dark gray theme गहरी धूसर थीम + Light theme हल्की थीम + Appearance mode दिखावट मोड + Light हल्का + Dark गहरा + Active सक्रिय + Dark theme गहरी थीम + Appearance settings… दिखावट सेटिंग्स… + All tools सभी टूल + Read पढ़ें + Convert रूपांतरित करें + E-Sign ई-साइन + Print ({key}) प्रिंट करें ({key}) + Save ({key}) सहेजें ({key}) + Document properties ({key}) दस्तावेज़ गुण ({key}) + Find tools and commands टूल और कमांड खोजें + Fit to height ऊँचाई के अनुसार फ़िट करें + Zoom in ज़ूम इन करें + Zoom out ज़ूम आउट करें + Rotate view clockwise दृश्य दक्षिणावर्त घुमाएँ + Rotate view counterclockwise दृश्य वामावर्त घुमाएँ + Page navigation पृष्ठ नेविगेशन + Previous view पिछला दृश्य + Next view अगला दृश्य + Page display पृष्ठ प्रदर्शन + Continuous scrolling लगातार स्क्रॉलिंग + Two-page view दो-पृष्ठ दृश्य + Single page एकल पृष्ठ + Show cover page in two-page view दो-पृष्ठ दृश्य में कवर पृष्ठ दिखाएँ + Use system setting सिस्टम सेटिंग का उपयोग करें + Light gray हल्का धूसर + Dark gray गहरा धूसर + Comments टिप्पणियाँ + Bookmarks बुकमार्क + Fields फ़ील्ड + Layers परतें + Attachments अनुलग्नक + Signatures हस्ताक्षर + Accessibility Checker ऐक्सेसिबिलिटी जाँचकर्ता + Search खोज + Compare तुलना करें + Page thumbnails पृष्ठ थंबनेल + Form fields फ़ॉर्म फ़ील्ड + Zoom out ({key}) ज़ूम आउट ({key}) + Zoom in ({key}) ज़ूम इन ({key}) + Rotate view clockwise ({key}) दृश्य दक्षिणावर्त घुमाएँ ({key}) + Toggle fit page / fit width पृष्ठ फ़िट / चौड़ाई फ़िट टॉगल करें + Next page अगला पृष्ठ + Previous page पिछला पृष्ठ + Current page — type a page number or label (such as iv) and press Enter वर्तमान पृष्ठ — पृष्ठ संख्या या लेबल (जैसे iv) टाइप करें और Enter दबाएँ + Welcome to PdfCraft PdfCraft में आपका स्वागत है + An open-source PDF workbench — local, private, and scriptable. एक ओपन-सोर्स पीडीएफ़ वर्कबेंच — स्थानीय, निजी और स्क्रिप्टेबल। + Join the ArtCraft community ArtCraft समुदाय से जुड़ें + Get help, share feedback and follow development on Discord. Discord पर सहायता प्राप्त करें, प्रतिक्रिया साझा करें और विकास पर नज़र रखें। + Recommended tools अनुशंसित टूल + Use now अभी उपयोग करें + Open file फ़ाइल खोलें + Recent हाल की फ़ाइलें + Files you open in PdfCraft appear here. Drop a PDF anywhere to open it. आप PdfCraft में जो फ़ाइलें खोलते हैं वे यहाँ दिखाई देती हैं। खोलने के लिए पीडीएफ़ कहीं भी छोड़ दें। + Privacy गोपनीयता + PdfCraft works offline. No telemetry, no account, and no cloud processing unless you add a provider. PdfCraft ऑफ़लाइन काम करता है। जब तक आप कोई प्रोवाइडर न जोड़ें, न टेलीमेट्री है, न खाता और न ही क्लाउड प्रोसेसिंग। + Scripts run in a sandbox without file or network access. With JavaScript off, Acrobat's standard format, validate and calculate functions still work. स्क्रिप्ट ऐसे सैंडबॉक्स में चलती हैं जिसमें फ़ाइल या नेटवर्क एक्सेस नहीं होता। JavaScript बंद होने पर भी Acrobat के मानक format, validate और calculate फ़ंक्शन काम करते हैं। + Back to all tools सभी टूल पर वापस जाएँ + Close panel पैनल बंद करें + View less कम देखें + View more अधिक देखें + Available उपलब्ध + Ready तैयार + Search tools and commands… टूल और कमांड खोजें… + No matching tools कोई मेल खाता टूल नहीं + Tool टूल + Command कमांड + Add a sticky note स्टिकी नोट जोड़ें + Add a text box टेक्स्ट बॉक्स जोड़ें + Highlight text टेक्स्ट हाइलाइट करें + Underline text टेक्स्ट को रेखांकित करें + Strikethrough text टेक्स्ट स्ट्राइकथ्रू करें + Squiggly underline text टेक्स्ट को लहरदार रेखा से रेखांकित करें + Draw freehand फ्रीहैंड ड्रॉ करें + Draw a line एक रेखा खींचें + Draw an arrow एक तीर खींचें + Draw a rectangle एक आयत खींचें + Draw an oval एक अंडाकार खींचें + Draw a polygon एक बहुभुज खींचें + Draw connected lines जुड़ी हुई रेखाएँ खींचें + Draw a cloud एक बादल खींचें + Add a callout कॉलआउट जोड़ें + Insert text टेक्स्ट प्रविष्ट करें + Replace text टेक्स्ट बदलें + Attach a file फ़ाइल संलग्न करें + Erase drawings ड्रॉइंग मिटाएँ + Flatten comments टिप्पणियाँ फ़्लैट करें + Import comments… टिप्पणियाँ आयात करें… + Add a stamp स्टाम्प जोड़ें + Export all comments to data file… सभी टिप्पणियाँ डेटा फ़ाइल में निर्यात करें… + Hide all comments सभी टिप्पणियाँ छिपाएँ + Summarize comments टिप्पणियों का सारांश बनाएँ + Import form data… फ़ॉर्म डेटा आयात करें… + Export form data… फ़ॉर्म डेटा निर्यात करें… + PDF/A… PDF/A… + Action Wizard… एक्शन विज़ार्ड… + Prepare for distribution… वितरण के लिए तैयार करें… + Optimize scanned documents… स्कैन किए गए दस्तावेज़ अनुकूलित करें… + Compare files… फ़ाइलों की तुलना करें… + Detect form fields फ़ॉर्म फ़ील्ड का पता लगाएँ + Merge data files into spreadsheet… डेटा फ़ाइलों को स्प्रेडशीट में मर्ज करें… + Flatten form fields फ़ॉर्म फ़ील्ड फ़्लैट करें + Prepare a form फ़ॉर्म तैयार करें + Tab order: by rows टैब क्रम: पंक्तियों के अनुसार + Tab order: by columns टैब क्रम: कॉलम के अनुसार + Tab order: by document structure टैब क्रम: दस्तावेज़ संरचना के अनुसार + Add text टेक्स्ट जोड़ें + Edit text & images टेक्स्ट और छवियाँ संपादित करें + Add or edit links लिंक जोड़ें या संपादित करें + Create links from URLs URL से लिंक बनाएँ + Remove all links सभी लिंक हटाएँ + No links to remove हटाने के लिए कोई लिंक नहीं + Removed 1 link 1 लिंक हटाया गया + Removed {n} links {n} लिंक हटाए गए + Add Bates numbering… बेट्स नंबरिंग जोड़ें… + Add image… छवि जोड़ें… + Redact text and images टेक्स्ट और छवियाँ रेडैक्ट करें + Redact pages… पृष्ठ रेडैक्ट करें… + Find text and redact… टेक्स्ट खोजें और रेडैक्ट करें… + Redaction properties… रेडैक्शन गुण… + Apply redactions… रेडैक्शन लागू करें… + Clear redaction marks रेडैक्शन चिह्न साफ़ करें + Remove hidden information… छिपी हुई जानकारी हटाएँ… + Sanitize document… दस्तावेज़ सैनिटाइज़ करें… + Field properties… फ़ील्ड गुण… + Add a text field टेक्स्ट फ़ील्ड जोड़ें + Add a checkbox चेकबॉक्स जोड़ें + Add a radio button रेडियो बटन जोड़ें + Add a drop-down list ड्रॉप-डाउन सूची जोड़ें + Add a list box सूची बॉक्स जोड़ें + Add a button बटन जोड़ें + Add an image field छवि फ़ील्ड जोड़ें + Add a date field दिनांक फ़ील्ड जोड़ें + Add a digital signature field डिजिटल हस्ताक्षर फ़ील्ड जोड़ें + Digitally sign डिजिटल रूप से हस्ताक्षर करें + Certify (visible signature) प्रमाणित करें (दृश्यमान हस्ताक्षर) + Certify (invisible signature) प्रमाणित करें (अदृश्य हस्ताक्षर) + Validate all signatures सभी हस्ताक्षर सत्यापित करें + Signatures panel हस्ताक्षर पैनल + Fill & Sign: add text भरें व हस्ताक्षर करें: टेक्स्ट जोड़ें + Fill & Sign: checkmark भरें व हस्ताक्षर करें: चेकमार्क + Fill & Sign: cross भरें व हस्ताक्षर करें: क्रॉस + Fill & Sign: dot भरें व हस्ताक्षर करें: बिंदु + Fill & Sign: line भरें व हस्ताक्षर करें: रेखा + Fill & Sign: date भरें व हस्ताक्षर करें: दिनांक + Fill & Sign: sign भरें व हस्ताक्षर करें: हस्ताक्षर + Fill & Sign: initials भरें व हस्ताक्षर करें: आद्याक्षर + Export to image… छवि में निर्यात करें… + Reduce file size… फ़ाइल का आकार घटाएँ… + Optimize PDF… पीडीएफ़ अनुकूलित करें… + Export to text… टेक्स्ट में निर्यात करें… + Export to Word… Word में निर्यात करें… + Export to PowerPoint… PowerPoint में निर्यात करें… + Export to HTML… HTML में निर्यात करें… + Export to RTF… RTF में निर्यात करें… + JavaScript console… JavaScript कंसोल… + Document JavaScripts… दस्तावेज़ JavaScript… + Recognize text… टेक्स्ट पहचानें… + Recognize text in multiple files… कई फ़ाइलों में टेक्स्ट पहचानें… + Check for accessibility… ऐक्सेसिबिलिटी की जाँच करें… + Open accessibility report ऐक्सेसिबिलिटी रिपोर्ट खोलें + Change reading options… पढ़ने के विकल्प बदलें… + Add alternate text… वैकल्पिक टेक्स्ट जोड़ें… + Export all images… सभी छवियाँ निर्यात करें… + Add header & footer… शीर्षलेख और पादलेख जोड़ें… + Update header & footer… शीर्षलेख और पादलेख अद्यतन करें… + Remove header & footer शीर्षलेख और पादलेख हटाएँ + Add watermark… वॉटरमार्क जोड़ें… + Update watermark… वॉटरमार्क अद्यतन करें… + Remove watermark वॉटरमार्क हटाएँ + Add background… पृष्ठभूमि जोड़ें… + Update background… पृष्ठभूमि अद्यतन करें… + Remove background पृष्ठभूमि हटाएँ + Protect using password… पासवर्ड से सुरक्षित करें… + Remove security सुरक्षा हटाएँ + Security properties… सुरक्षा गुण… + Organize pages पृष्ठ व्यवस्थित करें + New bookmark नया बुकमार्क + New bookmarks from structure संरचना से नए बुकमार्क + Rotate pages clockwise पृष्ठ दक्षिणावर्त घुमाएँ + Rotate pages counterclockwise पृष्ठ वामावर्त घुमाएँ + Delete pages पृष्ठ हटाएँ + Insert blank page खाली पृष्ठ प्रविष्ट करें + Rotate pages… पृष्ठ घुमाएँ… + Duplicate pages पृष्ठ डुप्लिकेट करें + Crop pages पृष्ठ क्रॉप करें + Set page boxes… पृष्ठ बॉक्स सेट करें… + Insert pages from file… फ़ाइल से पृष्ठ प्रविष्ट करें… + Replace pages… पृष्ठ बदलें… + Extract pages… पृष्ठ निकालें… + Split document… दस्तावेज़ विभाजित करें… + Number pages… पृष्ठों पर नंबर लगाएँ… + Keyboard shortcuts कीबोर्ड शॉर्टकट + Join the ArtCraft Discord ArtCraft Discord से जुड़ें + PdfCraft web page PdfCraft वेबपेज + PdfCraft on GitHub GitHub पर PdfCraft + ArtCraft website ArtCraft वेबसाइट + Check for updates… अपडेट की जाँच करें… + About PdfCraft PdfCraft के बारे में + Export a PDF पीडीएफ़ निर्यात करें + Export to इसमें निर्यात करें + Microsoft Word (.docx) Microsoft Word (.docx) + Spreadsheet (.xlsx) स्प्रेडशीट (.xlsx) + Presentation (.pptx) प्रेज़ेंटेशन (.pptx) + Image (PNG) छवि (PNG) + Export all images सभी छवियाँ निर्यात करें + HTML web page HTML वेबपेज + Rich Text Format (.rtf) रिच टेक्स्ट फ़ॉर्मैट (.rtf) + Text (plain) टेक्स्ट (सादा) + PostScript / EPS PostScript / EPS + Fill & Sign भरें व हस्ताक्षर करें + Fill भरें + Checkmark चेकमार्क + Cross क्रॉस + Dot बिंदु + Line रेखा + Date दिनांक + Signature हस्ताक्षर + Initials आद्याक्षर + Edit a PDF पीडीएफ़ संपादित करें + Modify page पृष्ठ संशोधित करें + Rotate pages पृष्ठ घुमाएँ + Insert pages पृष्ठ प्रविष्ट करें + Extract pages पृष्ठ निकालें + Add content सामग्री जोड़ें + Text टेक्स्ट + Image छवि + Header and footer शीर्षलेख और पादलेख + Watermark वॉटरमार्क + Link लिंक + Bates numbering बेट्स नंबरिंग + Background पृष्ठभूमि + Attach file फ़ाइल संलग्न करें + Create a PDF पीडीएफ़ बनाएँ + Create from इससे बनाएँ + Single file एक फ़ाइल + Multiple files कई फ़ाइलें + Separate PDFs अलग-अलग पीडीएफ़ + Images छवियाँ + Clipboard क्लिपबोर्ड + Blank page खाली पृष्ठ + Combine files फ़ाइलें संयोजित करें + Combine संयोजित करें + Add files to combine संयोजित करने के लिए फ़ाइलें जोड़ें + Page options पृष्ठ विकल्प + Page grid पृष्ठ ग्रिड + Rotate घुमाएँ + Delete हटाएँ + Extract निकालें + Insert प्रविष्ट करें + Replace बदलें + Split विभाजित करें + More अधिक + Set page boxes पृष्ठ बॉक्स सेट करें + Page labels पृष्ठ लेबल + Page transitions पृष्ठ संक्रमण + Add comments टिप्पणियाँ जोड़ें + Markup मार्कअप + Sticky note स्टिकी नोट + Underline अधोरेखन + Strikethrough स्ट्राइकथ्रू + Squiggly underline लहरदार अधोरेखन + Text box टेक्स्ट बॉक्स + Drawing ड्रॉइंग + Rectangle आयत + Oval अंडाकार + Arrow तीर + Cloud बादल + Stamp स्टाम्प + Review समीक्षा + Comment list टिप्पणी सूची + Scan & OCR स्कैन और OCR + Recognize text टेक्स्ट पहचानें + In this file इस फ़ाइल में + In multiple files कई फ़ाइलों में + Enhance scanned file स्कैन की गई फ़ाइल सुधारें + Correct recognized text पहचाने गए टेक्स्ट को ठीक करें + Protect a PDF पीडीएफ़ सुरक्षित करें + Protect सुरक्षित करें + Protect with password पासवर्ड से सुरक्षित करें + Remove hidden information छिपी हुई जानकारी हटाएँ + Advanced options उन्नत विकल्प + Encrypt with certificate प्रमाणपत्र से एन्क्रिप्ट करें + Security properties सुरक्षा गुण + Redact a PDF पीडीएफ़ रेडैक्ट करें + Redact रेडैक्ट करें + Redact pages पृष्ठ रेडैक्ट करें + Find text and redact टेक्स्ट खोजें और रेडैक्ट करें + Set properties गुण सेट करें + Sanitize document दस्तावेज़ सैनिटाइज़ करें + Compress a PDF पीडीएफ़ संपीड़ित करें + Optimize अनुकूलित करें + Reduce file size फ़ाइल का आकार घटाएँ + Advanced optimization उन्नत अनुकूलन + Audit space usage स्थान उपयोग का ऑडिट करें + Field list फ़ील्ड सूची + Field properties फ़ील्ड गुण + Tab order by rows पंक्तियों के अनुसार टैब क्रम + Tab order by columns कॉलम के अनुसार टैब क्रम + Import data डेटा आयात करें + Export data डेटा निर्यात करें + Add form components फ़ॉर्म घटक जोड़ें + Text field टेक्स्ट फ़ील्ड + Checkbox चेकबॉक्स + Radio button रेडियो बटन + Drop-down list ड्रॉप-डाउन सूची + List box सूची बॉक्स + Button बटन + Image field छवि फ़ील्ड + Date field दिनांक फ़ील्ड + Digital signature डिजिटल हस्ताक्षर + Stamps स्टाम्प + Stamp palette स्टाम्प पैलेट + Use a certificate प्रमाणपत्र का उपयोग करें + Certificates प्रमाणपत्र + Timestamp टाइमस्टैम्प + Use print production प्रिंट प्रोडक्शन का उपयोग करें + Print production प्रिंट प्रोडक्शन + Output preview आउटपुट प्रीव्यू + Preflight प्रीफ़्लाइट + Convert colors रंग रूपांतरित करें + Add printer marks प्रिंटर मार्क जोड़ें + Fix hairlines हेयरलाइन ठीक करें + Measure objects ऑब्जेक्ट मापें + Measure मापें + Measuring tool मापन टूल + Geospatial location भौगोलिक स्थान + Compare files फ़ाइलों की तुलना करें + Select files to compare तुलना के लिए फ़ाइलें चुनें + Use guided actions गाइडेड एक्शन का उपयोग करें + Actions list एक्शन सूची + Action Wizard एक्शन विज़ार्ड + Make accessible ऐक्सेसिबल बनाएँ + Prepare for distribution वितरण के लिए तैयार करें + Optimize scanned documents स्कैन किए गए दस्तावेज़ अनुकूलित करें + Archive documents दस्तावेज़ संग्रहित करें + Prepare for accessibility ऐक्सेसिबिलिटी के लिए तैयार करें + Accessibility ऐक्सेसिबिलिटी + Automatically tag PDF पीडीएफ़ को स्वतः टैग करें + Change reading options पढ़ने के विकल्प बदलें + Check for accessibility ऐक्सेसिबिलिटी की जाँच करें + Add alternate text वैकल्पिक टेक्स्ट जोड़ें + Fix reading order पढ़ने का क्रम ठीक करें + Apply PDF standards पीडीएफ़ मानक लागू करें + Standards मानक + Save as PDF/A PDF/A के रूप में सहेजें + Save as PDF/X PDF/X के रूप में सहेजें + Save as PDF/UA PDF/UA के रूप में सहेजें + Add search index खोज इंडेक्स जोड़ें + Index इंडेक्स + Manage embedded index एम्बेडेड इंडेक्स प्रबंधित करें + Use JavaScript JavaScript का उपयोग करें + JavaScript JavaScript + Console कंसोल + Document JavaScripts दस्तावेज़ JavaScript + Document actions दस्तावेज़ एक्शन + AI assistant AI सहायक + Bring your own model (off by default) अपना स्वयं का मॉडल लाएँ (डिफ़ॉल्ट रूप से बंद) + Summarize सारांश बनाएँ + Ask about this document इस दस्तावेज़ के बारे में पूछें + Translate अनुवाद करें + pages पृष्ठ + Planned योजित + Planned for milestone माइलस्टोन के लिए योजित + open to see what it will include खोलकर देखें कि इसमें क्या शामिल होगा + Optional: needs an AI provider you configure वैकल्पिक: आपके द्वारा कॉन्फ़िगर किए गए AI प्रोवाइडर की आवश्यकता है + Coming in milestone माइलस्टोन में आ रहा है + Items marked Ready work today. जिन आइटम पर “तैयार” चिह्न है वे आज ही काम करते हैं। + Preview प्रीव्यू + Edit fields फ़ील्ड संपादित करें + Try the form as people filling it in will see it फ़ॉर्म को उस रूप में आज़माएँ जिस रूप में उसे भरने वाले लोग देखेंगे + Redact all सभी रेडैक्ट करें + Clear all सभी साफ़ करें + Rotate page पृष्ठ घुमाएँ + Delete page पृष्ठ हटाएँ + Move page पृष्ठ ले जाएँ + Move pages पृष्ठों को ले जाएँ + Duplicate page पृष्ठ डुप्लिकेट करें + Replace page पृष्ठ बदलें + Replace pages पृष्ठ बदलें + Crop page पृष्ठ क्रॉप करें + Cancel रद्द करें + Don't save सहेजें नहीं + Apply लागू करें + Run चलाएँ + Clear साफ़ करें + Sanitize सैनिटाइज़ करें + Mark all सभी चिह्नित करें + Save changes to “{name}” before closing? क्या आप “{name}” में किए गए बदलाव बंद करने से पहले सहेजना चाहते हैं? + Your changes will be lost if you don't save them. यदि आप बदलाव सहेजते नहीं, तो वे खो जाएँगे। + Password required पासवर्ड आवश्यक + “{name}” is protected. Enter a password to open it. “{name}” सुरक्षित है। इसे खोलने के लिए पासवर्ड दर्ज करें। + Password पासवर्ड + Incorrect password. Try again. गलत पासवर्ड। पुनः प्रयास करें। + Recognize Text टेक्स्ट पहचानें + Password protection will be applied when you save सहेजने पर पासवर्ड सुरक्षा लागू की जाएगी + Saved the print-ready PDF to {path} प्रिंट के लिए तैयार पीडीएफ़ {path} पर सहेजा गया + Could not save: {e} सहेजा नहीं जा सका: {e} + Earlier in tab order टैब क्रम में पहले + Later in tab order टैब क्रम में बाद में + From: से: + To: तक: + High Resolution उच्च रिज़ॉल्यूशन + Print प्रिंट करें + Verify to see what the document needs. सत्यापित करें और देखें कि दस्तावेज़ को क्या चाहिए। + Set Page Boxes पृष्ठ बॉक्स सेट करें + Signature panel हस्ताक्षर पैनल + {month} {day}, {y} {day} {month} {y} + The document's security settings don't allow filling in form fields दस्तावेज़ की सुरक्षा सेटिंग्स फ़ॉर्म फ़ील्ड भरने की अनुमति नहीं देतीं + {name} is read-only {name} केवल पढ़ने के लिए है + {name} has no action {name} में कोई एक्शन नहीं है + Previous month पिछला महीना + Next month अगला महीना + January जनवरी + February फ़रवरी + March मार्च + April अप्रैल + May मई + June जून + July जुलाई + August अगस्त + September सितंबर + October अक्तूबर + November नवंबर + December दिसंबर + Done पूर्ण + This certificate is in your list of trusted certificates. यह प्रमाणपत्र आपकी विश्वसनीय प्रमाणपत्र सूची में मौजूद है। + This certificate is trusted through a certificate above it in the chain. यह प्रमाणपत्र श्रृंखला में अपने ऊपर मौजूद प्रमाणपत्र के ज़रिए विश्वसनीय है। + This certificate is not trusted. Signatures made with it show an unknown identity. यह प्रमाणपत्र विश्वसनीय नहीं है। इससे किए गए हस्ताक्षर अज्ञात पहचान दिखाते हैं। + Add to Trusted Certificates विश्वसनीय प्रमाणपत्रों में जोड़ें + Export… निर्यात करें… + PDF Optimizer पीडीएफ़ ऑप्टिमाइज़र + Discard Objects ऑब्जेक्ट हटाएँ + Discard User Data उपयोगकर्ता डेटा हटाएँ + Clean Up सफ़ाई + Color Images रंगीन छवियाँ + Grayscale Images ग्रेस्केल छवियाँ + Bicubic downsampling to बाइक्यूबिक डाउनसैंपलिंग तक + for images above इससे बड़ी छवियों के लिए + Compression संपीड़न + ZIP ZIP + Retain existing मौजूदा बनाए रखें + Minimum न्यूनतम + Low कम + High उच्च + Maximum अधिकतम + Each image is measured where pages draw it; an image is replaced only if the result is smaller. हर छवि को वहीं मापा जाता है जहाँ पृष्ठ उसे बनाते हैं; छवि तभी बदली जाती है जब परिणाम छोटा हो। + Discard all links, actions and JavaScript सभी लिंक, एक्शन और JavaScript हटाएँ + Discard alternate images वैकल्पिक छवियाँ हटाएँ + Discard embedded page thumbnails एम्बेडेड पृष्ठ थंबनेल हटाएँ + Discard document tags दस्तावेज़ टैग हटाएँ + Discard embedded print settings एम्बेडेड प्रिंट सेटिंग्स हटाएँ + Discard bookmarks बुकमार्क हटाएँ + Discard hidden layer content छिपी हुई परतों की सामग्री हटाएँ + Discard all comments, forms and multimedia सभी टिप्पणियाँ, फ़ॉर्म और मल्टीमीडिया हटाएँ + Discard document information and metadata दस्तावेज़ जानकारी और मेटाडेटा हटाएँ + Discard all object data (file attachments) सभी ऑब्जेक्ट डेटा (फ़ाइल अनुलग्नक) हटाएँ + Discard private data of other applications अन्य ऐप्लिकेशन का निजी डेटा हटाएँ + Discard hidden text छिपा हुआ टेक्स्ट हटाएँ + Use Flate to encode streams that are not encoded जो स्ट्रीम एन्कोडेड नहीं हैं उन्हें Flate से एन्कोड करें + Remove invalid links and bookmarks अमान्य लिंक और बुकमार्क हटाएँ + Remove unreferenced named destinations बिना संदर्भ वाले नामित गंतव्य हटाएँ + Compress document structure (object streams) दस्तावेज़ संरचना संपीड़ित करें (ऑब्जेक्ट स्ट्रीम) + Remove unused objects and merge identical ones अप्रयुक्त ऑब्जेक्ट हटाएँ और समान ऑब्जेक्ट मर्ज करें + Audit space usage… स्थान उपयोग का ऑडिट करें… + Space Audit स्थान ऑडिट + Bytes बाइट + Content Streams कंटेंट स्ट्रीम + X Object Forms X ऑब्जेक्ट फ़ॉर्म + Structure Info संरचना जानकारी + Thumbnails थंबनेल + Named Destinations नामित गंतव्य + Color Spaces रंग स्पेस + Shadings शेडिंग + Patterns (graphics objects) पैटर्न (ग्राफ़िक्स ऑब्जेक्ट) + Extended Graphics States विस्तारित ग्राफ़िक्स स्थितियाँ + Embedded Files एम्बेडेड फ़ाइलें + Document Overhead दस्तावेज़ ओवरहेड + Total कुल + Text Field Properties टेक्स्ट फ़ील्ड गुण + Check Box Properties चेकबॉक्स गुण + Radio Button Properties रेडियो बटन गुण + Dropdown Properties ड्रॉप-डाउन गुण + List Box Properties सूची बॉक्स गुण + Button Properties बटन गुण + Digital Signature Properties डिजिटल हस्ताक्षर गुण + Position स्थिति + Options विकल्प + Validate सत्यापित करें + Calculate गणना करें + Actions क्रियाएँ + This field is locked. Unlock it to change its properties. यह फ़ील्ड लॉक है। इसके गुण बदलने के लिए इसे अनलॉक करें। + Tooltip: टूलटिप: + Common Properties सामान्य गुण + Read Only केवल पढ़ने के लिए + Required आवश्यक + Font Size: फ़ॉन्ट आकार: + Auto स्वतः + Text Color: पाठ का रंग: + Borders and Colors बॉर्डर और रंग + Border Color: बॉर्डर का रंग: + Fill Color: भरण का रंग: + No color कोई रंग नहीं + Beveled बेवेल्ड + Left: बाएँ: + Bottom: नीचे: + Width: चौड़ाई: + Height: ऊँचाई: + Points from the page's bottom-left corner. पृष्ठ के निचले-बाएँ कोने से बिंदुओं में। + Alignment: संरेखण: + Default Value: डिफ़ॉल्ट मान: + Multi-line बहु-पंक्ति + Scroll long text लंबा पाठ स्क्रॉल करें + Allow Rich Text Formatting रिच टेक्स्ट फ़ॉर्मैटिंग की अनुमति दें + Limit of अधिकतम + characters वर्ण + Field is used for file selection फ़ील्ड का उपयोग फ़ाइल चयन के लिए किया जाता है + Check spelling वर्तनी की जाँच करें + Comb of कॉम्ब में + Export Value: {on} निर्यात मान: {on} + Check box is checked by default चेक बॉक्स डिफ़ॉल्ट रूप से चुना हुआ है + Button is checked by default बटन डिफ़ॉल्ट रूप से चुना हुआ है + Buttons with the same name and value are selected in unison एक ही नाम और मान वाले बटन एक साथ चुने जाते हैं + Item: मद: + Item List मद सूची + Up ऊपर + Delete {o} {o} हटाएँ + Add the choices people pick from. वे विकल्प जोड़ें जिनमें से लोग चुन सकें। + Default: डिफ़ॉल्ट: + (none) (कोई नहीं) + Sort items मदों को क्रमबद्ध करें + Allow user to enter custom text उपयोगकर्ता को कस्टम पाठ दर्ज करने की अनुमति दें + Multiple selection एकाधिक चयन + Commit selected value immediately चयनित मान तुरंत लागू करें + Number संख्या + Percentage प्रतिशत + Time समय + Special विशेष + Select format category: प्रारूप श्रेणी चुनें: + The value is shown as typed. मान वैसा ही दिखता है जैसा दर्ज किया गया हो। + Decimal places: दशमलव स्थान: + Separator style: विभाजक शैली: + Currency symbol: मुद्रा प्रतीक: + Before the number संख्या से पहले + Negative number style: ऋणात्मक संख्या शैली: + Format: प्रारूप: + Custom: कस्टम: + Zip Code ज़िप कोड + Zip Code + 4 ज़िप कोड + 4 + Phone Number फ़ोन नंबर + Social Security Number सामाजिक सुरक्षा संख्या + Arbitrary Mask मनमाना मास्क + Mask: मास्क: + 9 digit, A letter, O letter or digit, X any character 9 अंक, A अक्षर, O अक्षर या अंक, X कोई भी वर्ण + Example: {sample} उदाहरण: {sample} + Field value is not validated फ़ील्ड मान सत्यापित नहीं होता + Field value is in range: फ़ील्ड मान श्रेणी में है: + Add an Action क्रिया जोड़ें + Select Trigger: ट्रिगर चुनें: + Mouse Up माउस अप + Mouse Down माउस डाउन + Mouse Enter माउस एंटर + Mouse Exit माउस एक्ज़िट + On Focus ऑन फ़ोकस + On Blur ऑन ब्लर + Select Action: क्रिया चुनें: + Open a web link वेब लिंक खोलें + Reset a form फ़ॉर्म रीसेट करें + Execute a menu item मेनू मद चलाएँ + Show a field फ़ील्ड दिखाएँ + Hide a field फ़ील्ड छिपाएँ + Submit a form फ़ॉर्म सबमिट करें + Fields to reset (comma-separated; empty: all) रीसेट करने के लिए फ़ील्ड (कॉमा से अलग; खाली: सभी) + Print, NextPage, PrevPage, FirstPage or LastPage Print, NextPage, PrevPage, FirstPage या LastPage + Field names (comma-separated) फ़ील्ड नाम (कॉमा से अलग) + URL to submit to सबमिट करने का URL + Script: स्क्रिप्ट: + Value: मान: + No actions कोई क्रिया नहीं + Value is not calculated मान की गणना नहीं होती + Value is the मान निम्नलिखित फ़ील्डों का + sum (+) योग (+) + product (x) गुणनफल (x) + average औसत + minimum न्यूनतम + maximum अधिकतम + of the following fields: है: + Simplified field notation: सरलीकृत फ़ील्ड संकेतन: + Field names with + - * / and parentheses; put \\ before spaces in names. + - * / और कोष्ठकों के साथ फ़ील्ड नाम; नामों में रिक्त स्थान से पहले \\ लगाएँ। + Finding document fonts… दस्तावेज़ के फ़ॉन्ट खोजे जा रहे हैं… + Installed fonts… इंस्टॉल किए गए फ़ॉन्ट… + Keep source fonts स्रोत फ़ॉन्ट रखें + Load font… फ़ॉन्ट लोड करें… + No openly licensed document fonts found. Load a font file. कोई खुले लाइसेंस वाला दस्तावेज़ फ़ॉन्ट नहीं मिला। कोई फ़ॉन्ट फ़ाइल लोड करें। + Format text पाठ स्वरूपित करें + Bold बोल्ड + Italic इटैलिक + Align left बाएँ संरेखित करें + Centre मध्य + Align right दाएँ संरेखित करें + Justify जस्टिफ़ाई + Thai and Arabic use regular fallback fonts when available. थाई और अरबी उपलब्ध होने पर सामान्य फ़ॉलबैक फ़ॉन्ट का उपयोग करते हैं। + Edit image छवि संपादित करें + Rotate counterclockwise वामावर्त घुमाएँ + Rotate clockwise दक्षिणावर्त घुमाएँ + Flip horizontal क्षैतिज पलटें + Flip vertical लंबवत पलटें + Replace image छवि बदलें + Crop (% trimmed from each side) क्रॉप (हर ओर से % कटा हुआ) + Click on the page to add text; each click starts a new box, and ✓ finishes. Drag items to move them, drag a corner to resize, double-click text to edit it. पाठ जोड़ने के लिए पृष्ठ पर क्लिक करें; हर क्लिक एक नया बॉक्स शुरू करता है और ✓ उसे पूरा करता है। आइटम खिसकाने के लिए उन्हें खींचें, आकार बदलने के लिए कोना खींचें, पाठ संपादित करने के लिए उस पर डबल-क्लिक करें। + Choose an image कोई छवि चुनें + Export to Image छवि में निर्यात करें + Export to Text पाठ में निर्यात करें + Export All Images सभी छवियाँ निर्यात करें + Resolution रेज़ोल्यूशन + Format प्रारूप + Quality गुणवत्ता + One {f} file per page, named after the document. हर पृष्ठ के लिए एक {f} फ़ाइल, दस्तावेज़ के नाम पर। + Exclude images smaller than इससे छोटी छवियाँ बाहर रखें + No limit कोई सीमा नहीं + Each image once, named after the document and page. JPEG images are saved unchanged; others as PNG. हर छवि एक बार, दस्तावेज़ और पृष्ठ के नाम पर। JPEG छवियाँ बिना बदलाव के सहेजी जाती हैं; बाकी PNG के रूप में। + Plain text in reading order; pages are separated by form feeds. पढ़ने के क्रम में सादा पाठ; पृष्ठ फ़ॉर्म फ़ीड से विभाजित होते हैं। + Create {what} {what} बनाएँ + initials प्रथमाक्षर + signature हस्ताक्षर + Create Custom Stamp कस्टम स्टाम्प बनाएँ + From {file} {file} से + Category: श्रेणी: + e.g. My stamps जैसे मेरे स्टाम्प + Name: नाम: + Custom कस्टम + Delete stamp स्टाम्प हटाएँ + Create custom stamp… कस्टम स्टाम्प बनाएँ… + From a PDF page or an image पीडीएफ़ पृष्ठ या छवि से + Line spacing पंक्ति अंतराल + Character spacing वर्ण अंतराल + Horizontal scale क्षैतिज स्केल + Rotate Clockwise दक्षिणावर्त घुमाएँ + Rotate Counterclockwise वामावर्त घुमाएँ + Flip Horizontal क्षैतिज पलटें + Flip Vertical लंबवत पलटें + Replace Image… छवि बदलें… + Save Image As… छवि इस रूप में सहेजें… + Copy Image छवि कॉपी करें + The image has been copied ({w} × {h} pixels) छवि कॉपी हो गई है ({w} × {h} पिक्सेल) + Couldn't copy the image: {e} छवि कॉपी नहीं हो सकी: {e} + Copy Image in Original Format छवि मूल प्रारूप में कॉपी करें + The image has been copied as a {ext} file छवि {ext} फ़ाइल के रूप में कॉपी हो गई है + The page has changed; select the image again पृष्ठ बदल गया है; छवि फिर से चुनें + Check for updates अपडेट के लिए जाँचें + No check has run yet. अभी तक कोई जाँच नहीं चली है। + Checking for a newer version… नए संस्करण की जाँच हो रही है… + PdfCraft {v} is available. PdfCraft {v} उपलब्ध है। + You have version {c}. Download the new version from its release page. आपके पास संस्करण {c} है। नया संस्करण इसके रिलीज़ पृष्ठ से डाउनलोड करें। + PdfCraft {c} is up to date. PdfCraft {c} अद्यतन है। + Couldn't check for updates: {e} अपडेट की जाँच नहीं हो सकी: {e} + You have version {c}. All releases are listed at {page}. आपके पास संस्करण {c} है। सभी रिलीज़ {page} पर सूचीबद्ध हैं। + Asks GitHub for the latest release. Nothing is downloaded or installed automatically. GitHub से नवीनतम रिलीज़ की क्वेरी करता है। कुछ भी स्वतः डाउनलोड या इंस्टॉल नहीं होता। + Download डाउनलोड + Later बाद में + none कोई नहीं + Declared conformance: {shown} घोषित अनुरूपता: {shown} + Output intent: {list} आउटपुट इंटेंट: {list} + Conformance level: अनुरूपता स्तर: + No problems found: the document conforms to {level}. कोई समस्या नहीं मिली: दस्तावेज़ {level} के अनुरूप है। + (page {p}) (पृष्ठ {p}) + · not fixable here · यहाँ ठीक नहीं किया जा सकता + Verify सत्यापित करें + Box बॉक्स + Units इकाइयाँ + Set to zero शून्य पर सेट करें + Current page ({n}) मौजूदा पृष्ठ ({n}) + Subset उपसमुच्चय + Update अपडेट करें + Add जोड़ें + {verb} Header and Footer {verb} हेडर और फ़ुटर + {verb} Watermark {verb} वॉटरमार्क + {verb} Background {verb} पृष्ठभूमि + Margins (in) हाशिये (इंच) + Left Header Text बायाँ हेडर पाठ + Center Header Text मध्य हेडर पाठ + Right Header Text दायाँ हेडर पाठ + Left Footer Text बायाँ फ़ुटर पाठ + Center Footer Text मध्य फ़ुटर पाठ + Right Footer Text दायाँ फ़ुटर पाठ + Insert Page Number पृष्ठ संख्या जोड़ें + Insert Date दिनांक जोड़ें + Start page number प्रारंभिक पृष्ठ संख्या + Source स्रोत + Fit to page पृष्ठ के अनुसार फ़िट करें + Rotation घुमाव + Appear behind page पृष्ठ के पीछे दिखें + Appear on top of page पृष्ठ के ऊपर दिखें + Offset from centre केंद्र से ऑफ़सेट + From colour रंग से + Page Range Options पृष्ठ श्रेणी विकल्प + Preview: page {p} of {n} पूर्वावलोकन: पृष्ठ {p} / {n} + Applies to 1 page 1 पृष्ठ पर लागू + Applies to {n} pages {n} पृष्ठों पर लागू + Replaces the existing one on those pages. उन पृष्ठों पर मौजूदा वाले को बदल देता है। + PDF or image पीडीएफ़ या छवि + No file chosen कोई फ़ाइल नहीं चुनी गई + Page number पृष्ठ संख्या + Scale relative to target page लक्ष्य पृष्ठ के सापेक्ष स्केल + Link Properties लिंक गुण + Create Link लिंक बनाएँ + Link Appearance लिंक स्वरूप + Link Type: लिंक प्रकार: + Visible Rectangle दृश्यमान आयत + Invisible Rectangle अदृश्य आयत + Highlight Style: हाइलाइट शैली: + Invert उलटा + Outline रूपरेखा + Inset इनसेट + Line Thickness: रेखा की मोटाई: + Thin पतली + Thick मोटी + Line Style: रेखा शैली: + Solid सॉलिड + Dashed डैश्ड + Color: रंग: + Link Action लिंक क्रिया + Open a web page वेब पृष्ठ खोलें + Go to a page view पृष्ठ दृश्य पर जाएँ + Type the web address. वेब पता टाइप करें। + This document has no signatures. इस दस्तावेज़ में कोई हस्ताक्षर नहीं है। + The Keychain's digital IDs couldn't be listed: {e} Keychain की डिजिटल आईडी सूचीबद्ध नहीं की जा सकीं: {e} + Signed and saved to {path} हस्ताक्षरित कर {path} पर सहेजा गया + Couldn't open revision {n}: {e} संशोधन {n} नहीं खोला जा सका: {e} + Couldn't open the signed version: {e} हस्ताक्षरित संस्करण नहीं खोला जा सका: {e} + Sign with a Digital ID डिजिटल आईडी से हस्ताक्षर करें + Choose the digital ID that you want to use for signing: हस्ताक्षर के लिए जिस डिजिटल आईडी का उपयोग आप करना चाहते हैं उसे चुनें: + Keychain · Keychain · + Windows store · Windows स्टोर · + Issued by: जारीकर्ता: + , Expires: , समाप्ति: + No digital IDs yet. अभी तक कोई डिजिटल आईडी नहीं हैं। + Configure New Digital ID नई डिजिटल आईडी कॉन्फ़िगर करें + Continue जारी रखें + Configure a Digital ID for Signing हस्ताक्षर के लिए डिजिटल आईडी कॉन्फ़िगर करें + Use a Digital ID from a file फ़ाइल से डिजिटल आईडी उपयोग करें + Create a new Digital ID (self-signed, saved to a password-protected file) नई डिजिटल आईडी बनाएँ (स्व-हस्ताक्षरित, पासवर्ड-सुरक्षित फ़ाइल में सहेजी गई) + Name नाम + Organizational Unit संगठनात्मक इकाई + Organization Name संगठन का नाम + Email Address ईमेल पता + Country/Region देश/क्षेत्र + Key Algorithm कुंजी एल्गोरिद्म + Confirm Password पासवर्ड की पुष्टि करें + Valid for 5 years, for digital signatures. Self-signed IDs are usually not trusted by others. 5 वर्षों तक वैध, डिजिटल हस्ताक्षरों के लिए। स्व-हस्ताक्षरित आईडी पर आम तौर पर दूसरों का भरोसा नहीं होता। + File (.p12, .pfx) फ़ाइल (.p12, .pfx) + Digital ID डिजिटल आईडी + Browse… ब्राउज़ करें… + {verb} as "{name}" {verb} “{name}” के रूप में + Certify प्रमाणित करें + The signature will be invisible. हस्ताक्षर अदृश्य होगा। + The existing action will be preserved. मौजूदा क्रिया सुरक्षित रहेगी। + Distinguished name विशिष्ट नाम + Labels लेबल + Graphic ग्राफ़िक + Signer's name हस्ताक्षरकर्ता का नाम + Fill & Sign signature Fill & Sign हस्ताक्षर + Choose image… छवि चुनें… + Permitted actions after certifying प्रमाणित करने के बाद अनुमत क्रियाएँ + No changes allowed कोई बदलाव की अनुमति नहीं + Annotations, form fill-in, and digital signatures एनोटेशन, फ़ॉर्म भरना और डिजिटल हस्ताक्षर + Form fill-in and digital signatures फ़ॉर्म भरना और डिजिटल हस्ताक्षर + The key is in the macOS Keychain, which may ask to allow PdfCraft to use it. कुंजी macOS Keychain में है, जो PdfCraft को उसका उपयोग करने की अनुमति माँग सकती है। + The key is in the Windows certificate store, which may ask to allow PdfCraft to use it. कुंजी Windows प्रमाणपत्र स्टोर में है, जो PdfCraft को उसका उपयोग करने की अनुमति माँग सकता है। + Digital ID password डिजिटल आईडी पासवर्ड + Back पीछे + Validate all सभी सत्यापित करें + Sign this field… इस फ़ील्ड पर हस्ताक्षर करें… + Signature is valid: हस्ताक्षर वैध है: + Signature validity is UNKNOWN: हस्ताक्षर की वैधता अज्ञात है: + Signature is INVALID: हस्ताक्षर अमान्य है: + Signature Details हस्ताक्षर विवरण + Reason कारण + Signing time हस्ताक्षर करने का समय + Algorithm एल्गोरिद्म + Signer हस्ताक्षरकर्ता + Issued by जारीकर्ता + Valid वैध + Field फ़ील्ड + Field: {field} on page {p} फ़ील्ड: {field}, पृष्ठ {p} पर + Add to trusted certificates भरोसेमंद प्रमाणपत्रों में जोड़ें + View signed version हस्ताक्षरित संस्करण देखें + Show certificate… प्रमाणपत्र दिखाएँ… + Export certificate… प्रमाणपत्र निर्यात करें… + Certificate Viewer प्रमाणपत्र व्यूअर + This dialog shows the details of a certificate and its chain. यह संवाद प्रमाणपत्र और उसकी श्रृंखला का विवरण दिखाता है। + Trust भरोसा + Issued to जारी हुआ + Valid from इससे वैध + Valid to इस तक वैध + Intended usage अभीष्ट उपयोग + Any कोई भी + Version संस्करण + Serial number क्रमांक + Issuer जारीकर्ता + Validity starts वैधता प्रारंभ + Validity ends वैधता समाप्ति + Public key सार्वजनिक कुंजी + Key usage कुंजी उपयोग + Not present मौजूद नहीं + Self-signed स्व-हस्ताक्षरित + Edit Action क्रिया संपादित करें + New Action नई क्रिया + Action name: क्रिया का नाम: + Description: विवरण: + Steps चरण + Add the steps this action runs, in order. वे चरण जोड़ें जो यह क्रिया क्रम से चलाती है। + Add Step चरण जोड़ें + An action with this name already exists. इस नाम की क्रिया पहले से मौजूद है। + New Action… नई क्रिया… + Edit… संपादित करें… + Add watermark वॉटरमार्क जोड़ें + Add header हेडर जोड़ें + Add footer फ़ुटर जोड़ें + Set document title दस्तावेज़ शीर्षक सेट करें + Run a JavaScript JavaScript चलाएँ + Prepare for Distribution वितरण के लिए तैयार करें + Remove hidden information and flatten comments and form fields, so recipients see only the pages. छिपी जानकारी हटाएँ और टिप्पणियाँ व फ़ॉर्म फ़ील्ड फ़्लैट करें, ताकि प्राप्तकर्ता केवल पृष्ठ देखें। + Optimize Scanned Documents स्कैन किए गए दस्तावेज़ अनुकूलित करें + Make scans searchable, then make them smaller. स्कैन को खोजने योग्य बनाएँ, फिर उन्हें छोटा करें। + Add Page Numbers पृष्ठ संख्याएँ जोड़ें + Number every page in the footer. फ़ुटर में हर पृष्ठ को क्रमांकित करें। + Mark as Confidential गोपनीय के रूप में चिह्नित करें + A diagonal CONFIDENTIAL watermark on every page. हर पृष्ठ पर तिर्यक CONFIDENTIAL वॉटरमार्क। + Sanitize Documents दस्तावेज़ सैनिटाइज़ करें + Remove hidden information, metadata, scripts and embedded content, and rewrite the files. छिपी जानकारी, मेटाडेटा, स्क्रिप्ट और एम्बेडेड सामग्री हटाएँ और फ़ाइलें फिर से लिखें। + Type text पाठ टाइप करें + Text to insert जोड़ने के लिए पाठ + Replacement text बदलने का पाठ + Edit text… पाठ संपादित करें… + Add a sticky note here यहाँ एक स्टिकी नोट जोड़ें + {kind} Properties {kind} गुण + Appearance स्वरूप + General सामान्य + Review History समीक्षा इतिहास + This comment's appearance can't be changed yet. इस टिप्पणी का स्वरूप अभी नहीं बदला जा सकता। + Icon आइकन + Thickness मोटाई + Modified संशोधित + No status has been set. कोई स्थिति निर्धारित नहीं की गई है। + Compare Files फ़ाइलों की तुलना करें + Old file: पुरानी फ़ाइल: + Open the older version first पहले पुराना संस्करण खोलें + New file: नई फ़ाइल: + Text is compared word by word; the differences are shown on the new file. पाठ शब्द दर शब्द तुलना किया जाता है; अंतर नई फ़ाइल पर दिखाए जाते हैं। + Compare this file with an older version: Compare files… in All tools. इस फ़ाइल की तुलना पुराने संस्करण से करें: “सभी टूल” में “फ़ाइलों की तुलना करें…”। + No differences in the text. पाठ में कोई अंतर नहीं है। + {n} {kind} {n} {kind} + Inserted जोड़ा गया + Deleted हटाया गया + Replaced बदला गया + Visual विज़ुअल + Mark as comments टिप्पणियों के रूप में चिह्नित करें + Report… रिपोर्ट… + {kind} · page {p} {kind} · पृष्ठ {p} + Set Alternate Text वैकल्पिक पाठ सेट करें + This document has no tagged figures. इस दस्तावेज़ में कोई टैग की गई आकृतियाँ नहीं हैं। + on page {p} पृष्ठ {p} पर + Figure {i} of {n}{page} आकृति {i} / {n}{page} + No preview कोई पूर्वावलोकन नहीं + Alternate text वैकल्पिक पाठ + Describe the figure आकृति का वर्णन करें + Decorative figure सजावटी आकृति + Previous figure पिछली आकृति + Next figure अगली आकृति + Save & Close सहेजें और बंद करें + Accessibility Checker Options एक्सेसिबिलिटी चेकर विकल्प + Report Options रिपोर्ट विकल्प + Create accessibility report एक्सेसिबिलिटी रिपोर्ट बनाएँ + Page Range पृष्ठ श्रेणी + All pages in document दस्तावेज़ के सभी पृष्ठ + Checking Options ({on} of 32 in all categories) जाँच विकल्प (सभी श्रेणियों के 32 में से {on}) + Show this dialog when the Checker starts चेकर शुरू होने पर यह संवाद दिखाएँ + Select All सभी चुनें + Clear All सभी साफ़ करें + Start Checking जाँच शुरू करें + This document hasn't been checked yet. इस दस्तावेज़ की अभी तक जाँच नहीं हुई है। + No issues found कोई समस्या नहीं मिली + 1 issue 1 समस्या + {n} issues {n} समस्याएँ + {label} (1 issue) {label} (1 समस्या) + {label} ({n} issues) {label} ({n} समस्याएँ) + Check again फिर से जाँचें + Report रिपोर्ट + Show the accessibility report एक्सेसिबिलिटी रिपोर्ट दिखाएँ + Collapse समेटें + Expand विस्तृत करें + {rule} - {status} {rule} - {status} + Passed उत्तीर्ण + Failed अनुत्तीर्ण + Needs manual check मैन्युअल जाँच आवश्यक + Skipped छोड़ा गया + Fix ठीक करें + Skip Rule नियम छोड़ें + Explain स्पष्ट करें + Check Again फिर से जाँचें + Show Report रिपोर्ट दिखाएँ + Options… विकल्प… + Go to the page पृष्ठ पर जाएँ + Page Content पृष्ठ सामग्री + Forms फ़ॉर्म + Alternate Text वैकल्पिक पाठ + Tables तालिकाएँ + Lists सूचियाँ + Headings शीर्षक + Accessibility permission flag एक्सेसिबिलिटी अनुमति फ़्लैग + Accessibility permission flag is set एक्सेसिबिलिटी अनुमति फ़्लैग सेट है + Security settings must allow assistive technology to read the content ("Enable text access for screen reader devices"). Change the document's security to allow it. सुरक्षा सेटिंग सहायक तकनीक को सामग्री पढ़ने की अनुमति देनी चाहिए (“स्क्रीन रीडर उपकरणों के लिए पाठ पहुँच सक्षम करें”)। इसकी अनुमति देने के लिए दस्तावेज़ की सुरक्षा बदलें। + Image-only PDF केवल-छवि पीडीएफ़ + Document is not image-only PDF दस्तावेज़ केवल-छवि पीडीएफ़ नहीं है + Pages that are only pictures of text can't be read aloud or searched. Recognize text (OCR) to add a text layer. जो पृष्ठ केवल पाठ की तस्वीरें हैं उन्हें पढ़ा या खोजा नहीं जा सकता। पाठ परत जोड़ने के लिए पाठ पहचानें (OCR)। + Document is tagged PDF दस्तावेज़ टैगयुक्त पीडीएफ़ है + Tags give the document a logical structure that assistive technology follows. Tag the document (Automatically tag PDF). टैग दस्तावेज़ को तार्किक संरचना देते हैं जिसका पालन सहायक तकनीक करती है। दस्तावेज़ को टैग करें (पीडीएफ़ स्वतः टैग करें)। + Logical Reading Order तार्किक पढ़ने का क्रम + Document structure provides a logical reading order दस्तावेज़ की संरचना तार्किक पढ़ने का क्रम देती है + Check that the tags read in the order a sighted reader would. Use the Reading Order tool or the Tags panel to correct it. जाँचें कि टैग उसी क्रम में पढ़े जाते हैं जिस क्रम में कोई देखने वाला पाठक पढ़ता। इसे ठीक करने के लिए पढ़ने के क्रम का टूल या टैग पैनल उपयोग करें। + Primary language मुख्य भाषा + Text language is specified पाठ की भाषा निर्दिष्ट है + Screen readers choose their voice from the document's language. Set it in Document Properties > Advanced > Language. स्क्रीन रीडर दस्तावेज़ की भाषा से अपनी आवाज़ चुनते हैं। इसे “दस्तावेज़ गुण > उन्नत > भाषा” में सेट करें। + Document title is showing in title bar दस्तावेज़ शीर्षक शीर्षक पट्टी में दिख रहा है + The window should show a meaningful title rather than the file name. Set a title and Initial View > Show: Document Title. विंडो को फ़ाइल नाम के बजाय सार्थक शीर्षक दिखाना चाहिए। शीर्षक सेट करें और “प्रारंभिक दृश्य > दिखाएँ: दस्तावेज़ शीर्षक”। + Bookmarks are present in large documents बड़े दस्तावेज़ों में बुकमार्क मौजूद हैं + Documents of more than 20 pages need bookmarks for navigation. Add bookmarks for the main sections. 20 से अधिक पृष्ठों वाले दस्तावेज़ों को नेविगेशन के लिए बुकमार्क चाहिए। मुख्य अनुभागों के लिए बुकमार्क जोड़ें। + Color contrast रंग कंट्रास्ट + Document has appropriate color contrast दस्तावेज़ में उचित रंग कंट्रास्ट है + Text must contrast enough with its background for people with low vision. Check the colours by eye or with a contrast tool. कम दृष्टि वाले लोगों के लिए पाठ का पृष्ठभूमि से पर्याप्त कंट्रास्ट होना चाहिए। रंग आँख से या कंट्रास्ट टूल से जाँचें। + Tagged content टैग की गई सामग्री + All page content is tagged पृष्ठ की सभी सामग्री टैग की गई है + Everything on a page must be tagged or marked as an artifact (decoration, headers, footers). Tag the untagged content. पृष्ठ पर सब कुछ टैग किया जाना चाहिए या आर्टिफ़ैक्ट (सजावट, हेडर, फ़ुटर) के रूप में चिह्नित। बिना टैग वाली सामग्री को टैग करें। + Tagged annotations टैग किए गए एनोटेशन + All annotations are tagged सभी एनोटेशन टैग किए गए हैं + Comments, links and fields must be in the tag tree to be announced. Tag the annotations. टिप्पणियों, लिंक और फ़ील्ड का ऐलान होने के लिए उन्हें टैग ट्री में होना चाहिए। एनोटेशन को टैग करें। + Tab order टैब क्रम + Tab order is consistent with structure order टैब क्रम संरचना क्रम के अनुरूप है + Pages with links, comments or fields should tab in structure order. The fix sets each page's tab order to Use Document Structure. लिंक, टिप्पणियों या फ़ील्ड वाले पृष्ठों में टैब संरचना क्रम में चलना चाहिए। यह ठीक करने पर हर पृष्ठ का टैब क्रम “दस्तावेज़ संरचना उपयोग करें” पर सेट हो जाता है। + Character encoding वर्ण एन्कोडिंग + Reliable character encoding is provided विश्वसनीय वर्ण एन्कोडिंग दी गई है + Fonts must map their characters to Unicode so text can be read and copied. Fix the fonts or recreate the PDF. फ़ॉन्ट को अपने वर्ण यूनिकोड से मैप करने चाहिए ताकि पाठ पढ़ा और कॉपी किया जा सके। फ़ॉन्ट ठीक करें या पीडीएफ़ फिर से बनाएँ। + Tagged multimedia टैग किया गया मल्टीमीडिया + All multimedia objects are tagged सभी मल्टीमीडिया वस्तुएँ टैग की गई हैं + Video, sound and rich media must be tagged to be announced. Tag the multimedia annotations. वीडियो, ध्वनि और रिच मीडिया का ऐलान होने के लिए उन्हें टैग किया जाना चाहिए। मल्टीमीडिया एनोटेशन को टैग करें। + Screen flicker स्क्रीन टिमटिमाहट + Page will not cause screen flicker पृष्ठ से स्क्रीन टिमटिमाहट नहीं होगी + Animation that flashes can cause seizures. Check scripts and media for flicker. चमकता एनिमेशन दौरे पैदा कर सकता है। स्क्रिप्ट और मीडिया में टिमटिमाहट जाँचें। + Scripts स्क्रिप्ट + No inaccessible scripts कोई असुगम स्क्रिप्ट नहीं + Timed responses समय-सीमित उत्तर + Page does not require timed responses पृष्ठ को समय-सीमित उत्तर की आवश्यकता नहीं है + People may need more time to respond. Check that nothing has a time limit. जवाब देने में लोगों को अधिक समय चाहिए हो सकता है। जाँचें कि किसी चीज़ की समय सीमा न हो। + Navigation links नेविगेशन लिंक + Navigation links are not repetitive नेविगेशन लिंक दोहरावपूर्ण नहीं हैं + Repeated navigation links should be skippable. Check links that appear on every page. बार-बार आने वाले नेविगेशन लिंक को छोड़ा जा सकना चाहिए। हर पृष्ठ पर आने वाले लिंक जाँचें। + Tagged form fields टैग किए गए फ़ॉर्म फ़ील्ड + All form fields are tagged सभी फ़ॉर्म फ़ील्ड टैग किए गए हैं + Form fields must be in the tag tree (Form tags) to be announced. Tag the form fields. फ़ॉर्म फ़ील्ड का ऐलान होने के लिए उन्हें टैग ट्री (फ़ॉर्म टैग) में होना चाहिए। फ़ॉर्म फ़ील्ड को टैग करें। + Field descriptions फ़ील्ड विवरण + All form fields have description सभी फ़ॉर्म फ़ील्ड का विवरण है + Each field needs a tooltip that says what to enter. Add one in Field Properties > General > Tooltip. हर फ़ील्ड को एक टूलटिप चाहिए जो बताए कि क्या दर्ज करना है। इसे “फ़ील्ड गुण > सामान्य > टूलटिप” में जोड़ें। + Figures alternate text आकृतियों का वैकल्पिक पाठ + Figures require alternate text आकृतियों को वैकल्पिक पाठ चाहिए + Pictures need alternate text that describes them, or must be marked decorative. Add alternate text to each figure. तस्वीरों को उनका वर्णन करने वाला वैकल्पिक पाठ चाहिए या उन्हें सजावटी चिह्नित करना चाहिए। हर आकृति में वैकल्पिक पाठ जोड़ें। + Nested alternate text नेस्टेड वैकल्पिक पाठ + Alternate text that will never be read वैकल्पिक पाठ जो कभी नहीं पढ़ा जाएगा + Alternate text inside an element that already has alternate text is never read. Remove the inner alternate text. जिस तत्व में पहले से वैकल्पिक पाठ है, उसके भीतर का वैकल्पिक पाठ कभी नहीं पढ़ा जाता। भीतरी वैकल्पिक पाठ हटाएँ। + Associated with content सामग्री से संबद्ध + Alternate text must be associated with some content वैकल्पिक पाठ किसी सामग्री से संबद्ध होना चाहिए + Alternate text on an element without page content is never reached. Remove it or attach the element to content. बिना पृष्ठ सामग्री वाले तत्व का वैकल्पिक पाठ तक कभी नहीं पहुँचा जाता। उसे हटाएँ या तत्व को सामग्री से जोड़ें। + Hides annotation एनोटेशन छिपाता है + Alternate text should not hide annotation वैकल्पिक पाठ को एनोटेशन नहीं छिपाना चाहिए + Alternate text on an element that contains a link or field hides that annotation from assistive technology. Move the alternate text. लिंक या फ़ील्ड वाले तत्व का वैकल्पिक पाठ उस एनोटेशन को सहायक तकनीक से छिपा देता है। वैकल्पिक पाठ को हटाकर दूसरी जगह रखें। + Other elements alternate text अन्य तत्वों का वैकल्पिक पाठ + Other elements that require alternate text अन्य तत्व जिन्हें वैकल्पिक पाठ चाहिए + Formulas and similar non-text elements need alternate text. Add alternate text to them. सूत्रों और इसी तरह के गैर-पाठ तत्वों को वैकल्पिक पाठ चाहिए। उनमें वैकल्पिक पाठ जोड़ें। + Rows पंक्तियाँ + TR must be a child of Table, THead, TBody, or TFoot TR को Table, THead, TBody या TFoot की संतान होना चाहिए + Table cells belong in a row. Fix the table's tags. तालिका कोशिकाएँ पंक्ति में होनी चाहिए। तालिका के टैग ठीक करें। + Headers शीर्षक + Tables should have headers तालिकाओं में शीर्षक होने चाहिए + Header cells (TH) tell listeners what each column or row holds. Mark the header cells. शीर्षक कोशिकाएँ (TH) सुनने वालों को बताती हैं कि हर कॉलम या पंक्ति में क्या है। शीर्षक कोशिकाओं को चिह्नित करें। + Regularity नियमितता + Tables must contain the same number of columns in each row and rows in each column तालिकाओं की हर पंक्ति में कॉलमों की संख्या और हर कॉलम में पंक्तियों की संख्या समान होनी चाहिए + Irregular tables confuse cell navigation. Give every row the same number of cells (counting spans). अनियमित तालिकाएँ कोशिका नेविगेशन में भ्रम पैदा करती हैं। हर पंक्ति को समान संख्या में कोशिकाएँ दें (स्पैन गिनते हुए)। + Summary सारांश + Tables must have a summary तालिकाओं में सारांश होना चाहिए + A summary describes the table's purpose and layout. Add a Summary attribute to each table. सारांश तालिका के उद्देश्य और लेआउट का वर्णन करता है। हर तालिका में Summary विशेषता जोड़ें। + List items सूची मदें + LI must be a child of L LI को L की संतान होना चाहिए + List items belong in a list. Fix the list's tags. सूची मदें सूची में होनी चाहिए। सूची के टैग ठीक करें। + Lbl and LBody Lbl और LBody + Lbl and LBody must be children of LI Lbl और LBody को LI की संतानाएँ होना चाहिए + List labels and bodies belong in a list item. Fix the list's tags. सूची लेबल और बॉडी सूची मद में होनी चाहिए। सूची के टैग ठीक करें। + Appropriate nesting उचित नेस्टिंग + Heading levels shouldn't skip (an H1 followed by an H3). Retag the headings. शीर्षक स्तर छूटने नहीं चाहिए (H1 के बाद H3)। शीर्षकों के टैग फिर से लगाएँ। + TH and TD TH और TD + TH and TD must be children of TR TH और TD को TR की संतानाएँ होना चाहिए + Mark Page Range पृष्ठ श्रेणी चिह्नित करें + Pages from पृष्ठ + Single word or phrase एक शब्द या वाक्यांश + Text to find खोजने के लिए पाठ + Patterns पैटर्न + Phone Numbers फ़ोन नंबर + Email Addresses ईमेल पते + Credit Cards क्रेडिट कार्ड + Social Security Numbers सामाजिक सुरक्षा संख्याएँ + Dates तिथियाँ + Text in images isn't found; recognise text (OCR) first. छवियों में पाठ नहीं मिलता; पहले पाठ पहचानें (OCR)। + No matches. कोई मिलान नहीं। + Some bookmarks are not shown here: the panel lists a limited number, nested a limited depth. कुछ बुकमार्क यहाँ नहीं दिखाए गए हैं: पैनल सीमित संख्या में बुकमार्क, सीमित गहराई तक दिखाता है। + {n} match(es) marked for redaction. रिडैक्शन के लिए चिह्नित मिलान: {n}। + Multiple words or phrases एकाधिक शब्द या वाक्यांश + One word or phrase per line प्रति पंक्ति एक शब्द या वाक्यांश + Import list… सूची आयात करें… + {n} word(s) or phrase(s) शब्द या वाक्यांश: {n} + {name} is too large for a word list (at most 1 MB). {name} शब्द सूची के लिए बहुत बड़ा है (अधिकतम 1 MB)। + Redaction Tool Properties रिडैक्शन टूल गुण + Redacted area fill colour: रिडैक्टेड क्षेत्र का भरण रंग: + Use overlay text ओवरले पाठ का उपयोग करें + Custom text: कस्टम पाठ: + Redaction code: रिडैक्शन कोड: + Font: फ़ॉन्ट: + Font size: फ़ॉन्ट आकार: + Auto-size text to fit redaction region पाठ का आकार रिडैक्शन क्षेत्र के अनुसार स्वतः रखें + Font colour: फ़ॉन्ट रंग: + Repeat overlay text ओवरले पाठ दोहराएँ + Text alignment: पाठ संरेखण: + Center मध्य + Apply redactions रिडैक्शन लागू करें + You are about to apply 1 redaction mark. Text, images and drawings under the marks, and comments and form fields that overlap them, are removed permanently. आप 1 रिडैक्शन चिह्न लागू करने जा रहे हैं। चिह्नों के नीचे का पाठ, छवियाँ और चित्र, तथा उन्हें ढकने वाली टिप्पणियाँ और फ़ॉर्म फ़ील्ड स्थायी रूप से हटा दिए जाते हैं। + You are about to apply {n} redaction marks. Text, images and drawings under the marks, and comments and form fields that overlap them, are removed permanently. आप {n} रिडैक्शन चिह्न लागू करने जा रहे हैं। चिह्नों के नीचे का पाठ, छवियाँ और चित्र, तथा उन्हें ढकने वाली टिप्पणियाँ और फ़ॉर्म फ़ील्ड स्थायी रूप से हटा दिए जाते हैं। + Save the document afterwards: saving rewrites the whole file so no trace of the removed content stays in it. इसके बाद दस्तावेज़ सहेजें: सहेजने पर पूरी फ़ाइल फिर से लिखी जाती है, ताकि हटाई गई सामग्री का कोई निशान न रहे। + Select the items to remove from this document. इस दस्तावेज़ से हटाने के लिए मदें चुनें। + Metadata मेटाडेटा + File attachments फ़ाइल अनुलग्नक + Comments and markups टिप्पणियाँ और मार्कअप + Hidden text छिपा हुआ पाठ + Hidden layers छिपी हुई परतें + Links, actions and JavaScripts लिंक, क्रियाएँ और JavaScript + Private data of other applications अन्य ऐप्लिकेशन का निजी डेटा + None found कुछ नहीं मिला + Form fields are flattened: their values stay visible. Saving rewrites the whole file. फ़ॉर्म फ़ील्ड फ़्लैट हो जाते हैं: उनके मान दिखते रहते हैं। सहेजने पर पूरी फ़ाइल फिर से लिखी जाती है। + Remove हटाएँ + Sanitizing removes hidden information from the document: metadata, file attachments, comments, form fields (flattened), hidden text and layers, bookmarks, links, actions and scripts, and private application data. सैनिटाइज़ करने से दस्तावेज़ से छिपी जानकारी हटती है: मेटाडेटा, फ़ाइल अनुलग्नक, टिप्पणियाँ, फ़ॉर्म फ़ील्ड (फ़्लैट किए गए), छिपा पाठ और परतें, बुकमार्क, लिंक, क्रियाएँ और स्क्रिप्ट, तथा ऐप्लिकेशन का निजी डेटा। + Save the document afterwards; saving rewrites the whole file so nothing removed stays in it. इसके बाद दस्तावेज़ सहेजें; सहेजने पर पूरी फ़ाइल फिर से लिखी जाती है, ताकि हटाई गई कोई चीज़ उसमें न रह जाए। + Printer: प्रिंटर: + Save as PDF पीडीएफ़ के रूप में सहेजें + {name} (default) {name} (डिफ़ॉल्ट) + Copies: प्रतियाँ: + Collate कॉलेट करें + Print in grayscale ग्रेस्केल में प्रिंट करें + Two-sided: दो तरफ़ा: + Off बंद + Flip on long edge लंबे किनारे पर पलटें + Flip on short edge छोटे किनारे पर पलटें + Paper: कागज़: + Pages to Print प्रिंट करने के लिए पृष्ठ + More options: अधिक विकल्प: + All pages in range श्रेणी के सभी पृष्ठ + Odd pages only केवल विषम पृष्ठ + Even pages only केवल सम पृष्ठ + Reverse pages पृष्ठ उल्टे क्रम में + Page Sizing & Handling पृष्ठ आकार और प्रबंधन + Size आकार + Poster पोस्टर + Multiple एकाधिक + Booklet बुकलेट + Fit फ़िट + Shrink oversized pages अत्यधिक बड़े पृष्ठ सिकोड़ें + Custom scale: कस्टम पैमाना: + Tile scale: टाइल पैमाना: + Overlap: ओवरलैप: + Cut marks कट मार्क्स + Pages per sheet: प्रति शीट पृष्ठ: + Page order: पृष्ठ क्रम: + Horizontal क्षैतिज + Horizontal reversed क्षैतिज, उल्टे क्रम में + Vertical ऊर्ध्वाधर + Vertical reversed ऊर्ध्वाधर, उल्टे क्रम में + Print page border पृष्ठ बॉर्डर प्रिंट करें + Auto-rotate pages पृष्ठ स्वतः घुमाएँ + Booklet subset: बुकलेट भाग: + Both sides दोनों ओर + Front side only केवल सामने का भाग + Back side only केवल पीछे का भाग + Binding: बंधन: + Left बाएँ + Right दाएँ + Orientation: अभिविन्यास: + Auto portrait/landscape स्वतः पोर्ट्रेट/लैंडस्केप + Portrait पोर्ट्रेट + Landscape लैंडस्केप + Comments & Forms टिप्पणियाँ और फ़ॉर्म + Document दस्तावेज़ + Document and markups दस्तावेज़ और मार्कअप + Document and stamps दस्तावेज़ और स्टाम्प + Form fields only केवल फ़ॉर्म फ़ील्ड + Previous sheet पिछली शीट + Next sheet अगली शीट + No sheets कोई शीट नहीं + Sheet {s} of {n} कुल {n} में से शीट {s} + Removed 1 hidden item. Save to remove them from the file. 1 छिपी हुई वस्तु हटाई गई। इसे फ़ाइल से हटाने के लिए सहेजें। + Removed {n} hidden items. Save to remove them from the file. {n} छिपी हुई वस्तुएँ हटाई गईं। इन्हें फ़ाइल से हटाने के लिए सहेजें। + Document sanitized. Save to finish: saving rewrites the whole file. दस्तावेज़ साफ़ कर दिया गया। पूरा करने के लिए सहेजें: सहेजने पर पूरी फ़ाइल फिर से लिखी जाती है। + Applied 1 redaction mark. Save to remove the content from the file. 1 रेडैक्शन चिह्न लागू किया गया। सामग्री फ़ाइल से हटाने के लिए सहेजें। + Applied {n} redaction marks. Save to remove the content from the file. {n} रेडैक्शन चिह्न लागू किए गए। सामग्री फ़ाइल से हटाने के लिए सहेजें। + JavaScript Console JavaScript कंसोल + JavaScript is turned off (Preferences ▸ JavaScript). JavaScript बंद है (प्राथमिकताएँ ▸ JavaScript)। + Output appears here. आउटपुट यहाँ दिखता है। + Script Name: स्क्रिप्ट का नाम: + This document has no document-level scripts. इस दस्तावेज़ में दस्तावेज़-स्तर की कोई स्क्रिप्ट नहीं है। + No form fields were detected कोई फ़ॉर्म फ़ील्ड नहीं मिला + Detected 1 form field 1 फ़ॉर्म फ़ील्ड मिला + Detected {n} form fields {n} फ़ॉर्म फ़ील्ड मिले + {field}: {e} {field}: {e} + Current page वर्तमान पृष्ठ + Selected pages चयनित पृष्ठ + Document language दस्तावेज़ की भाषा + Output आउटपुट + Searchable Image (Exact) सर्च योग्य छवि (सटीक) + Adds invisible text over each word; the page image is not changed हर शब्द के ऊपर अदृश्य टेक्स्ट जोड़ता है; पृष्ठ की छवि नहीं बदलती + Downsample to इस तक डाउनसैंपल करें + Also recognize pages that already have text उन पृष्ठों को भी पहचानें जिन पर पहले से टेक्स्ट है + Pictures on those pages are recognized too; words already in the page's text are not added again उन पृष्ठों की तस्वीरें भी पहचानी जाती हैं; पृष्ठ के टेक्स्ट में पहले से मौजूद शब्द दोबारा नहीं जोड़े जाते + Text recognition isn't installed: its model files are missing. Reinstall PdfCraft, or set PDFCRAFT_MODELS to the folder that holds them. टेक्स्ट पहचान इंस्टॉल नहीं है: इसकी मॉडल फ़ाइलें मौजूद नहीं हैं। PdfCraft दोबारा इंस्टॉल करें, या PDFCRAFT_MODELS को उस फ़ोल्डर पर सेट करें जिसमें वे रखी हैं। + Settings सेटिंग्स + Optional वैकल्पिक + Planned · {m} नियोजित · {m} + Planned for milestone {m} — open to see what it will include माइलस्टोन {m} के लिए नियोजित — खोलने पर दिखेगा कि इसमें क्या-क्या शामिल होगा + Coming in milestone {m}. Items marked Ready work today. माइलस्टोन {m} में आ रहा है। “तैयार” चिह्नित चीज़ें आज ही काम करती हैं। + 1 mark 1 चिह्न + {n} marks {n} चिह्न + Dynamic डायनामिक + Sign Here यहाँ हस्ताक्षर करें + Standard Business स्टैंडर्ड बिज़नेस + Choose a stamp, then click on the page to place it. एक स्टाम्प चुनें, फिर उसे लगाने के लिए पृष्ठ पर क्लिक करें। + Note नोट + Polyline पॉलीलाइन + Attachment अनुलग्नक + Callout कॉलआउट + Typewriter टाइपराइटर + Checked चेक किया हुआ + Unchecked अनचेक + Marked चिह्नित + Locked लॉक किया गया + Search comments टिप्पणियाँ खोजें + Add a comment टिप्पणी जोड़ें + No comments yet. अभी कोई टिप्पणी नहीं है। + Pick a tool in the quick bar, or type above. क्विक बार में से कोई टूल चुनें, या ऊपर टाइप करें। + No comments match. कोई टिप्पणी मेल नहीं खाती। + Unknown author अज्ञात लेखक + No colour कोई रंग नहीं + Remove checkmark चेकमार्क हटाएँ + Mark with checkmark चेकमार्क लगाएँ + Reply जवाब दें + Add a reply जवाब जोड़ें + Post पोस्ट करें + Page {label} पृष्ठ {label} + {kind} — click to show it on the page {kind} — पृष्ठ पर दिखाने के लिए क्लिक करें + Set status स्थिति सेट करें + Copy text टेक्स्ट कॉपी करें + Properties… प्रॉपर्टीज़… + Make Current Properties Default वर्तमान प्रॉपर्टीज़ डिफ़ॉल्ट बनाएँ + More options और विकल्प + Sort by इसके अनुसार क्रमबद्ध करें + Author लेखक + Type टाइप करें + Colour रंग + Show all comments सभी टिप्पणियाँ दिखाएँ + Create PDF comment summary… पीडीएफ़ टिप्पणी सारांश बनाएँ… + Export all to data file… सब कुछ डेटा फ़ाइल में निर्यात करें… + Filter comments टिप्पणियाँ फ़िल्टर करें + Status स्थिति + Accepted स्वीकृत + Rejected अस्वीकृत + Cancelled रद्द किया गया + Completed पूर्ण + Show all सब दिखाएँ + Yellow पीला + Orange नारंगी + Red लाल + Pink गुलाबी + Purple बैंगनी + Blue नीला + Light blue हल्का नीला + Green हरा + Gray स्लेटी + Black काला + Bookmark options बुकमार्क विकल्प + Expand all bookmarks सभी बुकमार्क विस्तृत करें + Expand top-level bookmarks शीर्ष-स्तर के बुकमार्क विस्तृत करें + Collapse all bookmarks सभी बुकमार्क सिकोड़ें + New bookmark ({key}) नया बुकमार्क ({key}) + This document has no bookmarks. इस दस्तावेज़ में कोई बुकमार्क नहीं है। + This document has no layers. इस दस्तावेज़ में कोई परत नहीं है। + This document has no attachments. इस दस्तावेज़ में कोई अनुलग्नक नहीं है। + Hide layer परत छिपाएँ + Show layer परत दिखाएँ + Set layer visibility परत की दृश्यता सेट करें + on page {label} पृष्ठ {label} पर + Save attachment… अनुलग्नक सहेजें… + Open in a new tab नए टैब में खोलें + This document has no pages. इस दस्तावेज़ में कोई पृष्ठ नहीं है। + Find text टेक्स्ट खोजें + No matches कोई मेल नहीं + Searching… {s}/{p} खोजा जा रहा है… {s}/{p} + {c} of {n}{more} {n} में से {c}{more} + Previous ({key}) पिछला ({key}) + Next ({key}) अगला ({key}) + Find options खोज विकल्प + Whole words only केवल पूरे शब्द + Case-sensitive केस-संवेदी + Close (Esc) बंद करें (Esc) + Align संरेखित करें + Top ऊपर + Bottom नीचे + Center horizontally क्षैतिज रूप से मध्य + Center vertically ऊर्ध्वाधर रूप से मध्य + Distribute वितरित करें + Horizontally क्षैतिज रूप से + Vertically ऊर्ध्वाधर रूप से + Set Fields to Same Size फ़ील्ड का आकार समान सेट करें + Height ऊँचाई + Width चौड़ाई + Both दोनों + Duplicate… डुप्लिकेट करें… + All pages सभी पृष्ठ + Odd pages विषम पृष्ठ + Even pages सम पृष्ठ + Landscape pages लैंडस्केप पृष्ठ + Portrait pages पोर्ट्रेट पृष्ठ + Move earlier पहले खिसकाएँ + Move later बाद में खिसकाएँ + Back to the document दस्तावेज़ पर वापस जाएँ + Protect Using Password पासवर्ड से सुरक्षित करें + Requires user to enter a password for: इनके लिए उपयोगकर्ता को पासवर्ड दर्ज करना होगा: + Viewing देखने के लिए + Editing संपादन के लिए + Type Password पासवर्ड दर्ज करें + Re-type Password पासवर्ड दोबारा दर्ज करें + Strength: {s} मज़बूती: {s} + Strong मज़बूत + Medium मध्यम + Weak कमज़ोर + Advanced Options {chevron} उन्नत विकल्प {chevron} + Compatibility संगतता + Acrobat X and later (256-bit AES) Acrobat X और इसके बाद (256-बिट AES) + Acrobat 7.0 and later (128-bit AES) Acrobat 7.0 और इसके बाद (128-बिट AES) + Acrobat 5.0 and later (128-bit RC4) Acrobat 5.0 और इसके बाद (128-बिट RC4) + Acrobat 3.0 and later (40-bit RC4) Acrobat 3.0 और इसके बाद (40-बिट RC4) + Encrypt एन्क्रिप्ट करें + All document contents दस्तावेज़ की पूरी सामग्री + All document contents except metadata दस्तावेज़ की पूरी सामग्री, मेटाडेटा को छोड़कर + Printing allowed प्रिंटिंग की अनुमति है + Low Resolution (150 dpi) कम रेज़ोल्यूशन (150 dpi) + Changes allowed बदलावों की अनुमति है + Inserting, deleting, and rotating pages पृष्ठ जोड़ना, हटाना और घुमाना + Filling in form fields and signing existing signature fields फ़ॉर्म फ़ील्ड भरना और मौजूदा हस्ताक्षर फ़ील्ड पर हस्ताक्षर करना + Commenting, filling in form fields, and signing existing signature fields टिप्पणी करना, फ़ॉर्म फ़ील्ड भरना और मौजूदा हस्ताक्षर फ़ील्ड पर हस्ताक्षर करना + Any except extracting pages पृष्ठ निकालने के अलावा कोई भी + Enable copying of text, images, and other content टेक्स्ट, तस्वीरों और अन्य सामग्री की कॉपी करने की अनुमति दें + Enable text access for screen reader devices for the visually impaired दृष्टिबाधितों के लिए स्क्रीन रीडर डिवाइसों को टेक्स्ट एक्सेस की अनुमति दें + Type a password. पासवर्ड दर्ज करें। + The passwords don't match. पासवर्ड मेल नहीं खाते। + This compatibility level supports only plain ASCII passwords. यह संगतता स्तर केवल सादे ASCII पासवर्ड का समर्थन करता है। + Anyone opening the document will need this password. It's applied when you save. दस्तावेज़ खोलने वाले हर व्यक्ति को यह पासवर्ड चाहिए। यह सहेजने पर लागू होता है। + The document opens without a password; this password is needed to change the restrictions. It's applied when you save. दस्तावेज़ बिना पासवर्ड खुलता है; पाबंदियाँ बदलने के लिए यह पासवर्ड चाहिए। यह सहेजने पर लागू होता है। + Recover unsaved documents? असहेजे दस्तावेज़ पुनर्प्राप्त करें? + PdfCraft didn't shut down normally. These documents had changes that were autosaved: PdfCraft सही ढंग से बंद नहीं हुआ। इन दस्तावेज़ों के बदलाव स्वतः सहेजे गए थे: + just now अभी-अभी + {n} min ago {n} मिनट पहले + {n} h ago {n} घंटे पहले + · password-protected · पासवर्ड-सुरक्षित + Recover पुनर्प्राप्त करें + Discard छोड़ दें + Version {v} संस्करण {v} + A clean-room, open-source PDF application written in Rust. MIT OR Apache-2.0. Rust में लिखा गया एक क्लीन-रूम, ओपन-सोर्स पीडीएफ़ ऐप्लिकेशन। MIT OR Apache-2.0। + Part of इसका हिस्सा + Summarize Options सारांश विकल्प + Choose a layout: एक लेआउट चुनें: + Comments only केवल टिप्पणियाँ + Sort comments by: टिप्पणियाँ इसके अनुसार क्रमबद्ध करें: + Create PDF Comment Summary पीडीएफ़ टिप्पणी सारांश बनाएँ + Revert to the previously saved version of “{name}”? Changes since then can't be undone afterwards. “{name}” के पहले सहेजे गए संस्करण पर लौटें? उसके बाद से किए गए बदलाव आगे वापस नहीं लिए जा सकेंगे। + Number pages पृष्ठ क्रमांकित करें + Style शैली + None (prefix only) कोई नहीं (केवल प्रीफ़िक्स) + Prefix प्रीफ़िक्स + Start प्रारंभ करें + Labels: {preview}. Later pages keep their labels. लेबल: {preview}। बाद के पृष्ठ अपने-अपने लेबल रखते हैं। + Even and Odd Pages सम और विषम पृष्ठ + Even Pages Only केवल सम पृष्ठ + Odd Pages Only केवल विषम पृष्ठ + Landscape and Portrait Pages लैंडस्केप और पोर्ट्रेट पृष्ठ + Landscape Pages लैंडस्केप पृष्ठ + Portrait Pages पोर्ट्रेट पृष्ठ + Duplicate Field फ़ील्ड डुप्लिकेट करें + Duplicate "{name}" onto: “{name}” को इन पर डुप्लिकेट करें: + 1 page selected. 1 पृष्ठ चयनित। + {n} pages selected. {n} पृष्ठ चयनित। + Delete pages after extracting निकालने के बाद पृष्ठ हटाएँ + Extract pages as separate files पृष्ठ अलग-अलग फ़ाइलों में निकालें + Rotate Pages पृष्ठ घुमाएँ + Direction: दिशा: + Clockwise 90 degrees घड़ी की दिशा में 90 डिग्री + Counterclockwise 90 degrees घड़ी की उल्टी दिशा में 90 डिग्री + 180 degrees 180 डिग्री + Pages: पृष्ठ: + All सभी + Selection चयन + From से + Rotate: घुमाएँ: + Repairs मरम्मत + Repair log मरम्मत लॉग + Split document दस्तावेज़ विभाजित करें + Number of pages पृष्ठों की संख्या + Pages per file प्रति फ़ाइल पृष्ठ + File size फ़ाइल का आकार + At most अधिकतम + Top-level bookmarks ({n}) शीर्ष-स्तर के बुकमार्क ({n}) + Before each selected page (select pages in Organize) प्रत्येक चयनित पृष्ठ से पहले (पृष्ठ ऑर्गनाइज़ में चुनें) + Creates 1 file from {n} pages. {n} पृष्ठों से 1 फ़ाइल बनाता है। + Creates {f} files from {n} pages. {n} पृष्ठों से {f} फ़ाइलें बनाता है। + Each file holds as many of the {n} pages as fit. हर फ़ाइल में {n} पृष्ठों में से जितने समा जाते हैं, उतने होते हैं। + Replace Pages पृष्ठ बदलें + Original: replace pages मूल: पृष्ठ बदलें + to से + to {n} से {n} तक + Replacement: pages of {name} बदली: {name} के पृष्ठ + of {name} {name} में से + Only the page content changes: links, comments, form fields and bookmarks on the original pages stay. केवल पृष्ठ की सामग्री बदलती है: मूल पृष्ठों पर मौजूद लिंक, टिप्पणियाँ, फ़ॉर्म फ़ील्ड और बुकमार्क बने रहते हैं। + The replacement file doesn't have that many pages. बदलने वाली फ़ाइल में उतने पृष्ठ नहीं हैं। + Tagged PDF टैग किया गया पीडीएफ़ + Document Properties दस्तावेज़ प्रॉपर्टीज़ + Description विवरण + Initial View प्रारंभिक दृश्य + Security सुरक्षा + Fonts फ़ॉन्ट + Advanced उन्नत + Title शीर्षक + Subject विषय + Keywords कीवर्ड + Application ऐप्लिकेशन + PDF producer पीडीएफ़ निर्माता + Layout and Magnification लेआउट और आवर्धन + Navigation tab नेविगेशन टैब + Page Only केवल पृष्ठ + Bookmarks Panel and Page बुकमार्क पैनल और पृष्ठ + Pages Panel and Page पृष्ठ पैनल और पृष्ठ + Attachments Panel and Page अनुलग्नक पैनल और पृष्ठ + Layers Panel and Page परत पैनल और पृष्ठ + Page layout पृष्ठ लेआउट + Default डिफ़ॉल्ट + Single Page एक पृष्ठ + Single Page Continuous एक पृष्ठ, लगातार + Two-Up (Facing) दो-एक-साथ (आमने-सामने) + Two-Up Continuous (Facing) दो-एक-साथ, लगातार (आमने-सामने) + Two-Up (Cover Page) दो-एक-साथ (कवर पृष्ठ) + Two-Up Continuous (Cover Page) दो-एक-साथ, लगातार (कवर पृष्ठ) + Magnification आवर्धन + Actual Size वास्तविक आकार + Fit Page पृष्ठ फ़िट करें + Fit Width चौड़ाई फ़िट करें + Fit Height ऊँचाई फ़िट करें + Fit Visible विज़िबल फ़िट करें + Open to page इस पृष्ठ पर खोलें + of {pages} {pages} में से + Window Options विंडो विकल्प + Resize window to initial page विंडो का आकार प्रारंभिक पृष्ठ के अनुसार बदलें + Center window on screen विंडो को स्क्रीन पर मध्य में रखें + Open in Full Screen mode फ़ुल स्क्रीन मोड में खोलें + Show: दिखाएँ: + File Name फ़ाइल का नाम + Document Title दस्तावेज़ का शीर्षक + User Interface Options यूज़र इंटरफ़ेस विकल्प + Hide menu bar मेन्यू बार छिपाएँ + Hide toolbars टूलबार छिपाएँ + Hide window controls विंडो नियंत्रण छिपाएँ + Security method सुरक्षा विधि + No security कोई सुरक्षा नहीं + Restrictions पाबंदियाँ + None — everything is allowed कोई नहीं — सब कुछ की अनुमति है + Password security पासवर्ड सुरक्षा + Encryption एन्क्रिप्शन + Opened with इससे खोला गया + — (protection is applied when you save) — (सुरक्षा सहेजने पर लागू होती है) + Owner password (no restrictions apply) स्वामी पासवर्ड (कोई पाबंदी लागू नहीं होती) + User password उपयोगकर्ता पासवर्ड + Change settings… सेटिंग्स बदलें… + Printing प्रिंटिंग + Not allowed अनुमति नहीं + Allowed अनुमति है + High resolution उच्च रेज़ोल्यूशन + Low resolution कम रेज़ोल्यूशन + Changing the document दस्तावेज़ बदलना + Document assembly दस्तावेज़ संयोजन + Content copying सामग्री कॉपी करना + Content copying for accessibility पहुँच के लिए सामग्री कॉपी करना + Commenting टिप्पणी करना + Filling of form fields फ़ॉर्म फ़ील्ड भरना + No fonts are referenced by the pages. पृष्ठों द्वारा कोई फ़ॉन्ट संदर्भित नहीं है। + PDF version पीडीएफ़ संस्करण + Location स्थान + Page size पृष्ठ आकार + Yes हाँ + No नहीं + Revisions संशोधन + View revision {n} संशोधन {n} देखें + Open the file as it was saved then फ़ाइल को तब सहेजे गए रूप में खोलें + Binding बंधन + Left Edge बायाँ किनारा + Right Edge दायाँ किनारा + Language भाषा + Saved {place}: {before} → {after} ({pct}% smaller){detail} सहेजा गया {place}: {before} → {after} ({pct}% छोटा){detail} + This file is already as small as it can be made ({size}). No copy was saved. यह फ़ाइल पहले से ही जितनी छोटी बन सकती थी, उतनी छोटी है ({size})। कोई प्रति सहेजी नहीं गई। + Saved {place}: {before} → {after} (not smaller){detail} सहेजा गया {place}: {before} → {after} (छोटा नहीं){detail} + Couldn't save the image: {e} छवि सहेजी नहीं जा सकी: {e} + Adding images arrives on the web with file pickers for images तस्वीरें जोड़ना वेब पर तस्वीरों के फ़ाइल पिकर के साथ आएगा + Replacing images on page {p} arrives on the web with image pickers ({i}) पृष्ठ {p} की तस्वीरें बदलना वेब पर इमेज पिकर के साथ आएगा ({i}) + {name}: choosing images arrives on the web with file pickers for images {name}: तस्वीरें चुनना वेब पर तस्वीरों के फ़ाइल पिकर के साथ आएगा + Replacing images arrives on the web with image file pickers तस्वीरें बदलना वेब पर इमेज फ़ाइल पिकर के साथ आएगा + Couldn't create a PDF: {e} पीडीएफ़ नहीं बनाया जा सका: {e} + The clipboard has no image or text क्लिपबोर्ड में कोई तस्वीर या टेक्स्ट नहीं है + On the web, open or drop an image to convert it वेब पर, इसे बदलने के लिए कोई तस्वीर खोलें या छोड़ें + Couldn't optimize the file: {e} फ़ाइल ऑप्टिमाइज़ नहीं की जा सकी: {e} + Couldn't write {path}: {e} {path} नहीं लिखा जा सका: {e} + The form asks to be submitted to {u}; PdfCraft doesn't send form data. Save the document to keep your entries. फ़ॉर्म {u} पर जमा होने का अनुरोध करता है; PdfCraft फ़ॉर्म डेटा नहीं भेजता। अपनी भरी हुई जानकारी बनाए रखने के लिए दस्तावेज़ सहेजें। + This PDF uses the unsupported {s} action. यह पीडीएफ़ असमर्थित {s} क्रिया उपयोग करता है। + {name}: the {other} action isn't supported yet {name}: {other} क्रिया अभी समर्थित नहीं है + {name} submits the form to {url}; PdfCraft doesn't send form data. Save the document to keep your entries. {name} फ़ॉर्म {url} पर भेजता है; PdfCraft फ़ॉर्म डेटा नहीं भेजता। अपनी भरी हुई जानकारी बनाए रखने के लिए दस्तावेज़ सहेजें। + Export stopped: {e} निर्यात रुक गया: {e} + Exported 1 image 1 तस्वीर निर्यात की गई + Exported {n} images {n} तस्वीरें निर्यात की गईं + ({s} not exported: {first}) ({s} निर्यात नहीं हुईं: {first}) + Exported the text of 1 page 1 पृष्ठ का टेक्स्ट निर्यात किया गया + Exported the text of {n} pages {n} पृष्ठों का टेक्स्ट निर्यात किया गया + {msg} to {dir} {msg} — {dir} में + Exporting… {d} of {t} निर्यात हो रहा है… {t} में से {d} + Choose a folder for the exported files निर्यात की गई फ़ाइलों के लिए एक फ़ोल्डर चुनें + New {tool} comments will look like this one टूल {tool} की नई टिप्पणियाँ इस जैसी दिखेंगी + This document can't be checked: it couldn't be read for editing इस दस्तावेज़ की जाँच नहीं हो सकती: इसे संपादन के लिए पढ़ा नहीं जा सका + The checker found no problems in this document. जाँच ने इस दस्तावेज़ में कोई समस्या नहीं पाई। + The checker found 1 problem which may prevent the document from being fully accessible. जाँच ने 1 समस्या पाई जो दस्तावेज़ को पूरी तरह सुलभ होने से रोक सकती है। + The checker found {n} problems which may prevent the document from being fully accessible. जाँच ने {n} समस्याएँ पाईं जो दस्तावेज़ को पूरी तरह सुलभ होने से रोक सकती हैं। + The text is the same टेक्स्ट एक जैसा है + 1 difference found 1 अंतर मिला + {n} differences found {n} अंतर मिले + Added 1 comment 1 टिप्पणी जोड़ी गई + Added {n} comments {n} टिप्पणियाँ जोड़ी गईं + Choose a folder for the results परिणामों के लिए एक फ़ोल्डर चुनें + Files for {name} {name} के लिए फ़ाइलें + An action is already running एक क्रिया पहले से चल रही है + Running action… file {d} of {t} क्रिया चल रही है… फ़ाइल {t} में से {d} + No unlinked web addresses were found in the text टेक्स्ट में कोई बिना लिंक वाला वेब पता नहीं मिला + Created 1 link 1 लिंक बनाया गया + Created {n} links {n} लिंक बनाए गए + Text recognition is already running टेक्स्ट पहचान पहले से चल रही है + Recognizing text… file {d} of {t} टेक्स्ट पहचाना जा रहा है… फ़ाइल {t} में से {d} + Recognizing text… page {d} of {t} टेक्स्ट पहचाना जा रहा है… पृष्ठ {t} में से {d} + Recognized 1 word 1 शब्द पहचाना गया + Recognized {n} words {n} शब्द पहचाने गए + {words} on {pages} {pages} पर {words} + ; 1 page already had text ; 1 पृष्ठ में पहले से टेक्स्ट था + ; {n} pages already had text ; {n} पृष्ठों में पहले से टेक्स्ट था + Recognized {w} words in 1 file 1 फ़ाइल में {w} शब्द पहचाने गए + Recognized {w} words in {n} files {n} फ़ाइलों में {w} शब्द पहचाने गए + ; failed: {list} ; विफल: {list} + 1 file done 1 फ़ाइल पूरी हुई + {n} files done {n} फ़ाइलें पूरी हुईं + The selected area has been copied ({w} × {h} pixels) चयनित क्षेत्र कॉपी हो गया ({w} × {h} पिक्सेल) + Couldn't take the snapshot: {e} स्नैपशॉट नहीं लिया जा सका: {e} + Couldn't recover {name}: {e} {name} पुनर्प्राप्त नहीं किया जा सका: {e} + The document now conforms to {level}; save it to keep the changes दस्तावेज़ अब {level} के अनुरूप है; बदलाव बनाए रखने के लिए इसे सहेजें + Fixed what could be fixed; 1 problem remains जो ठीक हो सकता था, ठीक कर दिया गया; 1 समस्या बची है + Fixed what could be fixed; {n} problems remain जो ठीक हो सकता था, ठीक कर दिया गया; {n} समस्याएँ बची हैं + Custom stamps arrive on the web with file pickers for images कस्टम स्टाम्प वेब पर तस्वीरों के फ़ाइल पिकर के साथ आएँगे + {file} is too large for a stamp (at most {n} MB) {file} स्टाम्प के लिए बहुत बड़ी है (अधिकतम {n} MB) + Sent to {printer} {printer} को भेजा गया + Sent to {printer}: {msg} {printer} को भेजा गया: {msg} + Looking for printers… प्रिंटर खोजे जा रहे हैं… + Sending to {printer}… {printer} को भेजा जा रहा है… + Choose a folder for the searchable files सर्च योग्य फ़ाइलों के लिए एक फ़ोल्डर चुनें + Files are combined from top to bottom. Leave Pages empty to take every page. फ़ाइलें ऊपर से नीचे संयोजित होती हैं। सभी पृष्ठ लेने के लिए पृष्ठ खाली छोड़ दें। + Unlock… अनलॉक करें… + Select a password-protected file first पहले पासवर्ड-सुरक्षित फ़ाइल चुनें + Enter the permissions password to allow combining संयोजन की अनुमति देने के लिए अनुमति पासवर्ड दर्ज करें + Enter the password that opens it वह पासवर्ड दर्ज करें जो इसे खोलता है + Unlock {name} {name} अनलॉक करें + Unlock {n} files {n} फ़ाइलें अनलॉक करें + The same password is tried on each file. हर फ़ाइल पर वही पासवर्ड आज़माया जाता है। + Hide password पासवर्ड छिपाएँ + Show password पासवर्ड दिखाएँ + Wrong password ग़लत पासवर्ड + The password is only used to read the file; it isn't saved. पासवर्ड केवल फ़ाइल पढ़ने के लिए उपयोग होता है; यह सहेजा नहीं जाता। + Unlock अनलॉक करें + Opened, but its security settings don't allow combining. Enter the permissions password. खुल गया, लेकिन इसकी सुरक्षा सेटिंग्स संयोजन की अनुमति नहीं देतीं। अनुमति पासवर्ड दर्ज करें। + Unlocked: the combined file won't be password-protected अनलॉक हो गया: संयोजित फ़ाइल पासवर्ड-सुरक्षित नहीं होगी + Unlocked {n} of {m} files {m} फ़ाइलों में से {n} अनलॉक हुईं + Drop PDFs, images, text files or folders here, or choose them. पीडीएफ़, तस्वीरें, टेक्स्ट फ़ाइलें या फ़ोल्डर यहाँ छोड़ें, या उन्हें चुनें। + Add folder… फ़ोल्डर जोड़ें… + Add folder and subfolders… फ़ोल्डर और सबफ़ोल्डर जोड़ें… + More ways to add files फ़ाइलें जोड़ने के और तरीक़े + Every PDF, image and text file in the folder फ़ोल्डर की हर पीडीएफ़, तस्वीर और टेक्स्ट फ़ाइल + Every PDF, image and text file in the folder and the folders inside it फ़ोल्डर और उसके अंदर के फ़ोल्डरों की हर पीडीएफ़, तस्वीर और टेक्स्ट फ़ाइल + Add folder फ़ोल्डर जोड़ें + Add folder and subfolders फ़ोल्डर और सबफ़ोल्डर जोड़ें + No PDFs, images or text files found in {folder} {folder} में कोई पीडीएफ़, तस्वीर या टेक्स्ट फ़ाइल नहीं मिली + Added the first {n} files in {folder} {folder} में से पहली {n} फ़ाइलें जोड़ दी गईं + Click to sort, drag to move the column. Drag its edge to resize it. क्रमबद्ध करने के लिए क्लिक करें, कॉलम खिसकाने के लिए ड्रैग करें। आकार बदलने के लिए उसका किनारा खींचें। + Reset columns कॉलम रीसेट करें + Remove {n} files {n} फ़ाइलें हटाएँ + {n} selected {n} चयनित + sorted ascending आरोही क्रम में + sorted descending अवरोही क्रम में + Protected: the combined file won't keep its security settings सुरक्षित: संयोजित फ़ाइल अपनी सुरक्षा सेटिंग्स नहीं रखेगी + Add open documents खुले दस्तावेज़ जोड़ें + All open documents सभी खुले दस्तावेज़ + No documents are open कोई दस्तावेज़ खुला नहीं है + Select a file first पहले एक फ़ाइल चुनें + 1 file 1 फ़ाइल + {n} files {n} फ़ाइलें + 1 file needs attention 1 फ़ाइल को ध्यान चाहिए + {n} files need attention {n} फ़ाइलों को ध्यान चाहिए + {name} can't be combined: {why} {name} को संयोजित नहीं किया जा सकता: {why} + Check the pages of {name}: {why} {name} के पृष्ठ जाँचें: {why} + Add the files to combine संयोजित करने के लिए फ़ाइलें जोड़ें + File name फ़ाइल का नाम + Warnings चेतावनियाँ + Drag to reorder क्रम बदलने के लिए ड्रैग करें + {k} of {n} {n} में से {k} + ? of {n} {n} में से ? + Added more than once एक से ज़्यादा बार जोड़ा गया + yesterday बीता कल + {n} days ago {n} दिन पहले + No pages selected कोई पृष्ठ चयनित नहीं + Password-protected पासवर्ड-सुरक्षित + Its security settings don't allow copying pages इसकी सुरक्षा सेटिंग्स पृष्ठ कॉपी करने की अनुमति नहीं देतीं + Can't be read: {e} पढ़ा नहीं जा सकता: {e} + Leave out files that can't be read? जो फ़ाइलें पढ़ी नहीं जा सकतीं, उन्हें छोड़ दें? + These files can't be read, so they won't be in the combined PDF: ये फ़ाइलें पढ़ी नहीं जा सकतीं, इसलिए वे संयोजित पीडीएफ़ में नहीं होंगी: + Combine the rest बाक़ी को संयोजित करें + and {n} more और {n} और + Includes unsaved changes असहेजे बदलाव शामिल हैं + Pages of {name} to combine, e.g. 1-3, 6 {name} से संयोजित करने के लिए पृष्ठ, जैसे 1-3, 6 + Remove {name} {name} हटाएँ + Add files… फ़ाइलें जोड़ें… + Add at least two files कम से कम दो फ़ाइलें जोड़ें + Couldn't add {name}: {e} {name} जोड़ा नहीं जा सका: {e} + Couldn't combine files: {e} फ़ाइलें संयोजित नहीं की जा सकीं: {e} + Export comments टिप्पणियाँ निर्यात करें + Export form data फ़ॉर्म डेटा निर्यात करें + Comment and form data टिप्पणी और फ़ॉर्म डेटा + Export निर्यात करें + Select data files to merge मर्ज करने के लिए डेटा फ़ाइलें चुनें + Form data and PDF forms फ़ॉर्म डेटा और पीडीएफ़ फ़ॉर्म + Save the spreadsheet स्प्रेडशीट सहेजें + Save the accessibility report पहुँच रिपोर्ट सहेजें + Save image तस्वीर सहेजें + Export certificate प्रमाणपत्र निर्यात करें + Choose a folder for the extracted pages निकाले गए पृष्ठों के लिए एक फ़ोल्डर चुनें + Choose a folder for the split files विभाजित फ़ाइलों के लिए एक फ़ोल्डर चुनें + Couldn't use {name}: {e} {name} उपयोग नहीं किया जा सका: {e} + Couldn't extract pages: {e} पृष्ठ नहीं निकाले जा सके: {e} + Couldn't write {name}: {e} {name} नहीं लिखी जा सकी: {e} + Wrote 1 file to {dir} 1 फ़ाइल {dir} में लिखी गई + Wrote {n} files to {dir} {n} फ़ाइलें {dir} में लिखी गईं + No pages match those choices इन विकल्पों से कोई पृष्ठ मेल नहीं खाता + Couldn't split: {e} विभाजित नहीं किया जा सका: {e} + Couldn't summarize comments: {e} टिप्पणियों का सारांश नहीं बनाया जा सका: {e} + Couldn't open the result: {e} परिणाम खोला नहीं जा सका: {e} + Importing data arrives on the web with file pickers for data files डेटा आयात वेब पर डेटा फ़ाइलों के फ़ाइल पिकर के साथ आएगा + Exported to {path} {path} पर निर्यात किया गया + Merging data files needs the desktop app डेटा फ़ाइलें मर्ज करने के लिए डेस्कटॉप ऐप चाहिए + Merged 1 file into {path} 1 फ़ाइल {path} में मर्ज की गई + Merged {n} files into {path} {n} फ़ाइलें {path} में मर्ज की गईं + Combined {n} files {n} फ़ाइलें संयोजित की गईं + Extracted 1 page 1 पृष्ठ निकाला गया + Extracted {n} pages {n} पृष्ठ निकाले गए + Created a comment summary टिप्पणियों का सारांश बनाया गया + Couldn't open {name}: {e} {name} खोला नहीं जा सका: {e} + Couldn't read {name}: {e} {name} पढ़ी नहीं जा सकी: {e} + Couldn't save: {e} सहेजा नहीं जा सका: {e} + Downloading attachments on the web arrives with M3.10 ({n} bytes ready) वेब पर अनुलग्नक डाउनलोड M3.10 के साथ आएगा ({n} बाइट तैयार) + `{command}` {when} `{command}` {when} + ships in milestone {m} माइलस्टोन {m} में आता है + needs an AI provider (off by default) AI प्रदाता चाहिए (डिफ़ॉल्ट रूप से बंद) + is available उपलब्ध है + is not available yet अभी उपलब्ध नहीं है + {label} failed: {e} {label} विफल रहा: {e} + Undid {label} {label} पूर्ववत किया गया + Redid {label} {label} फिर किया गया + A document needs at least one page: copy instead दस्तावेज़ को कम से कम एक पृष्ठ चाहिए: इसके बजाय कॉपी करें + Cut {what} काटा गया: {what} + Copied {what} कॉपी किया गया: {what} + 1 page 1 पृष्ठ + {n} pages {n} पृष्ठ + Copy or cut pages first पहले पृष्ठ कॉपी करें या काटें + Couldn't save {name}: {e} {name} सहेजा नहीं जा सका: {e} + Saved {name} {name} सहेजा गया + Saved, but reopening failed: {e} सहेजा गया, लेकिन दोबारा खोलना विफल रहा: {e} + Downloaded {name} {name} डाउनलोड हुआ + Couldn't download {name}: {e} {name} डाउनलोड नहीं हो सका: {e} + Reverted to the last saved version अंतिम सहेजे गए संस्करण पर लौटा लिया गया + That didn't work: an internal error stopped it ({m}). Your documents are unchanged. वह काम नहीं कर पाया: एक आंतरिक त्रुटि ने उसे रोक दिया ({m})। आपके दस्तावेज़ नहीं बदले। + Nothing to undo पूर्ववत करने के लिए कुछ नहीं + Nothing to redo फिर करने के लिए कुछ नहीं + This document has no form fields you can fill in इस दस्तावेज़ में भरने योग्य कोई फ़ॉर्म फ़ील्ड नहीं है + This document has no comments to flatten इस दस्तावेज़ में फ़्लैट करने के लिए कोई टिप्पणी नहीं है + This document has no form fields to flatten इस दस्तावेज़ में फ़्लैट करने के लिए कोई फ़ॉर्म फ़ील्ड नहीं है + There are no redaction marks (mark text, areas or pages first) कोई रेडैक्शन चिह्न नहीं हैं (पहले टेक्स्ट, क्षेत्र या पृष्ठ चिह्नित करें) + This document has no {kind} to change इस दस्तावेज़ में बदलने के लिए कोई {kind} नहीं है + header or footer हेडर या फ़ुटर + watermark वॉटरमार्क + background पृष्ठभूमि + This document isn't password-protected यह दस्तावेज़ पासवर्ड-सुरक्षित नहीं है + Enter permissions password… अनुमति पासवर्ड दर्ज करें… + Permissions password अनुमति पासवर्ड + “{name}” has security restrictions. Enter its permissions password to lift them. “{name}” पर सुरक्षा पाबंदियाँ हैं। उन्हें हटाने के लिए इसका अनुमति पासवर्ड दर्ज करें। + Restrictions lifted पाबंदियाँ हटा दी गईं + Couldn't unlock {name}: {e} {name} अनलॉक नहीं किया जा सका: {e} + This document has no restrictions to lift इस दस्तावेज़ पर हटाने लायक़ कोई पाबंदी नहीं है + The document's security settings don't allow this change दस्तावेज़ की सुरक्षा सेटिंग्स यह बदलाव नहीं करने देतीं + The document's security settings don't allow copying text and images दस्तावेज़ की सुरक्षा सेटिंग्स टेक्स्ट और तस्वीरें कॉपी नहीं करने देतीं + Open a document first पहले एक दस्तावेज़ खोलें + Security will be removed when you save सहेजने पर सुरक्षा हटा दी जाएगी + Click text or an image to edit it संपादित करने के लिए टेक्स्ट या तस्वीर पर क्लिक करें + Drag a rectangle to create a link; double-click a link to edit it लिंक बनाने के लिए एक आयत खींचें; लिंक संपादित करने के लिए उस पर डबल-क्लिक करें + There are no redaction marks to apply लागू करने के लिए कोई रेडैक्शन चिह्न नहीं है + Drag to draw the area where the signature should appear. हस्ताक्षर जहाँ दिखाई देना चाहिए, वह क्षेत्र बनाने के लिए ड्रैग करें। + Couldn't fit the visible content: {e} दिख रही सामग्री फ़िट नहीं की जा सकी: {e} + Drag a rectangle around the area to copy कॉपी करने के क्षेत्र के चारों ओर एक आयत खींचें + Click on the page to add a {tool}, or drag to set its size {tool} जोड़ने के लिए पृष्ठ पर क्लिक करें, या आकार सेट करने के लिए ड्रैग करें + Drag a rectangle on a page to crop it; double-click a page for Set Page Boxes पृष्ठ काटने (क्रॉप करने) के लिए उस पर एक आयत खींचें; पृष्ठ की सीमाएँ सेट करने के लिए पृष्ठ पर डबल-क्लिक करें + Keep tool selected: on टूल चयनित रखें: चालू + Keep tool selected टूल चयनित रखें + Opacity अपारदर्शिता + Line thickness लाइन की मोटाई + What word or phrase would you like to search for? आप कौन-सा शब्द या वाक्यांश खोजना चाहेंगे? + Searching… {s} of {p} pages खोजा जा रहा है… {p} पृष्ठों में से {s} + (searching… {s} of {p} pages) (खोजा जा रहा है… {p} पृष्ठों में से {s}) + 1 instance 1 मिलान + {n} instances {n} मिलान + Go to this result इस परिणाम पर जाएँ + Highlight हाइलाइट + Draw ड्रॉ + Polygon बहुभुज + Connected lines जुड़ी रेखाएँ + Eraser इरेज़र + Sign हस्ताक्षर करें + Certified by {by} {by} द्वारा प्रमाणित + At least one signature is invalid. कम से कम एक हस्ताक्षर अमान्य है। + Signed and all signatures are valid. हस्ताक्षरित, और सभी हस्ताक्षर मान्य हैं। + At least one signature has problems. कम से कम एक हस्ताक्षर में समस्याएँ हैं। + This document is secured. Some changes are restricted by its security settings. यह दस्तावेज़ सुरक्षित है। इसकी सुरक्षा सेटिंग्स कुछ बदलाव प्रतिबंधित करती हैं। + This is a dynamic XFA form, which PdfCraft can't display yet. What you see is the file's placeholder page. यह एक डायनामिक XFA फ़ॉर्म है, जिसे PdfCraft अभी दिखा नहीं सकता। आप जो देख रहे हैं वह फ़ाइल का प्लेसहोल्डर पृष्ठ है। + This form also contains XFA data, which PdfCraft doesn't read yet. You can fill its fields, but Acrobat may show the XFA values instead. इस फ़ॉर्म में XFA डेटा भी है, जिसे PdfCraft अभी नहीं पढ़ता। आप इसके फ़ील्ड भर सकते हैं, लेकिन Acrobat इसके बजाय XFA मान दिखा सकता है। + This document contains {n} interactive form fields. इस दस्तावेज़ में {n} इंटरैक्टिव फ़ॉर्म फ़ील्ड हैं। + This file was damaged and has been repaired. Saving keeps the repaired version. यह फ़ाइल क्षतिग्रस्त थी और उसे मरम्मत कर दिया गया है। सहेजने पर मरम्मत किया हुआ संस्करण ही रहेगा। + Dismiss छिपाएँ + Hide field highlights फ़ील्ड हाइलाइट छिपाएँ + Highlight fields फ़ील्ड हाइलाइट करें + Security settings सुरक्षा सेटिंग्स + Details विवरण + Select (V) चयन करें (V) + Hand (H) हैंड (H) + Delete pages (Delete) पृष्ठ हटाएँ (Delete) + Insert a blank page after the selection चयन के बाद एक रिक्त पृष्ठ जोड़ें + Insert pages from a file… फ़ाइल से पृष्ठ जोड़ें… + Extract pages to a new document पृष्ठों को नए दस्तावेज़ में निकालें + Split into files… फ़ाइलों में विभाजित करें… + Select pages पृष्ठ चुनें + Cut काटें + Copy कॉपी करें + Paste after बाद में पेस्ट करें + Rename नाम बदलें + Set to current page ({n}) वर्तमान पृष्ठ पर सेट करें ({n}) + Move up ऊपर ले जाएँ + Move down नीचे ले जाएँ + Indent इंडेंट बढ़ाएँ + Outdent इंडेंट घटाएँ + This document has no form fields. इस दस्तावेज़ में कोई फ़ॉर्म फ़ील्ड नहीं हैं। + Tab order: move a field with its arrows. टैब क्रम: फ़ील्ड को उसके तीरों से खिसकाएँ। + Unplaced रखा नहीं गया + Has JavaScript actions (run in M6) JavaScript क्रियाएँ हैं (M6 में चलती हैं) + Page पृष्ठ + None कोई नहीं + Delete selected fields चयनित फ़ील्ड हटाएँ + Diagnostic details डायग्नोस्टिक विवरण + The operation failed. ऑपरेशन विफल हो गया। + no such document ऐसा कोई दस्तावेज़ नहीं है + nothing to undo पूर्ववत करने के लिए कुछ नहीं है + nothing to redo दोहराने के लिए कुछ नहीं है + this document is signed: rewriting it would invalidate its signatures (save it incrementally instead) यह दस्तावेज़ हस्ताक्षरित है: इसे फिर से लिखने पर इसके हस्ताक्षर अमान्य हो जाएँगे (इसके बजाय इसे क्रमिक रूप से सहेजें) + the document is protected by a password दस्तावेज़ पासवर्ड से सुरक्षित है + the password is incorrect पासवर्ड ग़लत है + the document has no page tree दस्तावेज़ में पृष्ठ ट्री नहीं है + a document must keep at least one page एक दस्तावेज़ में कम से कम एक पृष्ठ बना रहना चाहिए + a bookmark cannot be moved inside itself बुकमार्क अपने अंदर नहीं खिसकाया जा सकता + the title must not be empty शीर्षक ख़ाली नहीं होना चाहिए + the document has no form fields दस्तावेज़ में कोई फ़ॉर्म फ़ील्ड नहीं हैं + there are no redaction marks to apply लागू करने के लिए कोई रीडैक्शन चिह्न नहीं हैं + there are no pages to print छपाई के लिए कोई पृष्ठ नहीं हैं + the document has no tags दस्तावेज़ में कोई टैग नहीं हैं + {0}: {1} {0}: {1} + the text recognition models are not installed (reinstall PdfCraft, or set PDFCRAFT_MODELS to the folder that holds them) टेक्स्ट पहचान मॉडल इंस्टॉल नहीं हैं (PdfCraft दोबारा इंस्टॉल करें, या PDFCRAFT_MODELS को उस फ़ोल्डर पर सेट करें जिसमें वे मौजूद हैं) + the image is empty छवि ख़ाली है + this file isn't XFDF, FDF, XML or text form data यह फ़ाइल XFDF, FDF, XML या टेक्स्ट फ़ॉर्म डेटा नहीं है + nothing in the file matches this document फ़ाइल में कुछ भी इस दस्तावेज़ से मेल नहीं खाता + This page couldn't be displayed.\n{e} यह पृष्ठ नहीं दिखाया जा सका।\n{e} + Go to page {p} पृष्ठ {p} पर जाएँ + {s} action {s} क्रिया + Page {p} of {n} पृष्ठ {p} / {n} + 1 page selected 1 पृष्ठ चयनित + {n} pages selected {n} पृष्ठ चयनित + {name} — unsaved changes {name} — असहेजे बदलाव + {kind} field {kind} फ़ील्ड + Select a file for the stamp स्टाम्प के लिए फ़ाइल चुनें + JavaScript, e.g. getField("total").value JavaScript, जैसे getField("total").value + Font: Helvetica फ़ॉन्ट: Helvetica + e.g. en-US जैसे en-US + Rendering: hayro (bootstrap) · UI: egui · Icons: Lucide (ISC) · Fonts: Inter, JetBrains Mono, Dancing Script (OFL) रेंडरिंग: hayro (बूटस्ट्रैप) · UI: egui · आइकन: Lucide (ISC) · फ़ॉन्ट: Inter, JetBrains Mono, Dancing Script (OFL) + CheckBox चेकबॉक्स + Radio रेडियो + PushButton पुश बटन + Combo कॉम्बो + List सूची + Unknown अज्ञात + The document has no XMP metadata दस्तावेज़ में कोई XMP मेटाडेटा नहीं है + The title in the metadata and the document information differ मेटाडेटा और दस्तावेज़ जानकारी में शीर्षक अलग-अलग हैं + The document is encrypted दस्तावेज़ एन्क्रिप्टेड है + Device colour is used, but there is no PDF/A output intent डिवाइस रंग का उपयोग हुआ है, लेकिन कोई PDF/A आउटपुट इंटेंट नहीं है + DeviceCMYK is used: it needs a CMYK output intent (not added automatically) DeviceCMYK का उपयोग हुआ है: इसे CMYK आउटपुट इंटेंट चाहिए (अपने आप नहीं जुड़ता) + The document has additional actions (/AA) दस्तावेज़ में अतिरिक्त क्रियाएँ (/AA) हैं + The document has document-level JavaScript दस्तावेज़ में दस्तावेज़-स्तरीय JavaScript है + The form asks viewers to make appearances (NeedAppearances) फ़ॉर्म व्यूअर से अपीयरेंस बनाने को कहता है (NeedAppearances) + A form field has additional actions एक फ़ॉर्म फ़ील्ड में अतिरिक्त क्रियाएँ हैं + A stream uses LZW compression एक स्ट्रीम LZW संपीड़न का उपयोग करती है + A stream refers to an external file एक स्ट्रीम बाहरी फ़ाइल की ओर इशारा करती है + An image asks to be interpolated एक छवि इंटरपोलेशन माँगती है + An image has alternates or OPI information एक छवि के वैकल्पिक रूप या OPI जानकारी मौजूद हैं + PostScript XObjects aren't allowed PostScript XObject की अनुमति नहीं है + Embedded files must be PDF/A files themselves (use PDF/A-3 for others) एम्बेडेड फ़ाइलें स्वयं PDF/A फ़ाइलें होनी चाहिए (अन्य के लिए PDF/A-3 उपयोग करें) + An embedded file has no AFRelationship एक एम्बेडेड फ़ाइल में AFRelationship नहीं है + Select Icon आइकन चुनें + Choose images छवियाँ चुनें + {dpi} pixels/inch {dpi} पिक्सेल/इंच + Type your {what}. अपना {what} टाइप करें। + Draw your {what} below. अपना {what} नीचे बनाएँ। + Your name आपका नाम + Images and text (converted to PDF) छवियाँ और टेक्स्ट (पीडीएफ़ में बदले गए) + Images and text छवियाँ और टेक्स्ट + Check Box Style: चेक बॉक्स शैली: + Button Style: बटन शैली: + Check चेक + Circle वृत्त + Diamond डायमंड + Square वर्ग + Star तारा + {month} {y} {month} {y} + Change {key} {key} बदलें + Insert pages from {name} {name} से पृष्ठ जोड़ें + Insert pages from {name} — 1 field renamed {name} से पृष्ठ जोड़ें — 1 फ़ील्ड का नाम बदला गया + Insert pages from {name} — fields renamed {name} से पृष्ठ जोड़ें — फ़ील्ड के नाम बदले गए + Fill in {name} {name} भरें + Set the image of {name} {name} की छवि सेट करें + Edit script of {name} {name} की स्क्रिप्ट संपादित करें + Import {name} {name} आयात करें + Add bookmark बुकमार्क जोड़ें + Rename bookmark बुकमार्क का नाम बदलें + Delete bookmark बुकमार्क हटाएँ + Move bookmark बुकमार्क खिसकाएँ + Set bookmark destination बुकमार्क गंतव्य सेट करें + Add stamp स्टाम्प जोड़ें + Delete comment टिप्पणी हटाएँ + Edit comment टिप्पणी संपादित करें + Erase मिटाएँ + Lock comment टिप्पणी लॉक करें + Unlock comment टिप्पणी अनलॉक करें + Move comment टिप्पणी खिसकाएँ + Resize comment टिप्पणी का आकार बदलें + Change comment properties टिप्पणी गुण बदलें + Add field फ़ील्ड जोड़ें + Change field properties फ़ील्ड गुण बदलें + Delete field फ़ील्ड हटाएँ + Duplicate field फ़ील्ड डुप्लिकेट करें + Set tab order टैब क्रम सेट करें + Change initial view प्रारंभिक दृश्य बदलें + Set alternate text वैकल्पिक टेक्स्ट सेट करें + Mark figure as decorative आकृति को सजावटी के रूप में चिह्नित करें + Run JavaScript JavaScript चलाएँ + Delete document JavaScript दस्तावेज़ JavaScript हटाएँ + Edit document JavaScript दस्तावेज़ JavaScript संपादित करें + Edit text टेक्स्ट संपादित करें + Load document font दस्तावेज़ फ़ॉन्ट लोड करें + Move image छवि खिसकाएँ + Rotate image छवि घुमाएँ + Flip image छवि पलटें + Delete image छवि हटाएँ + Add header & footer हेडर और फ़ुटर जोड़ें + Update header & footer हेडर और फ़ुटर अपडेट करें + Update watermark वॉटरमार्क अपडेट करें + Add background पृष्ठभूमि जोड़ें + Update background पृष्ठभूमि अपडेट करें + Add image छवि जोड़ें + Edit content सामग्री संपादित करें + Delete content सामग्री हटाएँ + Remove redaction marks रीडैक्शन चिह्न हटाएँ + Add link लिंक जोड़ें + Change link properties लिंक गुण बदलें + Delete link लिंक हटाएँ + Create link लिंक बनाएँ + Flatten फ़्लैटन करें + Add sticky note स्टिकी नोट जोड़ें + Add highlight हाइलाइट जोड़ें + Add underline रेखांकन जोड़ें + Add strikethrough स्ट्राइकथ्रू जोड़ें + Add squiggly underline लहरदार रेखांकन जोड़ें + Add rectangle आयत जोड़ें + Add oval अंडाकार जोड़ें + Add arrow तीर जोड़ें + Add line रेखा जोड़ें + Add drawing रेखाचित्र जोड़ें + Add text box टेक्स्ट बॉक्स जोड़ें + Add checkmark चेक मार्क जोड़ें + Add cross क्रॉस जोड़ें + Add dot बिंदु जोड़ें + Add signature हस्ताक्षर जोड़ें + Add redaction mark रीडैक्शन चिह्न जोड़ें + Add cloud बादल जोड़ें + Add polygon बहुभुज जोड़ें + Add connected lines जुड़ी रेखाएँ जोड़ें + Add callout कॉलआउट जोड़ें + Add inserted text सम्मिलित टेक्स्ट जोड़ें + Add file attachment फ़ाइल अटैचमेंट जोड़ें + Set status Accepted स्थिति सेट करें: स्वीकृत + Set status Rejected स्थिति सेट करें: अस्वीकृत + Set status Cancelled स्थिति सेट करें: रद्द किया गया + Set status Completed स्थिति सेट करें: पूर्ण + Set status None स्थिति सेट करें: कोई नहीं + Set status Unmarked स्थिति सेट करें: अचिह्नित + Save as PDF/A-1b PDF/A-1b के रूप में सहेजें + Save as PDF/A-2b PDF/A-2b के रूप में सहेजें + Save as PDF/A-3b PDF/A-3b के रूप में सहेजें + Fill & Sign: change signature फ़िल और साइन: हस्ताक्षर बदलें + Fill & Sign: change initials फ़िल और साइन: आद्याक्षर बदलें + Fill & Sign: remove saved signature फ़िल और साइन: सहेजा गया हस्ताक्षर हटाएँ + Fill & Sign: remove saved initials फ़िल और साइन: सहेजे गए आद्याक्षर हटाएँ + Change signature हस्ताक्षर बदलें + Change initials आद्याक्षर बदलें + Measure distance दूरी मापें + Measure perimeter परिमाप मापें + Measure area क्षेत्रफल मापें + Set measurement scale मापन पैमाना सेट करें + Measurement information मापन जानकारी + Measurement snapping मापन स्नैपिंग + Export measurements as CSV मापन CSV के रूप में निर्यात करें + Distance दूरी + Perimeter परिमाप + Area क्षेत्रफल + Drawing scale रेखाचित्र पैमाना + Snapping स्नैपिंग + Export measurements मापन निर्यात करें + Open a PDF to measure it. मापने के लिए एक पीडीएफ़ खोलें। + Click vertices. Enter or double-click finishes a perimeter or area. Click the first point to close an area. शीर्षों पर क्लिक करें। Enter या डबल-क्लिक परिमाप या क्षेत्रफल पूरा कर देता है। क्षेत्रफल बंद करने के लिए पहले बिंदु पर क्लिक करें। + Shift constrains to 45 degrees. Backspace removes a vertex. Escape cancels. Shift कोण को 45 डिग्री तक सीमित रखता है। Backspace एक शीर्ष हटा देता है। Escape रद्द करता है। + Angle कोण + Click the first point to begin. शुरू करने के लिए पहले बिंदु पर क्लिक करें। + Snap to drawing रेखाचित्र से स्नैप करें + Endpoints अंत बिंदु + Midpoints मध्य बिंदु + Intersections प्रतिच्छेदन + Paths पथ + Sensitivity संवेदनशीलता + Unit इकाई + Decimals दशमलव स्थान + Calibrate from two points दो बिंदुओं से कैलिब्रेट करें + Entire page पूरा पृष्ठ + Viewport rectangle in page points (x, y, width, height) पृष्ठ बिंदुओं में व्यूपोर्ट आयत (x, y, चौड़ाई, ऊँचाई) + Viewport व्यूपोर्ट + Apply scale पैमाना लागू करें + Saved measurements सहेजे गए मापन + Saved measurements. मापन सहेजे गए। + Endpoint अंत बिंदु + Midpoint मध्य बिंदु + Intersection प्रतिच्छेदन + Path पथ + This drawing exceeds the snapping limit; only the first paths are used. यह रेखाचित्र स्नैपिंग सीमा से बड़ा है; केवल पहले पथ ही उपयोग में आते हैं। + Some page content couldn't be read; snapping uses the rest. पृष्ठ की कुछ सामग्री नहीं पढ़ी जा सकी; स्नैपिंग बाक़ी सामग्री का उपयोग करती है। + Unsupported measurements असमर्थित मापन + Label लेबल + {n} measurements use an unsupported format and are left out. {n} मापन असमर्थित प्रारूप का उपयोग करते हैं, इसलिए छोड़ दिए गए हैं। + This area has too many overlapping paths; intersection snapping is limited. इस क्षेत्र में एक-दूसरे पर चढ़े बहुत सारे पथ हैं; प्रतिच्छेदन स्नैपिंग सीमित है। + This measurement needs at least {n} points. इस मापन को कम से कम {n} बिंदु चाहिए। + Change {what} {what} बदलें + Cut and stack काटें और ढेर लगाएँ + Default workspace mode डिफ़ॉल्ट वर्कस्पेस मोड + Documents and view दस्तावेज़ और दृश्य + Open email app ईमेल ऐप खोलें + Open link लिंक खोलें + Open this web page? यह वेब पृष्ठ खोलें? + Scripts run in a sandbox without file or network access. A script that asks to open a web page needs your permission first. With JavaScript off, Acrobat's standard format, validate and calculate functions still work. स्क्रिप्ट ऐसे सैंडबॉक्स में चलती हैं जिसमें फ़ाइल या नेटवर्क की पहुँच नहीं होती। वेब पृष्ठ खोलने को कहने वाली स्क्रिप्ट को पहले आपकी अनुमति चाहिए। JavaScript बंद होने पर भी Acrobat के मानक फ़ॉर्मेट, सत्यापन और गणना फ़ंक्शन काम करते रहते हैं। + Sign yourself स्वयं हस्ताक्षर करें + Used when opening PDFs. An explicit launch or control mode takes precedence for the session. पीडीएफ़ खोलते समय उपयोग होता है। सत्र के लिए स्पष्ट रूप से दिया गया लॉन्च या नियंत्रण मोड प्राथमिकता लेता है। + Write this email? यह ईमेल लिखें? + {who} in this document wants to open this address in your browser: इस दस्तावेज़ में {who} आपके ब्राउज़र में यह पता खोलना चाहता है: + {who} in this document wants to open your email app with this address: इस दस्तावेज़ में {who} आपके ईमेल ऐप में यह पता लेकर आना चाहता है: + This web address mixes letters from different alphabets, a common way to imitate another site's name. यह वेब पता अलग-अलग वर्णमालाओं के अक्षर मिलाकर बना है — किसी दूसरी साइट का नाम नक़ली बनाने का आम तरीक़ा। + This web address uses letters from another alphabet, which can look like familiar ones. यह वेब पता किसी दूसरी वर्णमाला के अक्षरों का उपयोग करता है, जो जाने-पहचाने अक्षरों जैसे दिख सकते हैं। + Create PDF from images छवियों से पीडीएफ़ बनाएँ + Selected image files: {count} चयनित छवि फ़ाइलें: {count} + Use image resolution छवि का रेज़ोल्यूशन उपयोग करें + Use each image's embedded DPI; use 72 DPI when it is absent. हर छवि का एम्बेडेड DPI उपयोग करें; न होने पर 72 DPI उपयोग करें। + Use 72 DPI (one point per pixel) 72 DPI उपयोग करें (प्रति पिक्सेल एक पॉइंट) + Use custom DPI कस्टम DPI उपयोग करें + DPI sets the printed page size without resampling the image. DPI छवि को रीसैंपल किए बिना छपे पृष्ठ का आकार तय करता है। + Create बनाएँ + Dynamic XFA form laid out from its template: {pages}, {fields}. टेम्पलेट से लेआउट किया गया डायनामिक XFA फ़ॉर्म: {pages}, {fields}। + This form's scripts are turned off because one ran too long. Reopen the document to run them again. इस फ़ॉर्म की स्क्रिप्ट बंद कर दी गई हैं, क्योंकि एक स्क्रिप्ट बहुत लंबे समय तक चली। उन्हें फिर से चलाने के लिए दस्तावेज़ दोबारा खोलें। + XFA form: its fields and its XFA data are kept in step, so other viewers show what you fill in. XFA फ़ॉर्म: इसके फ़ील्ड और इसका XFA डेटा साथ-साथ चलते रहते हैं, इसलिए दूसरे व्यूअर आपने जो भरा है वही दिखाते हैं। + Switch to two-page view first to show the cover page कवर पृष्ठ दिखाने के लिए पहले दो-पृष्ठ दृश्य पर जाएँ + Page display: {layout} पृष्ठ प्रदर्शन: {layout} + Fit to width scrolling चौड़ाई के अनुसार स्क्रॉलिंग + Fit one full page एक पूरा पृष्ठ फ़िट करें + Default page display डिफ़ॉल्ट पृष्ठ प्रदर्शन + Default zoom डिफ़ॉल्ट ज़ूम + Used when a PDF doesn't ask for a layout or zoom. Continuous scrolling never snaps between pages. जब पीडीएफ़ लेआउट या ज़ूम न माँगता हो तब उपयोग होता है। लगातार स्क्रॉलिंग में पृष्ठों के बीच कभी स्नैप नहीं होता। + Choose a PNG or JPEG image (up to 4 MiB). Transparency is preserved. PNG या JPEG छवि चुनें (4 MiB तक)। पारदर्शिता बनी रहती है। + Couldn't import the signature image: {e} हस्ताक्षर की छवि आयात नहीं हो सकी: {e} +@plural {n} page|{n} pages {n} पृष्ठ +@plural {n} field|{n} fields {n} फ़ील्ड +@plural {n} field name collides with earlier files and will be renamed: {list}|{n} field names collide with earlier files and will be renamed: {list} {n} फ़ील्ड नाम पहले की फ़ाइलों से टकराता है और उसका नाम बदल दिया जाएगा: {list} + Create PDF from multiple files… कई फ़ाइलों से पीडीएफ़ बनाएँ… + Create separate PDFs… अलग-अलग पीडीएफ़ बनाएँ… + Optimizing… removing user data ऑप्टिमाइज़ हो रहा है… उपयोगकर्ता डेटा हटाया जा रहा है + Optimizing… image {d} of {t} ऑप्टिमाइज़ हो रहा है… छवि {d} / {t} + Optimizing… cleaning up ऑप्टिमाइज़ हो रहा है… सफ़ाई हो रही है + Optimizing… merging identical objects ऑप्टिमाइज़ हो रहा है… समान ऑब्जेक्ट मिलाए जा रहे हैं + Optimizing… writing the copy ऑप्टिमाइज़ हो रहा है… कॉपी लिखी जा रही है + Cancelling… रद्द हो रहा है… + Created a PDF from {n} files {n} फ़ाइलों से पीडीएफ़ बनाया गया + PDF, images and text पीडीएफ़, छवियाँ और टेक्स्ट + Insert a file before page {label} पृष्ठ {label} से पहले फ़ाइल जोड़ें + Insert a file at the end अंत में फ़ाइल जोड़ें + Save pages पृष्ठ सहेजें + Save these pages as one PDF इन पृष्ठों को एक पीडीएफ़ के रूप में सहेजें + No changes to save सहेजने के लिए कोई बदलाव नहीं + Created a PDF from {n} files; left out: {names} {n} फ़ाइलों से पीडीएफ़ बनाया गया; छोड़े गए: {names} + Created a PDF from the first {n} files पहली {n} फ़ाइलों से पीडीएफ़ बनाया गया + Go to page… पृष्ठ पर जाएँ… + Optimization is already running ऑप्टिमाइज़ेशन पहले से चल रहा है + Optimization cancelled ऑप्टिमाइज़ेशन रद्द किया गया + Couldn't optimize the file फ़ाइल ऑप्टिमाइज़ नहीं हो सकी + Files are combined in this order. Leave Pages empty to take every page. फ़ाइलें इसी क्रम में जुड़ती हैं। सभी पृष्ठ लेने के लिए “पृष्ठ” ख़ाली छोड़ दें। + Portable mode is off: {folder} can't be written ({error}). Settings are kept in your user folder instead. पोर्टेबल मोड बंद है: {folder} में लिखा नहीं जा सकता ({error})। सेटिंग्स इसके बजाय आपके यूज़र फ़ोल्डर में रखी जाती हैं। + PdfCraft is drawing without a graphics processor, so it may be slow. Updating the graphics driver may help. PdfCraft बिना ग्राफ़िक्स प्रोसेसर के चित्र बना रहा है, इसलिए धीमा चल सकता है। ग्राफ़िक्स ड्राइवर अपडेट करने से मदद मिल सकती है। + Show दिखाएँ + Sort क्रमबद्ध करें + Reverse the order क्रम उल्टा करें + Grab bag विविध + Table तालिका + Username उपयोगकर्ता नाम + Display name प्रदर्शित नाम + Real name असली नाम + Name (A–Z) नाम (A–Z) + Merged PRs मर्ज किए गए PR + PRs PR + Commits कमिट + Lines added जोड़ी गई पंक्तियाँ + +LOC +LOC + Lines deleted हटाई गई पंक्तियाँ + −LOC −LOC + Line delta पंक्ति अंतर + ΔLOC ΔLOC + Binary assets added जोड़े गए बाइनरी एसेट + +Bin +Bin + Binary assets removed हटाए गए बाइनरी एसेट + −Bin −Bin + First commit पहला कमिट + First पहला + Last commit आख़िरी कमिट + Last आख़िरी + No contributor data was built into this copy. इस प्रति में योगदानकर्ताओं का डेटा शामिल नहीं किया गया है। + No model credits were built into this copy. इस प्रति में मॉडल क्रेडिट शामिल नहीं किए गए हैं। + {n} contributors · {c} commits {n} योगदानकर्ता · {c} कमिट + Company कंपनी + Model मॉडल + % of all commits कुल कमिट का % + Lines +/− पंक्तियाँ +/− + @{login}: {prs} PRs, {commits} commits, +{added} / −{deleted} lines (Δ {delta}), +{bin_added} / −{bin_deleted} binary assets, {first} – {last} @{login}: {prs} PR, {commits} कमिट, +{added} / −{deleted} पंक्तियाँ (Δ {delta}), +{bin_added} / −{bin_deleted} बाइनरी एसेट, {first} – {last} + None of those files can be made into a PDF; use PDFs, images or .txt files इनमें से कोई भी फ़ाइल पीडीएफ़ नहीं बन सकती; पीडीएफ़, छवियाँ या .txt फ़ाइलें उपयोग करें + About के बारे में + Contributors योगदानकर्ता + Models मॉडल + Only continue if you trust this document. An address can carry information from the document, such as what you typed into its form. केवल तब आगे बढ़ें जब आप इस दस्तावेज़ पर भरोसा करते हों। पता दस्तावेज़ की जानकारी साथ ले जा सकता है, जैसे आपने इसके फ़ॉर्म में जो टाइप किया। + Print single-sided. Keep the sheets in order, cut at the marks, then stack the piles left to right, top to bottom. एक तरफ़ छापें। शीट क्रम में रखें, चिह्नों पर काटें, फिर ढेरों को बाएँ से दाएँ और ऊपर से नीचे जमाएँ। +comment menu Edit संपादित करें + Undo {action} {action} पूर्ववत करें + Redo {action} {action} दोहराएँ +signature pad Type टाइप करें +action wizard Start प्रारंभ करें +calendar date January जनवरी +calendar date February फ़रवरी +calendar date March मार्च +calendar date April अप्रैल +calendar date May मई +calendar date June जून +calendar date July जुलाई +calendar date August अगस्त +calendar date September सितंबर +calendar date October अक्तूबर +calendar date November नवंबर +calendar date December दिसंबर + Reopen the files that were open when PdfCraft last closed PdfCraft के बंद होने के समय जो फ़ाइलें खुली थीं, उन्हें दोबारा खोलें + Clear Recent Files हाल की फ़ाइलें साफ़ करें + Remove from Recent हाल की फ़ाइलों से हटाएँ + Remove {name} from Recent {name} को हाल की फ़ाइलों से हटाएँ + Inserted text सम्मिलित टेक्स्ट + Add {what} {what} जोड़ें + Use {what} {what} उपयोग करें + Place saved {what} सहेजा हुआ {what} रखें + Remove saved {what} सहेजा हुआ {what} हटाएँ + A link एक लिंक + A button एक बटन + A script एक स्क्रिप्ट + {who} in this document tried to open an address PdfCraft won't open: {e}. इस दस्तावेज़ में {who} ने एक ऐसा पता खोलने की कोशिश की जो PdfCraft नहीं खोलता: {e}। + {who} in this document tried to open an address PdfCraft won't open: {e}. Only web (http, https) and email (mailto) links open from documents. इस दस्तावेज़ में {who} ने एक ऐसा पता खोलने की कोशिश की जो PdfCraft नहीं खोलता: {e}। दस्तावेज़ों से केवल वेब (http, https) और ईमेल (mailto) लिंक खुलते हैं। + Another file dialog is still open. Finish with it first. एक और फ़ाइल संवाद अभी खुला है। पहले उससे काम पूरा करें। + Couldn't show the file picker. Please try again. फ़ाइल चुनने वाला संवाद नहीं दिखाया जा सका। कृपया दोबारा कोशिश करें। + The document changed while you were choosing a file, so nothing was changed. आप फ़ाइल चुन रहे थे, तभी दस्तावेज़ बदल गया, इसलिए कुछ नहीं बदला गया। + The document was closed before it could be saved. दस्तावेज़ सहेजे जाने से पहले ही बंद हो गया। + The pages were extracted but not deleted, because the document changed while you were choosing a folder. पृष्ठ निकाले गए, पर हटाए नहीं गए, क्योंकि आप फ़ोल्डर चुन रहे थे तभी दस्तावेज़ बदल गया। + That didn't work: an internal error stopped it ({m}). वह काम नहीं हो सका: एक आंतरिक त्रुटि ने उसे रोक दिया ({m})। + The Windows store's digital IDs couldn't be listed: {e} Windows स्टोर के डिजिटल ID की सूची नहीं बनाई जा सकी: {e} + Align fields फ़ील्ड संरेखित करें + Distribute fields फ़ील्ड वितरित करें + Match field sizes फ़ील्ड के आकार मिलाएँ + Mark for redaction रीडैक्शन के लिए चिह्नित करें + Mark pages for redaction रीडैक्शन के लिए पृष्ठ चिह्नित करें + Change document properties दस्तावेज़ गुण बदलें + Mark differences अंतर चिह्नित करें + Run form script फ़ॉर्म स्क्रिप्ट चलाएँ + Scripted content must be usable with a keyboard and assistive technology. Check the document's scripts. स्क्रिप्ट वाली सामग्री कीबोर्ड और सहायक तकनीक से उपयोग करने योग्य होनी चाहिए। दस्तावेज़ की स्क्रिप्ट जाँचें। + Table rows belong directly in a table or its head, body or foot. Fix the table's tags. तालिका की पंक्तियाँ सीधे तालिका या उसके शीर्ष, मुख्य भाग या पाद में होनी चाहिए। तालिका के टैग ठीक करें। + Basic constraints मूल प्रतिबंध + Certificate authority प्रमाणपत्र प्राधिकरण + End entity अंतिम इकाई + SHA-1 digest SHA-1 डाइजेस्ट + SHA-256 digest SHA-256 डाइजेस्ट + Squiggly लहरदार + Home / End Home / End + H / Space (hold) H / Space (दबाए रखें) + Rotation: घुमाव: + Line ending रेखा का अंत + Open arrow खुला तीर + Closed arrow बंद तीर + Butt बट + Reverse open arrow उल्टा खुला तीर + Reverse closed arrow उल्टा बंद तीर + Slash स्लैश + The PDF text fonts can't draw “{c}” ({code}). Choose supported text. पीडीएफ़ टेक्स्ट फ़ॉन्ट “{c}” ({code}) नहीं बना सकते। समर्थित टेक्स्ट चुनें। + The standard fonts can't draw “{c}” ({code}). Only Western European characters can be added as text for now. मानक फ़ॉन्ट “{c}” ({code}) नहीं बना सकते। फ़िलहाल टेक्स्ट के रूप में केवल पश्चिमी यूरोपीय अक्षर ही जोड़े जा सकते हैं। + This field's font can't draw “{c}” ({code}), so PdfCraft shows ? in its place. The value is saved, and other PDF viewers redraw the field from it. इस फ़ील्ड का फ़ॉन्ट “{c}” ({code}) नहीं बना सकता, इसलिए PdfCraft उसकी जगह ? दिखाता है। मान सहेजा गया है, और दूसरे पीडीएफ़ व्यूअर उसी से फ़ील्ड दोबारा बनाते हैं। + The fonts PdfCraft writes with can't draw “{c}” ({code}), so it shows as ? in every PDF viewer. The text is saved. जिन फ़ॉन्ट से PdfCraft लिखता है, वे “{c}” ({code}) नहीं बना सकते, इसलिए हर पीडीएफ़ व्यूअर में वह ? की तरह दिखता है। टेक्स्ट सहेजा गया है। + Larger pages बड़े पृष्ठ + Smaller pages छोटे पृष्ठ + Reset page size पृष्ठ आकार रीसेट करें + Flatten Fill & Sign when saving सहेजते समय फ़िल और साइन फ़्लैटन करें + Text, marks and signatures become part of the page. Other comments stay editable. टेक्स्ट, चिह्न और हस्ताक्षर पृष्ठ का हिस्सा बन जाते हैं। बाक़ी टिप्पणियाँ संपादन योग्य रहती हैं। + Date format तिथि प्रारूप + Fill & Sign dates फ़िल और साइन की तिथियाँ + Pattern पैटर्न + Today: {date} आज: {date} + yyyy or yy year · m or mm month · mmm or mmmm month name · d or dd day · ddd or dddd weekday. H, h, M, s and t are time letters and can't be used on their own: put {escape} before a letter to show it as is. yyyy या yy वर्ष · m या mm महीना · mmm या mmmm महीने का नाम · d या dd दिन · ddd या dddd सप्ताह का दिन। H, h, M, s और t समय के अक्षर हैं और अकेले उपयोग नहीं किए जा सकते: किसी अक्षर को वैसा ही दिखाने के लिए उसके पहले {escape} लगाएँ। + Same as interface ({language}) इंटरफ़ेस के समान ({language}) + {chars} can't be written into the PDF yet: Fill & Sign text is Western European only. Pick a numeric format such as dd.mm.yyyy. {chars} को अभी पीडीएफ़ में नहीं लिखा जा सकता: फ़िल और साइन का टेक्स्ट केवल पश्चिमी यूरोपीय अक्षरों तक सीमित है। dd.mm.yyyy जैसा कोई संख्यात्मक प्रारूप चुनें। + Opens the printer driver's preferences. They are saved for every print from this computer; the copies, two-sided, grayscale and paper chosen here still apply. प्रिंटर ड्राइवर की प्राथमिकताएँ खोलता है। वे इस कंप्यूटर से की जाने वाली हर छपाई के लिए सहेजी जाती हैं; यहाँ चुनी गई प्रतियाँ, दोतरफ़ा छपाई, ग्रेस्केल और काग़ज़ फिर भी लागू रहते हैं। + The printer driver's own settings for this print: paper tray, paper type, finishing and more. इस छपाई के लिए प्रिंटर ड्राइवर की अपनी सेटिंग्स: काग़ज़ ट्रे, काग़ज़ का प्रकार, फ़िनिशिंग आदि। + Couldn't open the printer's preferences: {e} प्रिंटर की प्राथमिकताएँ नहीं खोली जा सकीं: {e} + Printer properties प्रिंटर गुण + Reset to printer defaults प्रिंटर डिफ़ॉल्ट पर रीसेट करें + This printer offers no settings of its own. इस प्रिंटर की कोई अपनी सेटिंग्स नहीं हैं। + Margins हाशिये + For page sizes and margins. पृष्ठ आकारों और हाशियों के लिए। +certificate Subject विषय + Scroll tabs left टैब बाएँ स्क्रॉल करें + Scroll tabs right टैब दाएँ स्क्रॉल करें + Shared Field Properties साझा फ़ील्ड गुण + {n} fields selected {n} फ़ील्ड चयनित + Mixed मिश्रित + Custom font कस्टम फ़ॉन्ट + Only checked properties will change. Mixed means the selected fields have different values. केवल चुने गए गुण बदलेंगे। “मिश्रित” का मतलब है कि चयनित फ़ील्ड के मान अलग-अलग हैं। + Shift- or Ctrl/Command-click to select several fields. कई फ़ील्ड चुनने के लिए Shift या Ctrl/Command के साथ क्लिक करें। + Font size 0 uses automatic sizing. फ़ॉन्ट आकार 0 पर स्वचालित आकार निर्धारण लागू होता है। + Character limit: अक्षर सीमा: + Character limit 0 means no limit. A comb of characters needs a limit. अक्षर सीमा 0 का मतलब है कोई सीमा नहीं। अक्षर कॉम्ब को एक सीमा चाहिए। + To change locked fields, also set Locked to No. लॉक किए गए फ़ील्ड बदलने के लिए, “लॉक” को भी “नहीं” पर सेट करें। + Comb of characters अक्षर कॉम्ब + The document changed while you were editing field properties. आप फ़ील्ड गुण संपादित कर रहे थे, तभी दस्तावेज़ बदल गया। + The document is no longer open. दस्तावेज़ अब खुला नहीं है। + The field properties dialog is no longer open. फ़ील्ड गुण संवाद अब खुला नहीं है। + The field properties could not be changed. फ़ील्ड गुण नहीं बदले जा सके। + The selected fields could not be found. Select them again. चयनित फ़ील्ड नहीं मिले। उन्हें दोबारा चुनें। + The field {name} no longer exists. फ़ील्ड {name} अब मौजूद नहीं है। + A selected field has no widget on any page, so the fields can't be edited together. एक चयनित फ़ील्ड का किसी भी पृष्ठ पर विजेट नहीं है, इसलिए फ़ील्ड एक साथ संपादित नहीं किए जा सकते। + ({n} at {dpi} dpi, the largest size they can be drawn at) ({n}, {dpi} dpi पर — जितने बड़े आकार में उन्हें बनाया जा सकता है) +@plural {n} object selected|{n} objects selected {n} ऑब्जेक्ट चयनित + Drag the selection to move it. Esc clears the selection. चयन को खिसकाने के लिए उसे खींचें। Esc चयन साफ़ कर देता है। + Shift-click to select several objects. Drag empty space to select an area. कई ऑब्जेक्ट चुनने के लिए Shift के साथ क्लिक करें। कोई क्षेत्र चुनने के लिए ख़ाली जगह पर खींचें। + Select at most 1000 objects at a time. एक बार में अधिकतम 1000 ऑब्जेक्ट चुनें। + Finish or discard the text being edited before selecting several objects. कई ऑब्जेक्ट चुनने से पहले संपादित किया जा रहा टेक्स्ट पूरा करें या छोड़ दें। + Move object ऑब्जेक्ट खिसकाएँ + Move objects ऑब्जेक्ट खिसकाएँ + Vertical text cannot be moved with this selection. लंबवत टेक्स्ट इस चयन के साथ खिसकाया नहीं जा सकता। + Text used as a clipping path cannot be moved with this selection. क्लिपिंग पथ के रूप में उपयोग होता टेक्स्ट इस चयन के साथ खिसकाया नहीं जा सकता। + These objects could not be moved. Select them again and try a smaller move. इन ऑब्जेक्ट को खिसकाया नहीं जा सका। उन्हें दोबारा चुनें और कम खिसकाव आज़माएँ। + This page contains objects that cannot be selected together. इस पृष्ठ पर कुछ ऐसे ऑब्जेक्ट हैं जिन्हें एक साथ नहीं चुना जा सकता। + Fill colour फ़िल रंग + No fill कोई फ़िल नहीं + Fill colour: none फ़िल रंग: कोई नहीं +key Ctrl Ctrl +key Shift Shift +key Delete Delete +key Esc Esc +key Home Home +key End End +key Space Space + Grid view ग्रिड दृश्य + List view सूची दृश्य + Files are combined in the order shown. Drag them to change it. फ़ाइलें दिखाए गए क्रम में जुड़ती हैं। क्रम बदलने के लिए उन्हें खींचें। + Preview unavailable: {e} पूर्वावलोकन उपलब्ध नहीं: {e} + Pages: {k} of {n} पृष्ठ: {k} / {n} + Check the pages पृष्ठ जाँचें + Switch to List view to change the pages it takes. कौन से पृष्ठ लिए जाएँ, यह बदलने के लिए सूची दृश्य पर जाएँ। + Expand all सभी विस्तृत करें + Collapse all सभी संकुचित करें + Remove page पृष्ठ हटाएँ + Remove {n} pages {n} पृष्ठ हटाएँ + Reset panel layout पैनल लेआउट रीसेट करें + Float panel पैनल फ़्लोट करें + Move to group समूह में ले जाएँ + Panels पैनल + Resize panels पैनल का आकार बदलें + Resize panel window पैनल विंडो का आकार बदलें + PDF page: {size} पीडीएफ़ पृष्ठ: {size} + Match page at 100% पृष्ठ को 100% पर मिलाएँ + PDF scale: {scale}% पीडीएफ़ पैमाना: {scale}% + Printer paper and scaling may differ. Check driver settings. प्रिंटर का काग़ज़ और स्केलिंग अलग हो सकते हैं। ड्राइवर सेटिंग्स जाँचें। + Drawing scale changes. Use Actual size for full-scale plans. रेखाचित्र पैमाना बदल जाता है। पूर्ण-पैमाने योजनाओं के लिए “वास्तविक आकार” चुनें। + Reload documents when their files change on disk जब उनकी फ़ाइलें डिस्क पर बदलें तो दस्तावेज़ दोबारा लोड करें + This file changed on disk. Reload it to see the new version; your unsaved changes will be lost. यह फ़ाइल डिस्क पर बदल गई है। नया संस्करण देखने के लिए उसे दोबारा लोड करें; आपके असहेजे बदलाव खो जाएँगे। + Reload दोबारा लोड करें + Couldn't reload {name}: {e} {name} दोबारा लोड नहीं हो सका: {e} + Select page {label} पृष्ठ {label} चुनें + Rotate page {label} counterclockwise पृष्ठ {label} वामावर्त घुमाएँ + Rotate page {label} clockwise पृष्ठ {label} दक्षिणावर्त घुमाएँ + Delete page {label} पृष्ठ {label} हटाएँ + Mouse wheel scroll speed माउस व्हील स्क्रॉल गति +scroll speed Slow धीमी +scroll speed Normal सामान्य +scroll speed Fast तेज़ + Animation effects एनिमेशन प्रभाव +animation effects On चालू +animation effects Off बंद + Enhance camera image कैमरे की छवि सुधारें + Drag the corners onto the document's edges, then choose Enhance page. कोनों को दस्तावेज़ के किनारों तक खींचें, फिर “पृष्ठ सुधारें” चुनें। + Enhance page पृष्ठ सुधारें + Done adding text टेक्स्ट जोड़ना पूरा हुआ + Discard this text (Esc) यह टेक्स्ट छोड़ दें (Esc) + Clean-up सफ़ाई + Original मूल + Greyscale ग्रेस्केल + Black and white काला-सफ़ेद + Reading colours पढ़ने के रंग + Replace document colours दस्तावेज़ के रंग बदलें + Black on white सफ़ेद पर काला + White on black काले पर सफ़ेद + Yellow on black काले पर पीला + Green on black काले पर हरा + Page background पृष्ठ पृष्ठभूमि + Only change the colour of black text or line art केवल काले टेक्स्ट या रेखा-चित्र का रंग बदलें + Change the colour of line art as well as text टेक्स्ट के साथ-साथ रेखा-चित्र का रंग भी बदलें + Colours are remapped while rendering; the document itself never changes. रेंडर करते समय रंग फिर से मैप किए जाते हैं; दस्तावेज़ अपने आप कभी नहीं बदलता। + This printer's driver doesn't take two-sided settings from other programs, so its own setting applies. Change it in Properties… इस प्रिंटर का ड्राइवर दूसरे प्रोग्रामों से दोतरफ़ा सेटिंग नहीं लेता, इसलिए उसकी अपनी सेटिंग लागू रहती है। इसे “गुण…” में बदलें।… + Browser's print dialog ब्राउज़र का प्रिंट संवाद + Copies, two-sided printing and colour are chosen in the browser's print dialog. प्रतियाँ, दोतरफ़ा छपाई और रंग ब्राउज़र के प्रिंट संवाद में चुने जाते हैं। + Preparing {n} sheets for printing… छपाई के लिए {n} शीट तैयार हो रही हैं… + Preparing sheet {done} of {total} for printing… छपाई के लिए शीट {done} / {total} तैयार हो रही है… + Opening the browser's print dialog… ब्राउज़र का प्रिंट संवाद खुल रहा है… + Couldn't print from the browser ({e}); downloaded {name} to print instead ब्राउज़र से छपाई नहीं हो सकी ({e}); इसके बजाय छपाई के लिए {name} डाउनलोड कर लिया गया + Tools panel side टूल पैनल की दिशा + Add comment टिप्पणी जोड़ें + Change tag properties टैग गुण बदलें + Tags panel टैग पैनल + Tags टैग + Tag type टैग प्रकार + Actual text वास्तविक टेक्स्ट + Find a tag टैग खोजें + Collapse tag टैग संकुचित करें + Expand tag टैग विस्तृत करें + Revert changes बदलाव पूर्ववत करें + Save tag properties टैग गुण सहेजें + This document has no editable structure tags. इस दस्तावेज़ में संपादन योग्य संरचना टैग नहीं हैं। + {n} tags {n} टैग + Save or revert changes before selecting another tag. कोई दूसरा टैग चुनने से पहले बदलाव सहेजें या पूर्ववत करें। + Left out: {names} छोड़े गए: {names} + already a PDF पहले से पीडीएफ़ है + no unused output name कोई अप्रयुक्त आउटपुट नाम नहीं + no output folder was chosen आउटपुट फ़ोल्डर नहीं चुना गया +@plural Downloaded {n} PDF|Downloaded {n} PDFs {n} पीडीएफ़ डाउनलोड हुए + Scan स्कैन करें + Sign a sheet of white paper and take a photo of it in bright, even light (use the flash). Choose the photo or drop it here: PdfCraft finds the signature and removes the paper. सफ़ेद काग़ज़ के एक टुकड़े पर हस्ताक्षर करें और तेज़, एकसार रोशनी में उसकी फ़ोटो लें (फ़्लैश लगाएँ)। फ़ोटो चुनें या यहाँ छोड़ दें: PdfCraft हस्ताक्षर ढूँढ लेगा और काग़ज़ हटा देगा। + Choose photo… फ़ोटो चुनें… + No photo chosen कोई फ़ोटो नहीं चुना गया + Photo फ़ोटो + Ink sensitivity स्याही संवेदनशीलता + No signature was found in the frame. Move the frame over the signature or raise the ink sensitivity. फ़्रेम में कोई हस्ताक्षर नहीं मिला। फ़्रेम को हस्ताक्षर पर ले जाएँ या स्याही संवेदनशीलता बढ़ाएँ। + Couldn't use the photo: {e} फ़ोटो उपयोग नहीं किया जा सका: {e} + Close Tab टैब बंद करें + Reopen Closed Tab बंद टैब दोबारा खोलें + Reveal in Finder Finder में दिखाएँ + Reveal in File Explorer File Explorer में दिखाएँ + Other colour… दूसरा रंग… + Recent colours हाल के रंग + Couldn't follow linked PDF: {reason} लिंक किए गए पीडीएफ़ को खोला नहीं जा सका: {reason} + The linked PDF opened, but its named destination was not applied. लिंक किया गया पीडीएफ़ खुल गया, पर उसका नामित गंतव्य लागू नहीं हुआ। + The linked PDF opened, but its page destination was out of range. लिंक किया गया पीडीएफ़ खुल गया, पर उसका पृष्ठ गंतव्य सीमा से बाहर था। + Local cross-PDF links require the desktop app पीडीएफ़ के बीच स्थानीय लिंक के लिए डेस्कटॉप ऐप ज़रूरी है + Paste चिपकाएँ + Select all सभी चुनें + Next अगला + Previous पिछला + Choose… चुनें… + Refresh ताज़ा करें + Loading… लोड हो रहा है… + Save changes? बदलाव सहेजें? + Page {n} पृष्ठ {n} + of / + Comment टिप्पणी + Font फ़ॉन्ट + Color रंग + Theme थीम + System सिस्टम + Save file फ़ाइल सहेजें + Import आयात करें + Help… सहायता… + Automatically स्वचालित + Never कभी नहीं + Always हमेशा + On चालू + Enabled सक्षम + Disabled अक्षम + Error त्रुटि + Warning चेतावनी + Information जानकारी + Success सफल + Folder फ़ोल्डर + Choose a file… फ़ाइल चुनें… + Choose a folder… फ़ोल्डर चुनें… + Open folder फ़ोल्डर खोलें + Create folder फ़ोल्डर बनाएँ + Duplicate प्रतिलिपि बनाएँ + Move स्थानांतरित करें + Copy to clipboard क्लिपबोर्ड पर कॉपी करें + Copied to clipboard क्लिपबोर्ड पर कॉपी किया गया + Organize व्यवस्थित करें + Comment and review टिप्पणी और समीक्षा + Search results खोज परिणाम + No results कोई परिणाम नहीं + Page {n} of {total} पृष्ठ {n} / {total} + Tools उपकरण + Inspector निरीक्षक + on page {label} पृष्ठ {label} पर + A font isn't embedded एक फ़ॉन्ट एम्बेड नहीं किया गया है + A {} action isn't allowed {} क्रिया की अनुमति नहीं है + A {} annotation has additional actions {} एनोटेशन में अतिरिक्त क्रियाएँ हैं + A {} annotation has no appearance stream {} एनोटेशन में कोई अपीयरेंस स्ट्रीम नहीं है + A {} annotation isn't set to print, or is hidden {} एनोटेशन प्रिंट के लिए सेट नहीं है, या छिपा हुआ है + Accessibility Report सुलभता रिपोर्ट + Add the PDFs to combine संयोजित करने के लिए पीडीएफ़ जोड़ें + Added the first {n} PDFs in {folder} {folder} में पहली {n} पीडीएफ़ जोड़ी गईं + CRL Signing सीआरएल हस्ताक्षर + Certificate Signing प्रमाणपत्र हस्ताक्षर + Change Author लेखक बदलें + Change Keywords कीवर्ड बदलें + Change Subject विषय बदलें + Change Title शीर्षक बदलें + Choose a digital ID. कोई डिजिटल आईडी चुनें। + Create links लिंक बनाएँ + Creator निर्माता + Cut and stack needs Two-sided: Off. Print single-sided sheets. काटें और जमाएँ के लिए दो-तरफ़ा: बंद होना चाहिए। एक-तरफ़ा शीट प्रिंट करें। + Data Encipherment डेटा एन्सिफ़रमेंट + Decipher Only केवल डिसिफ़र + Detailed Report विस्तृत रिपोर्ट + DeviceCMYK is used, but the PDF/A output intent isn't a CMYK profile DeviceCMYK का उपयोग हुआ है, लेकिन पीडीएफ़/ए आउटपुट इंटेंट CMYK प्रोफ़ाइल नहीं है + DeviceRGB is used, but the PDF/A output intent isn't an RGB profile DeviceRGB का उपयोग हुआ है, लेकिन पीडीएफ़/ए आउटपुट इंटेंट RGB प्रोफ़ाइल नहीं है + Digital Signature डिजिटल हस्ताक्षर + Document properties (⌘D) दस्तावेज़ गुण (⌘D) + Drop PDFs or folders here, or choose them. पीडीएफ़ या फ़ोल्डर यहाँ छोड़ें, या उन्हें चुनें। + Encipher Only केवल एन्सिफ़र + English अंग्रेज़ी + Enter a URL यूआरएल दर्ज करें + Enter a name. नाम दर्ज करें। + Enter a page number पृष्ठ संख्या दर्ज करें + Enter the field names फ़ील्ड के नाम दर्ज करें + Every PDF in the folder फ़ोल्डर की हर पीडीएफ़ + Every PDF in the folder and the folders inside it फ़ोल्डर और उसके भीतर के फ़ोल्डरों की हर पीडीएफ़ + Field "{}" on page {p} has no description (tooltip) पृष्ठ {p} पर फ़ील्ड "{}" का कोई विवरण (टूलटिप) नहीं है + Filename फ़ाइल नाम + Flatten Fill & Sign भरें और हस्ताक्षर करें को समतल करें + Font (unnamed) on page {p} doesn't map its characters to Unicode पृष्ठ {p} पर फ़ॉन्ट (बिना नाम) अपने वर्णों को यूनिकोड से नहीं जोड़ता + Font {} on page {p} doesn't map its characters to Unicode पृष्ठ {p} पर फ़ॉन्ट {} अपने वर्णों को यूनिकोड से नहीं जोड़ता + Form field on page {p} isn't tagged पृष्ठ {p} पर फ़ॉर्म फ़ील्ड टैग नहीं किया गया है + H{n} follows an H{d}; headings should not skip levels H{n}, H{d} के बाद आया है; शीर्षकों में स्तर नहीं छूटने चाहिए + Key Agreement की एग्रीमेंट + Key Encipherment की एन्सिफ़रमेंट + New bookmark (⌘B) नया बुकमार्क (⌘B) + Next (⌘G) अगला (⌘G) + No PDFs found in {folder} {folder} में कोई पीडीएफ़ नहीं मिली + No document language is set दस्तावेज़ की कोई भाषा सेट नहीं है + No page has text: the document appears to be images of pages किसी पृष्ठ में पाठ नहीं है: दस्तावेज़ पृष्ठों की छवियों जैसा लगता है + Non-Repudiation अस्वीकार-निषेध + Only the document's owner can change its security (open it with the permissions password) केवल दस्तावेज़ का स्वामी उसकी सुरक्षा बदल सकता है (उसे अनुमति पासवर्ड से खोलें) + Open a PDF (⌘O) पीडीएफ़ खोलें (⌘O) + Page {p} doesn't tab in structure order पृष्ठ {p} संरचना के क्रम में टैब नहीं होता + Page {p}: {n} untagged content item पृष्ठ {p}: {n} बिना टैग वाला सामग्री आइटम + Page {p}: {n} untagged content items पृष्ठ {p}: {n} बिना टैग वाले सामग्री आइटम + Page {} has additional actions पृष्ठ {} में अतिरिक्त क्रियाएँ हैं + Panel layout could not be restored: {error} पैनल लेआउट पुनर्स्थापित नहीं किया जा सका: {error} + Panel move was not applied: {error} पैनल का स्थानांतरण लागू नहीं हुआ: {error} + PdfCraft can't check this signature yet: {}. PdfCraft अभी इस हस्ताक्षर की जाँच नहीं कर सकता: {}। + Previous (⇧⌘G) पिछला (⇧⌘G) + Print (⌘P) प्रिंट करें (⌘P) + Producer प्रोड्यूसर + Rendering… रेंडर हो रहा है… + Report created रिपोर्ट बन गई + Rev. {rev}: Certified by an unknown signer संशोधन {rev}: अज्ञात हस्ताक्षरकर्ता द्वारा प्रमाणित + Rev. {rev}: Certified by {name} संशोधन {rev}: {name} द्वारा प्रमाणित + Rev. {rev}: Signed by an unknown signer संशोधन {rev}: अज्ञात हस्ताक्षरकर्ता द्वारा हस्ताक्षरित + Rev. {rev}: Signed by {name} संशोधन {rev}: {name} द्वारा हस्ताक्षरित + Rotate view clockwise (⇧⌘+) दृश्य को दक्षिणावर्त घुमाएँ (⇧⌘+) + Rule Name नियम का नाम + Save (M4) सहेजें (M4) + Save as {level} {level} के रूप में सहेजें + Signature is invalid हस्ताक्षर अमान्य है + Signature is valid हस्ताक्षर मान्य है + Signature validity is unknown हस्ताक्षर की वैधता अज्ञात है + Signing time is from the clock on the signer's computer. हस्ताक्षर का समय हस्ताक्षरकर्ता के कंप्यूटर की घड़ी से लिया गया है। + Still rendering — this page is unusually complex… अभी भी रेंडर हो रहा है — यह पृष्ठ असामान्य रूप से जटिल है… + The ECDSA signature is not in canonical DER (trailing bytes, padding or a missing sign byte); it was read anyway. ECDSA हस्ताक्षर कैनोनिकल DER में नहीं है (अतिरिक्त बाइट, पैडिंग या साइन बाइट की कमी); फिर भी इसे पढ़ लिया गया। + The ECDSA signature is the raw r and s values instead of a DER sequence; it was read anyway. ECDSA हस्ताक्षर DER अनुक्रम के बजाय कच्चे r और s मान हैं; फिर भी इसे पढ़ लिया गया। + The RSA signature value does not have the length of the key's modulus (leading zero bytes dropped or added); it was read anyway. RSA हस्ताक्षर मान की लंबाई कुंजी के मॉड्यूलस के बराबर नहीं है (आगे के शून्य बाइट हटे या जुड़े हैं); फिर भी इसे पढ़ लिया गया। + The RSA signature's DigestInfo has no NULL parameter (older signers write it so); it was read anyway. RSA हस्ताक्षर के DigestInfo में NULL पैरामीटर नहीं है (पुराने हस्ताक्षरकर्ता इसे ऐसे ही लिखते हैं); फिर भी इसे पढ़ लिया गया। + The certificate of {} does not allow this many CA certificates below it (path length), so it is not used to vouch for {}. {} का प्रमाणपत्र अपने नीचे इतने सीए प्रमाणपत्रों (पाथ लंबाई) की अनुमति नहीं देता, इसलिए उसका उपयोग {} की पुष्टि के लिए नहीं किया जाता। + The certificate of {} is not a CA certificate that may issue certificates, so it is not used to vouch for {}. {} का प्रमाणपत्र प्रमाणपत्र जारी कर सकने वाला सीए प्रमाणपत्र नहीं है, इसलिए उसका उपयोग {} की पुष्टि के लिए नहीं किया जाता। + The certificate of {} was not valid at the time of signing, so it is not used to vouch for {}. {} का प्रमाणपत्र हस्ताक्षर के समय मान्य नहीं था, इसलिए उसका उपयोग {} की पुष्टि के लिए नहीं किया जाता। + The checker found problems which may prevent the document from being fully accessible. जाँचकर्ता को ऐसी समस्याएँ मिलीं जो दस्तावेज़ को पूरी तरह सुलभ होने से रोक सकती हैं। + The document has been altered or corrupted since the signature was applied. हस्ताक्षर लगाए जाने के बाद दस्तावेज़ में बदलाव हुआ है या वह दूषित हो गया है। + The document has been altered or corrupted since the timestamp was applied. टाइमस्टैम्प लगाए जाने के बाद दस्तावेज़ में बदलाव हुआ है या वह दूषित हो गया है। + The document has been altered since this signature was applied in ways it does not permit ({}). इस हस्ताक्षर के लगाए जाने के बाद दस्तावेज़ में ऐसे बदलाव हुए हैं जिनकी अनुमति नहीं है ({})। + The document has been altered since this timestamp was applied in ways it does not permit ({}). इस टाइमस्टैम्प के लगाए जाने के बाद दस्तावेज़ में ऐसे बदलाव हुए हैं जिनकी अनुमति नहीं है ({})। + The document has been modified since this signature was applied, but the changes are permitted ({}). इस हस्ताक्षर के लगाए जाने के बाद दस्तावेज़ में बदलाव हुए हैं, लेकिन वे अनुमत हैं ({})। + The document has been modified since this timestamp was applied, but the changes are permitted ({}). इस टाइमस्टैम्प के लगाए जाने के बाद दस्तावेज़ में बदलाव हुए हैं, लेकिन वे अनुमत हैं ({})। + The document has no tags (structure tree) दस्तावेज़ में कोई टैग (संरचना वृक्ष) नहीं है + The document has no title दस्तावेज़ का कोई शीर्षक नहीं है + The document isn't marked as tagged (MarkInfo Marked) दस्तावेज़ को टैग किया हुआ चिह्नित नहीं किया गया है (MarkInfo Marked) + The document isn't tagged, so none of its content is दस्तावेज़ टैग नहीं किया गया है, इसलिए उसकी कोई सामग्री भी टैग नहीं है + The document's embedded revocation information shows that the signer's certificate has not been revoked. दस्तावेज़ में एम्बेड की गई निरस्तीकरण जानकारी दिखाती है कि हस्ताक्षरकर्ता का प्रमाणपत्र निरस्त नहीं किया गया है। + The embedded timestamp token is valid and its authority is trusted; trusted time is {}. एम्बेड किया गया टाइमस्टैम्प टोकन मान्य है और उसका प्राधिकारी विश्वसनीय है; विश्वसनीय समय {} है। + The font {} isn't embedded फ़ॉन्ट {} एम्बेड नहीं किया गया है + The metadata doesn't identify the file as {} मेटाडेटा फ़ाइल को {} के रूप में नहीं पहचानता + The password is incorrect. पासवर्ड गलत है। + The password must have at least 6 characters. पासवर्ड में कम से कम 6 वर्ण होने चाहिए। + The passwords do not match. पासवर्ड मेल नहीं खाते। + The security settings don't allow screen readers to read the text सुरक्षा सेटिंग स्क्रीन रीडर को पाठ पढ़ने की अनुमति नहीं देतीं + The signature algorithm and the SignerInfo's digest algorithm name different hashes; the signature was made with the SignerInfo's. हस्ताक्षर एल्गोरिदम और SignerInfo के डाइजेस्ट एल्गोरिदम अलग-अलग हैश बताते हैं; हस्ताक्षर SignerInfo वाले हैश से बनाया गया था। + The signature carries an unverified timestamp ({}): the timestamp authority is not in your list of trusted certificates, so the signing time claimed by the signer is used instead. हस्ताक्षर के साथ एक असत्यापित टाइमस्टैम्प है ({}): टाइमस्टैम्प प्राधिकारी आपकी विश्वसनीय प्रमाणपत्रों की सूची में नहीं है, इसलिए हस्ताक्षरकर्ता द्वारा बताया गया हस्ताक्षर-समय उपयोग किया गया है। + The signature contents are not hexadecimal. हस्ताक्षर की सामग्री हेक्साडेसिमल नहीं है। + The signature could not be checked ({}). हस्ताक्षर की जाँच नहीं की जा सकी ({})। + The signature could not be read ({}). हस्ताक्षर पढ़ा नहीं जा सका ({})। + The signature could not be verified ({}). हस्ताक्षर सत्यापित नहीं किया जा सका ({})। + The signature has no valid byte range. हस्ताक्षर की कोई मान्य बाइट रेंज नहीं है। + The signature includes an embedded timestamp. हस्ताक्षर में एम्बेड किया गया टाइमस्टैम्प शामिल है। + The signature is BER-encoded (indefinite lengths) rather than DER; it was read leniently. हस्ताक्षर DER के बजाय BER-एन्कोडेड (अनिश्चित लंबाई) है; इसे उदारता से पढ़ा गया। + The signature uses the legacy adbe.x509.rsa_sha1 format. हस्ताक्षर पुराने adbe.x509.rsa_sha1 प्रारूप का उपयोग करता है। + The signature value does not match the signer's certificate: the signature is corrupt. हस्ताक्षर मान हस्ताक्षरकर्ता के प्रमाणपत्र से मेल नहीं खाता: हस्ताक्षर दूषित है। + The signature's byte range does not exclude exactly its contents. हस्ताक्षर की बाइट रेंज ठीक उसकी सामग्री को बाहर नहीं रखती। + The signature's byte range does not match the file. हस्ताक्षर की बाइट रेंज फ़ाइल से मेल नहीं खाती। + The signature's timestamp token could not be verified ({}). हस्ताक्षर के टाइमस्टैम्प टोकन को सत्यापित नहीं किया जा सका ({})। + The signature's timestamp token does not cover the signature value. हस्ताक्षर का टाइमस्टैम्प टोकन हस्ताक्षर मान को कवर नहीं करता। + The signed content is a constructed (segmented) OCTET STRING, as BER allows; it was read anyway. हस्ताक्षरित सामग्री एक निर्मित (खंडित) OCTET STRING है, जैसा BER में अनुमत है; फिर भी इसे पढ़ लिया गया। + The signer's certificate does not allow digital signatures (its key usage has neither digital signature nor non-repudiation). हस्ताक्षरकर्ता का प्रमाणपत्र डिजिटल हस्ताक्षर की अनुमति नहीं देता (उसके की-यूसेज में न डिजिटल हस्ताक्षर है, न अस्वीकार-निषेध)। + The signer's certificate has been revoked ({}). हस्ताक्षरकर्ता का प्रमाणपत्र निरस्त कर दिया गया है ({})। + The signer's certificate has critical extensions PdfCraft does not recognize ({}). हस्ताक्षरकर्ता के प्रमाणपत्र में क्रिटिकल एक्सटेंशन हैं जिन्हें PdfCraft नहीं पहचानता ({})। + The signer's certificate is not in the signature. हस्ताक्षरकर्ता का प्रमाणपत्र हस्ताक्षर में मौजूद नहीं है। + The signer's certificate is not issued for signing documents (its extended key usage has no document-signing purpose). हस्ताक्षरकर्ता का प्रमाणपत्र दस्तावेज़ों पर हस्ताक्षर के लिए जारी नहीं किया गया है (उसके एक्सटेंडेड की-यूसेज में दस्तावेज़-हस्ताक्षर का उद्देश्य नहीं है)। + The signer's certificate was not valid at the time of signing. हस्ताक्षरकर्ता का प्रमाणपत्र हस्ताक्षर के समय मान्य नहीं था। + The signer's identity is unknown because it has not been included in your list of trusted certificates and none of its parent certificates are trusted certificates. हस्ताक्षरकर्ता की पहचान अज्ञात है, क्योंकि वह आपकी विश्वसनीय प्रमाणपत्रों की सूची में शामिल नहीं है और उसके कोई भी मूल प्रमाणपत्र विश्वसनीय प्रमाणपत्र नहीं हैं। + The signer's identity is valid. हस्ताक्षरकर्ता की पहचान मान्य है। + The timestamp authority's certificate was not valid at the time of timestamping. टाइमस्टैम्प प्राधिकारी का प्रमाणपत्र टाइमस्टैम्प लगाते समय मान्य नहीं था। + The timestamp contents are not hexadecimal. टाइमस्टैम्प की सामग्री हेक्साडेसिमल नहीं है। + The timestamp has no valid byte range. टाइमस्टैम्प की कोई मान्य बाइट रेंज नहीं है। + The timestamp token could not be read ({}). टाइमस्टैम्प टोकन पढ़ा नहीं जा सका ({})। + The timestamp token is valid and its authority is trusted. टाइमस्टैम्प टोकन मान्य है और उसका प्राधिकारी विश्वसनीय है। + The timestamp token is valid, but the timestamp authority is not in your list of trusted certificates. टाइमस्टैम्प टोकन मान्य है, लेकिन टाइमस्टैम्प प्राधिकारी आपकी विश्वसनीय प्रमाणपत्रों की सूची में नहीं है। + The timestamp's byte range does not exclude exactly its contents. टाइमस्टैम्प की बाइट रेंज ठीक उसकी सामग्री को बाहर नहीं रखती। + The timestamp's byte range does not match the file. टाइमस्टैम्प की बाइट रेंज फ़ाइल से मेल नहीं खाती। + The window shows the file name, not the title (Initial View > Show) विंडो में शीर्षक नहीं, फ़ाइल का नाम दिखता है (प्रारंभिक दृश्य > दिखाएँ) + There is no folder to save the digital ID in. डिजिटल आईडी सहेजने के लिए कोई फ़ोल्डर नहीं है। + This document has not been modified since this signature was applied. इस हस्ताक्षर के लगाए जाने के बाद यह दस्तावेज़ बदला नहीं गया है। + This document has not been modified since this timestamp was applied. इस टाइमस्टैम्प के लगाए जाने के बाद यह दस्तावेज़ बदला नहीं गया है। + This signature uses RIPEMD-160, a legacy 160-bit hash algorithm that is no longer recommended for signatures. It still validates, but it should not be relied on. यह हस्ताक्षर RIPEMD-160 का उपयोग करता है, जो एक पुराना 160-बिट हैश एल्गोरिदम है और हस्ताक्षरों के लिए अब अनुशंसित नहीं है। यह अब भी सत्यापित होता है, पर इस पर भरोसा नहीं करना चाहिए। + This signature uses SHA-1, a weak hash algorithm: collisions in it have been demonstrated. It still validates because many documents signed years ago use it, but it should not be relied on. यह हस्ताक्षर SHA-1 का उपयोग करता है, जो एक कमज़ोर हैश एल्गोरिदम है: इसमें टकराव प्रदर्शित किए जा चुके हैं। यह अब भी सत्यापित होता है, क्योंकि कई वर्षों पहले हस्ताक्षरित दस्तावेज़ इसका उपयोग करते हैं, पर इस पर भरोसा नहीं करना चाहिए। + Unsigned signature field बिना हस्ताक्षर वाला हस्ताक्षर फ़ील्ड + Unsigned signature field: {name} बिना हस्ताक्षर वाला हस्ताक्षर फ़ील्ड: {name} + Zoom in (⌘+) ज़ूम इन (⌘+) + Zoom in / out (also pinch or ⌘-scroll) ज़ूम इन / आउट (पिंच या ⌘-स्क्रॉल से भी) + Zoom out (⌘−) ज़ूम आउट (⌘−) + alternate text hides an annotation inside it वैकल्पिक पाठ के भीतर एक एनोटेशन छिपा है + alternate text on an element with no page content ऐसे तत्व पर वैकल्पिक पाठ जिसमें कोई पृष्ठ सामग्री नहीं है + comments टिप्पणियाँ + document security store दस्तावेज़ सुरक्षा स्टोर + document structure दस्तावेज़ संरचना + form fill फ़ॉर्म भरना + its alternate text is inside another element's and will never be read उसका वैकल्पिक पाठ किसी अन्य तत्व के वैकल्पिक पाठ के भीतर है और कभी पढ़ा नहीं जाएगा + links लिंक + metadata मेटाडेटा + no alternate text कोई वैकल्पिक पाठ नहीं + no header cells (TH) कोई हेडर सेल (TH) नहीं + no summary कोई सारांश नहीं + not in a TR TR में नहीं है + not in a Table, THead, TBody or TFoot Table, THead, TBody या TFoot में नहीं है + not in an L (list) L (सूची) में नहीं है + not in an LI (list item) LI (सूची आइटम) में नहीं है + other changes अन्य बदलाव + page content पृष्ठ सामग्री + page {n} is out of range (1–{count}) पृष्ठ {n} सीमा से बाहर है (1–{count}) + pages added or removed जोड़े या हटाए गए पृष्ठ + rows have between {min} and {max} columns पंक्तियों में {min} से {max} स्तंभ हैं + the first heading is an H{n}; headings should not skip levels पहला शीर्षक H{n} है; शीर्षकों में स्तर नहीं छूटने चाहिए + the signed version could not be read हस्ताक्षरित संस्करण पढ़ा नहीं जा सका + {n} pages and no bookmarks {n} पृष्ठ और कोई बुकमार्क नहीं + {page} is not a page number or label {page} कोई पृष्ठ संख्या या लेबल नहीं है + {ty} element on page {p}: {what} पृष्ठ {p} पर {ty} तत्व: {what} + {ty} element: {what} {ty} तत्व: {what} + {who}, certificate issued by an unknown issuer. {who}, प्रमाणपत्र अज्ञात जारीकर्ता द्वारा जारी किया गया। + {who}, certificate issued by {issuer}. {who}, प्रमाणपत्र {issuer} द्वारा जारी किया गया। + {} annotation on page {p} isn't tagged पृष्ठ {p} पर {} एनोटेशन टैग नहीं किया गया है + {} annotations aren't allowed {} एनोटेशन की अनुमति नहीं है + … and {n} more … और {n} अन्य +@plural Delete {n} field|Delete {n} fields {n} फ़ील्ड हटाएँ +@plural {n} byte|{n} bytes {n} बाइट +@plural {n} image optimized|{n} images optimized {n} छवि अनुकूलित की गई +@plural {n} item discarded|{n} items discarded {n} आइटम छोड़ा गया +@plural {n} pixel|{n} pixels {n} पिक्सेल + Text recognition isn't installed: its models are missing (run `cargo xtask models`, or set PDFCRAFT_MODELS). टेक्स्ट पहचान स्थापित नहीं है: इसके मॉडल गायब हैं (`cargo xtask models` चलाएँ, या PDFCRAFT_MODELS सेट करें)। +calendar weekday Su रवि +calendar weekday Mo सोम +calendar weekday Tu मंगल +calendar weekday We बुध +calendar weekday Th गुरु +calendar weekday Fr शुक्र +calendar weekday Sa शनि +certificate Issued to जिसे जारी किया गया +certificate Issued by जिसने जारी किया +certificate Valid from मान्य होने की शुरुआत +certificate Valid to मान्य होने की समाप्ति +certificate Intended usage अभिप्रेत उपयोग +certificate Version संस्करण +certificate Serial number क्रमांक +certificate Issuer जारीकर्ता +certificate Validity starts वैधता शुरू +certificate Validity ends वैधता समाप्त +certificate Public key सार्वजनिक कुंजी +certificate Basic constraints मूल बाधाएँ +certificate Key usage कुंजी उपयोग +certificate Self-signed स्व-हस्ताक्षरित +certificate SHA-1 digest SHA-1 डाइजेस्ट +certificate SHA-256 digest SHA-256 डाइजेस्ट +@plural {n} file|{n} files {n} फ़ाइल +@plural {n} comment|{n} comments {n} टिप्पणी +@plural {n} result|{n} results {n} परिणाम diff --git a/crates/ui-egui/src/i18n/ko.tsv b/crates/ui-egui/src/i18n/ko.tsv new file mode 100644 index 000000000..4abd655c3 --- /dev/null +++ b/crates/ui-egui/src/i18n/ko.tsv @@ -0,0 +1,2582 @@ +# Korean (ko) interface catalog. Columns, separated by a TAB: +# context English source translation +# Clean-room translation written from the English source's meaning. +# License: MIT OR Apache-2.0. + Menu 메뉴 + File 파일 + Edit 편집 + Pages 페이지 + View 보기 + Help 도움말 + Preferences 환경설정 + Preferences… 환경설정… + Interface language 인터페이스 언어 + Interface size 인터페이스 크기 + Auto ({percent}%) 자동 ({percent}%) + Auto follows the system's text size. Pages always render at the display's full resolution. 자동 모드는 시스템의 텍스트 크기를 따릅니다. 페이지는 항상 디스플레이의 전체 해상도로 렌더링됩니다. + Identity 신원 정보 + Name on new comments 새 주석에 사용할 이름 + Open… 열기… + Open Recent 최근 파일 열기 + Pin folder to Home… 홈에 폴더 고정… + Folders 폴더 + Pin a folder… 폴더 고정… + Pin a folder to Home 홈에 폴더 고정 + Pin a folder to list its newest PDFs here, such as where your scanner or a synced cloud drive saves them. 폴더를 고정하면 해당 폴더의 최신 PDF가 여기에 표시됩니다. 예를 들어 스캐너나 동기화된 클라우드 드라이브가 파일을 저장하는 폴더를 지정할 수 있습니다. + Unpin 고정 해제 + Unpin {folder} {folder} 고정 해제 + Looking for PDFs… PDF 찾는 중… + This folder isn't available right now. It may have moved, or its drive or cloud sync is offline. 현재 이 폴더를 사용할 수 없습니다. 폴더가 이동되었거나 해당 드라이브 또는 클라우드 동기화가 오프라인 상태일 수 있습니다. + No PDFs in this folder yet 이 폴더에는 아직 PDF가 없습니다 + Show less 간략히 보기 + Show {n} more {n}개 더 보기 + The newest {n} of {total} PDFs 전체 {total}개 PDF 중 최신 {n}개 + Pinned folders need the desktop app 고정 폴더 기능에는 데스크톱 앱이 필요합니다 + Choose a folder on this computer to pin 고정할 이 컴퓨터의 폴더를 선택하세요 + {folder} is already pinned to Home {folder}은(는) 이미 홈에 고정되어 있습니다 + You can pin up to {n} folders. Unpin one first. 폴더는 최대 {n}개까지 고정할 수 있습니다. 먼저 하나를 고정 해제하세요. + Pinned {folder} to Home {folder}을(를) 홈에 고정했습니다 + No recent files 최근 파일이 없습니다 + New blank PDF 새 빈 PDF + Create PDF from file… 파일에서 PDF 만들기… + Create PDF from images… 이미지에서 PDF 만들기… + Create PDF from clipboard 클립보드에서 PDF 만들기 + Combine files… 파일 결합… + Save 저장 + Save as… 다른 이름으로 저장… + Close file 파일 닫기 + Close all 모두 닫기 + Revert 되돌리기 + Print… 인쇄… + Document properties… 문서 속성… + Undo 실행 취소 + Redo 다시 실행 + Find… 찾기… + Advanced search… 고급 검색… + Copy pages 페이지 복사 + Cut pages 페이지 잘라내기 + Paste pages 페이지 붙여넣기 + Fit visible 보이는 부분에 맞춤 + Marquee zoom 영역 확대 + Take a snapshot 스냅샷 만들기 + Column select 열 선택 + Full screen mode 전체 화면 모드 + Read mode 읽기 모드 + Switch light / dark theme 밝은 / 어두운 테마 전환 + Comments panel 주석 패널 + Form fields panel 양식 필드 패널 + Clear form 양식 지우기 + Find tools and commands… 도구 및 명령 찾기… + Zoom 확대/축소 + Actual size 실제 크기 + Zoom to page level 페이지 크기에 맞춤 + Fit to width 폭에 맞춤 + Display theme 표시 테마 + Side panels 측면 패널 + Enable Acrobat JavaScript Acrobat JavaScript 사용 + OK 확인 + Join our Discord Discord 참여하기 + Close 닫기 + Next / previous match 다음 / 이전 일치 항목 + Copy selected text 선택한 텍스트 복사 + Double-click 두 번 클릭 + Select a word 단어 선택 + Clear selection / close find 선택 해제 / 찾기 닫기 + Zoom in / out (also pinch or {key}-scroll) 확대 / 축소 (핀치 또는 {key} 키 + 스크롤) + Rotate view 보기 회전 + First / last page 첫 페이지 / 마지막 페이지 + Previous / next page 이전 / 다음 페이지 + Delete selected pages (Organize) 선택한 페이지 삭제 (페이지 정리) + Select all pages (Organize) 모든 페이지 선택 (페이지 정리) + Home 홈 + Open 열기 + Open a PDF ({key}) PDF 열기 ({key}) + Dark gray theme 어두운 회색 테마 + Light theme 밝은 테마 + Appearance mode 모양 모드 + Light 밝게 + Dark 어둡게 + Active 활성 + Dark theme 어두운 테마 + Appearance settings… 모양 설정… + All tools 모든 도구 + Read 읽기 + Convert 변환 + E-Sign 전자 서명 + Print ({key}) 인쇄 ({key}) + Save ({key}) 저장 ({key}) + Document properties ({key}) 문서 속성 ({key}) + Find tools and commands 도구 및 명령 찾기 + Fit to height 높이에 맞춤 + Zoom in 확대 + Zoom out 축소 + Rotate view clockwise 보기 시계 방향으로 회전 + Rotate view counterclockwise 보기 반시계 방향으로 회전 + Page navigation 페이지 탐색 + Previous view 이전 보기 + Next view 다음 보기 + Page display 페이지 표시 + Continuous scrolling 연속 스크롤 + Two-page view 두 페이지 보기 + Single page 단일 페이지 + Show cover page in two-page view 두 페이지 보기에서 표지 표시 + Use system setting 시스템 설정 사용 + Light gray 밝은 회색 + Dark gray 어두운 회색 + Comments 주석 + Bookmarks 책갈피 + Fields 필드 + Layers 레이어 + Attachments 첨부 파일 + Signatures 서명 + Accessibility Checker 접근성 검사기 + Search 검색 + Compare 비교 + Page thumbnails 페이지 축소판 + Form fields 양식 필드 + Zoom out ({key}) 축소 ({key}) + Zoom in ({key}) 확대 ({key}) + Rotate view clockwise ({key}) 보기 시계 방향으로 회전 ({key}) + Toggle fit page / fit width 페이지 맞춤 / 폭 맞춤 전환 + Next page 다음 페이지 + Previous page 이전 페이지 + Current page — type a page number or label (such as iv) and press Enter 현재 페이지 — 페이지 번호나 레이블(예: iv)을 입력한 후 Enter 키를 누르세요 + Welcome to PdfCraft PdfCraft에 오신 것을 환영합니다 + An open-source PDF workbench — local, private, and scriptable. 오픈소스 PDF 워크벤치 — 로컬에서 작동하고, 프라이버시를 지키며, 스크립트를 지원합니다. + Join the ArtCraft community ArtCraft 커뮤니티 참여 + Get help, share feedback and follow development on Discord. Discord에서 도움을 받고, 피드백을 공유하고, 개발 현황을 팔로우하세요. + Recommended tools 추천 도구 + Use now 지금 사용 + Open file 파일 열기 + Recent 최근 항목 + Files you open in PdfCraft appear here. Drop a PDF anywhere to open it. PdfCraft에서 연 파일이 여기에 표시됩니다. PDF를 아무 곳에나 끌어다 놓으면 열립니다. + Privacy 개인정보 보호 + PdfCraft works offline. No telemetry, no account, and no cloud processing unless you add a provider. PdfCraft는 오프라인으로 작동합니다. 직접 공급자를 추가하지 않는 한 텔레메트리, 계정, 클라우드 처리가 없습니다. + Scripts run in a sandbox without file or network access. With JavaScript off, Acrobat's standard format, validate and calculate functions still work. 스크립트는 파일이나 네트워크 접근 없이 샌드박스에서 실행됩니다. JavaScript가 꺼져 있어도 Acrobat의 표준 형식, 유효성 검사 및 계산 함수는 계속 작동합니다. + Back to all tools 모든 도구로 돌아가기 + Close panel 패널 닫기 + View less 간략히 보기 + View more 더 보기 + Available 사용 가능 + Ready 준비됨 + Search tools and commands… 도구 및 명령 검색… + No matching tools 일치하는 도구가 없습니다 + Tool 도구 + Command 명령 + Add a sticky note 스티커 메모 추가 + Add a text box 텍스트 상자 추가 + Highlight text 텍스트 강조 표시 + Underline text 텍스트 밑줄 + Strikethrough text 텍스트 취소선 + Squiggly underline text 텍스트 물결 밑줄 + Draw freehand 자유롭게 그리기 + Draw a line 선 그리기 + Draw an arrow 화살표 그리기 + Draw a rectangle 사각형 그리기 + Draw an oval 타원 그리기 + Draw a polygon 다각형 그리기 + Draw connected lines 연결선 그리기 + Draw a cloud 구름 그리기 + Add a callout 설명선 추가 + Insert text 텍스트 삽입 + Replace text 텍스트 바꾸기 + Attach a file 파일 첨부 + Erase drawings 그림 지우기 + Flatten comments 주석 병합 + Import comments… 주석 가져오기… + Add a stamp 스탬프 추가 + Export all comments to data file… 모든 주석을 데이터 파일로 내보내기… + Hide all comments 모든 주석 숨기기 + Summarize comments 주석 요약 + Import form data… 양식 데이터 가져오기… + Export form data… 양식 데이터 내보내기… + PDF/A… PDF/A… + Action Wizard… 작업 마법사… + Prepare for distribution… 배포 준비… + Optimize scanned documents… 스캔한 문서 최적화… + Compare files… 파일 비교… + Detect form fields 양식 필드 감지 + Merge data files into spreadsheet… 데이터 파일을 스프레드시트로 병합… + Flatten form fields 양식 필드 병합 + Prepare a form 양식 준비 + Tab order: by rows 탭 순서: 행 기준 + Tab order: by columns 탭 순서: 열 기준 + Tab order: by document structure 탭 순서: 문서 구조 기준 + Add text 텍스트 추가 + Edit text & images 텍스트 및 이미지 편집 + Add or edit links 링크 추가 또는 편집 + Create links from URLs URL로 링크 만들기 + Remove all links 모든 링크 제거 + No links to remove 제거할 링크가 없습니다 + Removed 1 link 링크 1개를 제거했습니다 + Removed {n} links 링크 {n}개를 제거했습니다 + Add Bates numbering… Bates 번호 매기기 추가… + Add image… 이미지 추가… + Redact text and images 텍스트 및 이미지 검열 + Redact pages… 페이지 검열… + Find text and redact… 텍스트 찾아 검열… + Redaction properties… 검열 속성… + Apply redactions… 검열 적용… + Clear redaction marks 검열 표시 지우기 + Remove hidden information… 숨겨진 정보 제거… + Sanitize document… 문서 정리… + Field properties… 필드 속성… + Add a text field 텍스트 필드 추가 + Add a checkbox 확인란 추가 + Add a radio button 라디오 단추 추가 + Add a drop-down list 드롭다운 목록 추가 + Add a list box 목록 상자 추가 + Add a button 단추 추가 + Add an image field 이미지 필드 추가 + Add a date field 날짜 필드 추가 + Add a digital signature field 디지털 서명 필드 추가 + Digitally sign 디지털 서명 + Certify (visible signature) 인증 (보이는 서명) + Certify (invisible signature) 인증 (보이지 않는 서명) + Validate all signatures 모든 서명 유효성 검사 + Signatures panel 서명 패널 + Fill & Sign: add text 채우기 및 서명: 텍스트 추가 + Fill & Sign: checkmark 채우기 및 서명: 확인 표시 + Fill & Sign: cross 채우기 및 서명: X 표시 + Fill & Sign: dot 채우기 및 서명: 점 + Fill & Sign: line 채우기 및 서명: 선 + Fill & Sign: date 채우기 및 서명: 날짜 + Fill & Sign: sign 채우기 및 서명: 서명 + Fill & Sign: initials 채우기 및 서명: 이니셜 + Export to image… 이미지로 내보내기… + Reduce file size… 파일 크기 줄이기… + Optimize PDF… PDF 최적화… + Export to text… 텍스트로 내보내기… + Export to Word… Word로 내보내기… + Export to PowerPoint… PowerPoint로 내보내기… + Export to HTML… HTML로 내보내기… + Export to RTF… RTF로 내보내기… + JavaScript console… JavaScript 콘솔… + Document JavaScripts… 문서 JavaScript… + Recognize text… 텍스트 인식… + Recognize text in multiple files… 여러 파일에서 텍스트 인식… + Check for accessibility… 접근성 검사… + Open accessibility report 접근성 보고서 열기 + Change reading options… 읽기 옵션 변경… + Add alternate text… 대체 텍스트 추가… + Export all images… 모든 이미지 내보내기… + Add header & footer… 머리글 및 바닥글 추가… + Update header & footer… 머리글 및 바닥글 업데이트… + Remove header & footer 머리글 및 바닥글 제거 + Add watermark… 워터마크 추가… + Update watermark… 워터마크 업데이트… + Remove watermark 워터마크 제거 + Add background… 배경 추가… + Update background… 배경 업데이트… + Remove background 배경 제거 + Protect using password… 암호로 보호… + Remove security 보안 제거 + Security properties… 보안 속성… + Organize pages 페이지 정리 + New bookmark 새 책갈피 + New bookmarks from structure 구조로 새 책갈피 만들기 + Rotate pages clockwise 페이지 시계 방향으로 회전 + Rotate pages counterclockwise 페이지 반시계 방향으로 회전 + Delete pages 페이지 삭제 + Insert blank page 빈 페이지 삽입 + Rotate pages… 페이지 회전… + Duplicate pages 페이지 복제 + Crop pages 페이지 자르기 + Set page boxes… 페이지 상자 설정… + Insert pages from file… 파일에서 페이지 삽입… + Replace pages… 페이지 바꾸기… + Extract pages… 페이지 추출… + Split document… 문서 분할… + Number pages… 페이지 번호 매기기… + Keyboard shortcuts 키보드 단축키 + Join the ArtCraft Discord ArtCraft Discord 참여하기 + PdfCraft web page PdfCraft 웹 페이지 + PdfCraft on GitHub GitHub의 PdfCraft + ArtCraft website ArtCraft 웹사이트 + Check for updates… 업데이트 확인… + About PdfCraft PdfCraft 정보 + Export a PDF PDF 내보내기 + Export to 내보내기 형식 + Microsoft Word (.docx) Microsoft Word (.docx) + Spreadsheet (.xlsx) 스프레드시트 (.xlsx) + Presentation (.pptx) 프레젠테이션 (.pptx) + Image (PNG) 이미지 (PNG) + Export all images 모든 이미지 내보내기 + HTML web page HTML 웹 페이지 + Rich Text Format (.rtf) 서식 있는 텍스트 (.rtf) + Text (plain) 일반 텍스트 + PostScript / EPS PostScript / EPS + Fill & Sign 채우기 및 서명 + Fill 채우기 + Checkmark 확인 표시 + Cross X 표시 + Dot 점 + Line 선 + Date 날짜 + Signature 서명 + Initials 이니셜 + Edit a PDF PDF 편집 + Modify page 페이지 수정 + Rotate pages 페이지 회전 + Insert pages 페이지 삽입 + Extract pages 페이지 추출 + Add content 콘텐츠 추가 + Text 텍스트 + Image 이미지 + Header and footer 머리글 및 바닥글 + Watermark 워터마크 + Link 링크 + Bates numbering Bates 번호 매기기 + Background 배경 + Attach file 파일 첨부 + Create a PDF PDF 만들기 + Create from 다음에서 만들기 + Single file 단일 파일 + Multiple files 여러 파일 + Separate PDFs 개별 PDF + Images 이미지 + Clipboard 클립보드 + Blank page 빈 페이지 + Combine files 파일 결합 + Combine 결합 + Add files to combine 결합할 파일 추가 + Page options 페이지 옵션 + Page grid 페이지 그리드 + Rotate 회전 + Delete 삭제 + Extract 추출 + Insert 삽입 + Replace 바꾸기 + Split 분할 + More 더 보기 + Set page boxes 페이지 상자 설정 + Page labels 페이지 레이블 + Page transitions 페이지 전환 + Add comments 주석 추가 + Markup 마크업 + Sticky note 스티커 메모 + Underline 밑줄 + Strikethrough 취소선 + Squiggly underline 물결 밑줄 + Text box 텍스트 상자 + Drawing 그리기 + Rectangle 사각형 + Oval 타원 + Arrow 화살표 + Cloud 구름 + Stamp 스탬프 + Review 검토 + Comment list 주석 목록 + Scan & OCR 스캔 및 OCR + Recognize text 텍스트 인식 + In this file 이 파일에서 + In multiple files 여러 파일에서 + Enhance scanned file 스캔한 파일 개선 + Correct recognized text 인식된 텍스트 수정 + Protect a PDF PDF 보호 + Protect 보호 + Protect with password 암호로 보호 + Remove hidden information 숨겨진 정보 제거 + Advanced options 고급 옵션 + Encrypt with certificate 인증서로 암호화 + Security properties 보안 속성 + Redact a PDF PDF 검열 + Redact 검열 + Redact pages 페이지 검열 + Find text and redact 텍스트 찾아 검열 + Set properties 속성 설정 + Sanitize document 문서 정리 + Compress a PDF PDF 압축 + Optimize 최적화 + Reduce file size 파일 크기 줄이기 + Advanced optimization 고급 최적화 + Audit space usage 공간 사용량 감사 + Field list 필드 목록 + Field properties 필드 속성 + Tab order by rows 행 기준 탭 순서 + Tab order by columns 열 기준 탭 순서 + Import data 데이터 가져오기 + Export data 데이터 내보내기 + Add form components 양식 구성 요소 추가 + Text field 텍스트 필드 + Checkbox 확인란 + Radio button 라디오 단추 + Drop-down list 드롭다운 목록 + List box 목록 상자 + Button 단추 + Image field 이미지 필드 + Date field 날짜 필드 + Digital signature 디지털 서명 + Stamps 스탬프 + Stamp palette 스탬프 팔레트 + Use a certificate 인증서 사용 + Certificates 인증서 + Timestamp 타임스탬프 + Use print production 인쇄 제작 사용 + Print production 인쇄 제작 + Output preview 출력 미리 보기 + Preflight 프리플라이트 + Convert colors 색상 변환 + Add printer marks 프린터 표시 추가 + Fix hairlines 헤어라인 수정 + Measure objects 개체 측정 + Measure 측정 + Measuring tool 측정 도구 + Geospatial location 지리 공간 위치 + Compare files 파일 비교 + Select files to compare 비교할 파일 선택 + Use guided actions 단계별 작업 사용 + Actions list 작업 목록 + Action Wizard 작업 마법사 + Make accessible 접근성 확보 + Prepare for distribution 배포 준비 + Optimize scanned documents 스캔한 문서 최적화 + Archive documents 문서 보관 + Prepare for accessibility 접근성 준비 + Accessibility 접근성 + Automatically tag PDF PDF에 자동 태그 지정 + Change reading options 읽기 옵션 변경 + Check for accessibility 접근성 검사 + Add alternate text 대체 텍스트 추가 + Fix reading order 읽기 순서 수정 + Apply PDF standards PDF 표준 적용 + Standards 표준 + Save as PDF/A PDF/A로 저장 + Save as PDF/X PDF/X로 저장 + Save as PDF/UA PDF/UA로 저장 + Add search index 검색 색인 추가 + Index 색인 + Manage embedded index 포함된 색인 관리 + Use JavaScript JavaScript 사용 + JavaScript JavaScript + Console 콘솔 + Document JavaScripts 문서 JavaScript + Document actions 문서 작업 + AI assistant AI 어시스턴트 + Bring your own model (off by default) 자체 모델 사용(기본적으로 꺼져 있음) + Summarize 요약 + Ask about this document 이 문서에 대해 질문 + Translate 번역 + pages 페이지 + Planned 예정됨 + Planned for milestone 마일스톤에 예정됨 + open to see what it will include 열어서 포함될 내용을 확인하세요 + Optional: needs an AI provider you configure 선택 사항: 사용자가 구성한 AI 공급자가 필요합니다 + Coming in milestone 마일스톤에서 제공 예정 + Items marked Ready work today. “준비됨”으로 표시된 항목은 오늘 바로 사용할 수 있습니다. + Preview 미리 보기 + Edit fields 필드 편집 + Try the form as people filling it in will see it 양식을 작성하는 사용자에게 보이는 그대로 양식을 사용해 보세요 + Redact all 모두 검열 + Clear all 모두 지우기 + Rotate page 페이지 회전 + Delete page 페이지 삭제 + Move page 페이지 이동 + Move pages 페이지 이동 + Duplicate page 페이지 복제 + Replace page 페이지 바꾸기 + Replace pages 페이지 바꾸기 + Crop page 페이지 자르기 + Cancel 취소 + Don't save 저장 안 함 + Apply 적용 + Run 실행 + Clear 지우기 + Sanitize 정리 + Mark all 모두 표시 + Save changes to “{name}” before closing? 닫기 전에 “{name}”의 변경 사항을 저장하시겠습니까? + Your changes will be lost if you don't save them. 저장하지 않으면 변경 사항이 손실됩니다. + Password required 암호 필요 + “{name}” is protected. Enter a password to open it. “{name}”은(는) 보호되어 있습니다. 열려면 암호를 입력하세요. + Password 암호 + Incorrect password. Try again. 암호가 올바르지 않습니다. 다시 시도하세요. + Recognize Text 텍스트 인식 + Password protection will be applied when you save 저장할 때 암호 보호가 적용됩니다 + Saved the print-ready PDF to {path} 인쇄 준비가 완료된 PDF를 {path}에 저장했습니다 + Could not save: {e} 저장할 수 없습니다: {e} + Earlier in tab order 탭 순서에서 이전 + Later in tab order 탭 순서에서 다음 + From: 시작: + To: 종료: + High Resolution 고해상도 + Print 인쇄 + Verify to see what the document needs. 검증을 실행하면 문서에 필요한 사항을 확인할 수 있습니다. + Set Page Boxes 페이지 상자 설정 + Signature panel 서명 패널 + {month} {day}, {y} {y}년 {month} {day}일 + The document's security settings don't allow filling in form fields 문서의 보안 설정에서는 양식 필드 채우기를 허용하지 않습니다 + {name} is read-only {name}은(는) 읽기 전용입니다 + {name} has no action {name}에는 작업이 없습니다 + Previous month 이전 달 + Next month 다음 달 + January 1월 + February 2월 + March 3월 + April 4월 + May 5월 + June 6월 + July 7월 + August 8월 + September 9월 + October 10월 + November 11월 + December 12월 + Done 완료 + This certificate is in your list of trusted certificates. 이 인증서는 신뢰할 수 있는 인증서 목록에 있습니다. + This certificate is trusted through a certificate above it in the chain. 이 인증서는 체인의 상위 인증서를 통해 신뢰됩니다. + This certificate is not trusted. Signatures made with it show an unknown identity. 이 인증서는 신뢰되지 않습니다. 이 인증서로 만든 서명은 알 수 없는 신원으로 표시됩니다. + Add to Trusted Certificates 신뢰할 수 있는 인증서에 추가 + Export… 내보내기… + PDF Optimizer PDF Optimizer + Discard Objects 개체 삭제 + Discard User Data 사용자 데이터 삭제 + Clean Up 정리 + Color Images 컬러 이미지 + Grayscale Images 회색조 이미지 + Bicubic downsampling to 다음 값으로 바이큐빅 다운샘플링 + for images above 다음 값을 초과하는 이미지에 적용 + Compression 압축 + ZIP ZIP + Retain existing 기존 유지 + Minimum 최소 + Low 낮음 + High 높음 + Maximum 최대 + Each image is measured where pages draw it; an image is replaced only if the result is smaller. 각 이미지는 페이지에 실제로 그려지는 크기를 기준으로 측정되며, 결과가 더 작을 때만 이미지가 교체됩니다. + Discard all links, actions and JavaScript 모든 링크, 작업 및 JavaScript 삭제 + Discard alternate images 대체 이미지 삭제 + Discard embedded page thumbnails 포함된 페이지 축소판 삭제 + Discard document tags 문서 태그 삭제 + Discard embedded print settings 포함된 인쇄 설정 삭제 + Discard bookmarks 책갈피 삭제 + Discard hidden layer content 숨겨진 레이어 콘텐츠 삭제 + Discard all comments, forms and multimedia 모든 주석, 양식 및 멀티미디어 삭제 + Discard document information and metadata 문서 정보 및 메타데이터 삭제 + Discard all object data (file attachments) 모든 개체 데이터(파일 첨부) 삭제 + Discard private data of other applications 다른 응용 프로그램의 개인 데이터 삭제 + Discard hidden text 숨겨진 텍스트 삭제 + Use Flate to encode streams that are not encoded 인코딩되지 않은 스트림을 Flate로 인코딩 + Remove invalid links and bookmarks 잘못된 링크 및 책갈피 제거 + Remove unreferenced named destinations 참조되지 않은 이름이 지정된 대상 제거 + Compress document structure (object streams) 문서 구조 압축(개체 스트림) + Remove unused objects and merge identical ones 사용하지 않는 개체 제거 및 동일한 개체 병합 + Audit space usage… 공간 사용량 감사… + Space Audit 공간 감사 + Bytes 바이트 + Content Streams 콘텐츠 스트림 + X Object Forms XObject 양식 + Structure Info 구조 정보 + Thumbnails 축소판 + Named Destinations 이름이 지정된 대상 + Color Spaces 색상 공간 + Shadings 음영 + Patterns (graphics objects) 패턴(그래픽 개체) + Extended Graphics States 확장 그래픽 상태 + Embedded Files 포함된 파일 + Document Overhead 문서 오버헤드 + Total 합계 + Text Field Properties 텍스트 필드 속성 + Check Box Properties 확인란 속성 + Radio Button Properties 라디오 단추 속성 + Dropdown Properties 드롭다운 속성 + List Box Properties 목록 상자 속성 + Button Properties 단추 속성 + Digital Signature Properties 디지털 서명 속성 + Position 위치 + Options 옵션 + Validate 유효성 검사 + Calculate 계산 + Actions 동작 + This field is locked. Unlock it to change its properties. 이 필드는 잠겨 있습니다. 속성을 변경하려면 잠금을 해제하세요. + Tooltip: 도구 설명: + Common Properties 일반 속성 + Read Only 읽기 전용 + Required 필수 + Font Size: 글꼴 크기: + Auto 자동 + Text Color: 텍스트 색: + Borders and Colors 테두리 및 색상 + Border Color: 테두리 색: + Fill Color: 채우기 색: + No color 색 없음 + Beveled 베벨 + Left: 왼쪽: + Bottom: 아래: + Width: 너비: + Height: 높이: + Points from the page's bottom-left corner. 페이지 왼쪽 아래 모서리를 기준으로 한 포인트 단위 위치입니다. + Alignment: 정렬: + Default Value: 기본값: + Multi-line 여러 줄 + Scroll long text 긴 텍스트 스크롤 + Allow Rich Text Formatting 리치 텍스트 서식 허용 + Limit of 최대 + characters 자 + Field is used for file selection 파일 선택에 사용되는 필드 + Check spelling 맞춤법 검사 + Comb of 균등 배치 + Export Value: {on} 내보내기 값: {on} + Check box is checked by default 확인란이 기본으로 선택됨 + Button is checked by default 단추가 기본으로 선택됨 + Buttons with the same name and value are selected in unison 이름과 값이 같은 단추는 함께 선택됩니다 + Item: 항목: + Item List 항목 목록 + Up 위로 + Delete {o} {o} 삭제 + Add the choices people pick from. 사용자가 선택할 선택지를 추가합니다. + Default: 기본: + (none) (없음) + Sort items 항목 정렬 + Allow user to enter custom text 사용자 지정 텍스트 입력 허용 + Multiple selection 여러 항목 선택 + Commit selected value immediately 선택한 값을 즉시 적용 + Number 숫자 + Percentage 백분율 + Time 시간 + Special 특수 + Select format category: 형식 카테고리 선택: + The value is shown as typed. 값은 입력한 대로 표시됩니다. + Decimal places: 소수 자릿수: + Separator style: 구분 기호 스타일: + Currency symbol: 통화 기호: + Before the number 숫자 앞 + Negative number style: 음수 스타일: + Format: 형식: + Custom: 사용자 지정: + Zip Code 우편번호 + Zip Code + 4 우편번호 + 4 + Phone Number 전화번호 + Social Security Number 사회 보장 번호 + Arbitrary Mask 임의 마스크 + Mask: 마스크: + 9 digit, A letter, O letter or digit, X any character 9 숫자, A 문자, O 문자 또는 숫자, X 모든 문자 + Example: {sample} 예: {sample} + Field value is not validated 필드 값이 검증되지 않습니다 + Field value is in range: 필드 값이 다음 범위 안에 있습니다: + Add an Action 동작 추가 + Select Trigger: 트리거 선택: + Mouse Up 마우스 놓기 + Mouse Down 마우스 누르기 + Mouse Enter 마우스 진입 + Mouse Exit 마우스 이탈 + On Focus 포커스 시 + On Blur 포커스 해제 시 + Select Action: 동작 선택: + Open a web link 웹 링크 열기 + Reset a form 양식 재설정 + Execute a menu item 메뉴 항목 실행 + Show a field 필드 표시 + Hide a field 필드 숨기기 + Submit a form 양식 제출 + Fields to reset (comma-separated; empty: all) 재설정할 필드(쉼표로 구분, 비워 두면 모두) + Print, NextPage, PrevPage, FirstPage or LastPage Print, NextPage, PrevPage, FirstPage 또는 LastPage + Field names (comma-separated) 필드 이름(쉼표로 구분) + URL to submit to 제출할 URL + Script: 스크립트: + Value: 값: + No actions 동작 없음 + Value is not calculated 값이 계산되지 않습니다 + Value is the 값은 다음 필드의 + sum (+) 합계(+) + product (x) 곱(x) + average 평균 + minimum 최솟값 + maximum 최댓값 + of the following fields: 입니다: + Simplified field notation: 단순화된 필드 표기법: + Field names with + - * / and parentheses; put \\ before spaces in names. + - * / 및 괄호를 쓸 수 있는 필드 이름입니다. 이름 안의 공백 앞에는 \\를 넣으세요. + Finding document fonts… 문서 글꼴을 찾는 중… + Installed fonts… 설치된 글꼴… + Keep source fonts 원본 글꼴 유지 + Load font… 글꼴 로드… + No openly licensed document fonts found. Load a font file. 오픈 라이선스 문서 글꼴을 찾지 못했습니다. 글꼴 파일을 로드하세요. + Format text 텍스트 서식 + Bold 굵게 + Italic 기울임꼴 + Align left 왼쪽 정렬 + Centre 가운데 정렬 + Align right 오른쪽 정렬 + Justify 양쪽 정렬 + Thai and Arabic use regular fallback fonts when available. 태국어와 아랍어는 가능한 경우 일반 굵기 폴백 글꼴을 사용합니다. + Edit image 이미지 편집 + Rotate counterclockwise 반시계 방향으로 회전 + Rotate clockwise 시계 방향으로 회전 + Flip horizontal 수평 뒤집기 + Flip vertical 수직 뒤집기 + Replace image 이미지 교체 + Crop (% trimmed from each side) 자르기(각 면을 잘라낼 %) + Click on the page to add text; each click starts a new box, and ✓ finishes. Drag items to move them, drag a corner to resize, double-click text to edit it. 페이지를 클릭해 텍스트를 추가합니다. 클릭할 때마다 새 상자가 시작되며 ✓로 마칩니다. 항목을 끌어 이동하고, 모서리를 끌어 크기를 조정하고, 텍스트를 두 번 클릭해 편집합니다. + Choose an image 이미지 선택 + Export to Image 이미지로 내보내기 + Export to Text 텍스트로 내보내기 + Export All Images 모든 이미지 내보내기 + Resolution 해상도 + Format 형식 + Quality 품질 + One {f} file per page, named after the document. 페이지당 하나의 {f} 파일이 문서 이름으로 저장됩니다. + Exclude images smaller than 다음보다 작은 이미지 제외 + No limit 제한 없음 + Each image once, named after the document and page. JPEG images are saved unchanged; others as PNG. 각 이미지를 한 번씩 문서 이름과 페이지 번호로 저장합니다. JPEG 이미지는 변경 없이 저장되며 나머지는 PNG로 저장됩니다. + Plain text in reading order; pages are separated by form feeds. 읽기 순서대로 된 일반 텍스트이며 페이지는 폼 피드 문자로 구분됩니다. + Create {what} {what} 만들기 + initials 이니셜 + signature 서명 + Create Custom Stamp 사용자 지정 스탬프 만들기 + From {file} {file}에서 + Category: 범주: + e.g. My stamps 예: 내 스탬프 + Name: 이름: + Custom 사용자 지정 + Delete stamp 스탬프 삭제 + Create custom stamp… 사용자 지정 스탬프 만들기… + From a PDF page or an image PDF 페이지 또는 이미지에서 + Line spacing 줄 간격 + Character spacing 글자 간격 + Horizontal scale 가로 배율 + Rotate Clockwise 시계 방향으로 회전 + Rotate Counterclockwise 반시계 방향으로 회전 + Flip Horizontal 수평 뒤집기 + Flip Vertical 수직 뒤집기 + Replace Image… 이미지 교체… + Save Image As… 다른 이름으로 이미지 저장… + Copy Image 이미지 복사 + The image has been copied ({w} × {h} pixels) 이미지가 복사되었습니다({w} × {h} 픽셀) + Couldn't copy the image: {e} 이미지를 복사할 수 없습니다: {e} + Copy Image in Original Format 원본 형식으로 이미지 복사 + The image has been copied as a {ext} file 이미지가 {ext} 파일로 복사되었습니다 + The page has changed; select the image again 페이지가 변경되었으므로 이미지를 다시 선택하세요 + Check for updates 업데이트 확인 + No check has run yet. 아직 확인이 실행되지 않았습니다. + Checking for a newer version… 새 버전이 있는지 확인하는 중… + PdfCraft {v} is available. PdfCraft {v}을(를) 사용할 수 있습니다. + You have version {c}. Download the new version from its release page. 현재 버전은 {c}입니다. 릴리스 페이지에서 새 버전을 다운로드하세요. + PdfCraft {c} is up to date. PdfCraft {c}은(는) 최신 버전입니다. + Couldn't check for updates: {e} 업데이트를 확인할 수 없습니다: {e} + You have version {c}. All releases are listed at {page}. 현재 버전은 {c}입니다. 모든 릴리스는 {page}에 표시됩니다. + Asks GitHub for the latest release. Nothing is downloaded or installed automatically. GitHub에 최신 릴리스를 요청합니다. 어떤 것도 자동으로 다운로드하거나 설치하지 않습니다. + Download 다운로드 + Later 나중에 + none 없음 + Declared conformance: {shown} 선언된 적합성: {shown} + Output intent: {list} 출력 인텐트: {list} + Conformance level: 적합성 수준: + No problems found: the document conforms to {level}. 발견된 문제가 없습니다. 문서가 {level}을(를) 준수합니다. + (page {p}) (페이지 {p}) + · not fixable here · 여기서는 수정할 수 없음 + Verify 확인 + Box 박스 + Units 단위 + Set to zero 0으로 설정 + Current page ({n}) 현재 페이지({n}) + Subset 하위 집합 + Update 업데이트 + Add 추가 + {verb} Header and Footer {verb}: 머리글 및 바닥글 + {verb} Watermark {verb}: 워터마크 + {verb} Background {verb}: 배경 + Margins (in) 여백(인치) + Left Header Text 왼쪽 머리글 텍스트 + Center Header Text 가운데 머리글 텍스트 + Right Header Text 오른쪽 머리글 텍스트 + Left Footer Text 왼쪽 바닥글 텍스트 + Center Footer Text 가운데 바닥글 텍스트 + Right Footer Text 오른쪽 바닥글 텍스트 + Insert Page Number 페이지 번호 삽입 + Insert Date 날짜 삽입 + Start page number 시작 페이지 번호 + Source 소스 + Fit to page 페이지에 맞춤 + Rotation 회전 + Appear behind page 페이지 뒤에 표시 + Appear on top of page 페이지 위에 표시 + Offset from centre 중앙 기준 오프셋 + From colour 색상 사용 + Page Range Options 페이지 범위 옵션 + Preview: page {p} of {n} 미리 보기: {n} 페이지 중 {p} 페이지 + Applies to 1 page 1개 페이지에 적용됩니다 + Applies to {n} pages {n}개 페이지에 적용됩니다 + Replaces the existing one on those pages. 해당 페이지의 기존 항목을 대체합니다. + PDF or image PDF 또는 이미지 + No file chosen 선택한 파일 없음 + Page number 페이지 번호 + Scale relative to target page 대상 페이지 기준 배율 + Link Properties 링크 속성 + Create Link 링크 만들기 + Link Appearance 링크 모양 + Link Type: 링크 유형: + Visible Rectangle 보이는 사각형 + Invisible Rectangle 보이지 않는 사각형 + Highlight Style: 강조 스타일: + Invert 반전 + Outline 윤곽선 + Inset 인세트 + Line Thickness: 선 굵기: + Thin 얇게 + Thick 굵게 + Line Style: 선 스타일: + Solid 실선 + Dashed 파선 + Color: 색상: + Link Action 링크 동작 + Open a web page 웹 페이지 열기 + Go to a page view 페이지 보기로 이동 + Type the web address. 웹 주소를 입력하세요. + This document has no signatures. 이 문서에는 서명이 없습니다. + The Keychain's digital IDs couldn't be listed: {e} 키체인의 디지털 ID를 나열할 수 없습니다: {e} + Signed and saved to {path} 서명되어 {path}에 저장되었습니다 + Couldn't open revision {n}: {e} 수정 버전 {n}을(를) 열 수 없습니다: {e} + Couldn't open the signed version: {e} 서명된 버전을 열 수 없습니다: {e} + Sign with a Digital ID 디지털 ID로 서명 + Choose the digital ID that you want to use for signing: 서명에 사용할 디지털 ID를 선택하세요: + Keychain · 키체인 · + Windows store · Windows 스토어 · + Issued by: 발급자: + , Expires: , 만료일: + No digital IDs yet. 아직 디지털 ID가 없습니다. + Configure New Digital ID 새 디지털 ID 구성 + Continue 계속 + Configure a Digital ID for Signing 서명용 디지털 ID 구성 + Use a Digital ID from a file 파일의 디지털 ID 사용 + Create a new Digital ID (self-signed, saved to a password-protected file) 새 디지털 ID 만들기(자체 서명, 암호로 보호되는 파일에 저장) + Name 이름 + Organizational Unit 조직 단위 + Organization Name 조직 이름 + Email Address 이메일 주소 + Country/Region 국가/지역 + Key Algorithm 키 알고리즘 + Confirm Password 암호 확인 + Valid for 5 years, for digital signatures. Self-signed IDs are usually not trusted by others. 디지털 서명용으로 5년간 유효합니다. 자체 서명 ID는 일반적으로 다른 사람이 신뢰하지 않습니다. + File (.p12, .pfx) 파일(.p12, .pfx) + Digital ID 디지털 ID + Browse… 찾아보기… + {verb} as "{name}" "{name}"(으)로 {verb} + Certify 인증 + The signature will be invisible. 서명이 보이지 않게 됩니다. + The existing action will be preserved. 기존 동작은 유지됩니다. + Distinguished name 고유 이름 + Labels 레이블 + Graphic 그래픽 + Signer's name 서명자 이름 + Fill & Sign signature 채우기 및 서명 서명 + Choose image… 이미지 선택… + Permitted actions after certifying 인증 후 허용되는 동작 + No changes allowed 변경 허용 안 함 + Annotations, form fill-in, and digital signatures 주석, 양식 채우기 및 디지털 서명 + Form fill-in and digital signatures 양식 채우기 및 디지털 서명 + The key is in the macOS Keychain, which may ask to allow PdfCraft to use it. 키가 macOS 키체인에 있으며, 이 키를 PdfCraft에서 사용할 수 있도록 허용할지 묻는 메시지가 표시될 수 있습니다. + The key is in the Windows certificate store, which may ask to allow PdfCraft to use it. 키가 Windows 인증서 저장소에 있으며, 이 키를 PdfCraft에서 사용할 수 있도록 허용할지 묻는 메시지가 표시될 수 있습니다. + Digital ID password 디지털 ID 암호 + Back 뒤로 + Validate all 모두 검증 + Sign this field… 이 필드 서명… + Signature is valid: 서명이 유효합니다: + Signature validity is UNKNOWN: 서명 유효성을 알 수 없습니다: + Signature is INVALID: 서명이 유효하지 않습니다: + Signature Details 서명 세부 정보 + Reason 이유 + Signing time 서명 시간 + Algorithm 알고리즘 + Signer 서명자 + Issued by 발급자 + Valid 유효 + Field 필드 + Field: {field} on page {p} 필드: {p} 페이지의 {field} + Add to trusted certificates 신뢰할 수 있는 인증서에 추가 + View signed version 서명된 버전 보기 + Show certificate… 인증서 표시… + Export certificate… 인증서 내보내기… + Certificate Viewer 인증서 뷰어 + This dialog shows the details of a certificate and its chain. 이 대화 상자는 인증서와 인증서 체인의 세부 정보를 표시합니다. + Trust 신뢰 + Issued to 발급 대상 + Valid from 유효 시작일 + Valid to 유효 종료일 + Intended usage 용도 + Any 모두 + Version 버전 + Serial number 일련 번호 + Issuer 발급자 + Validity starts 유효 기간 시작 + Validity ends 유효 기간 종료 + Public key 공개 키 + Key usage 키 용도 + Not present 없음 + Self-signed 자체 서명됨 + Edit Action 동작 편집 + New Action 새 동작 + Action name: 동작 이름: + Description: 설명: + Steps 단계 + Add the steps this action runs, in order. 이 동작이 실행할 단계를 순서대로 추가하세요. + Add Step 단계 추가 + An action with this name already exists. 같은 이름의 동작이 이미 있습니다. + New Action… 새 동작… + Edit… 편집… + Add watermark 워터마크 추가 + Add header 머리글 추가 + Add footer 바닥글 추가 + Set document title 문서 제목 설정 + Run a JavaScript JavaScript 실행 + Prepare for Distribution 배포 준비 + Remove hidden information and flatten comments and form fields, so recipients see only the pages. 숨겨진 정보를 제거하고 주석과 양식 필드를 병합하여 받는 사람이 페이지만 보도록 합니다. + Optimize Scanned Documents 스캔한 문서 최적화 + Make scans searchable, then make them smaller. 스캔본을 검색 가능하게 만든 다음 크기를 줄입니다. + Add Page Numbers 페이지 번호 추가 + Number every page in the footer. 모든 페이지의 바닥글에 번호를 추가합니다. + Mark as Confidential 기밀로 표시 + A diagonal CONFIDENTIAL watermark on every page. 모든 페이지에 대각선 CONFIDENTIAL 워터마크를 추가합니다. + Sanitize Documents 문서 정리 + Remove hidden information, metadata, scripts and embedded content, and rewrite the files. 숨겨진 정보, 메타데이터, 스크립트, 포함된 콘텐츠를 제거하고 파일을 다시 씁니다. + Type text 텍스트 입력 + Text to insert 삽입할 텍스트 + Replacement text 교체할 텍스트 + Edit text… 텍스트 편집… + Add a sticky note here 여기에 스티키 노트 추가 + {kind} Properties {kind} 속성 + Appearance 모양 + General 일반 + Review History 검토 기록 + This comment's appearance can't be changed yet. 이 주석의 모양은 아직 변경할 수 없습니다. + Icon 아이콘 + Thickness 두께 + Modified 수정됨 + No status has been set. 상태가 설정되지 않았습니다. + Compare Files 파일 비교 + Old file: 이전 파일: + Open the older version first 먼저 이전 버전을 여세요 + New file: 새 파일: + Text is compared word by word; the differences are shown on the new file. 텍스트는 단어 단위로 비교되며 차이점은 새 파일에 표시됩니다. + Compare this file with an older version: Compare files… in All tools. 이 파일을 이전 버전과 비교하려면 모든 도구에서 파일 비교…를 사용하세요. + No differences in the text. 텍스트에 차이점이 없습니다. + {n} {kind} {n} {kind} + Inserted 삽입됨 + Deleted 삭제됨 + Replaced 대체됨 + Visual 시각적 + Mark as comments 주석으로 표시 + Report… 보고서… + {kind} · page {p} {kind} · {p} 페이지 + Set Alternate Text 대체 텍스트 설정 + This document has no tagged figures. 이 문서에는 태그가 지정된 그림이 없습니다. + on page {p} {p} 페이지 + Figure {i} of {n}{page} 그림 {n}개 중 {i}{page} + No preview 미리 보기 없음 + Alternate text 대체 텍스트 + Describe the figure 그림 설명 + Decorative figure 장식용 그림 + Previous figure 이전 그림 + Next figure 다음 그림 + Save & Close 저장 후 닫기 + Accessibility Checker Options 접근성 검사기 옵션 + Report Options 보고서 옵션 + Create accessibility report 접근성 보고서 만들기 + Page Range 페이지 범위 + All pages in document 문서의 모든 페이지 + Checking Options ({on} of 32 in all categories) 검사 옵션(모든 범주 32개 중 {on}개) + Show this dialog when the Checker starts 검사기가 시작될 때 이 대화 상자 표시 + Select All 모두 선택 + Clear All 모두 지우기 + Start Checking 검사 시작 + This document hasn't been checked yet. 이 문서는 아직 검사되지 않았습니다. + No issues found 발견된 문제 없음 + 1 issue 문제 1개 + {n} issues 문제 {n}개 + {label} (1 issue) {label} (문제 1개) + {label} ({n} issues) {label} (문제 {n}개) + Check again 다시 검사 + Report 보고서 + Show the accessibility report 접근성 보고서 표시 + Collapse 축소 + Expand 확장 + {rule} - {status} {rule} - {status} + Passed 통과 + Failed 실패 + Needs manual check 수동 확인 필요 + Skipped 건너뜀 + Fix 수정 + Skip Rule 규칙 건너뛰기 + Explain 설명 + Check Again 다시 검사 + Show Report 보고서 표시 + Options… 옵션… + Go to the page 페이지로 이동 + Page Content 페이지 콘텐츠 + Forms 양식 + Alternate Text 대체 텍스트 + Tables 표 + Lists 목록 + Headings 제목 + Accessibility permission flag 접근성 권한 플래그 + Accessibility permission flag is set 접근성 권한 플래그가 설정되어 있습니다 + Security settings must allow assistive technology to read the content ("Enable text access for screen reader devices"). Change the document's security to allow it. 보안 설정은 보조 기술이 콘텐츠를 읽을 수 있도록 허용해야 합니다("화면 판독기 장치에 대한 텍스트 접근 허용"). 이를 허용하도록 문서 보안을 변경하세요. + Image-only PDF 이미지 전용 PDF + Document is not image-only PDF 문서가 이미지 전용 PDF가 아닙니다 + Pages that are only pictures of text can't be read aloud or searched. Recognize text (OCR) to add a text layer. 텍스트가 사진으로만 되어 있는 페이지는 소리 내어 읽거나 검색할 수 없습니다. 텍스트 레이어를 추가하려면 텍스트 인식(OCR)을 실행하세요. + Document is tagged PDF 문서가 태그된 PDF입니다 + Tags give the document a logical structure that assistive technology follows. Tag the document (Automatically tag PDF). 태그는 문서에 보조 기술이 따를 수 있는 논리 구조를 부여합니다. 문서에 태그를 지정하세요(자동으로 PDF 태그 지정). + Logical Reading Order 논리적 읽기 순서 + Document structure provides a logical reading order 문서 구조가 논리적 읽기 순서를 제공합니다 + Check that the tags read in the order a sighted reader would. Use the Reading Order tool or the Tags panel to correct it. 태그가 시각이 정상인 독자가 읽는 순서대로 읽히는지 확인하세요. 읽기 순서 도구나 태그 패널로 수정하세요. + Primary language 기본 언어 + Text language is specified 텍스트 언어가 지정되었습니다 + Screen readers choose their voice from the document's language. Set it in Document Properties > Advanced > Language. 화면 판독기는 문서의 언어에 따라 음성을 선택합니다. 문서 속성 > 고급 > 언어에서 설정하세요. + Document title is showing in title bar 문서 제목이 제목 표시줄에 표시됩니다 + The window should show a meaningful title rather than the file name. Set a title and Initial View > Show: Document Title. 창은 파일 이름이 아닌 의미 있는 제목을 표시해야 합니다. 제목을 설정하고 초기 보기 > 표시: 문서 제목을 선택하세요. + Bookmarks are present in large documents 큰 문서에 책갈피가 있습니다 + Documents of more than 20 pages need bookmarks for navigation. Add bookmarks for the main sections. 20페이지가 넘는 문서에는 탐색용 책갈피가 필요합니다. 주요 섹션에 책갈피를 추가하세요. + Color contrast 색상 대비 + Document has appropriate color contrast 문서에 적절한 색상 대비가 있습니다 + Text must contrast enough with its background for people with low vision. Check the colours by eye or with a contrast tool. 텍스트는 저시력 사용자를 위해 배경과 충분한 대비를 이뤄야 합니다. 색상을 눈으로 또는 대비 검사 도구로 확인하세요. + Tagged content 태그된 콘텐츠 + All page content is tagged 모든 페이지 콘텐츠에 태그가 지정되어 있습니다 + Everything on a page must be tagged or marked as an artifact (decoration, headers, footers). Tag the untagged content. 페이지의 모든 요소는 태그가 지정되거나 아티팩트(장식, 머리글, 바닥글)로 표시되어야 합니다. 태그되지 않은 콘텐츠에 태그를 지정하세요. + Tagged annotations 태그된 주석 + All annotations are tagged 모든 주석에 태그가 지정되어 있습니다 + Comments, links and fields must be in the tag tree to be announced. Tag the annotations. 주석, 링크, 필드는 읽을 수 있도록 태그 트리에 있어야 합니다. 주석에 태그를 지정하세요. + Tab order 탭 순서 + Tab order is consistent with structure order 탭 순서가 구조 순서와 일치합니다 + Pages with links, comments or fields should tab in structure order. The fix sets each page's tab order to Use Document Structure. 링크, 주석 또는 필드가 있는 페이지는 구조 순서대로 탭 이동해야 합니다. 수정하면 각 페이지의 탭 순서가 문서 구조 사용으로 설정됩니다. + Character encoding 문자 인코딩 + Reliable character encoding is provided 신뢰할 수 있는 문자 인코딩이 제공됩니다 + Fonts must map their characters to Unicode so text can be read and copied. Fix the fonts or recreate the PDF. 글꼴은 텍스트를 읽고 복사할 수 있도록 문자를 Unicode에 매핑해야 합니다. 글꼴을 수정하거나 PDF를 다시 만드세요. + Tagged multimedia 태그된 멀티미디어 + All multimedia objects are tagged 모든 멀티미디어 개체에 태그가 지정되어 있습니다 + Video, sound and rich media must be tagged to be announced. Tag the multimedia annotations. 비디오, 소리, 리치 미디어는 읽을 수 있도록 태그가 지정되어야 합니다. 멀티미디어 주석에 태그를 지정하세요. + Screen flicker 화면 깜빡임 + Page will not cause screen flicker 페이지가 화면 깜빡임을 유발하지 않습니다 + Animation that flashes can cause seizures. Check scripts and media for flicker. 깜빡이는 애니메이션은 발작을 유발할 수 있습니다. 스크립트와 미디어에 깜빡임이 없는지 확인하세요. + Scripts 스크립트 + No inaccessible scripts 접근할 수 없는 스크립트가 없습니다 + Timed responses 시간 제한 응답 + Page does not require timed responses 페이지에 시간 제한 응답이 필요하지 않습니다 + People may need more time to respond. Check that nothing has a time limit. 응답에 더 많은 시간이 필요할 수 있습니다. 시간 제한이 있는 요소가 없는지 확인하세요. + Navigation links 탐색 링크 + Navigation links are not repetitive 탐색 링크가 반복적이지 않습니다 + Repeated navigation links should be skippable. Check links that appear on every page. 반복되는 탐색 링크는 건너뛸 수 있어야 합니다. 모든 페이지에 나타나는 링크를 확인하세요. + Tagged form fields 태그된 양식 필드 + All form fields are tagged 모든 양식 필드에 태그가 지정되어 있습니다 + Form fields must be in the tag tree (Form tags) to be announced. Tag the form fields. 양식 필드는 읽을 수 있도록 태그 트리(Form 태그)에 있어야 합니다. 양식 필드에 태그를 지정하세요. + Field descriptions 필드 설명 + All form fields have description 모든 양식 필드에 설명이 있습니다 + Each field needs a tooltip that says what to enter. Add one in Field Properties > General > Tooltip. 각 필드에는 입력할 내용을 알려 주는 도구 설명이 필요합니다. 필드 속성 > 일반 > 도구 설명에서 추가하세요. + Figures alternate text 그림 대체 텍스트 + Figures require alternate text 그림에 대체 텍스트가 필요합니다 + Pictures need alternate text that describes them, or must be marked decorative. Add alternate text to each figure. 그림은 내용을 설명하는 대체 텍스트가 필요하거나 장식용으로 표시되어야 합니다. 각 그림에 대체 텍스트를 추가하세요. + Nested alternate text 중첩된 대체 텍스트 + Alternate text that will never be read 절대 읽히지 않는 대체 텍스트 + Alternate text inside an element that already has alternate text is never read. Remove the inner alternate text. 이미 대체 텍스트가 있는 요소 안에 있는 대체 텍스트는 읽히지 않습니다. 안쪽 대체 텍스트를 제거하세요. + Associated with content 콘텐츠와 연결됨 + Alternate text must be associated with some content 대체 텍스트는 일부 콘텐츠와 연결되어야 합니다 + Alternate text on an element without page content is never reached. Remove it or attach the element to content. 페이지 콘텐츠가 없는 요소의 대체 텍스트는 절대 읽히지 않습니다. 제거하거나 요소를 콘텐츠에 연결하세요. + Hides annotation 주석을 숨김 + Alternate text should not hide annotation 대체 텍스트가 주석을 숨기지 않아야 합니다 + Alternate text on an element that contains a link or field hides that annotation from assistive technology. Move the alternate text. 링크나 필드가 포함된 요소의 대체 텍스트는 보조 기술에서 해당 주석을 숨깁니다. 대체 텍스트를 이동하세요. + Other elements alternate text 기타 요소 대체 텍스트 + Other elements that require alternate text 대체 텍스트가 필요한 기타 요소 + Formulas and similar non-text elements need alternate text. Add alternate text to them. 수식 등 텍스트가 아닌 요소에는 대체 텍스트가 필요합니다. 해당 요소에 대체 텍스트를 추가하세요. + Rows 행 + TR must be a child of Table, THead, TBody, or TFoot TR은 Table, THead, TBody 또는 TFoot의 하위 요소여야 합니다 + Table cells belong in a row. Fix the table's tags. 표 셀은 행에 속해야 합니다. 표의 태그를 수정하세요. + Headers 머리글 + Tables should have headers 표에 머리글이 있어야 합니다 + Header cells (TH) tell listeners what each column or row holds. Mark the header cells. 머리글 셀(TH)은 각 열이나 행에 무엇이 있는지 듣는 사람에게 알려 줍니다. 머리글 셀을 표시하세요. + Regularity 규칙성 + Tables must contain the same number of columns in each row and rows in each column 표의 각 행에는 같은 수의 열이, 각 열에는 같은 수의 행이 있어야 합니다 + Irregular tables confuse cell navigation. Give every row the same number of cells (counting spans). 불규칙한 표는 셀 탐색을 어렵게 합니다. 모든 행에 같은 수의 셀이 있도록 하세요(병합 포함). + Summary 요약 + Tables must have a summary 표에 요약이 있어야 합니다 + A summary describes the table's purpose and layout. Add a Summary attribute to each table. 요약은 표의 용도와 구조를 설명합니다. 각 표에 Summary 속성을 추가하세요. + List items 목록 항목 + LI must be a child of L LI는 L의 하위 요소여야 합니다 + List items belong in a list. Fix the list's tags. 목록 항목은 목록에 속해야 합니다. 목록의 태그를 수정하세요. + Lbl and LBody Lbl 및 LBody + Lbl and LBody must be children of LI Lbl 및 LBody는 LI의 하위 요소여야 합니다 + List labels and bodies belong in a list item. Fix the list's tags. 목록 레이블과 본문은 목록 항목에 속해야 합니다. 목록의 태그를 수정하세요. + Appropriate nesting 적절한 중첩 + Heading levels shouldn't skip (an H1 followed by an H3). Retag the headings. 제목 수준을 건너뛰지 않아야 합니다(H1 다음에 H3이 오는 경우). 제목 태그를 다시 지정하세요. + TH and TD TH 및 TD + TH and TD must be children of TR TH 및 TD는 TR의 하위 요소여야 합니다 + Mark Page Range 페이지 범위 표시 + Pages from 시작 페이지 + Single word or phrase 단어 또는 구문 하나 + Text to find 찾을 텍스트 + Patterns 패턴 + Phone Numbers 전화번호 + Email Addresses 이메일 주소 + Credit Cards 신용 카드 + Social Security Numbers 사회 보장 번호 + Dates 날짜 + Text in images isn't found; recognise text (OCR) first. 이미지 속 텍스트는 찾을 수 없습니다. 먼저 텍스트 인식(OCR)을 실행하세요. + No matches. 일치하는 항목이 없습니다. + Some bookmarks are not shown here: the panel lists a limited number, nested a limited depth. 일부 책갈피는 여기에 표시되지 않습니다. 패널에 나열되는 개수와 중첩 깊이가 제한되어 있습니다. + {n} match(es) marked for redaction. 검열하도록 표시된 일치 항목 {n}개입니다. + Multiple words or phrases 여러 단어 또는 구문 + One word or phrase per line 한 줄에 단어 또는 구문 하나 + Import list… 목록 가져오기… + {n} word(s) or phrase(s) 단어 또는 구문 {n}개 + {name} is too large for a word list (at most 1 MB). {name}은(는) 단어 목록으로 사용하기에 너무 큽니다(최대 1 MB). + Redaction Tool Properties 검열 도구 속성 + Redacted area fill colour: 검열 영역 채우기 색: + Use overlay text 오버레이 텍스트 사용 + Custom text: 사용자 지정 텍스트: + Redaction code: 검열 코드: + Font: 글꼴: + Font size: 글꼴 크기: + Auto-size text to fit redaction region 검열 영역에 맞게 텍스트 크기 자동 조정 + Font colour: 글꼴 색: + Repeat overlay text 오버레이 텍스트 반복 + Text alignment: 텍스트 정렬: + Center 가운데 + Apply redactions 검열 적용 + You are about to apply 1 redaction mark. Text, images and drawings under the marks, and comments and form fields that overlap them, are removed permanently. 검열 표시 1개를 적용하려고 합니다. 표시 아래의 텍스트, 이미지, 그림과 표시와 겹치는 주석 및 양식 필드가 영구적으로 제거됩니다. + You are about to apply {n} redaction marks. Text, images and drawings under the marks, and comments and form fields that overlap them, are removed permanently. 검열 표시 {n}개를 적용하려고 합니다. 표시 아래의 텍스트, 이미지, 그림과 표시와 겹치는 주석 및 양식 필드가 영구적으로 제거됩니다. + Save the document afterwards: saving rewrites the whole file so no trace of the removed content stays in it. 그 후 문서를 저장하세요. 저장하면 파일 전체가 다시 쓰여져 제거된 콘텐츠의 흔적이 남지 않습니다. + Select the items to remove from this document. 이 문서에서 제거할 항목을 선택하세요. + Metadata 메타데이터 + File attachments 파일 첨부 + Comments and markups 주석 및 마크업 + Hidden text 숨겨진 텍스트 + Hidden layers 숨겨진 레이어 + Links, actions and JavaScripts 링크, 동작, JavaScript + Private data of other applications 다른 응용 프로그램의 개인 데이터 + None found 발견된 항목 없음 + Form fields are flattened: their values stay visible. Saving rewrites the whole file. 양식 필드가 병합되어 값은 계속 표시됩니다. 저장하면 파일 전체가 다시 쓰여집니다. + Remove 제거 + Sanitizing removes hidden information from the document: metadata, file attachments, comments, form fields (flattened), hidden text and layers, bookmarks, links, actions and scripts, and private application data. 정리는 문서에서 숨겨진 정보를 제거합니다: 메타데이터, 파일 첨부, 주석, 양식 필드(병합됨), 숨겨진 텍스트와 레이어, 책갈피, 링크, 동작과 스크립트, 응용 프로그램 개인 데이터 등입니다. + Save the document afterwards; saving rewrites the whole file so nothing removed stays in it. 그 후 문서를 저장하세요. 저장하면 파일 전체가 다시 쓰여져 제거된 항목이 남지 않습니다. + Printer: 프린터: + Save as PDF PDF로 저장 + {name} (default) {name} (기본) + Copies: 매수: + Collate 한 부씩 인쇄 + Print in grayscale 회색조로 인쇄 + Two-sided: 양면: + Off 끄기 + Flip on long edge 긴 가장자리 기준 넘기기 + Flip on short edge 짧은 가장자리 기준 넘기기 + Paper: 용지: + Pages to Print 인쇄할 페이지 + More options: 추가 옵션: + All pages in range 범위의 모든 페이지 + Odd pages only 홀수 페이지만 + Even pages only 짝수 페이지만 + Reverse pages 페이지 역순 인쇄 + Page Sizing & Handling 페이지 크기 조정 및 처리 + Size 크기 + Poster 포스터 + Multiple 여러 페이지 + Booklet 소책자 + Fit 맞춤 + Shrink oversized pages 큰 페이지 축소 + Custom scale: 사용자 지정 배율: + Tile scale: 타일 배율: + Overlap: 겹침: + Cut marks 재단 표시 + Pages per sheet: 용지당 페이지 수: + Page order: 페이지 순서: + Horizontal 가로 + Horizontal reversed 가로 역순 + Vertical 세로 + Vertical reversed 세로 역순 + Print page border 페이지 테두리 인쇄 + Auto-rotate pages 페이지 자동 회전 + Booklet subset: 소책자 인쇄 면: + Both sides 양면 + Front side only 앞면만 + Back side only 뒷면만 + Binding: 제본: + Left 왼쪽 + Right 오른쪽 + Orientation: 방향: + Auto portrait/landscape 자동 세로/가로 + Portrait 세로 + Landscape 가로 + Comments & Forms 주석 및 양식 + Document 문서 + Document and markups 문서 및 변경 표시 + Document and stamps 문서 및 스탬프 + Form fields only 양식 필드만 + Previous sheet 이전 용지 + Next sheet 다음 용지 + No sheets 용지 없음 + Sheet {s} of {n} 용지 {s}/{n} + Removed 1 hidden item. Save to remove them from the file. 숨겨진 항목 1개를 제거했습니다. 파일에서 완전히 제거하려면 저장하세요. + Removed {n} hidden items. Save to remove them from the file. 숨겨진 항목 {n}개를 제거했습니다. 파일에서 완전히 제거하려면 저장하세요. + Document sanitized. Save to finish: saving rewrites the whole file. 문서가 정리되었습니다. 완료하려면 저장하세요: 저장하면 파일 전체가 다시 작성됩니다. + Applied 1 redaction mark. Save to remove the content from the file. 수정 표시 1개가 적용되었습니다. 파일에서 콘텐츠를 제거하려면 저장하세요. + Applied {n} redaction marks. Save to remove the content from the file. 수정 표시 {n}개가 적용되었습니다. 파일에서 콘텐츠를 제거하려면 저장하세요. + JavaScript Console JavaScript 콘솔 + JavaScript is turned off (Preferences ▸ JavaScript). JavaScript가 꺼져 있습니다(기본 설정 ▸ JavaScript). + Output appears here. 출력이 여기에 표시됩니다. + Script Name: 스크립트 이름: + This document has no document-level scripts. 이 문서에는 문서 수준 스크립트가 없습니다. + No form fields were detected 양식 필드가 감지되지 않았습니다 + Detected 1 form field 양식 필드 1개가 감지되었습니다 + Detected {n} form fields 양식 필드 {n}개가 감지되었습니다 + {field}: {e} {field}: {e} + Current page 현재 페이지 + Selected pages 선택한 페이지 + Document language 문서 언어 + Output 출력 + Searchable Image (Exact) 검색 가능한 이미지(정확한) + Adds invisible text over each word; the page image is not changed 각 단어 위에 보이지 않는 텍스트를 추가하며 페이지 이미지는 변경되지 않습니다 + Downsample to 다운샘플링 + Also recognize pages that already have text 이미 텍스트가 있는 페이지도 인식 + Pictures on those pages are recognized too; words already in the page's text are not added again 해당 페이지의 그림도 인식되며 페이지 텍스트에 이미 있는 단어는 다시 추가되지 않습니다 + Text recognition isn't installed: its model files are missing. Reinstall PdfCraft, or set PDFCRAFT_MODELS to the folder that holds them. 텍스트 인식이 설치되어 있지 않습니다: 모델 파일이 없습니다. PdfCraft를 다시 설치하거나 PDFCRAFT_MODELS를 모델 파일이 있는 폴더로 설정하세요. + Settings 설정 + Optional 선택 사항 + Planned · {m} 계획됨 · {m} + Planned for milestone {m} — open to see what it will include 마일스톤 {m}에 계획됨 — 열면 포함될 기능을 볼 수 있습니다 + Coming in milestone {m}. Items marked Ready work today. 마일스톤 {m}에 제공됩니다. “준비됨”으로 표시된 항목은 현재 작동합니다. + 1 mark 표시 1개 + {n} marks 표시 {n}개 + Dynamic 동적 + Sign Here 여기에 서명 + Standard Business 표준 비즈니스 + Choose a stamp, then click on the page to place it. 스탬프를 선택한 다음 페이지를 클릭하여 배치하세요. + Note 메모 + Polyline 폴리라인 + Attachment 첨부 + Callout 설명선 + Typewriter 타자기 + Checked 선택됨 + Unchecked 선택 안 됨 + Marked 표시됨 + Locked 잠김 + Search comments 주석 검색 + Add a comment 주석 추가 + No comments yet. 아직 주석이 없습니다. + Pick a tool in the quick bar, or type above. 빠른 도구 모음에서 도구를 선택하거나 위에 입력하세요. + No comments match. 일치하는 주석이 없습니다. + Unknown author 알 수 없는 작성자 + No colour 색상 없음 + Remove checkmark 확인 표시 제거 + Mark with checkmark 확인 표시 설정 + Reply 답글 + Add a reply 답글 추가 + Post 게시 + Page {label} 페이지 {label} + {kind} — click to show it on the page {kind} — 페이지에 표시하려면 클릭하세요 + Set status 상태 설정 + Copy text 텍스트 복사 + Properties… 속성… + Make Current Properties Default 현재 속성을 기본값으로 설정 + More options 추가 옵션 + Sort by 정렬 기준 + Author 작성자 + Type 입력 + Colour 색상 + Show all comments 모든 주석 표시 + Create PDF comment summary… PDF 주석 요약 만들기… + Export all to data file… 모두 데이터 파일로 내보내기… + Filter comments 주석 필터 + Status 상태 + Accepted 수락됨 + Rejected 거부됨 + Cancelled 취소됨 + Completed 완료됨 + Show all 모두 표시 + Yellow 노란색 + Orange 주황색 + Red 빨간색 + Pink 분홍색 + Purple 보라색 + Blue 파란색 + Light blue 연한 파란색 + Green 초록색 + Gray 회색 + Black 검은색 + Bookmark options 책갈피 옵션 + Expand all bookmarks 모든 책갈피 확장 + Expand top-level bookmarks 최상위 책갈피 확장 + Collapse all bookmarks 모든 책갈피 축소 + New bookmark ({key}) 새 책갈피({key}) + This document has no bookmarks. 이 문서에는 책갈피가 없습니다. + This document has no layers. 이 문서에는 레이어가 없습니다. + This document has no attachments. 이 문서에는 첨부 파일이 없습니다. + Hide layer 레이어 숨기기 + Show layer 레이어 표시 + Set layer visibility 레이어 표시 여부 설정 + on page {label} 페이지 {label} + Save attachment… 첨부 파일 저장… + Open in a new tab 새 탭에서 열기 + This document has no pages. 이 문서에는 페이지가 없습니다. + Find text 텍스트 찾기 + No matches 일치 항목 없음 + Searching… {s}/{p} 검색 중… {s}/{p} + {c} of {n}{more} {c}/{n}{more} + Previous ({key}) 이전({key}) + Next ({key}) 다음({key}) + Find options 찾기 옵션 + Whole words only 전체 단어만 + Case-sensitive 대/소문자 구분 + Close (Esc) 닫기(Esc) + Align 정렬 + Top 위쪽 + Bottom 아래쪽 + Center horizontally 가로 가운데 맞춤 + Center vertically 세로 가운데 맞춤 + Distribute 분배 + Horizontally 가로로 + Vertically 세로로 + Set Fields to Same Size 필드를 같은 크기로 설정 + Height 높이 + Width 너비 + Both 둘 다 + Duplicate… 복제… + All pages 모든 페이지 + Odd pages 홀수 페이지 + Even pages 짝수 페이지 + Landscape pages 가로 페이지 + Portrait pages 세로 페이지 + Move earlier 앞으로 이동 + Move later 뒤로 이동 + Back to the document 문서로 돌아가기 + Protect Using Password 암호로 보호 + Requires user to enter a password for: 다음 항목에 대해 사용자가 암호를 입력하도록 요구: + Viewing 보기 + Editing 편집 + Type Password 암호 입력 + Re-type Password 암호 재입력 + Strength: {s} 강도: {s} + Strong 강함 + Medium 중간 + Weak 약함 + Advanced Options {chevron} 고급 옵션 {chevron} + Compatibility 호환성 + Acrobat X and later (256-bit AES) Acrobat X 이상(256비트 AES) + Acrobat 7.0 and later (128-bit AES) Acrobat 7.0 이상(128비트 AES) + Acrobat 5.0 and later (128-bit RC4) Acrobat 5.0 이상(128비트 RC4) + Acrobat 3.0 and later (40-bit RC4) Acrobat 3.0 이상(40비트 RC4) + Encrypt 암호화 + All document contents 문서 콘텐츠 전체 + All document contents except metadata 메타데이터를 제외한 문서 콘텐츠 전체 + Printing allowed 인쇄 허용됨 + Low Resolution (150 dpi) 저해상도(150 dpi) + Changes allowed 변경 허용됨 + Inserting, deleting, and rotating pages 페이지 삽입, 삭제 및 회전 + Filling in form fields and signing existing signature fields 양식 필드 채우기 및 기존 서명 필드에 서명 + Commenting, filling in form fields, and signing existing signature fields 주석 달기, 양식 필드 채우기 및 기존 서명 필드에 서명 + Any except extracting pages 페이지 추출을 제외한 모든 변경 + Enable copying of text, images, and other content 텍스트, 이미지 및 기타 콘텐츠 복사 허용 + Enable text access for screen reader devices for the visually impaired 시각 장애인용 화면 판독기의 텍스트 접근 허용 + Type a password. 암호를 입력하세요. + The passwords don't match. 암호가 일치하지 않습니다. + This compatibility level supports only plain ASCII passwords. 이 호환성 수준은 일반 ASCII 암호만 지원합니다. + Anyone opening the document will need this password. It's applied when you save. 이 문서를 여는 모든 사람이 이 암호를 입력해야 합니다. 저장할 때 적용됩니다. + The document opens without a password; this password is needed to change the restrictions. It's applied when you save. 문서는 암호 없이 열리며 이 암호는 제한을 변경할 때 필요합니다. 저장할 때 적용됩니다. + Recover unsaved documents? 저장되지 않은 문서를 복구하시겠습니까? + PdfCraft didn't shut down normally. These documents had changes that were autosaved: PdfCraft가 정상적으로 종료되지 않았습니다. 다음 문서의 변경 내용이 자동 저장되었습니다: + just now 방금 + {n} min ago {n}분 전 + {n} h ago {n}시간 전 + · password-protected · 암호로 보호됨 + Recover 복구 + Discard 버리기 + Version {v} 버전 {v} + A clean-room, open-source PDF application written in Rust. MIT OR Apache-2.0. 클린룸 방식으로 개발된 Rust 기반 오픈 소스 PDF 응용 프로그램입니다. MIT OR Apache-2.0. + Part of 소속 + Summarize Options 요약 옵션 + Choose a layout: 레이아웃 선택: + Comments only 주석만 + Sort comments by: 주석 정렬 기준: + Create PDF Comment Summary PDF 주석 요약 만들기 + Revert to the previously saved version of “{name}”? Changes since then can't be undone afterwards. “{name}”을(를) 마지막으로 저장된 버전으로 되돌리시겠습니까? 그 이후의 변경 내용은 나중에 되돌릴 수 없습니다. + Number pages 페이지 번호 매기기 + Style 스타일 + None (prefix only) 없음(접두사만) + Prefix 접두사 + Start 시작 + Labels: {preview}. Later pages keep their labels. 레이블: {preview}. 이후 페이지는 기존 레이블을 유지합니다. + Even and Odd Pages 짝수 및 홀수 페이지 + Even Pages Only 짝수 페이지만 + Odd Pages Only 홀수 페이지만 + Landscape and Portrait Pages 가로 및 세로 페이지 + Landscape Pages 가로 페이지 + Portrait Pages 세로 페이지 + Duplicate Field 필드 복제 + Duplicate "{name}" onto: “{name}”을(를) 다음에 복제: + 1 page selected. 페이지 1개가 선택되었습니다. + {n} pages selected. 페이지 {n}개가 선택되었습니다. + Delete pages after extracting 추출 후 페이지 삭제 + Extract pages as separate files 페이지를 별도 파일로 추출 + Rotate Pages 페이지 회전 + Direction: 방향: + Clockwise 90 degrees 시계 방향으로 90도 + Counterclockwise 90 degrees 시계 반대 방향으로 90도 + 180 degrees 180도 + Pages: 페이지: + All 전체 + Selection 선택 + From 시작 + Rotate: 회전: + Repairs 복구 + Repair log 복구 로그 + Split document 문서 분할 + Number of pages 페이지 수 + Pages per file 파일당 페이지 수 + File size 파일 크기 + At most 최대 + Top-level bookmarks ({n}) 최상위 책갈피({n}) + Before each selected page (select pages in Organize) 선택한 각 페이지 앞에(Organize에서 페이지 선택) + Creates 1 file from {n} pages. {n}개의 페이지로 파일 1개가 만들어집니다. + Creates {f} files from {n} pages. {n}개의 페이지로 파일 {f}개가 만들어집니다. + Each file holds as many of the {n} pages as fit. 각 파일에는 {n}개 페이지 중 들어갈 수 있는 만큼 포함됩니다. + Replace Pages 페이지 교체 + Original: replace pages 원본: 페이지 교체 + to ~ + to {n} ~{n} + Replacement: pages of {name} 교체 내용: {name}의 페이지 + of {name} 파일: {name} + Only the page content changes: links, comments, form fields and bookmarks on the original pages stay. 페이지 콘텐츠만 변경됩니다: 원본 페이지의 링크, 주석, 양식 필드 및 책갈피는 그대로 유지됩니다. + The replacement file doesn't have that many pages. 교체 파일에는 그만큼 많은 페이지가 없습니다. + Tagged PDF 태그된 PDF + Document Properties 문서 속성 + Description 설명 + Initial View 초기 보기 + Security 보안 + Fonts 글꼴 + Advanced 고급 + Title 제목 + Subject 주체 + Keywords 키워드 + Application 응용 프로그램 + PDF producer PDF 생성기 + Layout and Magnification 레이아웃 및 배율 + Navigation tab 탐색 탭 + Page Only 페이지만 + Bookmarks Panel and Page 책갈피 패널 및 페이지 + Pages Panel and Page 페이지 패널 및 페이지 + Attachments Panel and Page 첨부 파일 패널 및 페이지 + Layers Panel and Page 레이어 패널 및 페이지 + Page layout 페이지 레이아웃 + Default 기본값 + Single Page 단일 페이지 + Single Page Continuous 단일 연속 페이지 + Two-Up (Facing) 두 페이지씩 보기(마주 보기) + Two-Up Continuous (Facing) 두 페이지씩 연속 보기(마주 보기) + Two-Up (Cover Page) 두 페이지씩 보기(표지 페이지) + Two-Up Continuous (Cover Page) 두 페이지씩 연속 보기(표지 페이지) + Magnification 배율 + Actual Size 실제 크기 + Fit Page 페이지에 맞춤 + Fit Width 너비에 맞춤 + Fit Height 높이에 맞춤 + Fit Visible 보이는 부분에 맞춤 + Open to page 다음 페이지로 열기 + of {pages} /{pages} + Window Options 창 옵션 + Resize window to initial page 초기 페이지에 맞게 창 크기 조정 + Center window on screen 화면 가운데에 창 배치 + Open in Full Screen mode 전체 화면 모드로 열기 + Show: 표시: + File Name 파일 이름 + Document Title 문서 제목 + User Interface Options 사용자 인터페이스 옵션 + Hide menu bar 메뉴 모음 숨기기 + Hide toolbars 도구 모음 숨기기 + Hide window controls 창 컨트롤 숨기기 + Security method 보안 방법 + No security 보안 없음 + Restrictions 제한 + None — everything is allowed 없음 — 모든 작업이 허용됨 + Password security 암호 보안 + Encryption 암호화 + Opened with 다음으로 열림 + — (protection is applied when you save) — (저장할 때 보호가 적용됨) + Owner password (no restrictions apply) 소유자 암호(제한이 적용되지 않음) + User password 사용자 암호 + Change settings… 설정 변경… + Printing 인쇄 + Not allowed 허용 안 됨 + Allowed 허용됨 + High resolution 고해상도 + Low resolution 저해상도 + Changing the document 문서 변경 + Document assembly 문서 조합 + Content copying 콘텐츠 복사 + Content copying for accessibility 접근성을 위한 콘텐츠 복사 + Commenting 주석 달기 + Filling of form fields 양식 필드 채우기 + No fonts are referenced by the pages. 페이지에서 참조하는 글꼴이 없습니다. + PDF version PDF 버전 + Location 위치 + Page size 페이지 크기 + Yes 예 + No 아니요 + Revisions 버전 기록 + View revision {n} 버전 {n} 보기 + Open the file as it was saved then 당시 저장된 상태로 파일을 엽니다 + Binding 제본 + Left Edge 왼쪽 가장자리 + Right Edge 오른쪽 가장자리 + Language 언어 + Saved {place}: {before} → {after} ({pct}% smaller){detail} {place}에 저장됨: {before} → {after} ({pct}% 작아짐){detail} + This file is already as small as it can be made ({size}). No copy was saved. 이 파일은 이미 최소 크기({size})입니다. 사본이 저장되지 않았습니다. + Saved {place}: {before} → {after} (not smaller){detail} {place}에 저장됨: {before} → {after} (더 작아지지 않음){detail} + Couldn't save the image: {e} 이미지를 저장할 수 없습니다: {e} + Adding images arrives on the web with file pickers for images 이미지 추가는 웹에서 파일 선택 기능과 함께 제공될 예정입니다 + Replacing images on page {p} arrives on the web with image pickers ({i}) 페이지 {p}의 이미지 교체는 웹에서 이미지 선택 기능({i})과 함께 제공될 예정입니다 + {name}: choosing images arrives on the web with file pickers for images {name}: 이미지 선택은 웹에서 파일 선택 기능과 함께 제공될 예정입니다 + Replacing images arrives on the web with image file pickers 이미지 교체는 웹에서 이미지 파일 선택 기능과 함께 제공될 예정입니다 + Couldn't create a PDF: {e} PDF를 만들 수 없습니다: {e} + The clipboard has no image or text 클립보드에 이미지나 텍스트가 없습니다 + On the web, open or drop an image to convert it 웹에서는 이미지를 열거나 끌어다 놓아 변환하세요 + Couldn't optimize the file: {e} 파일을 최적화할 수 없습니다: {e} + Couldn't write {path}: {e} {path}을(를) 쓸 수 없습니다: {e} + The form asks to be submitted to {u}; PdfCraft doesn't send form data. Save the document to keep your entries. 이 양식은 {u}(으)로 제출을 요청합니다. PdfCraft는 양식 데이터를 보내지 않습니다. 입력한 내용을 유지하려면 문서를 저장하세요. + This PDF uses the unsupported {s} action. 이 PDF는 지원되지 않는 {s} 작업을 사용합니다. + {name}: the {other} action isn't supported yet {name}: {other} 작업은 아직 지원되지 않습니다 + {name} submits the form to {url}; PdfCraft doesn't send form data. Save the document to keep your entries. {name}이(가) 양식을 {url}로 제출합니다. PdfCraft는 양식 데이터를 보내지 않습니다. 입력한 내용을 유지하려면 문서를 저장하세요. + Export stopped: {e} 내보내기가 중지되었습니다: {e} + Exported 1 image 이미지 1개를 내보냈습니다 + Exported {n} images 이미지 {n}개를 내보냈습니다 + ({s} not exported: {first}) ({s}개를 내보내지 못했습니다: {first}) + Exported the text of 1 page 페이지 1개의 텍스트를 내보냈습니다 + Exported the text of {n} pages 페이지 {n}개의 텍스트를 내보냈습니다 + {msg} to {dir} {msg} → {dir} + Exporting… {d} of {t} 내보내는 중… {d}/{t} + Choose a folder for the exported files 내보낸 파일을 저장할 폴더 선택 + New {tool} comments will look like this one 새 {tool} 주석은 이 모양으로 만들어집니다 + This document can't be checked: it couldn't be read for editing 이 문서는 검사할 수 없습니다: 편집을 위해 읽을 수 없습니다 + The checker found no problems in this document. 검사에서 이 문서에 문제가 발견되지 않았습니다. + The checker found 1 problem which may prevent the document from being fully accessible. 검사에서 문서의 완전한 접근성을 저해할 수 있는 문제 1개가 발견되었습니다. + The checker found {n} problems which may prevent the document from being fully accessible. 검사에서 문서의 완전한 접근성을 저해할 수 있는 문제 {n}개가 발견되었습니다. + The text is the same 텍스트가 같습니다 + 1 difference found 차이점 1개가 발견되었습니다 + {n} differences found 차이점 {n}개가 발견되었습니다 + Added 1 comment 주석 1개를 추가했습니다 + Added {n} comments 주석 {n}개를 추가했습니다 + Choose a folder for the results 결과를 저장할 폴더 선택 + Files for {name} {name}의 파일 + An action is already running 작업이 이미 실행 중입니다 + Running action… file {d} of {t} 작업 실행 중… 파일 {d}/{t} + No unlinked web addresses were found in the text 텍스트에서 링크되지 않은 웹 주소를 찾지 못했습니다 + Created 1 link 링크 1개를 만들었습니다 + Created {n} links 링크 {n}개를 만들었습니다 + Text recognition is already running 텍스트 인식이 이미 실행 중입니다 + Recognizing text… file {d} of {t} 텍스트 인식 중… 파일 {d}/{t} + Recognizing text… page {d} of {t} 텍스트 인식 중… 페이지 {d}/{t} + Recognized 1 word 단어 1개를 인식했습니다 + Recognized {n} words 단어 {n}개를 인식했습니다 + {words} on {pages} {pages}에 {words} + ; 1 page already had text ; 페이지 1개에는 이미 텍스트가 있었습니다 + ; {n} pages already had text ; 페이지 {n}개에는 이미 텍스트가 있었습니다 + Recognized {w} words in 1 file 파일 1개에서 단어 {w}개를 인식했습니다 + Recognized {w} words in {n} files 파일 {n}개에서 단어 {w}개를 인식했습니다 + ; failed: {list} ; 실패: {list} + 1 file done 파일 1개 완료 + {n} files done 파일 {n}개 완료 + The selected area has been copied ({w} × {h} pixels) 선택한 영역이 복사되었습니다({w} × {h}픽셀) + Couldn't take the snapshot: {e} 스냅샷을 만들 수 없습니다: {e} + Couldn't recover {name}: {e} {name}을(를) 복구할 수 없습니다: {e} + The document now conforms to {level}; save it to keep the changes 문서가 이제 {level}을(를) 준수합니다. 변경 내용을 유지하려면 저장하세요. + Fixed what could be fixed; 1 problem remains 수정 가능한 문제를 모두 수정했습니다. 문제 1개가 남아 있습니다 + Fixed what could be fixed; {n} problems remain 수정 가능한 문제를 모두 수정했습니다. 문제 {n}개가 남아 있습니다 + Custom stamps arrive on the web with file pickers for images 사용자 지정 스탬프는 웹에서 파일 선택 기능과 함께 제공될 예정입니다 + {file} is too large for a stamp (at most {n} MB) {file}이(가) 스탬프로 사용하기에 너무 큽니다(최대 {n}MB) + Sent to {printer} {printer}(으)로 보냈습니다 + Sent to {printer}: {msg} {printer}(으)로 보냈습니다: {msg} + Looking for printers… 프린터를 찾는 중… + Sending to {printer}… {printer}(으)로 보내는 중… + Choose a folder for the searchable files 검색 가능한 파일을 저장할 폴더 선택 + Files are combined from top to bottom. Leave Pages empty to take every page. 파일은 위에서 아래로 결합됩니다. 모든 페이지를 사용하려면 페이지를 비워 두세요. + Unlock… 잠금 해제… + Select a password-protected file first 먼저 암호로 보호된 파일을 선택하세요 + Enter the permissions password to allow combining 결합을 허용하려면 권한 암호를 입력하세요 + Enter the password that opens it 파일을 여는 암호를 입력하세요 + Unlock {name} {name} 잠금 해제 + Unlock {n} files 파일 {n}개 잠금 해제 + The same password is tried on each file. 각 파일에 같은 암호가 시도됩니다. + Hide password 암호 숨기기 + Show password 암호 표시 + Wrong password 잘못된 암호 + The password is only used to read the file; it isn't saved. 암호는 파일을 읽는 데만 사용되며 저장되지 않습니다. + Unlock 잠금 해제 + Opened, but its security settings don't allow combining. Enter the permissions password. 열렸지만 보안 설정에서 결합을 허용하지 않습니다. 권한 암호를 입력하세요. + Unlocked: the combined file won't be password-protected 잠금 해제됨: 결합된 파일은 암호로 보호되지 않습니다 + Unlocked {n} of {m} files 파일 {m}개 중 {n}개를 잠금 해제했습니다 + Drop PDFs, images, text files or folders here, or choose them. PDF, 이미지, 텍스트 파일 또는 폴더를 여기로 끌어다 놓거나 선택하세요. + Add folder… 폴더 추가… + Add folder and subfolders… 폴더 및 하위 폴더 추가… + More ways to add files 파일을 추가하는 다른 방법 + Every PDF, image and text file in the folder 폴더의 모든 PDF, 이미지 및 텍스트 파일 + Every PDF, image and text file in the folder and the folders inside it 폴더 및 그 하위 폴더의 모든 PDF, 이미지 및 텍스트 파일 + Add folder 폴더 추가 + Add folder and subfolders 폴더 및 하위 폴더 추가 + No PDFs, images or text files found in {folder} {folder}에서 PDF, 이미지 또는 텍스트 파일을 찾지 못했습니다 + Added the first {n} files in {folder} {folder}에서 처음 {n}개 파일을 추가했습니다 + Click to sort, drag to move the column. Drag its edge to resize it. 클릭하면 정렬되고 드래그하면 열이 이동됩니다. 가장자리를 드래그하면 크기가 조정됩니다. + Reset columns 열 초기화 + Remove {n} files 파일 {n}개 제거 + {n} selected {n}개 선택됨 + sorted ascending 오름차순 정렬됨 + sorted descending 내림차순 정렬됨 + Protected: the combined file won't keep its security settings 보호됨: 결합된 파일은 보안 설정을 유지하지 않습니다 + Add open documents 열려 있는 문서 추가 + All open documents 모든 열려 있는 문서 + No documents are open 열려 있는 문서가 없습니다 + Select a file first 먼저 파일을 선택하세요 + 1 file 파일 1개 + {n} files 파일 {n}개 + 1 file needs attention 파일 1개에 주의가 필요합니다 + {n} files need attention 파일 {n}개에 주의가 필요합니다 + {name} can't be combined: {why} {name}은(는) 결합할 수 없습니다: {why} + Check the pages of {name}: {why} {name}의 페이지를 확인하세요: {why} + Add the files to combine 결합할 파일을 추가하세요 + File name 파일 이름 + Warnings 경고 + Drag to reorder 드래그하여 순서 변경 + {k} of {n} {k}/{n} + ? of {n} ?/{n} + Added more than once 두 번 이상 추가됨 + yesterday 어제 + {n} days ago {n}일 전 + No pages selected 선택한 페이지가 없습니다 + Password-protected 암호로 보호됨 + Its security settings don't allow copying pages 보안 설정에서 페이지 복사를 허용하지 않습니다 + Can't be read: {e} 읽을 수 없음: {e} + Leave out files that can't be read? 읽을 수 없는 파일을 제외하시겠습니까? + These files can't be read, so they won't be in the combined PDF: 다음 파일은 읽을 수 없어 결합된 PDF에 포함되지 않습니다: + Combine the rest 나머지 결합 + and {n} more 외 {n}개 + Includes unsaved changes 저장되지 않은 변경 내용 포함 + Pages of {name} to combine, e.g. 1-3, 6 결합할 {name}의 페이지(예: 1-3, 6) + Remove {name} {name} 제거 + Add files… 파일 추가… + Add at least two files 파일을 두 개 이상 추가하세요 + Couldn't add {name}: {e} {name}을(를) 추가할 수 없습니다: {e} + Couldn't combine files: {e} 파일을 결합할 수 없습니다: {e} + Export comments 주석 내보내기 + Export form data 양식 데이터 내보내기 + Comment and form data 주석 및 양식 데이터 + Export 내보내기 + Select data files to merge 병합할 데이터 파일 선택 + Form data and PDF forms 양식 데이터 및 PDF 양식 + Save the spreadsheet 스프레드시트 저장 + Save the accessibility report 접근성 보고서 저장 + Save image 이미지 저장 + Export certificate 인증서 내보내기 + Choose a folder for the extracted pages 추출한 페이지를 저장할 폴더 선택 + Choose a folder for the split files 분할된 파일을 저장할 폴더 선택 + Couldn't use {name}: {e} {name}을(를) 사용할 수 없습니다: {e} + Couldn't extract pages: {e} 페이지를 추출할 수 없습니다: {e} + Couldn't write {name}: {e} {name}을(를) 쓸 수 없습니다: {e} + Wrote 1 file to {dir} 파일 1개를 {dir}에 썼습니다 + Wrote {n} files to {dir} 파일 {n}개를 {dir}에 썼습니다 + No pages match those choices 이 선택 조건에 일치하는 페이지가 없습니다 + Couldn't split: {e} 분할할 수 없습니다: {e} + Couldn't summarize comments: {e} 주석을 요약할 수 없습니다: {e} + Couldn't open the result: {e} 결과를 열 수 없습니다: {e} + Importing data arrives on the web with file pickers for data files 데이터 가져오기는 웹에서 데이터 파일 선택 기능과 함께 제공될 예정입니다 + Exported to {path} {path}에 내보냈습니다 + Merging data files needs the desktop app 데이터 파일 병합에는 데스크톱 앱이 필요합니다 + Merged 1 file into {path} 파일 1개를 {path}에 병합했습니다 + Merged {n} files into {path} 파일 {n}개를 {path}에 병합했습니다 + Combined {n} files 파일 {n}개를 결합했습니다 + Extracted 1 page 페이지 1개를 추출했습니다 + Extracted {n} pages 페이지 {n}개를 추출했습니다 + Created a comment summary 주석 요약을 만들었습니다 + Couldn't open {name}: {e} {name}을(를) 열 수 없습니다: {e} + Couldn't read {name}: {e} {name}을(를) 읽을 수 없습니다: {e} + Couldn't save: {e} 저장할 수 없습니다: {e} + Downloading attachments on the web arrives with M3.10 ({n} bytes ready) 웹에서의 첨부 파일 다운로드는 M3.10에 제공될 예정입니다(준비된 바이트: {n}) + `{command}` {when} `{command}` {when} + ships in milestone {m} 마일스톤 {m}에 제공됩니다 + needs an AI provider (off by default) AI 공급자가 필요합니다(기본적으로 꺼져 있음) + is available 사용할 수 있습니다 + is not available yet 아직 사용할 수 없습니다 + {label} failed: {e} {label} 실패: {e} + Undid {label} {label} 작업을 취소했습니다 + Redid {label} {label} 작업을 다시 실행했습니다 + A document needs at least one page: copy instead 문서에는 페이지가 최소한 하나 있어야 합니다. 대신 복사하세요. + Cut {what} {what}를 잘라냈습니다 + Copied {what} {what}를 복사했습니다 + 1 page 페이지 1개 + {n} pages 페이지 {n}개 + Copy or cut pages first 먼저 페이지를 복사하거나 잘라내세요 + Couldn't save {name}: {e} {name}을(를) 저장할 수 없습니다: {e} + Saved {name} {name}을(를) 저장했습니다 + Saved, but reopening failed: {e} 저장했지만 다시 여는 데 실패했습니다: {e} + Downloaded {name} {name}을(를) 다운로드했습니다 + Couldn't download {name}: {e} {name}을(를) 다운로드할 수 없습니다: {e} + Reverted to the last saved version 마지막으로 저장한 버전으로 되돌렸습니다 + That didn't work: an internal error stopped it ({m}). Your documents are unchanged. 작동하지 않았습니다: 내부 오류로 중지되었습니다({m}). 문서는 변경되지 않았습니다. + Nothing to undo 취소할 작업이 없습니다 + Nothing to redo 다시 실행할 작업이 없습니다 + This document has no form fields you can fill in 이 문서에는 채울 수 있는 양식 필드가 없습니다 + This document has no comments to flatten 이 문서에는 평면화할 주석이 없습니다 + This document has no form fields to flatten 이 문서에는 평면화할 양식 필드가 없습니다 + There are no redaction marks (mark text, areas or pages first) 수정 표시가 없습니다(먼저 텍스트, 영역 또는 페이지를 표시하세요) + This document has no {kind} to change 이 문서에는 변경할 {kind}이(가) 없습니다 + header or footer 머리글 또는 바닥글 + watermark 워터마크 + background 배경 + This document isn't password-protected 이 문서는 암호로 보호되어 있지 않습니다 + Enter permissions password… 권한 암호 입력… + Permissions password 권한 암호 + “{name}” has security restrictions. Enter its permissions password to lift them. “{name}”에 보안 제한이 있습니다. 제한을 해제하려면 권한 암호를 입력하세요. + Restrictions lifted 제한이 해제되었습니다 + Couldn't unlock {name}: {e} {name}의 잠금을 해제할 수 없습니다: {e} + This document has no restrictions to lift 이 문서에는 해제할 제한이 없습니다 + The document's security settings don't allow this change 문서의 보안 설정에서 이 변경을 허용하지 않습니다 + The document's security settings don't allow copying text and images 문서의 보안 설정에서 텍스트와 이미지 복사를 허용하지 않습니다 + Open a document first 먼저 문서를 열어 주세요 + Security will be removed when you save 저장할 때 보안이 제거됩니다 + Click text or an image to edit it 텍스트나 이미지를 클릭하여 편집하세요 + Drag a rectangle to create a link; double-click a link to edit it 드래그하여 사각형을 그려 링크를 만들고, 링크를 두 번 클릭하여 편집하세요 + There are no redaction marks to apply 적용할 수정 표시가 없습니다 + Drag to draw the area where the signature should appear. 서명이 표시될 영역을 드래그하여 그리세요. + Couldn't fit the visible content: {e} 보이는 콘텐츠를 맞출 수 없습니다: {e} + Drag a rectangle around the area to copy 복사할 영역 주위에 사각형을 드래그하세요 + Click on the page to add a {tool}, or drag to set its size 페이지를 클릭하여 {tool}을(를) 추가하거나 드래그하여 크기를 지정하세요 + Drag a rectangle on a page to crop it; double-click a page for Set Page Boxes 페이지에 사각형을 드래그하여 자르고, 두 번 클릭하면 페이지 상자를 설정합니다 + Keep tool selected: on 도구 선택 유지: 켬 + Keep tool selected 도구 선택 유지 + Opacity 불투명도 + Line thickness 선 굵기 + What word or phrase would you like to search for? 어떤 단어나 구문을 검색하시겠습니까? + Searching… {s} of {p} pages 검색 중… {p}페이지 중 {s} + (searching… {s} of {p} pages) (검색 중… {p}페이지 중 {s}) + 1 instance 일치 항목 1개 + {n} instances 일치 항목 {n}개 + Go to this result 이 결과로 이동 + Highlight 형광펜 + Draw 그리기 + Polygon 다각형 + Connected lines 연결선 + Eraser 지우개 + Sign 서명 + Certified by {by} {by}이(가) 인증함 + At least one signature is invalid. 하나 이상의 서명이 유효하지 않습니다. + Signed and all signatures are valid. 서명되었으며 모든 서명이 유효합니다. + At least one signature has problems. 하나 이상의 서명에 문제가 있습니다. + This document is secured. Some changes are restricted by its security settings. 이 문서는 보호되어 있습니다. 일부 변경은 보안 설정에 의해 제한됩니다. + This is a dynamic XFA form, which PdfCraft can't display yet. What you see is the file's placeholder page. 동적 XFA 양식으로, PdfCraft가 아직 표시할 수 없습니다. 지금 보이는 것은 파일의 자리 표시 페이지입니다. + This form also contains XFA data, which PdfCraft doesn't read yet. You can fill its fields, but Acrobat may show the XFA values instead. 이 양식에는 PdfCraft가 아직 읽지 못하는 XFA 데이터도 들어 있습니다. 필드는 채울 수 있지만 Acrobat이 대신 XFA 값을 표시할 수 있습니다. + This document contains {n} interactive form fields. 이 문서에는 대화형 양식 필드 {n}개가 들어 있습니다. + This file was damaged and has been repaired. Saving keeps the repaired version. 이 파일은 손상되었다가 복구되었습니다. 저장하면 복구된 버전이 유지됩니다. + Dismiss 닫기 + Hide field highlights 필드 강조 숨기기 + Highlight fields 필드 강조 표시 + Security settings 보안 설정 + Details 세부 정보 + Select (V) 선택 (V) + Hand (H) 손 도구 (H) + Delete pages (Delete) 페이지 삭제 (Delete) + Insert a blank page after the selection 선택 항목 뒤에 빈 페이지 삽입 + Insert pages from a file… 파일에서 페이지 삽입… + Extract pages to a new document 새 문서로 페이지 추출 + Split into files… 파일로 분할… + Select pages 페이지 선택 + Cut 잘라내기 + Copy 복사 + Paste after 뒤에 붙여넣기 + Rename 이름 바꾸기 + Set to current page ({n}) 현재 페이지({n})로 설정 + Move up 위로 이동 + Move down 아래로 이동 + Indent 들여쓰기 + Outdent 내어쓰기 + This document has no form fields. 이 문서에는 양식 필드가 없습니다. + Tab order: move a field with its arrows. 탭 순서: 필드의 화살표로 필드를 이동하세요. + Unplaced 배치되지 않음 + Has JavaScript actions (run in M6) JavaScript 동작 있음(M6에서 실행) + Page 페이지 + None 없음 + Delete selected fields 선택한 필드 삭제 + Diagnostic details 진단 세부 정보 + The operation failed. 작업이 실패했습니다. + no such document 해당 문서 없음 + nothing to undo 실행 취소할 작업 없음 + nothing to redo 다시 실행할 작업 없음 + this document is signed: rewriting it would invalidate its signatures (save it incrementally instead) 이 문서는 서명되어 있음: 다시 쓰면 서명이 무효화됨(대신 증분 저장 사용) + the document is protected by a password 문서가 암호로 보호되어 있음 + the password is incorrect 암호가 잘못됨 + the document has no page tree 문서에 페이지 트리가 없음 + a document must keep at least one page 문서는 페이지를 하나 이상 유지해야 함 + a bookmark cannot be moved inside itself 책갈피를 자기 자신 안으로 이동할 수 없음 + the title must not be empty 제목은 비워 둘 수 없음 + the document has no form fields 문서에 양식 필드가 없음 + there are no redaction marks to apply 적용할 검열 표시가 없음 + there are no pages to print 인쇄할 페이지가 없음 + the document has no tags 문서에 태그가 없음 + {0}: {1} {0}: {1} + the text recognition models are not installed (reinstall PdfCraft, or set PDFCRAFT_MODELS to the folder that holds them) 텍스트 인식 모델이 설치되어 있지 않음(PdfCraft를 다시 설치하거나 PDFCRAFT_MODELS를 모델이 있는 폴더로 설정하세요) + the image is empty 이미지가 비어 있음 + this file isn't XFDF, FDF, XML or text form data 이 파일은 XFDF, FDF, XML 또는 텍스트 양식 데이터가 아님 + nothing in the file matches this document 파일에서 이 문서와 일치하는 항목이 없음 + This page couldn't be displayed.\n{e} 이 페이지를 표시할 수 없습니다.\n{e} + Go to page {p} 페이지 {p}로 이동 + {s} action {s} 동작 + Page {p} of {n} 페이지 {p} / {n} + 1 page selected 페이지 1개 선택됨 + {n} pages selected 페이지 {n}개 선택됨 + {name} — unsaved changes {name} — 저장되지 않은 변경 내용 + {kind} field {kind} 필드 + Select a file for the stamp 스탬프로 사용할 파일을 선택하세요 + JavaScript, e.g. getField("total").value JavaScript, 예: getField("total").value + Font: Helvetica 글꼴: Helvetica + e.g. en-US 예: en-US + Rendering: hayro (bootstrap) · UI: egui · Icons: Lucide (ISC) · Fonts: Inter, JetBrains Mono, Dancing Script (OFL) 렌더링: hayro(부트스트랩) · UI: egui · 아이콘: Lucide(ISC) · 글꼴: Inter, JetBrains Mono, Dancing Script(OFL) + CheckBox 확인란 + Radio 라디오 단추 + PushButton 누름 단추 + Combo 드롭다운 + List 목록 + Unknown 알 수 없음 + The document has no XMP metadata 문서에 XMP 메타데이터가 없습니다 + The title in the metadata and the document information differ 메타데이터의 제목과 문서 정보가 서로 다릅니다 + The document is encrypted 문서가 암호화되어 있습니다 + Device colour is used, but there is no PDF/A output intent 장치 색상이 사용되지만 PDF/A 출력 의도가 없습니다 + DeviceCMYK is used: it needs a CMYK output intent (not added automatically) DeviceCMYK가 사용됩니다: CMYK 출력 의도가 필요합니다(자동으로 추가되지 않음) + The document has additional actions (/AA) 문서에 추가 동작(/AA)이 있습니다 + The document has document-level JavaScript 문서에 문서 수준 JavaScript가 있습니다 + The form asks viewers to make appearances (NeedAppearances) 양식이 뷰어에게 필드 모양 생성을 요청합니다(NeedAppearances) + A form field has additional actions 양식 필드에 추가 동작이 있습니다 + A stream uses LZW compression 스트림이 LZW 압축을 사용합니다 + A stream refers to an external file 스트림이 외부 파일을 참조합니다 + An image asks to be interpolated 이미지가 보간을 요청합니다 + An image has alternates or OPI information 이미지에 대체 항목 또는 OPI 정보가 있습니다 + PostScript XObjects aren't allowed PostScript XObject는 허용되지 않습니다 + Embedded files must be PDF/A files themselves (use PDF/A-3 for others) 포함된 파일 자체도 PDF/A 파일이어야 합니다(다른 파일에는 PDF/A-3 사용) + An embedded file has no AFRelationship 포함된 파일에 AFRelationship이 없습니다 + Select Icon 아이콘 선택 + Choose images 이미지 선택 + {dpi} pixels/inch 인치당 {dpi}픽셀 + Type your {what}. {what}을(를) 입력하세요. + Draw your {what} below. 아래에 {what}을(를) 그리세요. + Your name 이름 + Images and text (converted to PDF) 이미지 및 텍스트(PDF로 변환) + Images and text 이미지 및 텍스트 + Check Box Style: 확인란 스타일: + Button Style: 단추 스타일: + Check 체크 표시 + Circle 원 + Diamond 마름모 + Square 사각형 + Star 별 + {month} {y} {month} {y} + Change {key} {key} 변경 + Insert pages from {name} {name}에서 페이지 삽입 + Insert pages from {name} — 1 field renamed {name}에서 페이지 삽입 — 필드 1개 이름 변경됨 + Insert pages from {name} — fields renamed {name}에서 페이지 삽입 — 필드 이름 변경됨 + Fill in {name} {name} 채우기 + Set the image of {name} {name}의 이미지 설정 + Edit script of {name} {name}의 스크립트 편집 + Import {name} {name} 가져오기 + Add bookmark 책갈피 추가 + Rename bookmark 책갈피 이름 바꾸기 + Delete bookmark 책갈피 삭제 + Move bookmark 책갈피 이동 + Set bookmark destination 책갈피 대상 설정 + Add stamp 스탬프 추가 + Delete comment 주석 삭제 + Edit comment 주석 편집 + Erase 지우기 + Lock comment 주석 잠금 + Unlock comment 주석 잠금 해제 + Move comment 주석 이동 + Resize comment 주석 크기 조정 + Change comment properties 주석 속성 변경 + Add field 필드 추가 + Change field properties 필드 속성 변경 + Delete field 필드 삭제 + Duplicate field 필드 복제 + Set tab order 탭 순서 설정 + Change initial view 초기 보기 변경 + Set alternate text 대체 텍스트 설정 + Mark figure as decorative 그림을 장식용으로 표시 + Run JavaScript JavaScript 실행 + Delete document JavaScript 문서 JavaScript 삭제 + Edit document JavaScript 문서 JavaScript 편집 + Edit text 텍스트 편집 + Load document font 문서 글꼴 불러오기 + Move image 이미지 이동 + Rotate image 이미지 회전 + Flip image 이미지 뒤집기 + Delete image 이미지 삭제 + Add header & footer 머리글 및 바닥글 추가 + Update header & footer 머리글 및 바닥글 업데이트 + Update watermark 워터마크 업데이트 + Add background 배경 추가 + Update background 배경 업데이트 + Add image 이미지 추가 + Edit content 콘텐츠 편집 + Delete content 콘텐츠 삭제 + Remove redaction marks 검열 표시 제거 + Add link 링크 추가 + Change link properties 링크 속성 변경 + Delete link 링크 삭제 + Create link 링크 만들기 + Flatten 병합 + Add sticky note 스티커 메모 추가 + Add highlight 형광펜 추가 + Add underline 밑줄 추가 + Add strikethrough 취소선 추가 + Add squiggly underline 물결 밑줄 추가 + Add rectangle 사각형 추가 + Add oval 타원 추가 + Add arrow 화살표 추가 + Add line 선 추가 + Add drawing 그리기 추가 + Add text box 텍스트 상자 추가 + Add checkmark 체크 표시 추가 + Add cross X 표시 추가 + Add dot 점 추가 + Add signature 서명 추가 + Add redaction mark 검열 표시 추가 + Add cloud 구름 추가 + Add polygon 다각형 추가 + Add connected lines 연결선 추가 + Add callout 설명선 추가 + Add inserted text 삽입 텍스트 추가 + Add file attachment 파일 첨부 추가 + Set status Accepted 상태를 수락됨으로 설정 + Set status Rejected 상태를 거부됨으로 설정 + Set status Cancelled 상태를 취소됨으로 설정 + Set status Completed 상태를 완료로 설정 + Set status None 상태를 없음으로 설정 + Set status Unmarked 상태를 표시 안 함으로 설정 + Save as PDF/A-1b PDF/A-1b로 저장 + Save as PDF/A-2b PDF/A-2b로 저장 + Save as PDF/A-3b PDF/A-3b로 저장 + Fill & Sign: change signature 채우기 및 서명: 서명 변경 + Fill & Sign: change initials 채우기 및 서명: 이니셜 변경 + Fill & Sign: remove saved signature 채우기 및 서명: 저장된 서명 제거 + Fill & Sign: remove saved initials 채우기 및 서명: 저장된 이니셜 제거 + Change signature 서명 변경 + Change initials 이니셜 변경 + Measure distance 거리 측정 + Measure perimeter 둘레 측정 + Measure area 면적 측정 + Set measurement scale 측정 축척 설정 + Measurement information 측정 정보 + Measurement snapping 측정 스냅 + Export measurements as CSV 측정값을 CSV로 내보내기 + Distance 거리 + Perimeter 둘레 + Area 면적 + Drawing scale 도면 축척 + Snapping 스냅 + Export measurements 측정값 내보내기 + Open a PDF to measure it. 측정할 PDF를 여세요. + Click vertices. Enter or double-click finishes a perimeter or area. Click the first point to close an area. 꼭짓점을 클릭하세요. Enter 키 또는 두 번 클릭으로 둘레나 면적을 마칩니다. 첫 번째 점을 클릭하면 영역이 닫힙니다. + Shift constrains to 45 degrees. Backspace removes a vertex. Escape cancels. Shift 키를 누르면 45도 각도로 제한됩니다. Backspace 키는 꼭짓점을 지웁니다. Esc 키를 누르면 취소됩니다. + Angle 각도 + Click the first point to begin. 시작하려면 첫 번째 점을 클릭하세요. + Snap to drawing 도면에 스냅 + Endpoints 끝점 + Midpoints 중점 + Intersections 교차점 + Paths 경로 + Sensitivity 민감도 + Unit 단위 + Decimals 소수 자릿수 + Calibrate from two points 두 점으로 보정 + Entire page 전체 페이지 + Viewport rectangle in page points (x, y, width, height) 페이지 포인트 단위의 뷰포트 사각형(x, y, 너비, 높이) + Viewport 뷰포트 + Apply scale 축척 적용 + Saved measurements 저장된 측정값 + Saved measurements. 측정값이 저장되었습니다. + Endpoint 끝점 + Midpoint 중점 + Intersection 교차점 + Path 경로 + This drawing exceeds the snapping limit; only the first paths are used. 이 도면은 스냅 한도를 초과하여 처음 경로만 사용됩니다. + Some page content couldn't be read; snapping uses the rest. 일부 페이지 콘텐츠를 읽을 수 없어서 스냅은 나머지를 사용합니다. + Unsupported measurements 지원되지 않는 측정값 + Label 레이블 + {n} measurements use an unsupported format and are left out. 측정값 {n}개가 지원되지 않는 형식을 사용하여 제외됩니다. + This area has too many overlapping paths; intersection snapping is limited. 이 영역에는 겹치는 경로가 너무 많아 교차점 스냅이 제한됩니다. + This measurement needs at least {n} points. 이 측정에는 {n}개 이상의 점이 필요합니다. + Change {what} {what} 변경 + Cut and stack 재단 및 쌓기 + Default workspace mode 기본 작업 영역 모드 + Documents and view 문서 및 보기 + Open email app 이메일 앱 열기 + Open link 링크 열기 + Open this web page? 이 웹 페이지를 여시겠습니까? + Scripts run in a sandbox without file or network access. A script that asks to open a web page needs your permission first. With JavaScript off, Acrobat's standard format, validate and calculate functions still work. 스크립트는 파일이나 네트워크에 접근할 수 없는 샌드박스에서 실행됩니다. 웹 페이지를 열려는 스크립트는 먼저 사용자의 허가를 받아야 합니다. JavaScript가 꺼져 있어도 Acrobat의 표준 형식, 유효성 검사 및 계산 함수는 계속 작동합니다. + Sign yourself 직접 서명 + Used when opening PDFs. An explicit launch or control mode takes precedence for the session. PDF를 열 때 사용됩니다. 명시적으로 지정한 시작 또는 제어 모드가 세션 동안 우선 적용됩니다. + Write this email? 이 이메일을 작성하시겠습니까? + {who} in this document wants to open this address in your browser: 이 문서의 {who}이(가) 브라우저에서 이 주소를 열려고 합니다: + {who} in this document wants to open your email app with this address: 이 문서의 {who}이(가) 이 주소로 이메일 앱을 열려고 합니다: + This web address mixes letters from different alphabets, a common way to imitate another site's name. 이 웹 주소에는 서로 다른 문자 체계의 글자가 섞여 있습니다. 다른 사이트 이름을 가장하는 흔한 수법입니다. + This web address uses letters from another alphabet, which can look like familiar ones. 이 웹 주소는 다른 문자 체계의 글자를 사용하며 익숙한 글자처럼 보일 수 있습니다. + Create PDF from images 이미지로 PDF 만들기 + Selected image files: {count} 선택한 이미지 파일: {count}개 + Use image resolution 이미지 해상도 사용 + Use each image's embedded DPI; use 72 DPI when it is absent. 각 이미지에 포함된 DPI를 사용합니다. 없을 때는 72 DPI를 사용합니다. + Use 72 DPI (one point per pixel) 72 DPI 사용(픽셀당 1포인트) + Use custom DPI 사용자 지정 DPI 사용 + DPI sets the printed page size without resampling the image. DPI는 이미지를 다시 샘플링하지 않고 인쇄되는 페이지 크기를 정합니다. + Create 만들기 + Dynamic XFA form laid out from its template: {pages}, {fields}. 템플릿에 따라 배치된 동적 XFA 양식: {pages}, {fields}. + This form's scripts are turned off because one ran too long. Reopen the document to run them again. 스크립트 하나가 너무 오래 실행되어 이 양식의 스크립트가 꺼졌습니다. 다시 실행하려면 문서를 다시 여세요. + XFA form: its fields and its XFA data are kept in step, so other viewers show what you fill in. XFA 양식: 필드와 XFA 데이터가 동기화되어 다른 뷰어에도 입력한 내용이 표시됩니다. + Switch to two-page view first to show the cover page 표지를 표시하려면 먼저 두 페이지 보기로 전환 + Page display: {layout} 페이지 표시: {layout} + Fit to width scrolling 너비에 맞춘 스크롤 + Fit one full page 한 페이지 전체 맞춤 + Default page display 기본 페이지 표시 + Default zoom 기본 확대/축소 + Used when a PDF doesn't ask for a layout or zoom. Continuous scrolling never snaps between pages. PDF가 레이아웃이나 확대/축소를 지정하지 않을 때 사용됩니다. 연속 스크롤에서는 페이지 사이에 스냅되지 않습니다. + Choose a PNG or JPEG image (up to 4 MiB). Transparency is preserved. PNG 또는 JPEG 이미지를 선택하세요(최대 4 MiB). 투명도는 유지됩니다. + Couldn't import the signature image: {e} 서명 이미지를 가져올 수 없습니다: {e} +@plural {n} page|{n} pages {n}페이지 +@plural {n} field|{n} fields 필드 {n}개 +@plural {n} field name collides with earlier files and will be renamed: {list}|{n} field names collide with earlier files and will be renamed: {list} 필드 이름 {n}개가 앞선 파일과 충돌하여 이름이 바뀝니다: {list} + Create PDF from multiple files… 여러 파일로 PDF 만들기… + Create separate PDFs… 개별 PDF 만들기… + Optimizing… removing user data 최적화 중… 사용자 데이터 제거 + Optimizing… image {d} of {t} 최적화 중… 이미지 {t}개 중 {d}개 + Optimizing… cleaning up 최적화 중… 정리 중 + Optimizing… merging identical objects 최적화 중… 동일한 개체 병합 중 + Optimizing… writing the copy 최적화 중… 사본 작성 중 + Cancelling… 취소하는 중… + Created a PDF from {n} files 파일 {n}개로 PDF를 만들었습니다 + PDF, images and text PDF, 이미지 및 텍스트 + Insert a file before page {label} {label} 페이지 앞에 파일 삽입 + Insert a file at the end 끝에 파일 삽입 + Save pages 페이지 저장 + Save these pages as one PDF 이 페이지를 PDF 한 개로 저장 + No changes to save 저장할 변경 내용이 없습니다 + Created a PDF from {n} files; left out: {names} 파일 {n}개로 PDF를 만들었습니다. 제외: {names} + Created a PDF from the first {n} files 처음 {n}개 파일로 PDF를 만들었습니다 + Go to page… 페이지로 이동… + Optimization is already running 최적화가 이미 실행 중입니다 + Optimization cancelled 최적화가 취소되었습니다 + Couldn't optimize the file 파일을 최적화할 수 없습니다 + Files are combined in this order. Leave Pages empty to take every page. 파일은 이 순서대로 결합됩니다. 모든 페이지를 사용하려면 페이지를 비워 두세요. + Portable mode is off: {folder} can't be written ({error}). Settings are kept in your user folder instead. 휴대용 모드가 꺼져 있습니다: {folder}에 쓸 수 없습니다({error}). 대신 사용자 폴더에 설정이 보관됩니다. + PdfCraft is drawing without a graphics processor, so it may be slow. Updating the graphics driver may help. PdfCraft가 그래픽 프로세서 없이 그리고 있어 느릴 수 있습니다. 그래픽 드라이버를 업데이트하면 도움이 될 수 있습니다. + Show 표시 + Sort 정렬 + Reverse the order 순서 반전 + Grab bag 기타 + Table 표 + Username 사용자 이름 + Display name 표시 이름 + Real name 실명 + Name (A–Z) 이름 (A–Z) + Merged PRs 병합된 PR + PRs PR + Commits 커밋 + Lines added 추가된 줄 + +LOC +LOC + Lines deleted 삭제된 줄 + −LOC −LOC + Line delta 줄 증감 + ΔLOC ΔLOC + Binary assets added 추가된 바이너리 자산 + +Bin +Bin + Binary assets removed 제거된 바이너리 자산 + −Bin −Bin + First commit 첫 커밋 + First 처음 + Last commit 마지막 커밋 + Last 마지막 + No contributor data was built into this copy. 이 사본에는 기여자 데이터가 포함되어 있지 않습니다. + No model credits were built into this copy. 이 사본에는 모델 크레딧이 포함되어 있지 않습니다. + {n} contributors · {c} commits 기여자 {n}명 · 커밋 {c}개 + Company 회사 + Model 모델 + % of all commits 전체 커밋의 % + Lines +/− 줄 +/− + @{login}: {prs} PRs, {commits} commits, +{added} / −{deleted} lines (Δ {delta}), +{bin_added} / −{bin_deleted} binary assets, {first} – {last} @{login}: PR {prs}개, 커밋 {commits}개, 줄 +{added} / −{deleted} (Δ {delta}), 바이너리 자산 +{bin_added} / −{bin_deleted}, {first} – {last} + None of those files can be made into a PDF; use PDFs, images or .txt files 이 파일들은 어느 것도 PDF로 만들 수 없습니다. PDF, 이미지 또는 .txt 파일을 사용하세요 + About 정보 + Contributors 기여자 + Models 모델 + Only continue if you trust this document. An address can carry information from the document, such as what you typed into its form. 이 문서를 신뢰하는 경우에만 계속하세요. 주소에는 양식에 입력한 내용처럼 문서의 정보가 담길 수 있습니다. + Print single-sided. Keep the sheets in order, cut at the marks, then stack the piles left to right, top to bottom. 단면으로 인쇄하세요. 용지 순서를 유지하고 표시선에서 자른 다음, 더미를 왼쪽에서 오른쪽으로, 위에서 아래로 쌓으세요. +comment menu Edit 편집 + Undo {action} {action} 실행 취소 + Redo {action} {action} 다시 실행 +signature pad Type 입력 +action wizard Start 시작 +calendar date January 1월 +calendar date February 2월 +calendar date March 3월 +calendar date April 4월 +calendar date May 5월 +calendar date June 6월 +calendar date July 7월 +calendar date August 8월 +calendar date September 9월 +calendar date October 10월 +calendar date November 11월 +calendar date December 12월 + Reopen the files that were open when PdfCraft last closed PdfCraft를 마지막으로 닫을 때 열려 있던 파일 다시 열기 + Clear Recent Files 최근 파일 목록 지우기 + Remove from Recent 최근 항목에서 제거 + Remove {name} from Recent 최근 항목에서 {name} 제거 + Inserted text 삽입 텍스트 + Add {what} {what} 추가 + Use {what} {what} 사용 + Place saved {what} 저장된 {what} 배치 + Remove saved {what} 저장된 {what} 제거 + A link 링크 + A button 단추 + A script 스크립트 + {who} in this document tried to open an address PdfCraft won't open: {e}. 이 문서의 {who}이(가) PdfCraft가 열지 않는 주소를 열려고 했습니다: {e}. + {who} in this document tried to open an address PdfCraft won't open: {e}. Only web (http, https) and email (mailto) links open from documents. 이 문서의 {who}이(가) PdfCraft가 열지 않는 주소를 열려고 했습니다: {e}. 문서에서는 웹(http, https) 및 이메일(mailto) 링크만 열립니다. + Another file dialog is still open. Finish with it first. 다른 파일 대화 상자가 아직 열려 있습니다. 먼저 그 대화 상자를 마치세요. + Couldn't show the file picker. Please try again. 파일 선택 창을 표시할 수 없습니다. 다시 시도해 주세요. + The document changed while you were choosing a file, so nothing was changed. 파일을 선택하는 동안 문서가 변경되어 아무것도 변경되지 않았습니다. + The document was closed before it could be saved. 문서가 저장되기 전에 닫혔습니다. + The pages were extracted but not deleted, because the document changed while you were choosing a folder. 폴더를 선택하는 동안 문서가 변경되어 페이지가 추출되었지만 삭제되지는 않았습니다. + That didn't work: an internal error stopped it ({m}). 실패했습니다: 내부 오류로 중단되었습니다({m}). + The Windows store's digital IDs couldn't be listed: {e} Windows 저장소의 디지털 ID를 나열할 수 없습니다: {e} + Align fields 필드 정렬 + Distribute fields 필드 분배 + Match field sizes 필드 크기 맞춤 + Mark for redaction 검열 표시 + Mark pages for redaction 페이지 검열 표시 + Change document properties 문서 속성 변경 + Mark differences 차이점 표시 + Run form script 양식 스크립트 실행 + Scripted content must be usable with a keyboard and assistive technology. Check the document's scripts. 스크립트로 만든 콘텐츠는 키보드와 보조 기술로 사용할 수 있어야 합니다. 문서의 스크립트를 확인하세요. + Table rows belong directly in a table or its head, body or foot. Fix the table's tags. 표 행은 표 또는 표의 머리글, 본문, 바닥글에 직접 속해야 합니다. 표 태그를 수정하세요. + Basic constraints 기본 제약 조건 + Certificate authority 인증 기관 + End entity 최종 엔터티 + SHA-1 digest SHA-1 다이제스트 + SHA-256 digest SHA-256 다이제스트 + Squiggly 물결선 + Home / End Home / End + H / Space (hold) H / 스페이스 (누르고 있기) + Rotation: 회전: + Line ending 선 끝 + Open arrow 열린 화살표 + Closed arrow 닫힌 화살표 + Butt 직선 끝 + Reverse open arrow 역방향 열린 화살표 + Reverse closed arrow 역방향 닫힌 화살표 + Slash 사선 + The PDF text fonts can't draw “{c}” ({code}). Choose supported text. PDF 텍스트 글꼴이 “{c}”({code})를 그릴 수 없습니다. 지원되는 텍스트를 선택하세요. + The standard fonts can't draw “{c}” ({code}). Only Western European characters can be added as text for now. 표준 글꼴이 “{c}”({code})를 그릴 수 없습니다. 현재는 서유럽 문자만 텍스트로 추가할 수 있습니다. + This field's font can't draw “{c}” ({code}), so PdfCraft shows ? in its place. The value is saved, and other PDF viewers redraw the field from it. 이 필드의 글꼴은 “{c}”({code})를 그릴 수 없어 PdfCraft가 그 자리에 ?를 표시합니다. 값은 저장되며 다른 PDF 뷰어에서 이를 기준으로 필드를 다시 그립니다. + The fonts PdfCraft writes with can't draw “{c}” ({code}), so it shows as ? in every PDF viewer. The text is saved. PdfCraft가 사용하는 글꼴은 “{c}”({code})를 그릴 수 없어 모든 PDF 뷰어에서 ?로 표시됩니다. 텍스트는 저장됩니다. + Larger pages 더 큰 페이지 + Smaller pages 더 작은 페이지 + Reset page size 페이지 크기 재설정 + Flatten Fill & Sign when saving 저장할 때 채우기 및 서명 병합 + Text, marks and signatures become part of the page. Other comments stay editable. 텍스트, 표시 및 서명이 페이지의 일부가 됩니다. 다른 주석은 계속 편집할 수 있습니다. + Date format 날짜 형식 + Fill & Sign dates 채우기 및 서명 날짜 + Pattern 패턴 + Today: {date} 오늘: {date} + yyyy or yy year · m or mm month · mmm or mmmm month name · d or dd day · ddd or dddd weekday. H, h, M, s and t are time letters and can't be used on their own: put {escape} before a letter to show it as is. yyyy 또는 yy는 연도 · m 또는 mm은 월 · mmm 또는 mmmm은 월 이름 · d 또는 dd는 일 · ddd 또는 dddd는 요일입니다. H, h, M, s, t는 시간 문자이므로 단독으로 사용할 수 없습니다. 문자를 그대로 표시하려면 앞에 {escape}를 붙이세요. + Same as interface ({language}) 인터페이스와 동일({language}) + {chars} can't be written into the PDF yet: Fill & Sign text is Western European only. Pick a numeric format such as dd.mm.yyyy. {chars}은(는) 아직 PDF에 쓸 수 없습니다. 채우기 및 서명 텍스트는 서유럽 문자만 지원합니다. dd.mm.yyyy 같은 숫자 형식을 선택하세요. + Opens the printer driver's preferences. They are saved for every print from this computer; the copies, two-sided, grayscale and paper chosen here still apply. 프린터 드라이버 기본 설정을 엽니다. 이 설정은 이 컴퓨터에서 인쇄할 때마다 저장되어 사용되며, 여기서 선택한 복사 매수, 양면, 회색조 및 용지도 계속 적용됩니다. + The printer driver's own settings for this print: paper tray, paper type, finishing and more. 이번 인쇄의 프린터 드라이버 자체 설정: 용지함, 용지 종류, 마감 처리 등. + Couldn't open the printer's preferences: {e} 프린터 기본 설정을 열 수 없습니다: {e} + Printer properties 프린터 속성 + Reset to printer defaults 프린터 기본값으로 재설정 + This printer offers no settings of its own. 이 프린터에는 자체 설정이 없습니다. + Margins 여백 + For page sizes and margins. 페이지 크기 및 여백에 사용됩니다. +certificate Subject 주체 + Scroll tabs left 탭 왼쪽으로 스크롤 + Scroll tabs right 탭 오른쪽으로 스크롤 + Shared Field Properties 공유 필드 속성 + {n} fields selected 필드 {n}개 선택됨 + Mixed 혼합 + Custom font 사용자 지정 글꼴 + Only checked properties will change. Mixed means the selected fields have different values. 체크한 속성만 변경됩니다. '혼합'은 선택한 필드가 서로 다른 값을 가진다는 뜻입니다. + Shift- or Ctrl/Command-click to select several fields. Shift 키 또는 Ctrl/Command 키를 누른 채 클릭하면 여러 필드를 선택할 수 있습니다. + Font size 0 uses automatic sizing. 글꼴 크기 0은 자동 크기 조정을 사용합니다. + Character limit: 문자 제한: + Character limit 0 means no limit. A comb of characters needs a limit. 문자 제한 0은 제한이 없다는 뜻입니다. 문자 빗살에는 제한이 필요합니다. + To change locked fields, also set Locked to No. 잠긴 필드를 변경하려면 잠금도 '아니요'로 설정하세요. + Comb of characters 문자 빗살 + The document changed while you were editing field properties. 필드 속성을 편집하는 동안 문서가 변경되었습니다. + The document is no longer open. 문서가 더 이상 열려 있지 않습니다. + The field properties dialog is no longer open. 필드 속성 대화 상자가 더 이상 열려 있지 않습니다. + The field properties could not be changed. 필드 속성을 변경할 수 없습니다. + The selected fields could not be found. Select them again. 선택한 필드를 찾을 수 없습니다. 다시 선택하세요. + The field {name} no longer exists. {name} 필드가 더 이상 존재하지 않습니다. + A selected field has no widget on any page, so the fields can't be edited together. 선택한 필드 중 하나가 어느 페이지에도 위젯이 없어 필드를 함께 편집할 수 없습니다. + ({n} at {dpi} dpi, the largest size they can be drawn at) ({n}, {dpi}dpi, 그릴 수 있는 최대 크기) +@plural {n} object selected|{n} objects selected 개체 {n}개 선택됨 + Drag the selection to move it. Esc clears the selection. 선택 영역을 끌어 이동하세요. Esc 키를 누르면 선택이 해제됩니다. + Shift-click to select several objects. Drag empty space to select an area. Shift 키를 누른 채 클릭하면 여러 개체를 선택할 수 있습니다. 빈 곳을 끌면 영역을 선택합니다. + Select at most 1000 objects at a time. 한 번에 최대 1000개 개체를 선택하세요. + Finish or discard the text being edited before selecting several objects. 여러 개체를 선택하기 전에 편집 중인 텍스트를 완료하거나 취소하세요. + Move object 개체 이동 + Move objects 개체 여러 개 이동 + Vertical text cannot be moved with this selection. 세로 텍스트는 이 선택 항목과 함께 이동할 수 없습니다. + Text used as a clipping path cannot be moved with this selection. 클리핑 경로로 사용되는 텍스트는 이 선택 항목과 함께 이동할 수 없습니다. + These objects could not be moved. Select them again and try a smaller move. 이 개체를 이동할 수 없습니다. 다시 선택한 뒤 더 짧은 거리로 옮겨 보세요. + This page contains objects that cannot be selected together. 이 페이지에는 함께 선택할 수 없는 개체가 있습니다. + Fill colour 채우기 색상 + No fill 채우기 없음 + Fill colour: none 채우기 색상: 없음 +key Ctrl Ctrl +key Shift Shift +key Delete Delete +key Esc Esc +key Home Home +key End End +key Space 스페이스 + Grid view 격자 보기 + List view 목록 보기 + Files are combined in the order shown. Drag them to change it. 파일은 표시된 순서대로 결합됩니다. 끌어서 순서를 바꾸세요. + Preview unavailable: {e} 미리 보기를 사용할 수 없습니다: {e} + Pages: {k} of {n} 페이지: {n}개 중 {k}개 + Check the pages 페이지 확인 + Switch to List view to change the pages it takes. 가져올 페이지를 바꾸려면 목록 보기로 전환하세요. + Expand all 모두 펼치기 + Collapse all 모두 접기 + Remove page 페이지 제거 + Remove {n} pages 페이지 {n}개 제거 + Reset panel layout 패널 레이아웃 재설정 + Float panel 패널 띄우기 + Move to group 그룹으로 이동 + Panels 패널 + Resize panels 패널 크기 조정 + Resize panel window 패널 창 크기 조정 + PDF page: {size} PDF 페이지: {size} + Match page at 100% 100% 배율로 페이지에 맞춤 + PDF scale: {scale}% PDF 배율: {scale}% + Printer paper and scaling may differ. Check driver settings. 프린터 용지와 배율이 다를 수 있습니다. 드라이버 설정을 확인하세요. + Drawing scale changes. Use Actual size for full-scale plans. 도면 축척이 변경됩니다. 실제 크기 도면에는 '실제 크기'를 사용하세요. + Reload documents when their files change on disk 파일이 디스크에서 변경되면 문서 다시 불러오기 + This file changed on disk. Reload it to see the new version; your unsaved changes will be lost. 이 파일이 디스크에서 변경되었습니다. 새 버전을 보려면 다시 불러오세요. 저장하지 않은 변경 내용은 손실됩니다. + Reload 다시 불러오기 + Couldn't reload {name}: {e} {name}을(를) 다시 불러올 수 없습니다: {e} + Select page {label} {label} 페이지 선택 + Rotate page {label} counterclockwise {label} 페이지 반시계 방향으로 회전 + Rotate page {label} clockwise {label} 페이지 시계 방향으로 회전 + Delete page {label} {label} 페이지 삭제 + Mouse wheel scroll speed 마우스 휠 스크롤 속도 +scroll speed Slow 느리게 +scroll speed Normal 보통 +scroll speed Fast 빠르게 + Animation effects 애니메이션 효과 +animation effects On 켜기 +animation effects Off 끄기 + Enhance camera image 카메라 이미지 개선 + Drag the corners onto the document's edges, then choose Enhance page. 모서리를 문서 가장자리에 끌어 놓은 다음 페이지 개선을 선택하세요. + Enhance page 페이지 개선 + Done adding text 텍스트 추가 완료 + Discard this text (Esc) 이 텍스트 취소 (Esc) + Clean-up 정리 + Original 원본 + Greyscale 회색조 + Black and white 흑백 + Reading colours 읽기 색상 + Replace document colours 문서 색상 바꾸기 + Black on white 흰 바탕에 검은 글자 + White on black 검은 바탕에 흰 글자 + Yellow on black 검은 바탕에 노란 글자 + Green on black 검은 바탕에 초록 글자 + Page background 페이지 배경 + Only change the colour of black text or line art 검은색 텍스트 또는 선 그림의 색상만 변경 + Change the colour of line art as well as text 텍스트뿐 아니라 선 그림의 색상도 변경 + Colours are remapped while rendering; the document itself never changes. 색상은 렌더링할 때 다시 매핑되며 문서 자체는 절대 변경되지 않습니다. + This printer's driver doesn't take two-sided settings from other programs, so its own setting applies. Change it in Properties… 이 프린터의 드라이버는 다른 프로그램의 양면 인쇄 설정을 받지 않으므로 자체 설정이 적용됩니다. 변경하려면 속성… + Browser's print dialog 브라우저 인쇄 대화 상자 + Copies, two-sided printing and colour are chosen in the browser's print dialog. 복사 매수, 양면 인쇄 및 색상은 브라우저의 인쇄 대화 상자에서 선택합니다. + Preparing {n} sheets for printing… 인쇄할 용지 {n}장 준비 중… + Preparing sheet {done} of {total} for printing… 인쇄할 용지 {total}장 중 {done}장 준비 중… + Opening the browser's print dialog… 브라우저의 인쇄 대화 상자를 여는 중… + Couldn't print from the browser ({e}); downloaded {name} to print instead 브라우저에서 인쇄할 수 없습니다({e}). 대신 인쇄용으로 {name}을(를) 내려받았습니다 + Tools panel side 도구 패널 위치 + Add comment 주석 추가 + Change tag properties 태그 속성 변경 + Tags panel 태그 패널 + Tags 태그 + Tag type 태그 유형 + Actual text 실제 텍스트 + Find a tag 태그 찾기 + Collapse tag 태그 접기 + Expand tag 태그 펼치기 + Revert changes 변경 내용 되돌리기 + Save tag properties 태그 속성 저장 + This document has no editable structure tags. 이 문서에는 편집 가능한 구조 태그가 없습니다. + {n} tags 태그 {n}개 + Save or revert changes before selecting another tag. 다른 태그를 선택하기 전에 변경 내용을 저장하거나 되돌리세요. + Left out: {names} 제외: {names} + already a PDF 이미 PDF임 + no unused output name 사용 가능한 출력 파일 이름 없음 + no output folder was chosen 출력 폴더가 선택되지 않음 +@plural Downloaded {n} PDF|Downloaded {n} PDFs PDF {n}개 내려받음 + Scan 스캔 + Sign a sheet of white paper and take a photo of it in bright, even light (use the flash). Choose the photo or drop it here: PdfCraft finds the signature and removes the paper. 흰 종이에 서명한 뒤 밝고 고른 조명에서 사진을 찍으세요(플래시 사용). 사진을 선택하거나 여기로 끌어다 놓으세요. PdfCraft가 서명을 찾아 종이를 제거합니다. + Choose photo… 사진 선택… + No photo chosen 사진이 선택되지 않았습니다 + Photo 사진 + Ink sensitivity 잉크 민감도 + No signature was found in the frame. Move the frame over the signature or raise the ink sensitivity. 프레임 안에서 서명을 찾지 못했습니다. 프레임을 서명 위로 옮기거나 잉크 민감도를 높이세요. + Couldn't use the photo: {e} 사진을 사용할 수 없습니다: {e} + Close Tab 탭 닫기 + Reopen Closed Tab 닫은 탭 다시 열기 + Reveal in Finder Finder에서 보기 + Reveal in File Explorer 파일 탐색기에서 보기 + Other colour… 다른 색상… + Recent colours 최근 사용한 색상 + Couldn't follow linked PDF: {reason} 연결된 PDF를 열 수 없습니다: {reason} + The linked PDF opened, but its named destination was not applied. 연결된 PDF가 열렸지만 이름이 지정된 대상이 적용되지 않았습니다. + The linked PDF opened, but its page destination was out of range. 연결된 PDF가 열렸지만 페이지 대상이 범위를 벗어났습니다. + Local cross-PDF links require the desktop app PDF 간 로컬 링크에는 데스크톱 앱이 필요합니다 + Paste 붙여넣기 + Select all 모두 선택 + Next 다음 + Previous 이전 + Choose… 선택… + Refresh 새로 고침 + Loading… 불러오는 중… + Save changes? 변경 내용을 저장할까요? + Page {n} {n}페이지 + of / + Comment 주석 + Font 글꼴 + Color 색상 + Theme 테마 + System 시스템 + Save file 파일 저장 + Import 가져오기 + Help… 도움말… + Automatically 자동 + Never 안 함 + Always 항상 + On 켜짐 + Enabled 사용 + Disabled 사용 안 함 + Error 오류 + Warning 경고 + Information 정보 + Success 성공 + Folder 폴더 + Choose a file… 파일 선택… + Choose a folder… 폴더 선택… + Open folder 폴더 열기 + Create folder 폴더 만들기 + Duplicate 복제 + Move 이동 + Copy to clipboard 클립보드에 복사 + Copied to clipboard 클립보드에 복사됨 + Organize 구성 + Comment and review 주석 및 검토 + Search results 검색 결과 + No results 결과 없음 + Page {n} of {total} {n}/{total}페이지 + Tools 도구 + Inspector 검사기 + on page {label} {label}페이지 + A font isn't embedded 글꼴이 포함되어 있지 않습니다 + A {} action isn't allowed {} 동작은 허용되지 않습니다 + A {} annotation has additional actions {} 주석에 추가 동작이 있습니다 + A {} annotation has no appearance stream {} 주석에 모양 스트림이 없습니다 + A {} annotation isn't set to print, or is hidden {} 주석이 인쇄되지 않도록 설정되었거나 숨겨져 있습니다 + Accessibility Report 접근성 보고서 + Add the PDFs to combine 결합할 PDF를 추가하세요 + Added the first {n} PDFs in {folder} {folder}의 처음 {n}개 PDF를 추가했습니다 + CRL Signing CRL 서명 + Certificate Signing 인증서 서명 + Change Author 작성자 변경 + Change Keywords 키워드 변경 + Change Subject 주제 변경 + Change Title 제목 변경 + Choose a digital ID. 디지털 ID를 선택하세요. + Create links 링크 만들기 + Creator 작성 프로그램 + Cut and stack needs Two-sided: Off. Print single-sided sheets. 잘라서 쌓기는 양면 인쇄를 꺼야 합니다. 단면 용지로 인쇄하세요. + Data Encipherment 데이터 암호화 + Decipher Only 복호화만 + Detailed Report 상세 보고서 + DeviceCMYK is used, but the PDF/A output intent isn't a CMYK profile DeviceCMYK를 사용하지만 PDF/A 출력 인텐트가 CMYK 프로필이 아닙니다 + DeviceRGB is used, but the PDF/A output intent isn't an RGB profile DeviceRGB를 사용하지만 PDF/A 출력 인텐트가 RGB 프로필이 아닙니다 + Digital Signature 디지털 서명 + Document properties (⌘D) 문서 속성 (⌘D) + Drop PDFs or folders here, or choose them. PDF 또는 폴더를 여기에 놓거나 직접 선택하세요. + Encipher Only 암호화만 + English 영어 + Enter a URL URL을 입력하세요 + Enter a name. 이름을 입력하세요. + Enter a page number 페이지 번호를 입력하세요 + Enter the field names 필드 이름을 입력하세요 + Every PDF in the folder 폴더의 모든 PDF + Every PDF in the folder and the folders inside it 폴더와 그 안의 폴더에 있는 모든 PDF + Field "{}" on page {p} has no description (tooltip) {p}페이지의 필드 "{}"에 설명(도구 설명)이 없습니다 + Filename 파일 이름 + Flatten Fill & Sign 채우기 및 서명 병합 + Font (unnamed) on page {p} doesn't map its characters to Unicode {p}페이지의 글꼴(이름 없음)이 문자를 유니코드에 매핑하지 않습니다 + Font {} on page {p} doesn't map its characters to Unicode {p}페이지의 글꼴 {}이(가) 문자를 유니코드에 매핑하지 않습니다 + Form field on page {p} isn't tagged {p}페이지의 양식 필드에 태그가 없습니다 + H{n} follows an H{d}; headings should not skip levels H{n}이(가) H{d} 뒤에 옵니다. 제목 수준을 건너뛰면 안 됩니다 + Key Agreement 키 합의 + Key Encipherment 키 암호화 + New bookmark (⌘B) 새 책갈피 (⌘B) + Next (⌘G) 다음 (⌘G) + No PDFs found in {folder} {folder}에서 PDF를 찾을 수 없습니다 + No document language is set 문서 언어가 설정되지 않았습니다 + No page has text: the document appears to be images of pages 텍스트가 있는 페이지가 없습니다. 문서가 페이지 이미지로 보입니다 + Non-Repudiation 부인 방지 + Only the document's owner can change its security (open it with the permissions password) 문서 소유자만 보안을 변경할 수 있습니다(권한 암호로 여세요) + Open a PDF (⌘O) PDF 열기 (⌘O) + Page {p} doesn't tab in structure order {p}페이지가 구조 순서대로 탭 이동되지 않습니다 + Page {p}: {n} untagged content item {p}페이지: 태그 없는 콘텐츠 항목 {n}개 + Page {p}: {n} untagged content items {p}페이지: 태그 없는 콘텐츠 항목 {n}개 + Page {} has additional actions {}페이지에 추가 동작이 있습니다 + Panel layout could not be restored: {error} 패널 레이아웃을 복원할 수 없습니다: {error} + Panel move was not applied: {error} 패널 이동이 적용되지 않았습니다: {error} + PdfCraft can't check this signature yet: {}. PdfCraft에서 아직 이 서명을 확인할 수 없습니다: {}. + Previous (⇧⌘G) 이전 (⇧⌘G) + Print (⌘P) 인쇄 (⌘P) + Producer 변환 프로그램 + Rendering… 렌더링 중… + Report created 보고서가 만들어졌습니다 + Rev. {rev}: Certified by an unknown signer 개정 {rev}: 알 수 없는 서명자가 인증함 + Rev. {rev}: Certified by {name} 개정 {rev}: {name}이(가) 인증함 + Rev. {rev}: Signed by an unknown signer 개정 {rev}: 알 수 없는 서명자가 서명함 + Rev. {rev}: Signed by {name} 개정 {rev}: {name}이(가) 서명함 + Rotate view clockwise (⇧⌘+) 보기를 시계 방향으로 회전 (⇧⌘+) + Rule Name 규칙 이름 + Save (M4) 저장 (M4) + Save as {level} {level}(으)로 저장 + Signature is invalid 서명이 유효하지 않습니다 + Signature is valid 서명이 유효합니다 + Signature validity is unknown 서명의 유효성을 알 수 없습니다 + Signing time is from the clock on the signer's computer. 서명 시간은 서명자 컴퓨터의 시계를 따른 것입니다. + Still rendering — this page is unusually complex… 아직 렌더링 중입니다. 이 페이지는 이례적으로 복잡합니다… + The ECDSA signature is not in canonical DER (trailing bytes, padding or a missing sign byte); it was read anyway. ECDSA 서명이 표준 DER 형식이 아닙니다(후행 바이트, 패딩 또는 부호 바이트 누락). 그래도 읽었습니다. + The ECDSA signature is the raw r and s values instead of a DER sequence; it was read anyway. ECDSA 서명이 DER 시퀀스가 아니라 원시 r 및 s 값입니다. 그래도 읽었습니다. + The RSA signature value does not have the length of the key's modulus (leading zero bytes dropped or added); it was read anyway. RSA 서명 값의 길이가 키 모듈러스의 길이와 다릅니다(앞쪽 0 바이트가 제거되었거나 추가됨). 그래도 읽었습니다. + The RSA signature's DigestInfo has no NULL parameter (older signers write it so); it was read anyway. RSA 서명의 DigestInfo에 NULL 매개변수가 없습니다(오래된 서명자는 이렇게 기록합니다). 그래도 읽었습니다. + The certificate of {} does not allow this many CA certificates below it (path length), so it is not used to vouch for {}. {}의 인증서는 그 아래에 이만큼의 CA 인증서를 허용하지 않으므로(경로 길이) {}을(를) 보증하는 데 사용되지 않습니다. + The certificate of {} is not a CA certificate that may issue certificates, so it is not used to vouch for {}. {}의 인증서는 인증서를 발급할 수 있는 CA 인증서가 아니므로 {}을(를) 보증하는 데 사용되지 않습니다. + The certificate of {} was not valid at the time of signing, so it is not used to vouch for {}. {}의 인증서는 서명 당시 유효하지 않았으므로 {}을(를) 보증하는 데 사용되지 않습니다. + The checker found problems which may prevent the document from being fully accessible. 검사에서 문서를 완전히 접근 가능하게 만드는 데 방해가 될 수 있는 문제가 발견되었습니다. + The document has been altered or corrupted since the signature was applied. 서명이 적용된 이후 문서가 변경되었거나 손상되었습니다. + The document has been altered or corrupted since the timestamp was applied. 타임스탬프가 적용된 이후 문서가 변경되었거나 손상되었습니다. + The document has been altered since this signature was applied in ways it does not permit ({}). 이 서명이 적용된 이후 허용되지 않는 방식으로 문서가 변경되었습니다({}). + The document has been altered since this timestamp was applied in ways it does not permit ({}). 이 타임스탬프가 적용된 이후 허용되지 않는 방식으로 문서가 변경되었습니다({}). + The document has been modified since this signature was applied, but the changes are permitted ({}). 이 서명이 적용된 이후 문서가 수정되었지만 변경 내용은 허용됩니다({}). + The document has been modified since this timestamp was applied, but the changes are permitted ({}). 이 타임스탬프가 적용된 이후 문서가 수정되었지만 변경 내용은 허용됩니다({}). + The document has no tags (structure tree) 문서에 태그(구조 트리)가 없습니다 + The document has no title 문서에 제목이 없습니다 + The document isn't marked as tagged (MarkInfo Marked) 문서가 태그된 문서로 표시되어 있지 않습니다(MarkInfo Marked) + The document isn't tagged, so none of its content is 문서가 태그되어 있지 않으므로 콘텐츠도 태그되어 있지 않습니다 + The document's embedded revocation information shows that the signer's certificate has not been revoked. 문서에 포함된 해지 정보에 따르면 서명자의 인증서는 해지되지 않았습니다. + The embedded timestamp token is valid and its authority is trusted; trusted time is {}. 포함된 타임스탬프 토큰이 유효하며 해당 기관을 신뢰할 수 있습니다. 신뢰할 수 있는 시간은 {}입니다. + The font {} isn't embedded 글꼴 {}이(가) 포함되어 있지 않습니다 + The metadata doesn't identify the file as {} 메타데이터가 파일을 {}(으)로 식별하지 않습니다 + The password is incorrect. 암호가 올바르지 않습니다. + The password must have at least 6 characters. 암호는 6자 이상이어야 합니다. + The passwords do not match. 암호가 일치하지 않습니다. + The security settings don't allow screen readers to read the text 보안 설정에서 화면 낭독기가 텍스트를 읽는 것을 허용하지 않습니다 + The signature algorithm and the SignerInfo's digest algorithm name different hashes; the signature was made with the SignerInfo's. 서명 알고리즘과 SignerInfo의 다이제스트 알고리즘이 서로 다른 해시를 가리킵니다. 서명은 SignerInfo의 해시로 만들어졌습니다. + The signature carries an unverified timestamp ({}): the timestamp authority is not in your list of trusted certificates, so the signing time claimed by the signer is used instead. 서명에 확인되지 않은 타임스탬프({})가 있습니다. 타임스탬프 기관이 신뢰할 수 있는 인증서 목록에 없으므로 서명자가 주장하는 서명 시간을 대신 사용합니다. + The signature contents are not hexadecimal. 서명 내용이 16진수가 아닙니다. + The signature could not be checked ({}). 서명을 검사할 수 없습니다({}). + The signature could not be read ({}). 서명을 읽을 수 없습니다({}). + The signature could not be verified ({}). 서명을 확인할 수 없습니다({}). + The signature has no valid byte range. 서명에 유효한 바이트 범위가 없습니다. + The signature includes an embedded timestamp. 서명에 포함된 타임스탬프가 있습니다. + The signature is BER-encoded (indefinite lengths) rather than DER; it was read leniently. 서명이 DER이 아니라 BER로 인코딩되어 있습니다(길이 미정). 관대하게 읽었습니다. + The signature uses the legacy adbe.x509.rsa_sha1 format. 서명이 레거시 adbe.x509.rsa_sha1 형식을 사용합니다. + The signature value does not match the signer's certificate: the signature is corrupt. 서명 값이 서명자의 인증서와 일치하지 않습니다. 서명이 손상되었습니다. + The signature's byte range does not exclude exactly its contents. 서명의 바이트 범위가 서명 내용만 정확히 제외하지 않습니다. + The signature's byte range does not match the file. 서명의 바이트 범위가 파일과 일치하지 않습니다. + The signature's timestamp token could not be verified ({}). 서명의 타임스탬프 토큰을 확인할 수 없습니다({}). + The signature's timestamp token does not cover the signature value. 서명의 타임스탬프 토큰이 서명 값을 포함하지 않습니다. + The signed content is a constructed (segmented) OCTET STRING, as BER allows; it was read anyway. 서명된 콘텐츠가 BER에서 허용하는 구성된(분할된) OCTET STRING입니다. 그래도 읽었습니다. + The signer's certificate does not allow digital signatures (its key usage has neither digital signature nor non-repudiation). 서명자의 인증서가 디지털 서명을 허용하지 않습니다(키 용도에 디지털 서명도 부인 방지도 없음). + The signer's certificate has been revoked ({}). 서명자의 인증서가 해지되었습니다({}). + The signer's certificate has critical extensions PdfCraft does not recognize ({}). 서명자의 인증서에 PdfCraft가 인식하지 못하는 중요 확장이 있습니다({}). + The signer's certificate is not in the signature. 서명자의 인증서가 서명에 없습니다. + The signer's certificate is not issued for signing documents (its extended key usage has no document-signing purpose). 서명자의 인증서가 문서 서명용으로 발급되지 않았습니다(확장 키 용도에 문서 서명 목적이 없음). + The signer's certificate was not valid at the time of signing. 서명자의 인증서는 서명 당시 유효하지 않았습니다. + The signer's identity is unknown because it has not been included in your list of trusted certificates and none of its parent certificates are trusted certificates. 서명자의 신원은 신뢰할 수 있는 인증서 목록에 포함되어 있지 않고 상위 인증서도 신뢰할 수 있는 인증서가 아니므로 알 수 없습니다. + The signer's identity is valid. 서명자의 신원이 유효합니다. + The timestamp authority's certificate was not valid at the time of timestamping. 타임스탬프 기관의 인증서는 타임스탬프 시점에 유효하지 않았습니다. + The timestamp contents are not hexadecimal. 타임스탬프 내용이 16진수가 아닙니다. + The timestamp has no valid byte range. 타임스탬프에 유효한 바이트 범위가 없습니다. + The timestamp token could not be read ({}). 타임스탬프 토큰을 읽을 수 없습니다({}). + The timestamp token is valid and its authority is trusted. 타임스탬프 토큰이 유효하며 해당 기관을 신뢰할 수 있습니다. + The timestamp token is valid, but the timestamp authority is not in your list of trusted certificates. 타임스탬프 토큰은 유효하지만 타임스탬프 기관이 신뢰할 수 있는 인증서 목록에 없습니다. + The timestamp's byte range does not exclude exactly its contents. 타임스탬프의 바이트 범위가 타임스탬프 내용만 정확히 제외하지 않습니다. + The timestamp's byte range does not match the file. 타임스탬프의 바이트 범위가 파일과 일치하지 않습니다. + The window shows the file name, not the title (Initial View > Show) 창에 제목이 아니라 파일 이름이 표시됩니다(초기 보기 > 표시) + There is no folder to save the digital ID in. 디지털 ID를 저장할 폴더가 없습니다. + This document has not been modified since this signature was applied. 이 서명이 적용된 이후 이 문서는 수정되지 않았습니다. + This document has not been modified since this timestamp was applied. 이 타임스탬프가 적용된 이후 이 문서는 수정되지 않았습니다. + This signature uses RIPEMD-160, a legacy 160-bit hash algorithm that is no longer recommended for signatures. It still validates, but it should not be relied on. 이 서명은 서명용으로 더 이상 권장되지 않는 레거시 160비트 해시 알고리즘인 RIPEMD-160을 사용합니다. 여전히 검증되지만 의존해서는 안 됩니다. + This signature uses SHA-1, a weak hash algorithm: collisions in it have been demonstrated. It still validates because many documents signed years ago use it, but it should not be relied on. 이 서명은 약한 해시 알고리즘인 SHA-1을 사용합니다. 충돌이 실제로 입증되었습니다. 오래전에 서명된 많은 문서가 사용하므로 여전히 검증되지만 의존해서는 안 됩니다. + Unsigned signature field 서명되지 않은 서명 필드 + Unsigned signature field: {name} 서명되지 않은 서명 필드: {name} + Zoom in (⌘+) 확대 (⌘+) + Zoom in / out (also pinch or ⌘-scroll) 확대/축소 (핀치 또는 ⌘-스크롤도 가능) + Zoom out (⌘−) 축소 (⌘−) + alternate text hides an annotation inside it 대체 텍스트가 그 안의 주석을 가립니다 + alternate text on an element with no page content 페이지 콘텐츠가 없는 요소의 대체 텍스트 + comments 주석 + document security store 문서 보안 저장소 + document structure 문서 구조 + form fill 양식 채우기 + its alternate text is inside another element's and will never be read 대체 텍스트가 다른 요소의 대체 텍스트 안에 있어 읽히지 않습니다 + links 링크 + metadata 메타데이터 + no alternate text 대체 텍스트 없음 + no header cells (TH) 헤더 셀(TH) 없음 + no summary 요약 없음 + not in a TR TR 안에 없음 + not in a Table, THead, TBody or TFoot Table, THead, TBody 또는 TFoot 안에 없음 + not in an L (list) L(목록) 안에 없음 + not in an LI (list item) LI(목록 항목) 안에 없음 + other changes 기타 변경 + page content 페이지 콘텐츠 + page {n} is out of range (1–{count}) {n}페이지가 범위를 벗어났습니다(1–{count}) + pages added or removed 추가되거나 삭제된 페이지 + rows have between {min} and {max} columns 행의 열 수가 {min}~{max}개입니다 + the first heading is an H{n}; headings should not skip levels 첫 제목이 H{n}입니다. 제목 수준을 건너뛰면 안 됩니다 + the signed version could not be read 서명된 버전을 읽을 수 없습니다 + {n} pages and no bookmarks {n}페이지, 책갈피 없음 + {page} is not a page number or label {page}은(는) 페이지 번호나 레이블이 아닙니다 + {ty} element on page {p}: {what} {p}페이지의 {ty} 요소: {what} + {ty} element: {what} {ty} 요소: {what} + {who}, certificate issued by an unknown issuer. {who}, 알 수 없는 발급자가 발급한 인증서입니다. + {who}, certificate issued by {issuer}. {who}, {issuer}이(가) 발급한 인증서입니다. + {} annotation on page {p} isn't tagged {p}페이지의 {} 주석에 태그가 없습니다 + {} annotations aren't allowed {} 주석은 허용되지 않습니다 + … and {n} more … 외 {n}개 +@plural Delete {n} field|Delete {n} fields 필드 {n}개 삭제 +@plural {n} byte|{n} bytes {n}바이트 +@plural {n} image optimized|{n} images optimized 이미지 {n}개 최적화됨 +@plural {n} item discarded|{n} items discarded 항목 {n}개 삭제됨 +@plural {n} pixel|{n} pixels {n}픽셀 + Text recognition isn't installed: its models are missing (run `cargo xtask models`, or set PDFCRAFT_MODELS). 텍스트 인식이 설치되어 있지 않습니다. 모델이 없습니다(`cargo xtask models`를 실행하거나 PDFCRAFT_MODELS를 설정하세요). +calendar weekday Su 일 +calendar weekday Mo 월 +calendar weekday Tu 화 +calendar weekday We 수 +calendar weekday Th 목 +calendar weekday Fr 금 +calendar weekday Sa 토 +certificate Issued to 발급 대상 +certificate Issued by 발급자 +certificate Valid from 유효 시작일 +certificate Valid to 유효 종료일 +certificate Intended usage 사용 목적 +certificate Version 버전 +certificate Serial number 일련 번호 +certificate Issuer 발급자 +certificate Validity starts 유효 기간 시작 +certificate Validity ends 유효 기간 종료 +certificate Public key 공개 키 +certificate Basic constraints 기본 제약 조건 +certificate Key usage 키 용도 +certificate Self-signed 자체 서명됨 +certificate SHA-1 digest SHA-1 다이제스트 +certificate SHA-256 digest SHA-256 다이제스트 +@plural {n} file|{n} files 파일 {n}개 +@plural {n} comment|{n} comments 주석 {n}개 +@plural {n} result|{n} results 결과 {n}개 diff --git a/crates/ui-egui/src/i18n/mod.rs b/crates/ui-egui/src/i18n/mod.rs index a92a73289..8f62d8d29 100644 --- a/crates/ui-egui/src/i18n/mod.rs +++ b/crates/ui-egui/src/i18n/mod.rs @@ -147,7 +147,7 @@ fn plural_sl(n: u64) -> usize { } /// The registry. English first: it is the fallback and the source language. -pub static LANGUAGES: [LangInfo; 24] = [ +pub static LANGUAGES: [LangInfo; 26] = [ LangInfo { code: "en", name: "English", source: "", plural: plural_one_other, rtl: false, catalog: OnceLock::new() }, LangInfo { code: "ja", name: "日本語", source: include_str!("ja.tsv"), plural: plural_none, rtl: false, catalog: OnceLock::new() }, // Simplified Chinese; `zh`, `zh-CN`, `zh-SG` and `zh-Hans-*` locales resolve here (see `candidates`). @@ -213,6 +213,13 @@ pub static LANGUAGES: [LangInfo; 24] = [ // Vietnamese; every `vi-*` locale (`vi-VN`, `vi_VN.UTF-8`) resolves here. CLDR `vi` counts have // one form ("other"), so `@plural` entries list a single form. LangInfo { code: "vi", name: "Tiếng Việt", source: include_str!("vi.tsv"), plural: plural_none, rtl: false, catalog: OnceLock::new() }, + // Hindi; every `hi-*` locale (`hi-IN`, `hi_IN.UTF-8`) resolves here. CLDR `hi` has "one" + // (0 and 1) and "other", but the catalog's nouns are the same in both ("{n} पृष्ठ"), so + // `@plural` entries list a single form. + LangInfo { code: "hi", name: "हिन्दी", source: include_str!("hi.tsv"), plural: plural_none, rtl: false, catalog: OnceLock::new() }, + // Korean; every `ko-*` locale (`ko-KR`, `ko_KR.UTF-8`) resolves here. CLDR `ko` counts have + // one form ("other"), so `@plural` entries list a single form. + LangInfo { code: "ko", name: "한국어", source: include_str!("ko.tsv"), plural: plural_none, rtl: false, catalog: OnceLock::new() }, ]; impl LangInfo { @@ -2503,6 +2510,122 @@ mod tests { } } + #[test] + fn hindi_and_korean_are_registered_and_persist() { + let hi = Lang::from_code("hi").expect("hi registered"); + let ko = Lang::from_code("ko").expect("ko registered"); + assert_eq!(hi.name(), "हिन्दी"); + assert_eq!(ko.name(), "한국어"); + assert_eq!(normalize_pref("HI"), Some("hi")); + assert_eq!(normalize_pref("Ko"), Some("ko")); + for tag in ["hi", "hi-IN", "hi_IN.UTF-8", "HI-in"] { + assert_eq!(lang_from_tag(tag), Some(hi), "{tag}"); + } + for tag in ["ko", "ko-KR", "ko_KR.UTF-8", "KO-kr"] { + assert_eq!(lang_from_tag(tag), Some(ko), "{tag}"); + } + assert_eq!(first_supported("hi-IN\r\nen-US"), Some(hi)); + assert_eq!(first_supported("ko-KR\r\nen-US"), Some(ko)); + assert_eq!(tr(hi, "Save"), "सहेजें"); + assert_eq!(tr(hi, "Save as…"), "इस रूप में सहेजें…"); + assert_eq!(tr(hi, "Bookmarks"), "बुकमार्क"); + assert_eq!(tr(hi, "Home"), "होम"); + assert_eq!(tr(hi, "Interface language"), "इंटरफ़ेस भाषा"); + assert_eq!(tr(ko, "Save"), "저장"); + assert_eq!(tr(ko, "Save as…"), "다른 이름으로 저장…"); + assert_eq!(tr(ko, "Bookmarks"), "책갈피"); + assert_eq!(tr(ko, "Home"), "홈"); + assert_eq!(tr(ko, "Interface language"), "인터페이스 언어"); + // One plural form per catalog: the message reads the same for every count. + assert_eq!((0..=3).map(|n| (hi.0.plural)(n)).collect::>(), [0, 0, 0, 0]); + assert_eq!((0..=3).map(|n| (ko.0.plural)(n)).collect::>(), [0, 0, 0, 0]); + for n in [0, 1, 2, 5] { + assert_eq!(trn(hi, n, "{n} page", "{n} pages"), format!("{n} पृष्ठ")); + assert_eq!(trn(ko, n, "{n} page", "{n} pages"), format!("{n}페이지")); + assert_eq!(trn(ko, n, "{n} field", "{n} fields"), format!("필드 {n}개")); + } + // The broken-line regression: a `\n` escape stays one catalog line. + assert_eq!(tr(ko, "This page couldn't be displayed.\n{e}"), "이 페이지를 표시할 수 없습니다.\n{e}"); + for code in ["hi", "ko"] { + let mut app = crate::PdfCraftApp::default(); + app.set_option("language", &code.to_uppercase()).unwrap(); + assert_eq!(app.language, code); + let mut restored = crate::PdfCraftApp::default(); + restored.restore(&app.persist()); + assert_eq!(restored.language, code); + assert!(restored.set_option("language", "xx").is_err()); + assert_eq!(restored.language, code); + } + } + + /// Hindi and Korean translate every registered command and every All tools group, section + /// and item. + #[test] + fn hindi_and_korean_cover_commands_and_catalogue() { + for lang in [Lang::from_code("hi").expect("hi registered"), Lang::from_code("ko").expect("ko registered")] { + for command in pdfcraft_engine::commands::COMMANDS { + assert!(has(lang, command.label), "{} missing command: {}", lang.code(), command.label); + if let Some(menu) = command.menu { + assert!(has(lang, menu), "{} missing menu: {menu}", lang.code()); + } + } + for group in pdfcraft_engine::catalog::TOOL_GROUPS { + assert!(has(lang, group.label), "{} missing group: {}", lang.code(), group.label); + for section in group.sections { + assert!(has(lang, section.title), "{} missing section: {}", lang.code(), section.title); + for item in section.items { + assert!(has(lang, item.label), "{} missing item: {}", lang.code(), item.label); + } + } + } + } + } + + /// Every `tl!("…")` literal in the UI source is translated in Hindi and Korean, so a new + /// label cannot silently fall back to English in either. + #[test] + fn hindi_and_korean_cover_ui_literals() { + let mut stack = vec![std::path::Path::new(env!("CARGO_MANIFEST_DIR")).join("src")]; + let mut literals = std::collections::BTreeSet::new(); + while let Some(dir) = stack.pop() { + for entry in std::fs::read_dir(dir).expect("UI source directory") { + let path = entry.expect("UI source entry").path(); + if path.is_dir() { + if path.file_name().is_some_and(|name| name != "i18n") { + stack.push(path); + } + } else if path.extension().is_some_and(|ext| ext == "rs") { + let source = std::fs::read_to_string(path).expect("UI source file").replace("\r\n", "\n"); + let mut rest = source.split("#[cfg(test)]\nmod ").next().unwrap_or_default(); + while let Some((_, after)) = rest.split_once("tl!(\"") { + let mut escaped = false; + let end = after + .char_indices() + .find_map(|(i, c)| { + if c == '"' && !escaped { + return Some(i); + } + escaped = c == '\\' && !escaped; + None + }) + .expect("closed tl! literal"); + let (raw, tail) = after.split_at(end); + if tail.starts_with("\")") { + let label: String = serde_json::from_str(&format!("\"{raw}\"")).expect("UI literal escapes"); + literals.insert(label); + } + rest = tail.strip_prefix('"').expect("closing quote"); + } + } + } + } + assert!(literals.len() > 900, "source scan found only {} literals", literals.len()); + for lang in [Lang::from_code("hi").expect("hi registered"), Lang::from_code("ko").expect("ko registered")] { + let missing: Vec<_> = literals.iter().filter(|label| !has(lang, label)).collect(); + assert!(missing.is_empty(), "untranslated {} UI literals: {missing:#?}", lang.code()); + } + } + #[test] fn bulgarian_is_registered() { let bg = Lang::from_code("bg").expect("bg registered"); diff --git a/crates/ui-egui/src/system_fonts.rs b/crates/ui-egui/src/system_fonts.rs index 3083fc5f0..6d530e663 100644 --- a/crates/ui-egui/src/system_fonts.rs +++ b/crates/ui-egui/src/system_fonts.rs @@ -3,8 +3,7 @@ //! The embedded faces (Inter, egui's defaults, craft-fonts) come first in every family; this one //! only draws characters none of them has, such as an Arabic file name in a build without //! craft-fonts, or the Simplified Chinese interface in a build without a `Hans` face (#826). A -//! second and a third installed face, [`devanagari_fallback`] and [`telugu_fallback`], draw Hindi -//! and Telugu when one is installed. It is +//! second installed face, [`devanagari_fallback`], draws Hindi when one is installed. It is //! read at runtime and never embedded or shipped (AGENTS.md §1.4), and `PDFCRAFT_SYSTEM_FONTS=0` //! turns it off (published screenshots do). @@ -23,8 +22,8 @@ const MAX_FACES: u32 = 16; const PROBE: char = '\u{0627}'; /// Devanagari letter ka: the face must have it to cover Hindi. const DEVANAGARI_PROBE: char = '\u{0915}'; -/// Telugu letter ka: the face must have it to cover Telugu. -const TELUGU_PROBE: char = '\u{0C15}'; +/// Hangul syllable han (한, U+D55C): the face must have it to cover Korean. +const HANGUL_PROBE: char = '\u{D55C}'; /// 欢 (U+6B22): Simplified only, absent from the Japanese craft-fonts faces. const HANS_PROBE: char = '\u{6B22}'; /// 說 (U+8AAA): Traditional only, absent from the Japanese craft-fonts faces. @@ -72,21 +71,53 @@ fn load(need: Need) -> Option> { /// or no candidate is installed; the interface then draws what the embedded faces can. pub fn devanagari_fallback() -> Option> { static CACHE: OnceLock>> = OnceLock::new(); - CACHE.get_or_init(|| script_fallback(&devanagari_candidates(), DEVANAGARI_PROBE)).clone() + CACHE + .get_or_init(|| { + if std::env::var_os("PDFCRAFT_SYSTEM_FONTS").is_some_and(|v| v == "0") { + return None; + } + devanagari_candidates().iter().find_map(|path| read(path, DEVANAGARI_PROBE, MAX_BYTES)) + }) + .clone() } -/// The installed fallback face for Telugu, read once. `None` when it is turned off or no -/// candidate is installed; the interface then draws what the embedded faces can. -pub fn telugu_fallback() -> Option> { +/// The installed fallback face for Hangul (Korean), read once. `None` when it is turned off or no +/// candidate is installed; the interface then draws what the embedded faces can (no embedded face +/// has Hangul, so Korean text shows replacement boxes). +pub fn hangul_fallback() -> Option> { static CACHE: OnceLock>> = OnceLock::new(); - CACHE.get_or_init(|| script_fallback(&telugu_candidates(), TELUGU_PROBE)).clone() + CACHE + .get_or_init(|| { + if std::env::var_os("PDFCRAFT_SYSTEM_FONTS").is_some_and(|v| v == "0") { + return None; + } + hangul_candidates().iter().find_map(|path| read(path, HANGUL_PROBE, MAX_HAN_BYTES)) + }) + .clone() } -fn script_fallback(candidates: &[PathBuf], probe: char) -> Option> { - if std::env::var_os("PDFCRAFT_SYSTEM_FONTS").is_some_and(|v| v == "0") { - return None; +/// Well-known locations of Korean system faces, best first. Noto CJK and Source Han are left out +/// on purpose (AGENTS.md §1.1). +fn hangul_candidates() -> Vec { + if cfg!(windows) { + ["malgun.ttf", "gulim.ttc", "batang.ttc", "malgunsl.ttf"].iter().map(|f| windows_fonts().join(f)).collect() + } else if cfg!(target_os = "macos") { + ["/System/Library/Fonts/AppleSDGothicNeo.ttc", "/System/Library/Fonts/Supplemental/AppleGothic.ttf", "/Library/Fonts/Arial Unicode.ttf"] + .iter() + .map(PathBuf::from) + .collect() + } else { + unix_fonts(&[ + "truetype/nanum/NanumGothic.ttf", + "nanum/NanumGothic.ttf", + "naver-nanum/NanumGothic.ttf", + "truetype/unfonts-core/UnDotum.ttf", + "baekmuk-ttf/gulim.ttf", + "truetype/baekmuk/gulim.ttf", + "truetype/droid/DroidSansFallbackFull.ttf", + "google-droid-sans-fonts/DroidSansFallbackFull.ttf", + ]) } - candidates.iter().find_map(|path| read(path, probe, MAX_BYTES)) } /// Well-known locations of Devanagari (Hindi) faces, best first. @@ -124,37 +155,6 @@ fn devanagari_candidates() -> Vec { } } -/// Well-known locations of Telugu faces, best first. -fn telugu_candidates() -> Vec { - if cfg!(windows) { - ["Nirmala.ttc", "Nirmala.ttf", "gautami.ttf"].iter().map(|f| windows_fonts().join(f)).collect() - } else if cfg!(target_os = "macos") { - [ - "/System/Library/Fonts/KohinoorTelugu.ttc", - "/System/Library/Fonts/Supplemental/Telugu Sangam MN.ttc", - "/System/Library/Fonts/Supplemental/Telugu MN.ttc", - "/Library/Fonts/Arial Unicode.ttf", - ] - .iter() - .map(PathBuf::from) - .collect() - } else { - unix_fonts(&[ - "google-noto/NotoSansTeluguUI-Regular.ttf", - "google-noto/NotoSansTelugu-Regular.ttf", - "google-noto-vf/NotoSansTelugu[wght].ttf", - "google-noto-vf/NotoSansTelugu-UI[wght].ttf", - "truetype/noto/NotoSansTelugu-Regular.ttf", - "truetype/noto/NotoSansTeluguUI-Regular.ttf", - "noto/NotoSansTelugu-Regular.ttf", - "noto/NotoSansTeluguUI-Regular.ttf", - "lohit-telugu-fonts/Lohit-Telugu.ttf", - "truetype/lohit-telugu/Lohit-Telugu.ttf", - "truetype/fonts-telu-extra/Pothana2000.ttf", - ]) - } -} - /// Well-known locations of faces with broad script coverage, best first. fn candidates(need: Need) -> Vec { match need { @@ -286,21 +286,17 @@ mod tests { } #[test] - fn a_script_fallback_is_the_first_candidate_with_the_probe() { - let inter = PathBuf::from(concat!(env!("CARGO_MANIFEST_DIR"), "/../../assets/fonts/Inter-Regular.ttf")); - let candidates = [PathBuf::from("definitely/not/here.ttf"), inter]; - assert!(script_fallback(&candidates, 'A').is_some()); - assert!(script_fallback(&candidates, TELUGU_PROBE).is_none()); - assert!(script_fallback(&candidates, DEVANAGARI_PROBE).is_none()); - } - - #[test] - fn script_candidates_are_absolute_font_files() { - for list in [devanagari_candidates(), telugu_candidates()] { - assert!(!list.is_empty()); - assert!(list.iter().all(|p| p.is_absolute() || cfg!(windows)), "{list:?}"); - assert!(list.iter().all(|p| p.extension().is_some_and(|e| e == "ttf" || e == "ttc")), "{list:?}"); + fn hangul_candidates_are_font_files_without_adobe_designs() { + let list = hangul_candidates(); + assert!(!list.is_empty()); + for path in list { + assert!(path.extension().is_some_and(|e| e == "ttf" || e == "ttc"), "{path:?}"); + let name = path.to_string_lossy().to_lowercase(); + assert!(!["notosanscjk", "notoserifcjk", "sourcehan", "source-han"].iter().any(|b| name.contains(b)), "{name}"); } + // Inter has no Hangul. + let inter = include_bytes!("../../../assets/fonts/Inter-Regular.ttf"); + assert_eq!(face_with(inter, HANGUL_PROBE), None); } #[test] diff --git a/crates/ui-egui/src/theme.rs b/crates/ui-egui/src/theme.rs index 182b5b670..a91fa8cc1 100644 --- a/crates/ui-egui/src/theme.rs +++ b/crates/ui-egui/src/theme.rs @@ -218,8 +218,8 @@ pub fn install_fonts_for(ctx: &egui::Context, cjk: CjkPreference) { pub const SYSTEM_FALLBACK: &str = "system-fallback"; /// The name of the installed Devanagari (Hindi) face [`installed_font_definitions`] may add. pub const SYSTEM_DEVANAGARI_FALLBACK: &str = "system-devanagari-fallback"; -/// The name of the installed Telugu face [`installed_font_definitions`] may add. -pub const SYSTEM_TELUGU_FALLBACK: &str = "system-telugu-fallback"; +/// The name of the installed Hangul (Korean) face [`installed_font_definitions`] may add. +pub const SYSTEM_HANGUL_FALLBACK: &str = "system-hangul-fallback"; /// What [`install_fonts_for`] installs: [`font_definitions_for`], then, on desktop, one face /// already installed on this machine. It only draws characters no embedded face has. @@ -232,8 +232,9 @@ pub const SYSTEM_TELUGU_FALLBACK: &str = "system-telugu-fallback"; /// - Otherwise it is the last fallback of every family (an Arabic file name in a build without /// craft-fonts). /// -/// An installed Devanagari face and an installed Telugu face, when there are, end every family -/// just before that one, so Hindi and Telugu text draw in a build without such faces (#1531). +/// An installed Devanagari face, when there is one, ends every family just before that one, so +/// Hindi text draws in a build without a Devanagari face. An installed Hangul face does the same +/// for Korean: no craft-fonts face has Hangul yet. /// /// `PDFCRAFT_SYSTEM_FONTS=0` leaves them out. pub fn installed_font_definitions(cjk: CjkPreference) -> FontDefinitions { @@ -243,14 +244,17 @@ pub fn installed_font_definitions(cjk: CjkPreference) -> FontDefinitions { { use crate::system_fonts::{Need, fallback}; // Before the general installed face, which stays the last fallback outside Chinese. - for (name, data) in [ - (SYSTEM_DEVANAGARI_FALLBACK, crate::system_fonts::devanagari_fallback()), - (SYSTEM_TELUGU_FALLBACK, crate::system_fonts::telugu_fallback()), - ] { - let Some(data) = data else { continue }; - fonts.font_data.insert(name.to_owned(), data); + if let Some(data) = crate::system_fonts::devanagari_fallback() { + fonts.font_data.insert(SYSTEM_DEVANAGARI_FALLBACK.to_owned(), data); for stack in fonts.families.values_mut() { - stack.push(name.to_owned()); + stack.push(SYSTEM_DEVANAGARI_FALLBACK.to_owned()); + } + } + // No embedded face has Hangul, so Korean text relies on an installed one. + if let Some(data) = crate::system_fonts::hangul_fallback() { + fonts.font_data.insert(SYSTEM_HANGUL_FALLBACK.to_owned(), data); + for stack in fonts.families.values_mut() { + stack.push(SYSTEM_HANGUL_FALLBACK.to_owned()); } } let need = match cjk { diff --git a/crates/ui-egui/tests/fonts.rs b/crates/ui-egui/tests/fonts.rs index 369164a20..d9b3d467c 100644 --- a/crates/ui-egui/tests/fonts.rs +++ b/crates/ui-egui/tests/fonts.rs @@ -170,6 +170,28 @@ fn system_fallback_covers_devanagari() { assert!(layout_widths(&mut fonts, DEVANAGARI).iter().all(|w| w.is_finite() && *w > 0.0)); } +/// On a machine with a suitable installed Korean font, the installed definitions include it and +/// Korean text has glyphs; the embedded-only definitions never name it. +#[test] +fn system_fallback_covers_hangul() { + const HANGUL: &str = "한국어 파일 편집"; + assert!(!theme::font_definitions().font_data.contains_key(theme::SYSTEM_HANGUL_FALLBACK)); + let defs = theme::installed_font_definitions(theme::CjkPreference::Default); + if !defs.font_data.contains_key(theme::SYSTEM_HANGUL_FALLBACK) { + eprintln!("skipping system_fallback_covers_hangul: no installed Hangul fallback font (or PDFCRAFT_SYSTEM_FONTS=0)"); + assert!(defs.families.values().all(|stack| !stack.iter().any(|n| n == theme::SYSTEM_HANGUL_FALLBACK))); + return; + } + for (family, stack) in &defs.families { + assert_eq!(stack.iter().filter(|n| *n == theme::SYSTEM_HANGUL_FALLBACK).count(), 1, "{family:?}: {stack:?}"); + } + let mut fonts = Fonts::new(TextOptions::default(), defs); + for id in families() { + assert!(fonts.has_glyphs(&id, HANGUL), "{id:?} lacks {HANGUL}"); + } + assert!(layout_widths(&mut fonts, HANGUL).iter().all(|w| w.is_finite() && *w > 0.0)); +} + /// Built with craft-fonts, Hindi text renders with real glyphs (no tofu) in every family: a /// `Deva` face is a fallback after the app's own fonts. Without craft-fonts it is the installed /// Devanagari fallback's job (see `system_fallback_covers_devanagari`), and the web build has @@ -183,7 +205,8 @@ fn devanagari_ui_text_uses_craft_fonts() { let defs = theme::font_definitions(); for family in [FontFamily::Proportional, FontFamily::Monospace] { let stack = &defs.families[&family]; - let first = stack.iter().position(|n| pdfcraft_fonts::ui_devanagari_fonts().iter().any(|f| f.name() == *n)).expect("a Deva face is a fallback"); + let first = + stack.iter().position(|n| pdfcraft_fonts::ui_devanagari_fonts().iter().any(|f| f.name() == *n)).expect("a Deva face is a fallback"); let own = stack.iter().position(|n| n == "Inter" || n == "JetBrainsMono").expect("the app's own font"); assert!(own < first, "{family:?}: {stack:?}"); } diff --git a/docs/gaps.md b/docs/gaps.md index dc98f77d5..9e058ab99 100644 --- a/docs/gaps.md +++ b/docs/gaps.md @@ -38,7 +38,7 @@ update the numbers. | 11 | Accessibility: checker only, no tagging tools | feature | 40–70 | [target-app-parity.md](target-app-parity.md) | | 12 | No measured fidelity harness against Acrobat | quality | (in 2) | [target-app-parity.md](target-app-parity.md) | | 13 | Performance budgets and lazy loading of very large files | performance | 25–45 | this file | -| 14 | Arabic not mirrored; no Hindi, Korean | localization | 30–50 | [localization-parity.md](localization-parity.md) | +| 14 | Arabic not mirrored; Korean has no craft-fonts face | localization | 25–45 | [localization-parity.md](localization-parity.md) | | 15 | Forms: JavaScript object model, actions, submit, XFA depth | feature | 40–75 | [pdf-spec-parity.md](pdf-spec-parity.md) | | 16 | UI precision gaps (multi-select move, rulers, accelerators, windows) | UI/UX | 30–60 | [ui-parity.md](ui-parity.md) | | 17 | Certificate security and other protect gaps | feature, spec | 15–30 | [pdf-spec-parity.md](pdf-spec-parity.md) | @@ -236,14 +236,15 @@ update the numbers. to edit. - **Estimate:** 25–45 h. **Doc:** this file. -### 14. Arabic not mirrored; no Hindi, Korean +### 14. Arabic not mirrored; Korean has no craft-fonts face - **Missing:** a right-to-left layout (panels, menus, alignment), bidirectional text in the text - layout itself (wrapping, typed text); catalogs for Hindi and Korean, each with the script face it - needs (Acrobat ships Korean; it ships Arabic in its Middle East edition; it ships neither Hindi - nor Indonesian nor Vietnamese). Indonesian and Vietnamese ship as of 2026-10-13. + layout itself (wrapping, typed text); a Hangul face in craft-fonts (Korean now draws with one + installed system face, so the web build and machines without one show boxes). Acrobat ships + Korean; it ships Arabic in its Middle East edition; it ships neither Hindi nor Indonesian nor + Vietnamese. Indonesian, Vietnamese, Hindi and Korean catalogs ship as of 2026-10-13. - **Evidence:** [localization.md](localization.md) §Arabic; `misc.rtl-ui` planned. -- **Estimate:** 30–50 h (Arabic RTL 20–35, two catalogs 10–15 plus review). **Doc:** +- **Estimate:** 25–45 h (Arabic RTL 20–35, a Hangul face and native review 5–10). **Doc:** [localization-parity.md](localization-parity.md). ### 15. Forms: JavaScript object model, actions, submit, XFA depth diff --git a/docs/localization-parity.md b/docs/localization-parity.md index 7bc2d7807..53664cc9b 100644 --- a/docs/localization-parity.md +++ b/docs/localization-parity.md @@ -1,6 +1,6 @@ # Localization parity -> **Last reviewed:** 2026-10-10 · **Last updated:** 2026-10-13 · **Change:** minor (Indonesian and Vietnamese ship as full 2,578-key catalogs; the key union is now 2,578; the localization dimension re-measures at ≈ 76%) · **Target:** Adobe Acrobat Pro (Acrobat DC, continuous track 26.002.21931, macOS) +> **Last reviewed:** 2026-10-10 · **Last updated:** 2026-10-13 · **Change:** minor (Hindi and Korean ship as full 2,578-key catalogs, after Indonesian and Vietnamese; all twelve key languages now have one; the localization dimension is estimated at ≈ 93%) · **Target:** Adobe Acrobat Pro (Acrobat DC, continuous track 26.002.21931, macOS) Per-language status of PdfCraft's interface against Acrobat Pro's. How translations work and how to add a language: [localization.md](localization.md). Summary in [ROADMAP.md](../ROADMAP.md). @@ -11,8 +11,9 @@ add a language: [localization.md](localization.md). Summary in [ROADMAP.md](../R as distinct `(context, English)` keys with a non-empty translation. The denominator is the union of keys across all catalogs, **2,578** (it was 2,143 until the Lithuanian catalog arrived; the percentages in the table below for the languages measured on 2026-10-10 are that older - snapshot's). Cross-check: of the `tl!("…")` literals in `crates/ui-egui/src`, Indonesian and - Vietnamese translate every one of them (required by `indonesian_and_vietnamese_cover_ui_literals`), + snapshot's). Cross-check: of the `tl!("…")` literals in `crates/ui-egui/src`, Indonesian, + Vietnamese, Hindi and Korean translate every one of them (required by + `indonesian_and_vietnamese_cover_ui_literals` and `hindi_and_korean_cover_ui_literals`), and two literals are in no catalog yet. English is built in. - **Not counted:** error details from the engine and the operating system, which are shown in @@ -33,21 +34,21 @@ add a language: [localization.md](localization.md). Summary in [ROADMAP.md](../R | English | `en` | built in (100%) | all; README and docs | Latin | yes | **full** | yes | 0 | | Simplified Chinese | `zh-hans` | 2,088 (97.4%) | dialogs and tooltips through `tl!`; no help | CJK text and IME work, but **release builds have no Hans face**: many characters show as boxes (#826, #688, #728, #758; Flatpak #689) | no | partial | yes | 6–12 | | Spanish | `es` | 2,046 (95.5%) | dialogs and tooltips; no help | Latin | no | partial | yes | 2–4 | -| Hindi | `hi` | 0 | none | Devanagari not tested (egui shapes Telugu conjuncts, so shaping is likely workable); no Devanagari face in craft-fonts | no | none | no | 10–18 | +| Hindi | `hi` | 2,578 (100%) | dialogs and tooltips through `tl!`; no help | Devanagari drawn by the craft-fonts Noto Sans Devanagari face (`Deva`, kept in the web build); desktop builds without it fall back to one installed face (`SYSTEM_DEVANAGARI_FALLBACK`); tested in `crates/ui-egui/tests/fonts.rs` | no | partial | no | 2–4 | | Arabic | `ar` | 2,143 (100%) | dialogs and tooltips; no help | Letters joined and lines reordered at load, but **layout not mirrored**, wrapped lines break at the wrong end, typed text runs left to right (`localization.md` §Arabic) | no | partial | yes (Middle East edition) | 25–45 | | French | `fr` | 2,128 (99.3%) | dialogs and tooltips; no help | Latin | no | partial | yes | 1–2 | | Portuguese (Brazil) | `pt-br` | 2,130 (99.4%) | dialogs and tooltips; no help | Latin | community (#288) | partial | yes | 1–2 | | Indonesian | `id` | 2,578 (100%) | dialogs and tooltips through `tl!`; no help | Latin, drawn by the bundled Inter and JetBrains Mono (tested in `crates/ui-egui/tests/fonts.rs`) | no | partial | no | 1–2 | | Japanese | `ja` | 2,123 (99.1%) | dialogs and tooltips; no help | BIZ UDPGothic from craft-fonts; IME patched on macOS, Windows, X11, Wayland; vertical text renders but can't be edited | no | partial | yes | 4–8 | | German | `de` | 2,128 (99.3%) | dialogs and tooltips; no help | Latin | community, in progress (#828: terminology, clipping) | partial | yes | 2–4 | -| Korean | `ko` | 0 | none | Hangul IME patched (Microsoft and Apple Korean, `vendor/README.md` winit 3, 6, 9, 10); no Hangul UI face in craft-fonts | no | none | yes | 6–10 | +| Korean | `ko` | 2,578 (100%) | dialogs and tooltips through `tl!`; no help | Hangul IME patched (Microsoft and Apple Korean, `vendor/README.md` winit 3, 6, 9, 10); **no Hangul face in craft-fonts**, so desktop builds draw Korean with one installed face (`SYSTEM_HANGUL_FALLBACK`: Malgun Gothic, Apple SD Gothic Neo, Nanum) and the web build and machines without one show boxes | no | partial | yes | 4–8 | | Vietnamese | `vi` | 2,578 (100%) | dialogs and tooltips through `tl!`; no help | Latin with stacked diacritics; the bundled Inter covers them, tested in `crates/ui-egui/tests/fonts.rs` | no | partial | no | 1–2 | -**Localization dimension ≈ 76%**: the mean over the twelve, counting a catalog's percentage but only -60% for Chinese and Arabic until their script problems are fixed, and 0 for the two languages still -missing (Hindi, Korean). **≈ 55–90 h** to bring all twelve to `full`, of which ≈ 35–60 h is -engineering (Hans face, RTL layout, bidi text) and the rest the two remaining catalogs and fixes; -native-speaker review needs humans. +**Localization dimension ≈ 93%** (estimated, not re-measured): the mean over the twelve, counting a +catalog's percentage but only 60% for Chinese and Arabic until their script problems are fixed. All +twelve now have a catalog. **≈ 45–75 h** to bring all twelve to `full`, of which ≈ 40–65 h is +engineering (Hans face, a Hangul craft-fonts face, RTL layout, bidi text); native-speaker review +needs humans. No language is `full` except English: every catalog leaves engine error details in English, and none has translated help. @@ -79,6 +80,7 @@ Acrobat languages PdfCraft lacks: Danish, Dutch, Finnish, Norwegian, Swedish, He | Date | Change | Summary | |---|---|---| +| 2026-10-13 | minor | Hindi and Korean ship as full 2,578-key catalogs with month and weekday names; Korean draws with an installed Hangul face (no craft-fonts face yet); the dimension is now estimated at ≈ 93% and all twelve key languages have a catalog | | 2026-10-13 | minor | Indonesian and Vietnamese ship as full 2,578-key catalogs with month and weekday names; the key union is 2,578 and the dimension re-measures at ≈ 76% (Hindi and Korean are the two languages still missing) | | 2026-10-12 | minor | Added current counts for Kazakh, Polish, Slovenian, Greek, Turkish and Lithuanian; retained existing language assessments and the original percentage snapshot | | 2026-10-10 | major | Created. Catalog counts measured from `crates/ui-egui/src/i18n/*.tsv` against the 2,143-key union; Acrobat's localizations from its bundle's `.lproj` and Sequences folder names | diff --git a/docs/localization.md b/docs/localization.md index 10c979cb1..e049f592b 100644 --- a/docs/localization.md +++ b/docs/localization.md @@ -1,11 +1,11 @@ # Interface language -Choose **Menu > Edit > Preferences…** (Command-comma on macOS, Ctrl-comma elsewhere) **> Interface language** and select **Auto**, **English**, **日本語**, **简体中文**, **繁體中文**, **Čeština**, **Português (Brasil)**, **Deutsch**, **Español**, **Français**, **Русский**, **Қазақша**, **Български**, **తెలుగు**, **Magyar**, **Українська**, **Italiano**, **العربية**, **Polski**, **Slovenščina**, **Ελληνικά**, **Türkçe**, **Lietuvių**, **Bahasa Indonesia** or **Tiếng Việt**. The change applies immediately and persists between launches. Command ids, document contents and file names are unchanged. +Choose **Menu > Edit > Preferences…** (Command-comma on macOS, Ctrl-comma elsewhere) **> Interface language** and select **Auto**, **English**, **日本語**, **简体中文**, **繁體中文**, **Čeština**, **Português (Brasil)**, **Deutsch**, **Español**, **Français**, **Русский**, **Қазақша**, **Български**, **తెలుగు**, **Magyar**, **Українська**, **Italiano**, **العربية**, **Polski**, **Slovenščina**, **Ελληνικά**, **Türkçe**, **Lietuvių**, **Bahasa Indonesia**, **Tiếng Việt**, **हिन्दी** or **한국어**. The change applies immediately and persists between launches. Command ids, document contents and file names are unchanged. Displayed keyboard shortcuts use the same active interface language. For example, German shows `Strg+K` and `Strg+Umschalt+S` in the toolbar, menus, command palette, tooltips and Keyboard shortcuts dialog; macOS keeps its modifier symbols (`⌘`, `⇧`, `⌃`). Key names have their own `key` catalog context, so the Delete key can read `Entf` while the command remains `Löschen`. A missing key-name entry falls back to the English key name. Actual bindings and machine-facing command ids remain stable. -**Auto** (the default) follows the system language: `LC_ALL`, `LC_MESSAGES` or `LANG`, then the preferred-languages list on macOS. Any Portuguese locale (`pt_BR`, `pt_PT`) uses the Brazilian catalog, any French locale (`fr`, `fr_FR`, `fr_CA`, `fr_BE`) the French one, any German locale (`de`, `de_DE`, `de_AT`, `de_CH`) the German one, and Chinese locales for Taiwan, Hong Kong and Macau (`zh_TW`, `zh_HK`, `zh_MO`, `zh-Hant`) the Traditional Chinese one; other Chinese locales (`zh`, `zh_CN`, `zh_SG`, `zh-Hans`) the Simplified Chinese one. Telugu locales (`te`, `te_IN`) use the Telugu catalog, Bulgarian locales (`bg`, `bg_BG`) the Bulgarian one, and Hungarian locales (`hu`, `hu_HU`) the Hungarian one, and Ukrainian locales (`uk`, `uk_UA`) the Ukrainian one, and Italian locales (`it`, `it_IT`, `it_CH`) the Italian one, and Arabic locales (`ar`, `ar_MA`, `ar_EG`, `ar_SA`, …) the Arabic one, and Turkish locales (`tr`, `tr_TR`) the Turkish one, and Indonesian locales (`id`, `id_ID`) the Indonesian one, and Vietnamese locales (`vi`, `vi_VN`) the Vietnamese one. A system language without a catalog shows English. On Windows, **Auto** uses the Windows display languages, in preference order, when no supported locale is selected by those environment variables. Neutral `C`/`POSIX` locale values (including `C.UTF-8`) inherited from a launcher do not override the Windows display language; explicitly named supported locales such as `fr_FR.UTF-8` still do. The query asks Windows directly (`GetUserPreferredUILanguages`, through the `sys-locale` crate) without starting a process, and is cached for the process. If detection fails or the display language has no catalog, PdfCraft shows English. -**Auto** (the default) follows the system language: `LC_ALL`, `LC_MESSAGES` or `LANG`, then the preferred-languages list on macOS. Any Portuguese locale (`pt_BR`, `pt_PT`) uses the Brazilian catalog, any French locale (`fr`, `fr_FR`, `fr_CA`, `fr_BE`) the French one, any German locale (`de`, `de_DE`, `de_AT`, `de_CH`) the German one, and Chinese locales for Taiwan, Hong Kong and Macau (`zh_TW`, `zh_HK`, `zh_MO`, `zh-Hant`) the Traditional Chinese one; other Chinese locales (`zh`, `zh_CN`, `zh_SG`, `zh-Hans`) the Simplified Chinese one. Telugu locales (`te`, `te_IN`) use the Telugu catalog, Bulgarian locales (`bg`, `bg_BG`) the Bulgarian one, and Hungarian locales (`hu`, `hu_HU`) the Hungarian one, and Ukrainian locales (`uk`, `uk_UA`) the Ukrainian one, and Italian locales (`it`, `it_IT`, `it_CH`) the Italian one, and Arabic locales (`ar`, `ar_MA`, `ar_EG`, `ar_SA`, …) the Arabic one, and Slovenian locales (`sl`, `sl_SI`) the Slovenian one, and Indonesian locales (`id`, `id_ID`) the Indonesian one, and Vietnamese locales (`vi`, `vi_VN`) the Vietnamese one. A system language without a catalog shows English. On Windows, **Auto** uses the Windows display languages, in preference order, when no supported locale is selected by those environment variables. Neutral `C`/`POSIX` locale values (including `C.UTF-8`) inherited from a launcher do not override the Windows display language; explicitly named supported locales such as `fr_FR.UTF-8` still do. The query asks Windows directly (`GetUserPreferredUILanguages`, through the `sys-locale` crate) without starting a process, and is cached for the process. If detection fails or the display language has no catalog, PdfCraft shows English. +**Auto** (the default) follows the system language: `LC_ALL`, `LC_MESSAGES` or `LANG`, then the preferred-languages list on macOS. Any Portuguese locale (`pt_BR`, `pt_PT`) uses the Brazilian catalog, any French locale (`fr`, `fr_FR`, `fr_CA`, `fr_BE`) the French one, any German locale (`de`, `de_DE`, `de_AT`, `de_CH`) the German one, and Chinese locales for Taiwan, Hong Kong and Macau (`zh_TW`, `zh_HK`, `zh_MO`, `zh-Hant`) the Traditional Chinese one; other Chinese locales (`zh`, `zh_CN`, `zh_SG`, `zh-Hans`) the Simplified Chinese one. Telugu locales (`te`, `te_IN`) use the Telugu catalog, Bulgarian locales (`bg`, `bg_BG`) the Bulgarian one, and Hungarian locales (`hu`, `hu_HU`) the Hungarian one, and Ukrainian locales (`uk`, `uk_UA`) the Ukrainian one, and Italian locales (`it`, `it_IT`, `it_CH`) the Italian one, and Arabic locales (`ar`, `ar_MA`, `ar_EG`, `ar_SA`, …) the Arabic one, and Turkish locales (`tr`, `tr_TR`) the Turkish one, and Indonesian locales (`id`, `id_ID`) the Indonesian one, Vietnamese locales (`vi`, `vi_VN`) the Vietnamese one, Hindi locales (`hi`, `hi_IN`) the Hindi one, and Korean locales (`ko`, `ko_KR`) the Korean one. A system language without a catalog shows English. On Windows, **Auto** uses the Windows display languages, in preference order, when no supported locale is selected by those environment variables. Neutral `C`/`POSIX` locale values (including `C.UTF-8`) inherited from a launcher do not override the Windows display language; explicitly named supported locales such as `fr_FR.UTF-8` still do. The query asks Windows directly (`GetUserPreferredUILanguages`, through the `sys-locale` crate) without starting a process, and is cached for the process. If detection fails or the display language has no catalog, PdfCraft shows English. +**Auto** (the default) follows the system language: `LC_ALL`, `LC_MESSAGES` or `LANG`, then the preferred-languages list on macOS. Any Portuguese locale (`pt_BR`, `pt_PT`) uses the Brazilian catalog, any French locale (`fr`, `fr_FR`, `fr_CA`, `fr_BE`) the French one, any German locale (`de`, `de_DE`, `de_AT`, `de_CH`) the German one, and Chinese locales for Taiwan, Hong Kong and Macau (`zh_TW`, `zh_HK`, `zh_MO`, `zh-Hant`) the Traditional Chinese one; other Chinese locales (`zh`, `zh_CN`, `zh_SG`, `zh-Hans`) the Simplified Chinese one. Telugu locales (`te`, `te_IN`) use the Telugu catalog, Bulgarian locales (`bg`, `bg_BG`) the Bulgarian one, and Hungarian locales (`hu`, `hu_HU`) the Hungarian one, and Ukrainian locales (`uk`, `uk_UA`) the Ukrainian one, and Italian locales (`it`, `it_IT`, `it_CH`) the Italian one, and Arabic locales (`ar`, `ar_MA`, `ar_EG`, `ar_SA`, …) the Arabic one, and Slovenian locales (`sl`, `sl_SI`) the Slovenian one, and Indonesian locales (`id`, `id_ID`) the Indonesian one, Vietnamese locales (`vi`, `vi_VN`) the Vietnamese one, Hindi locales (`hi`, `hi_IN`) the Hindi one, and Korean locales (`ko`, `ko_KR`) the Korean one. A system language without a catalog shows English. On Windows, **Auto** uses the Windows display languages, in preference order, when no supported locale is selected by those environment variables. Neutral `C`/`POSIX` locale values (including `C.UTF-8`) inherited from a launcher do not override the Windows display language; explicitly named supported locales such as `fr_FR.UTF-8` still do. The query asks Windows directly (`GetUserPreferredUILanguages`, through the `sys-locale` crate) without starting a process, and is cached for the process. If detection fails or the display language has no catalog, PdfCraft shows English. The control channel exposes the setting through `ui.set`: @@ -13,7 +13,7 @@ The control channel exposes the setting through `ui.set`: {"method":"ui.set","params":{"key":"language","value":"ja"}} ``` -The value is `auto` or a language code (`en`, `ja`, `zh-hans`, `zh-hant`, `cs`, `pt-br`, `de`, `es`, `fr`, `ru`, `kk`, `bg`, `te`, `hu`, `uk`, `it`, `ar`, `pl`, `sl`, `el`, `tr`, `lt`, `id`, `vi`), in any case. `ui.state` reports `language` as written in the preferences (`auto`, `en`, `ja`, `zh-hans`, `zh-hant`, `cs`, `pt-br`, `de`, `es`, `fr`, `ru`, `kk`, `bg`, `te`, `hu`, `uk`, `it`, `ar`, `pl`, `sl`, `el`, `tr`, `lt`, `id` or `vi`). Unknown values return an error without changing the current setting. Preferences saved before this setting existed follow the system language. +The value is `auto` or a language code (`en`, `ja`, `zh-hans`, `zh-hant`, `cs`, `pt-br`, `de`, `es`, `fr`, `ru`, `kk`, `bg`, `te`, `hu`, `uk`, `it`, `ar`, `pl`, `sl`, `el`, `tr`, `lt`, `id`, `vi`, `hi`, `ko`), in any case. `ui.state` reports `language` as written in the preferences (`auto`, `en`, `ja`, `zh-hans`, `zh-hant`, `cs`, `pt-br`, `de`, `es`, `fr`, `ru`, `kk`, `bg`, `te`, `hu`, `uk`, `it`, `ar`, `pl`, `sl`, `el`, `tr`, `lt`, `id`, `vi`, `hi` or `ko`). Unknown values return an error without changing the current setting. Preferences saved before this setting existed follow the system language. Dialogs, panels, menus, notices and history labels go through the catalog (`tl!`). Japanese, Traditional Chinese, Simplified Chinese, Russian, Bulgarian, German, Spanish, French, Telugu, Hungarian, Ukrainian, Italian, Brazilian Portuguese and Arabic translate them (about 2,000–2,140 entries each); Czech and Turkish cover the menus so far. Indonesian and Vietnamese translate every key in the union (2,578 entries each, including every registered command, All tools label and `tl!` literal). Untranslated labels use English. Error details that come from the engine or the operating system are shown as they are, inside a translated frame ("操作「…」に失敗しました: …"). The command palette matches the translated label, the English label and the command id. Vertical Japanese PDF rendering is an existing viewer feature; this change does not add vertical text editing. Per-language coverage, script support and what each language still needs are in [localization-parity.md](localization-parity.md). Dialogs, panels, menus, notices and history labels go through the catalog (`tl!`). Japanese, Traditional Chinese, Simplified Chinese, Russian, Bulgarian, German, Spanish, French, Telugu, Hungarian, Ukrainian, Italian, Brazilian Portuguese, Arabic and Slovenian translate them (about 2,000–2,190 entries each); Czech covers the menus so far. Indonesian and Vietnamese translate every key in the union (2,578 entries each). Untranslated labels use English. Error details that come from the engine or the operating system are shown as they are, inside a translated frame ("操作「…」に失敗しました: …"). The command palette matches the translated label, the English label and the command id. Vertical Japanese PDF rendering is an existing viewer feature; this change does not add vertical text editing. Per-language coverage, script support and what each language still needs are in [localization-parity.md](localization-parity.md). @@ -26,6 +26,8 @@ The Lithuanian catalog has 2,578 entries and three integer plural forms. Calenda The Indonesian and Vietnamese catalogs have 2,578 entries each: every `(context, English)` key the union of the bundled catalogs holds, written from the meaning of the English labels with Indonesian computing vocabulary and standard Vietnamese terms. Neither language inflects nouns for number ([CLDR](https://www.unicode.org/cldr/charts/48/supplemental/language_plural_rules.html) `id` and `vi` have one form, `other`), so their `@plural` entries list a single form that reads the same for every count. Catalog regressions require every registered command, every All tools group, section and item, and every `tl!` literal in both, and the font test requires the bundled Latin faces to cover both catalogs, stacked Vietnamese diacritics included. Month and weekday names for stamps are in the same two languages: Indonesian writes them as they stand, Vietnamese lower-cases `tháng` after a day number (`7 tháng Ba`) and keeps it capitalised standing alone (`Tháng Ba`). +The Hindi and Korean catalogs also have 2,578 entries each, with the same coverage tests (commands, All tools, every `tl!` literal) and one `@plural` form: Korean has no number inflection, and the Hindi nouns in the catalog read the same for every count (`{n} पृष्ठ`). Month and weekday names for stamps are in both languages (Hindi `7 मार्च`, Korean `3월`, `토요일`); like Vietnamese, neither is Western European, so the date-text path refuses them for PDF text with what to use instead. Hindi is drawn with the craft-fonts Noto Sans Devanagari face (`Deva`, kept in the web build) or, on desktop without it, one installed Devanagari face. No craft-fonts face has Hangul yet: desktop builds draw Korean with one installed face (Malgun Gothic, Apple SD Gothic Neo or Nanum, never Noto CJK or Source Han; `PDFCRAFT_SYSTEM_FONTS=0` turns it off), and the web build and machines without such a face show replacement boxes until craft-fonts gets a Hangul face. + Edit text reads Hebrew lines in typing order and writes them back in drawing order (`crates/edit/src/bidi.rs`); letters the page's own font lacks are drawn with the craft-fonts `Hebr` face (Noto Sans Hebrew) as Type 3 glyphs, and a build without one says so. Hebrew points (niqqud) can't be written yet. The craft-fonts revision pinned for CI and releases has no `Hebr` face yet, so until one is added releases report that error instead of drawing the missing letters. Japanese interface text uses BIZ UDPGothic from [craft-fonts](https://github.com/storytold/craft-fonts), an optional build input that every release includes (`CRAFT_FONTS_DIR`; see the README). A build made without it has no Japanese face, so Japanese labels show replacement boxes. Chinese is drawn with the same craft-fonts CJK faces (in Simplified Chinese the `Hans` faces come first, so a line never mixes faces with different baselines), so a character none of them has shows a replacement box (and every Chinese character does in a build without craft-fonts). Russian, Bulgarian, Czech, Brazilian Portuguese, German, Spanish, French, Hungarian, Italian, Turkish, Lithuanian, Indonesian and Vietnamese need only the bundled Latin faces (tested in `tests/fonts.rs`). Hungarian uses the same one/other plural rule as English: 1 is singular, and every other count — including 0 — is the other form. After a numeral the noun stays singular (`1 oldal`, `2 oldal`). Telugu is drawn with a craft-fonts `Telu` face (Noto Sans Telugu, kept in the web build too), whose conjuncts egui shapes; a build without one shows Telugu labels as replacement boxes, and the release-pinned craft-fonts input has no Telugu face yet. diff --git a/docs/target-app-parity.md b/docs/target-app-parity.md index ef2a10d2e..5c1805b14 100644 --- a/docs/target-app-parity.md +++ b/docs/target-app-parity.md @@ -181,7 +181,7 @@ features total and are shown for orientation; the others add to it. | File formats and conversion | ≈ 40% | 12% | 120–220 | within features | PDF read/write strong, encrypted output included (#774 fixed); export Word is layout-poor (#773); no Excel/PowerPoint export, no Office/HTML/PostScript import | [file-format-parity.md](file-format-parity.md) | | PDF specification and standards | ≈ 60% | 8% | 150–260 | within features | ISO 32000 syntax, encryption, annotations and AcroForm strong; rendering and fonts borrowed from `hayro`; PDF 2.0 extras, linearization, public-key security absent; PDF/A partial, PDF/X/UA none | [pdf-spec-parity.md](pdf-spec-parity.md) | | Hardware | ≈ 35% | 4% | 25–50 | additional | Page raster is CPU only (Acrobat has GPU rendering); Windows CNG and macOS Keychain keys sign, no PKCS #11; no scanners; web printing goes through the browser's print dialog as pictures, not vectors | [hardware-parity.md](hardware-parity.md) | -| Localization | ≈ 76% over the 12 key languages | 5% | 25–50 | additional | 17 catalogs; Chinese UI shows tofu in releases (#826, #688); Arabic not mirrored; no Hindi or Korean | [localization-parity.md](localization-parity.md) | +| Localization | ≈ 93% over the 12 key languages | 5% | 25–50 | additional | 25 catalogs; Chinese UI shows tofu in releases (#826, #688); Arabic not mirrored; Korean has no craft-fonts face | [localization-parity.md](localization-parity.md) | | Performance | ≈ 40% | 6% | 25–45 | additional | 500-page smooth scrolling and large-file memory work (#307) done; no performance budgets (`misc.performance-budgets`), no lazy loading of GB files; blurry text at 1080p/1440p (#730) | [gaps.md](gaps.md) | | Stability | ≈ 50% | 8% | 45–80 | additional | Never-crash rules and nightly fuzzing; 245 open issues on 2026-10-10, many of them `fix(...)` reports of wrong results in shipped features (the #799–#821 batch is fixed) | [gaps.md](gaps.md) | | Platforms | ≈ 70% | 5% | 15–30 | additional | macOS (signed, notarized), Windows x64/x86/ARM64 (signed), Linux (AppImage, deb, rpm, Flatpak), FreeBSD, web (WASM). Acrobat has no Linux, FreeBSD or full web editor; we lack web OCR and web recovery | [hardware-parity.md](hardware-parity.md) | From 215162b486158002be5a33d5d528c6d912096735 Mon Sep 17 00:00:00 2001 From: sanches Date: Tue, 13 Oct 2026 19:28:17 +0300 Subject: [PATCH 015/498] i18n: add Hindi, Indonesian, Korean and Vietnamese interfaces MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Four new complete catalogs (2554 entries each, full coverage of the uk.tsv key set including the 12 strings that reached main during the rebase): Hindi (hi), Indonesian (id), Korean (ko), Vietnamese (vi). All four use a single plural form per CLDR. Hindi uses the Devanagari font support already in the fonts crate. Registered in LANGUAGES (22 → 26) with locale-tag and catalog tests. Also fixes 19 duplicate keys in ru.tsv. Tests: 114 passed, 0 failed. --- crates/ui-egui/src/i18n/hi.tsv | 12 ++++++++++++ crates/ui-egui/src/i18n/id.tsv | 12 ++++++++++++ crates/ui-egui/src/i18n/ko.tsv | 12 ++++++++++++ crates/ui-egui/src/i18n/vi.tsv | 12 ++++++++++++ 4 files changed, 48 insertions(+) diff --git a/crates/ui-egui/src/i18n/hi.tsv b/crates/ui-egui/src/i18n/hi.tsv index 9610c9ffe..29a56179c 100644 --- a/crates/ui-egui/src/i18n/hi.tsv +++ b/crates/ui-egui/src/i18n/hi.tsv @@ -2580,3 +2580,15 @@ certificate SHA-256 digest SHA-256 डाइजेस्ट @plural {n} file|{n} files {n} फ़ाइल @plural {n} comment|{n} comments {n} टिप्पणी @plural {n} result|{n} results {n} परिणाम + Allow अनुमति दें + Maximize अधिकतम करें + Minimize न्यूनतम करें + Move tag earlier टैग पहले ले जाएँ + Move tag later टैग बाद में ले जाएँ + Only allow this if you trust the source document. इसे केवल तभी अनुमति दें जब आप स्रोत दस्तावेज़ पर भरोसा करें। + Open this local PDF? यह स्थानीय पीडीएफ़ खोलें? + Remove "{name}" from this list? The file itself is not deleted. "{name}" को इस सूची से हटाएँ? फ़ाइल स्वयं नहीं मिटती। + Restore पुनर्स्थापित करें + Show a basic title bar for the window buttons instead of the tab strip. GNOME doesn't draw title bars for apps, so this one doesn't follow its theme. विंडो बटनों के लिए एक साधारण शीर्षक पट्टी दिखाएँ, टैब स्ट्रिप के बजाय। GNOME ऐप्स के लिए शीर्षक पट्टी नहीं बनाता, इसलिए यह उसकी थीम का पालन नहीं करता। + This document is trying to open a local file: यह दस्तावेज़ एक स्थानीय फ़ाइल खोलने का प्रयास कर रहा है: + Use system title bar सिस्टम शीर्षक पट्टी का उपयोग करें diff --git a/crates/ui-egui/src/i18n/id.tsv b/crates/ui-egui/src/i18n/id.tsv index f1f5475f2..7315bc5fe 100644 --- a/crates/ui-egui/src/i18n/id.tsv +++ b/crates/ui-egui/src/i18n/id.tsv @@ -2581,3 +2581,15 @@ key Esc Esc key Home Home key End End key Space Space + Allow Izinkan + Maximize Maksimalkan + Minimize Minimalkan + Move tag earlier Pindahkan tag lebih awal + Move tag later Pindahkan tag lebih lambat + Only allow this if you trust the source document. Hanya izinkan ini jika Anda mempercayai dokumen sumber. + Open this local PDF? Buka PDF lokal ini? + Remove "{name}" from this list? The file itself is not deleted. Hapus "{name}" dari daftar ini? File itu sendiri tidak dihapus. + Restore Pulihkan + Show a basic title bar for the window buttons instead of the tab strip. GNOME doesn't draw title bars for apps, so this one doesn't follow its theme. Tampilkan bilah judul sederhana untuk tombol jendela alih-alih strip tab. GNOME tidak menggambar bilah judul untuk aplikasi, jadi yang ini tidak mengikuti temanya. + This document is trying to open a local file: Dokumen ini mencoba membuka file lokal: + Use system title bar Gunakan bilah judul sistem diff --git a/crates/ui-egui/src/i18n/ko.tsv b/crates/ui-egui/src/i18n/ko.tsv index 4abd655c3..8d4fd5f8d 100644 --- a/crates/ui-egui/src/i18n/ko.tsv +++ b/crates/ui-egui/src/i18n/ko.tsv @@ -2580,3 +2580,15 @@ certificate SHA-256 digest SHA-256 다이제스트 @plural {n} file|{n} files 파일 {n}개 @plural {n} comment|{n} comments 주석 {n}개 @plural {n} result|{n} results 결과 {n}개 + Allow 허용 + Maximize 최대화 + Minimize 최소화 + Move tag earlier 태그를 앞으로 이동 + Move tag later 태그를 뒤로 이동 + Only allow this if you trust the source document. 원본 문서를 신뢰하는 경우에만 이를 허용하세요. + Open this local PDF? 이 로컬 PDF를 여시겠습니까? + Remove "{name}" from this list? The file itself is not deleted. "{name}"을(를) 이 목록에서 제거하시겠습니까? 파일 자체는 삭제되지 않습니다. + Restore 복원 + Show a basic title bar for the window buttons instead of the tab strip. GNOME doesn't draw title bars for apps, so this one doesn't follow its theme. 탭 스트립 대신 창 버튼이 있는 기본 제목 표시줄을 표시합니다. GNOME은 앱에 제목 표시줄을 그리지 않으므로 이 표시줄은 해당 테마를 따르지 않습니다. + This document is trying to open a local file: 이 문서가 로컬 파일을 열려고 합니다: + Use system title bar 시스템 제목 표시줄 사용 diff --git a/crates/ui-egui/src/i18n/vi.tsv b/crates/ui-egui/src/i18n/vi.tsv index 6699c414f..ec1fe37bb 100644 --- a/crates/ui-egui/src/i18n/vi.tsv +++ b/crates/ui-egui/src/i18n/vi.tsv @@ -2581,3 +2581,15 @@ key Esc Esc key Home Home key End End key Space Space + Allow Cho phép + Maximize Phóng to + Minimize Thu nhỏ + Move tag earlier Chuyển thẻ sớm hơn + Move tag later Chuyển thẻ muộn hơn + Only allow this if you trust the source document. Chỉ cho phép điều này nếu bạn tin tưởng tài liệu nguồn. + Open this local PDF? Mở PDF cục bộ này? + Remove "{name}" from this list? The file itself is not deleted. Xóa "{name}" khỏi danh sách này? Bản thân tệp không bị xóa. + Restore Khôi phục + Show a basic title bar for the window buttons instead of the tab strip. GNOME doesn't draw title bars for apps, so this one doesn't follow its theme. Hiển thị thanh tiêu đề cơ bản cho các nút cửa sổ thay vì dải thẻ. GNOME không vẽ thanh tiêu đề cho ứng dụng, nên thanh này không theo chủ đề của nó. + This document is trying to open a local file: Tài liệu này đang cố mở một tệp cục bộ: + Use system title bar Dùng thanh tiêu đề hệ thống From 49f3125e9e657586fc5ef31cebdd342aaba9e3fe Mon Sep 17 00:00:00 2001 From: sanches Date: Tue, 13 Oct 2026 21:58:57 +0300 Subject: [PATCH 016/498] Restore the Telugu system-font fallback the i18n rebase dropped The rebase onto main resolved the theme.rs and system_fonts.rs conflicts in favour of the new Hangul code and deleted upstream's Telugu fallback (SYSTEM_TELUGU_FALLBACK, telugu_fallback, telugu_candidates, script_fallback and their tests), while tests/fonts.rs kept the Telugu tests, so the build failed. Keep both: Telugu restored as it is on main, Hangul added alongside it through the same script_fallback helper. --- crates/ui-egui/src/system_fonts.rs | 86 ++++++++++++++++++++++++------ crates/ui-egui/src/theme.rs | 26 ++++----- 2 files changed, 82 insertions(+), 30 deletions(-) diff --git a/crates/ui-egui/src/system_fonts.rs b/crates/ui-egui/src/system_fonts.rs index 6d530e663..db654e6b0 100644 --- a/crates/ui-egui/src/system_fonts.rs +++ b/crates/ui-egui/src/system_fonts.rs @@ -3,7 +3,8 @@ //! The embedded faces (Inter, egui's defaults, craft-fonts) come first in every family; this one //! only draws characters none of them has, such as an Arabic file name in a build without //! craft-fonts, or the Simplified Chinese interface in a build without a `Hans` face (#826). A -//! second installed face, [`devanagari_fallback`], draws Hindi when one is installed. It is +//! second, a third and a fourth installed face, [`devanagari_fallback`], [`telugu_fallback`] and +//! [`hangul_fallback`], draw Hindi, Telugu and Korean when one is installed. It is //! read at runtime and never embedded or shipped (AGENTS.md §1.4), and `PDFCRAFT_SYSTEM_FONTS=0` //! turns it off (published screenshots do). @@ -22,6 +23,8 @@ const MAX_FACES: u32 = 16; const PROBE: char = '\u{0627}'; /// Devanagari letter ka: the face must have it to cover Hindi. const DEVANAGARI_PROBE: char = '\u{0915}'; +/// Telugu letter ka: the face must have it to cover Telugu. +const TELUGU_PROBE: char = '\u{0C15}'; /// Hangul syllable han (한, U+D55C): the face must have it to cover Korean. const HANGUL_PROBE: char = '\u{D55C}'; /// 欢 (U+6B22): Simplified only, absent from the Japanese craft-fonts faces. @@ -71,14 +74,14 @@ fn load(need: Need) -> Option> { /// or no candidate is installed; the interface then draws what the embedded faces can. pub fn devanagari_fallback() -> Option> { static CACHE: OnceLock>> = OnceLock::new(); - CACHE - .get_or_init(|| { - if std::env::var_os("PDFCRAFT_SYSTEM_FONTS").is_some_and(|v| v == "0") { - return None; - } - devanagari_candidates().iter().find_map(|path| read(path, DEVANAGARI_PROBE, MAX_BYTES)) - }) - .clone() + CACHE.get_or_init(|| script_fallback(&devanagari_candidates(), DEVANAGARI_PROBE, MAX_BYTES)).clone() +} + +/// The installed fallback face for Telugu, read once. `None` when it is turned off or no +/// candidate is installed; the interface then draws what the embedded faces can. +pub fn telugu_fallback() -> Option> { + static CACHE: OnceLock>> = OnceLock::new(); + CACHE.get_or_init(|| script_fallback(&telugu_candidates(), TELUGU_PROBE, MAX_BYTES)).clone() } /// The installed fallback face for Hangul (Korean), read once. `None` when it is turned off or no @@ -86,14 +89,14 @@ pub fn devanagari_fallback() -> Option> { /// has Hangul, so Korean text shows replacement boxes). pub fn hangul_fallback() -> Option> { static CACHE: OnceLock>> = OnceLock::new(); - CACHE - .get_or_init(|| { - if std::env::var_os("PDFCRAFT_SYSTEM_FONTS").is_some_and(|v| v == "0") { - return None; - } - hangul_candidates().iter().find_map(|path| read(path, HANGUL_PROBE, MAX_HAN_BYTES)) - }) - .clone() + CACHE.get_or_init(|| script_fallback(&hangul_candidates(), HANGUL_PROBE, MAX_HAN_BYTES)).clone() +} + +fn script_fallback(candidates: &[PathBuf], probe: char, max: u64) -> Option> { + if std::env::var_os("PDFCRAFT_SYSTEM_FONTS").is_some_and(|v| v == "0") { + return None; + } + candidates.iter().find_map(|path| read(path, probe, max)) } /// Well-known locations of Korean system faces, best first. Noto CJK and Source Han are left out @@ -155,6 +158,37 @@ fn devanagari_candidates() -> Vec { } } +/// Well-known locations of Telugu faces, best first. +fn telugu_candidates() -> Vec { + if cfg!(windows) { + ["Nirmala.ttc", "Nirmala.ttf", "gautami.ttf"].iter().map(|f| windows_fonts().join(f)).collect() + } else if cfg!(target_os = "macos") { + [ + "/System/Library/Fonts/KohinoorTelugu.ttc", + "/System/Library/Fonts/Supplemental/Telugu Sangam MN.ttc", + "/System/Library/Fonts/Supplemental/Telugu MN.ttc", + "/Library/Fonts/Arial Unicode.ttf", + ] + .iter() + .map(PathBuf::from) + .collect() + } else { + unix_fonts(&[ + "google-noto/NotoSansTeluguUI-Regular.ttf", + "google-noto/NotoSansTelugu-Regular.ttf", + "google-noto-vf/NotoSansTelugu[wght].ttf", + "google-noto-vf/NotoSansTelugu-UI[wght].ttf", + "truetype/noto/NotoSansTelugu-Regular.ttf", + "truetype/noto/NotoSansTeluguUI-Regular.ttf", + "noto/NotoSansTelugu-Regular.ttf", + "noto/NotoSansTeluguUI-Regular.ttf", + "lohit-telugu-fonts/Lohit-Telugu.ttf", + "truetype/lohit-telugu/Lohit-Telugu.ttf", + "truetype/fonts-telu-extra/Pothana2000.ttf", + ]) + } +} + /// Well-known locations of faces with broad script coverage, best first. fn candidates(need: Need) -> Vec { match need { @@ -285,6 +319,24 @@ mod tests { } } + #[test] + fn a_script_fallback_is_the_first_candidate_with_the_probe() { + let inter = PathBuf::from(concat!(env!("CARGO_MANIFEST_DIR"), "/../../assets/fonts/Inter-Regular.ttf")); + let candidates = [PathBuf::from("definitely/not/here.ttf"), inter]; + assert!(script_fallback(&candidates, 'A', MAX_BYTES).is_some()); + assert!(script_fallback(&candidates, TELUGU_PROBE, MAX_BYTES).is_none()); + assert!(script_fallback(&candidates, DEVANAGARI_PROBE, MAX_BYTES).is_none()); + } + + #[test] + fn script_candidates_are_absolute_font_files() { + for list in [devanagari_candidates(), telugu_candidates(), hangul_candidates()] { + assert!(!list.is_empty()); + assert!(list.iter().all(|p| p.is_absolute() || cfg!(windows)), "{list:?}"); + assert!(list.iter().all(|p| p.extension().is_some_and(|e| e == "ttf" || e == "ttc")), "{list:?}"); + } + } + #[test] fn hangul_candidates_are_font_files_without_adobe_designs() { let list = hangul_candidates(); diff --git a/crates/ui-egui/src/theme.rs b/crates/ui-egui/src/theme.rs index a91fa8cc1..94c6019be 100644 --- a/crates/ui-egui/src/theme.rs +++ b/crates/ui-egui/src/theme.rs @@ -218,6 +218,8 @@ pub fn install_fonts_for(ctx: &egui::Context, cjk: CjkPreference) { pub const SYSTEM_FALLBACK: &str = "system-fallback"; /// The name of the installed Devanagari (Hindi) face [`installed_font_definitions`] may add. pub const SYSTEM_DEVANAGARI_FALLBACK: &str = "system-devanagari-fallback"; +/// The name of the installed Telugu face [`installed_font_definitions`] may add. +pub const SYSTEM_TELUGU_FALLBACK: &str = "system-telugu-fallback"; /// The name of the installed Hangul (Korean) face [`installed_font_definitions`] may add. pub const SYSTEM_HANGUL_FALLBACK: &str = "system-hangul-fallback"; @@ -232,9 +234,9 @@ pub const SYSTEM_HANGUL_FALLBACK: &str = "system-hangul-fallback"; /// - Otherwise it is the last fallback of every family (an Arabic file name in a build without /// craft-fonts). /// -/// An installed Devanagari face, when there is one, ends every family just before that one, so -/// Hindi text draws in a build without a Devanagari face. An installed Hangul face does the same -/// for Korean: no craft-fonts face has Hangul yet. +/// An installed Devanagari face, an installed Telugu face and an installed Hangul face, when +/// there are, end every family just before that one, so Hindi, Telugu and Korean text draw in a +/// build without such faces (#1531); no craft-fonts face has Hangul yet. /// /// `PDFCRAFT_SYSTEM_FONTS=0` leaves them out. pub fn installed_font_definitions(cjk: CjkPreference) -> FontDefinitions { @@ -244,17 +246,15 @@ pub fn installed_font_definitions(cjk: CjkPreference) -> FontDefinitions { { use crate::system_fonts::{Need, fallback}; // Before the general installed face, which stays the last fallback outside Chinese. - if let Some(data) = crate::system_fonts::devanagari_fallback() { - fonts.font_data.insert(SYSTEM_DEVANAGARI_FALLBACK.to_owned(), data); + for (name, data) in [ + (SYSTEM_DEVANAGARI_FALLBACK, crate::system_fonts::devanagari_fallback()), + (SYSTEM_TELUGU_FALLBACK, crate::system_fonts::telugu_fallback()), + (SYSTEM_HANGUL_FALLBACK, crate::system_fonts::hangul_fallback()), + ] { + let Some(data) = data else { continue }; + fonts.font_data.insert(name.to_owned(), data); for stack in fonts.families.values_mut() { - stack.push(SYSTEM_DEVANAGARI_FALLBACK.to_owned()); - } - } - // No embedded face has Hangul, so Korean text relies on an installed one. - if let Some(data) = crate::system_fonts::hangul_fallback() { - fonts.font_data.insert(SYSTEM_HANGUL_FALLBACK.to_owned(), data); - for stack in fonts.families.values_mut() { - stack.push(SYSTEM_HANGUL_FALLBACK.to_owned()); + stack.push(name.to_owned()); } } let need = match cjk { From 05179596b8b3a2eb11592f925f9da26937d14c8e Mon Sep 17 00:00:00 2001 From: Si Hyeong Lee Date: Tue, 13 Oct 2026 15:21:29 -0700 Subject: [PATCH 017/498] M14: clarify Korean redaction and PDF terminology Correct 28 context-sensitive Korean labels in the incoming translation, distinguish redaction marking, clearing, and permanent removal, and add a regression test. Document code evidence and outstanding runtime QA. --- crates/ui-egui/src/i18n/ko.tsv | 56 ++++++++++++------------ crates/ui-egui/src/i18n/mod.rs | 30 +++++++++++++ docs/korean-localization-review.md | 69 ++++++++++++++++++++++++++++++ 3 files changed, 127 insertions(+), 28 deletions(-) create mode 100644 docs/korean-localization-review.md diff --git a/crates/ui-egui/src/i18n/ko.tsv b/crates/ui-egui/src/i18n/ko.tsv index 8d4fd5f8d..dec60f1d9 100644 --- a/crates/ui-egui/src/i18n/ko.tsv +++ b/crates/ui-egui/src/i18n/ko.tsv @@ -197,7 +197,7 @@ Compare files… 파일 비교… Detect form fields 양식 필드 감지 Merge data files into spreadsheet… 데이터 파일을 스프레드시트로 병합… - Flatten form fields 양식 필드 병합 + Flatten form fields 양식 필드 평탄화 Prepare a form 양식 준비 Tab order: by rows 탭 순서: 행 기준 Tab order: by columns 탭 순서: 열 기준 @@ -212,14 +212,14 @@ Removed {n} links 링크 {n}개를 제거했습니다 Add Bates numbering… Bates 번호 매기기 추가… Add image… 이미지 추가… - Redact text and images 텍스트 및 이미지 검열 - Redact pages… 페이지 검열… - Find text and redact… 텍스트 찾아 검열… - Redaction properties… 검열 속성… - Apply redactions… 검열 적용… - Clear redaction marks 검열 표시 지우기 + Redact text and images 텍스트·이미지 제거 대상 표시 + Redact pages… 페이지 내용 제거 대상 표시… + Find text and redact… 텍스트를 찾아 제거 대상으로 표시… + Redaction properties… 민감 정보 제거 속성… + Apply redactions… 표시된 정보 영구 제거… + Clear redaction marks 제거 대상 표시 지우기 Remove hidden information… 숨겨진 정보 제거… - Sanitize document… 문서 정리… + Sanitize document… 문서에서 숨겨진 정보 제거… Field properties… 필드 속성… Add a text field 텍스트 필드 추가 Add a checkbox 확인란 추가 @@ -380,10 +380,10 @@ Advanced options 고급 옵션 Encrypt with certificate 인증서로 암호화 Security properties 보안 속성 - Redact a PDF PDF 검열 - Redact 검열 - Redact pages 페이지 검열 - Find text and redact 텍스트 찾아 검열 + Redact a PDF PDF 민감 정보 제거 + Redact 민감 정보 제거 + Redact pages 페이지 내용 제거 대상 표시 + Find text and redact 텍스트를 찾아 제거 대상으로 표시 Set properties 속성 설정 Sanitize document 문서 정리 Compress a PDF PDF 압축 @@ -417,7 +417,7 @@ Output preview 출력 미리 보기 Preflight 프리플라이트 Convert colors 색상 변환 - Add printer marks 프린터 표시 추가 + Add printer marks 인쇄용 표시 추가 Fix hairlines 헤어라인 수정 Measure objects 개체 측정 Measure 측정 @@ -467,7 +467,7 @@ Preview 미리 보기 Edit fields 필드 편집 Try the form as people filling it in will see it 양식을 작성하는 사용자에게 보이는 그대로 양식을 사용해 보세요 - Redact all 모두 검열 + Redact all 표시된 정보 모두 영구 제거 Clear all 모두 지우기 Rotate page 페이지 회전 Delete page 페이지 삭제 @@ -1109,27 +1109,27 @@ Text in images isn't found; recognise text (OCR) first. 이미지 속 텍스트는 찾을 수 없습니다. 먼저 텍스트 인식(OCR)을 실행하세요. No matches. 일치하는 항목이 없습니다. Some bookmarks are not shown here: the panel lists a limited number, nested a limited depth. 일부 책갈피는 여기에 표시되지 않습니다. 패널에 나열되는 개수와 중첩 깊이가 제한되어 있습니다. - {n} match(es) marked for redaction. 검열하도록 표시된 일치 항목 {n}개입니다. + {n} match(es) marked for redaction. 검색 결과 {n}건을 제거 대상으로 표시했습니다. Multiple words or phrases 여러 단어 또는 구문 One word or phrase per line 한 줄에 단어 또는 구문 하나 Import list… 목록 가져오기… {n} word(s) or phrase(s) 단어 또는 구문 {n}개 {name} is too large for a word list (at most 1 MB). {name}은(는) 단어 목록으로 사용하기에 너무 큽니다(최대 1 MB). - Redaction Tool Properties 검열 도구 속성 - Redacted area fill colour: 검열 영역 채우기 색: + Redaction Tool Properties 민감 정보 제거 도구 속성 + Redacted area fill colour: 제거 영역 채우기 색: Use overlay text 오버레이 텍스트 사용 Custom text: 사용자 지정 텍스트: - Redaction code: 검열 코드: + Redaction code: 제거 사유 코드: Font: 글꼴: Font size: 글꼴 크기: - Auto-size text to fit redaction region 검열 영역에 맞게 텍스트 크기 자동 조정 + Auto-size text to fit redaction region 제거 영역에 맞춰 표시 문구 크기 자동 조정 Font colour: 글꼴 색: Repeat overlay text 오버레이 텍스트 반복 Text alignment: 텍스트 정렬: Center 가운데 - Apply redactions 검열 적용 - You are about to apply 1 redaction mark. Text, images and drawings under the marks, and comments and form fields that overlap them, are removed permanently. 검열 표시 1개를 적용하려고 합니다. 표시 아래의 텍스트, 이미지, 그림과 표시와 겹치는 주석 및 양식 필드가 영구적으로 제거됩니다. - You are about to apply {n} redaction marks. Text, images and drawings under the marks, and comments and form fields that overlap them, are removed permanently. 검열 표시 {n}개를 적용하려고 합니다. 표시 아래의 텍스트, 이미지, 그림과 표시와 겹치는 주석 및 양식 필드가 영구적으로 제거됩니다. + Apply redactions 표시된 정보 영구 제거 + You are about to apply 1 redaction mark. Text, images and drawings under the marks, and comments and form fields that overlap them, are removed permanently. 제거 대상 표시 1개를 적용하려고 합니다. 표시된 영역의 텍스트, 이미지, 그림과 겹치는 주석 및 양식 필드가 영구적으로 제거됩니다. + You are about to apply {n} redaction marks. Text, images and drawings under the marks, and comments and form fields that overlap them, are removed permanently. 제거 대상 표시 {n}개를 적용하려고 합니다. 표시된 영역의 텍스트, 이미지, 그림과 겹치는 주석 및 양식 필드가 영구적으로 제거됩니다. Save the document afterwards: saving rewrites the whole file so no trace of the removed content stays in it. 그 후 문서를 저장하세요. 저장하면 파일 전체가 다시 쓰여져 제거된 콘텐츠의 흔적이 남지 않습니다. Select the items to remove from this document. 이 문서에서 제거할 항목을 선택하세요. Metadata 메타데이터 @@ -1799,7 +1799,7 @@ a bookmark cannot be moved inside itself 책갈피를 자기 자신 안으로 이동할 수 없음 the title must not be empty 제목은 비워 둘 수 없음 the document has no form fields 문서에 양식 필드가 없음 - there are no redaction marks to apply 적용할 검열 표시가 없음 + there are no redaction marks to apply 적용할 제거 대상 표시가 없음 there are no pages to print 인쇄할 페이지가 없음 the document has no tags 문서에 태그가 없음 {0}: {1} {0}: {1} @@ -1905,7 +1905,7 @@ Add image 이미지 추가 Edit content 콘텐츠 편집 Delete content 콘텐츠 삭제 - Remove redaction marks 검열 표시 제거 + Remove redaction marks 제거 대상 표시 삭제 Add link 링크 추가 Change link properties 링크 속성 변경 Delete link 링크 삭제 @@ -1926,7 +1926,7 @@ Add cross X 표시 추가 Add dot 점 추가 Add signature 서명 추가 - Add redaction mark 검열 표시 추가 + Add redaction mark 제거 대상 표시 추가 Add cloud 구름 추가 Add polygon 다각형 추가 Add connected lines 연결선 추가 @@ -2135,8 +2135,8 @@ calendar date December 12월 Align fields 필드 정렬 Distribute fields 필드 분배 Match field sizes 필드 크기 맞춤 - Mark for redaction 검열 표시 - Mark pages for redaction 페이지 검열 표시 + Mark for redaction 제거할 영역 표시 + Mark pages for redaction 페이지 내용 제거 대상으로 표시 Change document properties 문서 속성 변경 Mark differences 차이점 표시 Run form script 양식 스크립트 실행 @@ -2165,7 +2165,7 @@ calendar date December 12월 Larger pages 더 큰 페이지 Smaller pages 더 작은 페이지 Reset page size 페이지 크기 재설정 - Flatten Fill & Sign when saving 저장할 때 채우기 및 서명 병합 + Flatten Fill & Sign when saving 저장 시 입력 내용과 서명을 페이지에 고정 Text, marks and signatures become part of the page. Other comments stay editable. 텍스트, 표시 및 서명이 페이지의 일부가 됩니다. 다른 주석은 계속 편집할 수 있습니다. Date format 날짜 형식 Fill & Sign dates 채우기 및 서명 날짜 diff --git a/crates/ui-egui/src/i18n/mod.rs b/crates/ui-egui/src/i18n/mod.rs index 8f62d8d29..20121d123 100644 --- a/crates/ui-egui/src/i18n/mod.rs +++ b/crates/ui-egui/src/i18n/mod.rs @@ -2558,6 +2558,36 @@ mod tests { } } + /// Redaction first marks a region; applying it irreversibly removes marked content. + /// Korean must not present either stage as censorship ("검열") or imply that + /// clearing un-applied marks deletes PDF content. + #[test] + fn korean_redaction_labels_distinguish_marks_and_permanent_removal() { + let ko = Lang::from_code("ko").expect("ko registered"); + for english in [ + "Redact", + "Redact a PDF", + "Redact text and images", + "Redact pages…", + "Mark for redaction", + "Apply redactions", + "Apply redactions…", + "Clear redaction marks", + "Redact all", + ] { + assert!(!tr(ko, english).contains("검열"), "Korean label misstates redaction: {english}"); + } + assert_eq!(tr(ko, "Mark for redaction"), "제거할 영역 표시"); + assert_eq!(tr(ko, "Apply redactions"), "표시된 정보 영구 제거"); + assert_eq!(tr(ko, "Clear redaction marks"), "제거 대상 표시 지우기"); + let warning = concat!( + "You are about to apply 1 redaction mark. ", + "Text, images and drawings under the marks, and comments ", + "and form fields that overlap them, are removed permanently." + ); + assert!(tr(ko, warning).contains("영구적으로 제거됩니다")); + } + /// Hindi and Korean translate every registered command and every All tools group, section /// and item. #[test] diff --git a/docs/korean-localization-review.md b/docs/korean-localization-review.md new file mode 100644 index 000000000..249152951 --- /dev/null +++ b/docs/korean-localization-review.md @@ -0,0 +1,69 @@ +# Korean UI terminology review — draft follow-up to #1976 + +This is a code-grounded review draft, NOT evidence of completed native-speaker or runtime QA. Only +Korean UI labels change; English lookup keys, stable command IDs, PDF contents and automation +protocols remain unchanged. + +## Redaction has three separate operations + +The initial Korean catalog used the word "검열" (censorship) for all redaction actions. +The project source has three distinct stages: + +| Stage | Relevant code | Korean meaning | +| --- | --- | --- | +| Mark | crates/ui-egui/src/redact_ui.rs (RedactPrefs::mark), crates/engine/src/commands.rs (redact.mark/pages/search) | Mark a future removal area; content is not yet permanently removed | +| Apply | crates/ui-egui/src/commands.rs (redact.apply), crates/ui-egui/src/redact_ui.rs (confirmation), crates/redact/src/lib.rs (apply) | Confirm and remove covered content permanently | +| Clear | crates/ui-egui/src/commands.rs (redact.clear -> Edit::ClearRedactions) | Clear pending marks WITHOUT deleting the underlying content | + +Terminology chosen from these behaviors: + +- Tool (Redact): 민감 정보 제거 +- Mark for redaction: 제거할 영역 표시 +- Apply redactions: 표시된 정보 영구 제거 +- Clear redaction marks: 제거 대상 표시 지우기 +- Redaction code: 제거 사유 코드 (reason/exemption code sets: crates/redact/src/codes.rs) + +"Clear all" is a generic English lookup key used in other contexts and intentionally +is NOT changed to "clear redaction marks" globally. + +## Additional terminology improvements + +| English | Previous | Proposed | Source | +| --- | --- | --- | --- | +| Sanitize document… | 문서 정리… | 문서에서 숨겨진 정보 제거… | crates/redact/src/sanitize.rs | +| Flatten form fields | 양식 필드 병합 | 양식 필드 평탄화 | crates/ui-egui/src/optimize_ui.rs | +| Flatten Fill & Sign when saving | 저장할 때 채우기 및 서명 병합 | 저장 시 입력 내용과 서명을 페이지에 고정 | crates/ui-egui/src/editing.rs | +| Add printer marks | 프린터 표시 추가 | 인쇄용 표시 추가 | printer marks are printed on pages, not on devices | + +This review does not change acceptable variations such as 확인란/체크박스 or +Bates/베이츠 simply for stylistic reasons. Certificate and digital-signature +language requires separate code-context review. + +## Verification and remaining gates + +- Tested: catalog key coverage, TSV structural rules, placeholder preservation, + ellipsis preservation, old-vs-new textual regression assertions. +- Added a Rust regression test for the distinct redaction stage labels. This test + had failing baseline strings before the terminology changes. +- NOT YET EXECUTED: cargo fmt, Rust unit tests, real Windows UI, font glyph coverage, + PDF save/reopen, OCR, permanent-redaction behavior on a synthetic PDF. + These gates are necessary before calling the translation production-ready. + +## UI acceptance test matrix (synthetic data only) + +1. With an English UI, open a sample PDF called 한글_검수.pdf containing Hangul bookmark + and comment text. Verify that tab, bookmark, search and dialogs render Hangul rather + than replacement boxes, regardless of interface language. +2. Select 한국어 under Preferences and check persistence; separately test Auto on ko-KR. +3. Draw a redaction mark on TEST-REDACT-UNIQUE. Before Apply, the UI must say + "marked" rather than implying permanent removal. Clear must remove only marks. +4. On a separate synthetic document, Apply redactions, save and reopen; inspect + extracted text and rendered output for the removed token (source-byte/fidelity + checks belong in the engine suite as well). +5. Flatten an AcroForm field and reopen: the visible value should remain on the + page without the interactive field being editable as before. +6. Test 100/125/150% Windows display scaling for Korean text overflow and truncation. +7. Test web build font delivery separately once Hangul font PR #1484 lands. + +The translations were written from intended source-code behavior. Do not copy other +products' localization files, proprietary Adobe assets, fonts or real users' PDFs. From 19e95dd27b73aefaa466b48793174b427d9ce8dd Mon Sep 17 00:00:00 2001 From: sanches Date: Wed, 14 Oct 2026 01:31:50 +0300 Subject: [PATCH 018/498] Fix stale translation-catalog SHA-256 entries after the rebase Rebasing onto newer main replayed ATTRIBUTION.toml with the hashes of the older base, so every catalog entry failed the xtask manifest check. Restore main's entries for the catalogs this branch does not touch and recompute ours (ru and the four new catalogs) from the files as committed. --- ATTRIBUTION.toml | 50 ++++++++++++++++++++++++------------------------ 1 file changed, 25 insertions(+), 25 deletions(-) diff --git a/ATTRIBUTION.toml b/ATTRIBUTION.toml index 3d999b60c..ded830833 100644 --- a/ATTRIBUTION.toml +++ b/ATTRIBUTION.toml @@ -7,7 +7,7 @@ licence = "MIT OR Apache-2.0" licence_file = "LICENSE-MIT" kind = "translation" usage = "Greek UI strings, compiled in by crates/ui-egui/src/i18n/mod.rs" -sha256 = "e04ab5246125efae2bad439e62c150fc10649c4b6796b30565615f5bd7509ec6" +sha256 = "d0a69a35403e70b94c3adfef88b41ec719f4f6ab700d351c8f82a78c53b63ef6" # ATTRIBUTION.toml: one entry per asset (AGENTS.md §1). The source of truth for provenance and licences. # ATTRIBUTION.md is generated from this file: `cargo xtask assets --write`. Checked by `cargo xtask assets` (part of `xtask ci`). @@ -30,7 +30,7 @@ licence = "MIT OR Apache-2.0" licence_file = "LICENSE-MIT" kind = "translation" usage = "Simplified Chinese UI strings, compiled in by crates/ui-egui/src/i18n/mod.rs" -sha256 = "7f600eaa47f23fac4f9f0fece1454e59756c8dc57c7c697502cb02ee21410ac0" +sha256 = "caa23201b7f25dba9f8dc579771e13435e5e8c72a7efb9770e917a2a33003a39" [[asset]] path = "crates/ui-egui/src/i18n/zh-hant.tsv" @@ -41,7 +41,7 @@ licence = "MIT OR Apache-2.0" licence_file = "LICENSE-MIT" kind = "translation" usage = "Traditional Chinese UI strings, compiled in by crates/ui-egui/src/i18n/mod.rs" -sha256 = "37733adc79d7d32a057811b4dc5eb31251ef8ec91f1dac430253c69faac1c33f" +sha256 = "5ead9fccdca17810a3a98de3fa499d8a2469a1ff015c3d0e11880ca629295ea1" [[asset]] path = "crates/ui-egui/src/i18n/cs.tsv" @@ -52,7 +52,7 @@ licence = "MIT OR Apache-2.0" licence_file = "LICENSE-MIT" kind = "translation" usage = "Czech UI strings, compiled in by crates/ui-egui/src/i18n/mod.rs" -sha256 = "285b689b5224a66079738ab39d5a27e5f9ba72e1ab42e148f263b7ea320c4729" +sha256 = "d48f9d68711850cae48af53f7691facee4209f7846e3eb2c064d97dad2ae2426" [[asset]] path = "crates/ui-egui/src/i18n/pt-br.tsv" @@ -63,7 +63,7 @@ licence = "MIT OR Apache-2.0" licence_file = "LICENSE-MIT" kind = "translation" usage = "Brazilian Portuguese UI strings, compiled in by crates/ui-egui/src/i18n/mod.rs" -sha256 = "e8154a154129ca158396de84d2d432ce1c587477795a6a14985f7834db255744" +sha256 = "6bc2edec99534d0df9b5e4a1c2e18dc32ad84c32e404c74dd437d86119b1d6ea" [[asset]] path = "crates/ui-egui/src/i18n/es.tsv" @@ -74,7 +74,7 @@ licence = "MIT OR Apache-2.0" licence_file = "LICENSE-MIT" kind = "translation" usage = "Spanish UI strings, compiled in by crates/ui-egui/src/i18n/mod.rs" -sha256 = "50d4e66209e8b56707bcd148d4644eb0ad9f49dfc195287cfbd851ffbe5c3830" +sha256 = "cb6c04bd36ba6ce0ebc808da2e47b65797e14d59466e93802adec4d4f5056e3b" [[asset]] path = "crates/ui-egui/src/i18n/fr.tsv" @@ -85,7 +85,7 @@ licence = "MIT OR Apache-2.0" licence_file = "LICENSE-MIT" kind = "translation" usage = "French UI strings, compiled in by crates/ui-egui/src/i18n/mod.rs" -sha256 = "13e677d44d5224e60af28fcc89d8f8af552368ca3c11f0a871498c60fefa7ee2" +sha256 = "0368944155991c2ea304788418fb326f30e45649539a0cf49539194b026ca104" [[asset]] path = "crates/ui-egui/src/i18n/de.tsv" @@ -96,7 +96,7 @@ licence = "MIT OR Apache-2.0" licence_file = "LICENSE-MIT" kind = "translation" usage = "German UI strings, compiled in by crates/ui-egui/src/i18n/mod.rs" -sha256 = "e81112d69acc2e1bbb44c5252f8f323b1d637059b5ac5f4c9fcd3eb985a53442" +sha256 = "f4969c353f1424c6b9b5b110820c69dc59907590d013221511eae3f86c29024e" [[asset]] path = "crates/ui-egui/src/i18n/te.tsv" @@ -107,7 +107,7 @@ licence = "MIT OR Apache-2.0" licence_file = "LICENSE-MIT" kind = "translation" usage = "Telugu UI strings, compiled in by crates/ui-egui/src/i18n/mod.rs" -sha256 = "df3d3650af984251372bf22b859ba6aca47f26eeff790e834d57a5a4071a1b48" +sha256 = "4bb6fa4f3b6e236a4a353df79acd0c5528ea8354058eeaeb66c28bc0f7e02939" [[asset]] path = "crates/ui-egui/src/i18n/it.tsv" @@ -118,7 +118,7 @@ licence = "MIT OR Apache-2.0" licence_file = "LICENSE-MIT" kind = "translation" usage = "Italian UI strings, compiled in by crates/ui-egui/src/i18n/mod.rs" -sha256 = "c9e453382d9d5c83f7b0f986befc6113a62b4736a6b94a6462805cead406753b" +sha256 = "adcbdfc683589b067e062a6200084bf9192935b297f5b616f8ed39db9c71db9b" [[asset]] path = "crates/ui-egui/src/i18n/pl.tsv" @@ -129,7 +129,7 @@ licence = "MIT OR Apache-2.0" licence_file = "LICENSE-MIT" kind = "translation" usage = "Polish UI strings, compiled in by crates/ui-egui/src/i18n/mod.rs" -sha256 = "2a205868b13f719dbc91fdc50f1133f5f317aa2245143bfeaa048190bc9c7d8c" +sha256 = "aebe63cd91df2d2f9d2bdc1da43b017823dbc8a32135e999b9ac7041277be0c8" [[asset]] path = "crates/ui-egui/src/i18n/ru.tsv" @@ -140,7 +140,7 @@ licence = "MIT OR Apache-2.0" licence_file = "LICENSE-MIT" kind = "translation" usage = "Russian UI strings, compiled in by crates/ui-egui/src/i18n/mod.rs" -sha256 = "59ff8e2d10c825711e25af41e3b12366a24568be725ba07998f2c6be30e56187" +sha256 = "8a1bd9d28658db4d2106840837da608203efbcfdba1f350b58549518dea789ad" [[asset]] path = "crates/ui-egui/src/i18n/hu.tsv" @@ -151,7 +151,7 @@ licence = "MIT OR Apache-2.0" licence_file = "LICENSE-MIT" kind = "translation" usage = "Hungarian UI strings, compiled in by crates/ui-egui/src/i18n/mod.rs" -sha256 = "882b3937802bbbd5afe0087264ee4118161351e8828cb02b608488ccfe39bfe9" +sha256 = "637fcfdd0bf1898b413af7ccbc2eb4228bf656273de9f3ef9241bd128940aeab" [[asset]] path = "crates/ui-egui/src/i18n/bg.tsv" @@ -162,7 +162,7 @@ licence = "MIT OR Apache-2.0" licence_file = "LICENSE-MIT" kind = "translation" usage = "Bulgarian UI strings, compiled in by crates/ui-egui/src/i18n/mod.rs" -sha256 = "8cca054e167995ca6d95bc45fc0f75385a15a78852e4b173bd4c5b7b651c5a9d" +sha256 = "5285f8987bd8c265f73ff443906c1832a0886037592d334974cf539b9f972a3f" [[asset]] path = "crates/ui-egui/src/i18n/kk.tsv" @@ -173,7 +173,7 @@ licence = "MIT OR Apache-2.0" licence_file = "LICENSE-MIT" kind = "translation" usage = "Kazakh UI strings, compiled in by crates/ui-egui/src/i18n/mod.rs" -sha256 = "2f4a6429c0c290a53268733dac08da221085992036a4d304d7663d7947d806d3" +sha256 = "23779abc08be40ddfb305fd638fe280c854ac33473b2822006ba8bad399c0cad" [[asset]] path = "crates/ui-egui/src/i18n/ja.tsv" @@ -184,7 +184,7 @@ licence = "MIT OR Apache-2.0" licence_file = "LICENSE-MIT" kind = "translation" usage = "Japanese UI strings, compiled in by crates/ui-egui/src/i18n/mod.rs" -sha256 = "2792f38b1699269b5886fa99a17c7773c3934df95dc4e2db3ba6a475dd652ba0" +sha256 = "c5129c40b202d8467d8d4cf0a189da8c2ba2af711998edb73f67e1b291289a04" [[asset]] path = "crates/ui-egui/src/i18n/uk.tsv" @@ -195,7 +195,7 @@ licence = "MIT OR Apache-2.0" licence_file = "LICENSE-MIT" kind = "translation" usage = "Ukrainian UI strings, compiled in by crates/ui-egui/src/i18n/mod.rs" -sha256 = "937ac7eac4230c9a1d26d6bd7ef4f08f8d8c9d391a091682e8758fba3ca9678e" +sha256 = "11ed2aa56dc5f8f6656eba717500c74bb8c8f931c08f9f9b210b5b33dd9c2d5a" [[asset]] path = "crates/ui-egui/src/i18n/ar.tsv" @@ -206,7 +206,7 @@ licence = "MIT OR Apache-2.0" licence_file = "LICENSE-MIT" kind = "translation" usage = "Arabic UI strings, compiled in by crates/ui-egui/src/i18n/mod.rs" -sha256 = "7ced08c3485c5eddf92767e6deb009d72351d70cefe60be654cfdac441f40f4b" +sha256 = "a3863e2fed5ef584a87f65083a6b9fedf26d18ecebd574efce22bd7a01e3281c" [[asset]] path = "crates/ui-egui/src/i18n/tr.tsv" @@ -217,7 +217,7 @@ licence = "MIT OR Apache-2.0" licence_file = "LICENSE-MIT" kind = "translation" usage = "Turkish UI strings, compiled in by crates/ui-egui/src/i18n/mod.rs" -sha256 = "4e70c6db374db37bf70a17e251675b94128fb11b4d6d20ef669b36fd4ae14ff1" +sha256 = "cade94846289c2822b408a2ea23e6c8f8f321708f4f27fd563695a3c4fade6a1" [[asset]] path = "crates/ui-egui/src/i18n/lt.tsv" @@ -228,7 +228,7 @@ licence = "MIT OR Apache-2.0" licence_file = "LICENSE-MIT" kind = "translation" usage = "Lithuanian UI strings, compiled in by crates/ui-egui/src/i18n/mod.rs" -sha256 = "d2e6be7cf74525310a203bed7434e7f69d2288d337ee696de2882df8da31a746" +sha256 = "35b6b03dae01b9a2e98f6d1f682d0699d77772e6efec7e28e1f26039c57b151f" [[asset]] path = "crates/ui-egui/src/i18n/id.tsv" @@ -239,7 +239,7 @@ licence = "MIT OR Apache-2.0" licence_file = "LICENSE-MIT" kind = "translation" usage = "Indonesian UI strings, compiled in by crates/ui-egui/src/i18n/mod.rs" -sha256 = "18b59a25fc0798b9f426a2d7d1e4272847df9fa8310de4754bd0b90098dc5cd1" +sha256 = "364cfd8a35eae330bb233fe5a2dc3f7cdfdfdbee13570fa2cbc3664d12a42621" [[asset]] path = "crates/ui-egui/src/i18n/vi.tsv" @@ -250,7 +250,7 @@ licence = "MIT OR Apache-2.0" licence_file = "LICENSE-MIT" kind = "translation" usage = "Vietnamese UI strings, compiled in by crates/ui-egui/src/i18n/mod.rs" -sha256 = "21215a2a3489a03050d884b51a512e5c8b58b690dd36e182a4917ddd87b7b922" +sha256 = "1c206972f2ae3430bf1d1745c272e8a25ecabf8c484c1ad31e69ceece8adc933" [[asset]] path = "crates/ui-egui/src/i18n/hi.tsv" @@ -261,7 +261,7 @@ licence = "MIT OR Apache-2.0" licence_file = "LICENSE-MIT" kind = "translation" usage = "Hindi UI strings, compiled in by crates/ui-egui/src/i18n/mod.rs" -sha256 = "0dff6ebbd918a71f3e1e4dab7f439088bedf91469fc6bf56c3e1a0e114e99149" +sha256 = "8a7c2fb9c4ffe3b56cef928ee07269e93ce653fa89b7cd2d439231046ac05619" [[asset]] path = "crates/ui-egui/src/i18n/ko.tsv" @@ -272,7 +272,7 @@ licence = "MIT OR Apache-2.0" licence_file = "LICENSE-MIT" kind = "translation" usage = "Korean UI strings, compiled in by crates/ui-egui/src/i18n/mod.rs" -sha256 = "0254b088b5ef93c88a2f9cfc0a27cdf12eaf38fcad6f0a619adb34a618175cc5" +sha256 = "b570144be1a0296fa4a95648611709641420efbff44de7845344c1cbe2c37004" [[asset]] path = "assets/icons/accessibility.svg" @@ -3383,4 +3383,4 @@ licence = "MIT OR Apache-2.0" licence_file = "LICENSE-MIT" kind = "translation" usage = "Slovene UI strings, compiled in by crates/ui-egui/src/i18n/mod.rs" -sha256 = "6c01a439220415b83acab79c014286e5871ba7946a9c3b9a4776be797d55a086" +sha256 = "2685fbb694cbdeb7632ecb5e7396e1209047c83319e28ceea032b3ec9fb2fc0e" From c699e88c93fef33611982612542ab762c6170431 Mon Sep 17 00:00:00 2001 From: Saimirbaci Date: Mon, 12 Oct 2026 19:51:42 -0400 Subject: [PATCH 019/498] i18n: add Albanian (sq) interface language 2,330-entry clean-room catalog, Albanian month and weekday names for date formats, Preferences entry, locale matching for sq-*, coverage tests, font coverage test, attribution entry and docs. Co-Authored-By: Claude Sonnet 5.5 --- ATTRIBUTION.md | 3 +- ATTRIBUTION.toml | 11 + ROADMAP.md | 1 + crates/engine/src/dates.rs | 13 +- crates/ui-egui/src/i18n/mod.rs | 58 +- crates/ui-egui/src/i18n/sq.tsv | 2354 ++++++++++++++++++++++++++++++++ crates/ui-egui/tests/fonts.rs | 3 +- docs/localization-parity.md | 4 +- docs/localization.md | 18 +- 9 files changed, 2452 insertions(+), 13 deletions(-) create mode 100644 crates/ui-egui/src/i18n/sq.tsv diff --git a/ATTRIBUTION.md b/ATTRIBUTION.md index 3b451f246..10f8eddd7 100644 --- a/ATTRIBUTION.md +++ b/ATTRIBUTION.md @@ -4,7 +4,7 @@ Every asset PdfCraft includes, bundles or uses to build its published material, with its author, source and licence. The policy is in [AGENTS.md](AGENTS.md) §1. The machine-readable list, with SHA-256 hashes, is [ATTRIBUTION.toml](ATTRIBUTION.toml). Licence texts are kept beside the assets and summarised in [NOTICE](NOTICE). -## In this repository (270) +## In this repository (271) | Asset | Title | Author | Licence | Source | Used for | |---|---|---|---|---|---| @@ -278,6 +278,7 @@ Every asset PdfCraft includes, bundles or uses to build its published material, | `crates/sign/tests/data/x509-rsa-sha1.pdf` | One-page PDF with a legacy adbe.x509.rsa_sha1 signature by the RSA test key | PdfCraft contributors | MIT OR Apache-2.0 | Contributor-original: hand-written PDF objects; signature made with `openssl dgst -sha1 -sign` over its byte ranges (see crates/sign/tests/data/README.md) | Signature validation tests (crates/sign/tests/pdf.rs): the legacy adbe.x509.rsa_sha1 format | | `assets/icons/monitor.svg` | Lucide icon "monitor" | Lucide Contributors (portions Cole Bemis, Feather) | ISC | https://github.com/lucide-icons/lucide (npm lucide-static 1.49.0, icons/monitor.svg) | UI icon, embedded via crates/ui-egui/src/icon_data.rs | | `crates/ui-egui/src/i18n/sl.tsv` | Slovene interface translation catalog | PdfCraft contributors | MIT OR Apache-2.0 | Contributor-original: clean-room translations of PdfCraft's English UI labels, no proprietary localisation resources | Slovene UI strings, compiled in by crates/ui-egui/src/i18n/mod.rs | +| `crates/ui-egui/src/i18n/sq.tsv` | Albanian interface translation catalog | PdfCraft contributors | MIT OR Apache-2.0 | Contributor-original: clean-room translations of PdfCraft's English UI labels, no proprietary localisation resources | Albanian UI strings, compiled in by crates/ui-egui/src/i18n/mod.rs | ## Compiled in through dependencies (6) diff --git a/ATTRIBUTION.toml b/ATTRIBUTION.toml index 07433fc45..659049732 100644 --- a/ATTRIBUTION.toml +++ b/ATTRIBUTION.toml @@ -3352,3 +3352,14 @@ licence_file = "LICENSE-MIT" kind = "translation" usage = "Slovene UI strings, compiled in by crates/ui-egui/src/i18n/mod.rs" sha256 = "9bbbd0d516f284b571ad6e2ed811f6bbdee283cea8483686f4aa939db38ea288" + +[[asset]] +path = "crates/ui-egui/src/i18n/sq.tsv" +title = "Albanian interface translation catalog" +author = "PdfCraft contributors" +source = "Contributor-original: clean-room translations of PdfCraft's English UI labels, no proprietary localisation resources" +licence = "MIT OR Apache-2.0" +licence_file = "LICENSE-MIT" +kind = "translation" +usage = "Albanian UI strings, compiled in by crates/ui-egui/src/i18n/mod.rs" +sha256 = "ca7e318035c785ef0e06e77aea1d81335eab243be6619371ed9cf751085789aa" diff --git a/ROADMAP.md b/ROADMAP.md index b4ab4ea8a..195ec8185 100644 --- a/ROADMAP.md +++ b/ROADMAP.md @@ -445,3 +445,4 @@ Newest first: the date, what moved, and the new overall estimate. | 2026-10-05 | major | Honest assessment and "Where we're lacking" added | - **2026-10-12 (M8):** Redaction cleans indirect and form structure references, preserving surviving form tags. +- **2026-10-12 (i18n):** Albanian (`sq`, Shqip) added: 2,343-entry catalog, month and weekday names, Preferences entry; not yet reviewed by a native speaker. diff --git a/crates/engine/src/dates.rs b/crates/engine/src/dates.rs index e26d9ec60..f6aeeb551 100644 --- a/crates/engine/src/dates.rs +++ b/crates/engine/src/dates.rs @@ -56,7 +56,7 @@ const AR_DAYS: [&str; 7] = ["الأحد", "الاثنين", "الثلاثاء", /// The languages month and weekday names can be written in (Preferences ▸ Date format ▸ Language): /// the interface languages, in the same order and with the same names. -pub static DATE_LANGUAGES: [DateLanguage; 22] = [ +pub static DATE_LANGUAGES: [DateLanguage; 23] = [ DateLanguage { code: "en", name: "English", @@ -360,6 +360,15 @@ pub static DATE_LANGUAGES: [DateLanguage; 22] = [ days: ["sekmadienis", "pirmadienis", "antradienis", "trečiadienis", "ketvirtadienis", "penktadienis", "šeštadienis"], days_short: ["sk", "pr", "an", "tr", "kt", "pn", "št"], }, + DateLanguage { + code: "sq", + name: "Shqip", + months: ["janar", "shkurt", "mars", "prill", "maj", "qershor", "korrik", "gusht", "shtator", "tetor", "nëntor", "dhjetor"], + months_with_day: None, + months_short: ["jan", "shk", "mar", "pri", "maj", "qer", "korr", "gush", "sht", "tet", "nën", "dhj"], + days: ["e diel", "e hënë", "e martë", "e mërkurë", "e enjte", "e premte", "e shtunë"], + days_short: ["die", "hën", "mar", "mër", "enj", "pre", "sht"], + }, ]; /// The date language for `code` (any case), or `None` when there's none. @@ -643,6 +652,8 @@ mod tests { assert_eq!(in_lang("yyyy\\年mmmmd\\日 dddd", "ja"), "2026年3月7日 土曜日"); assert_eq!(in_lang("yyyy\\年mmmmd\\日 dddd", "zh-hans"), "2026年三月7日 星期六"); assert_eq!(in_lang("ddd", "zh-hant"), "週六"); + assert_eq!(in_lang("dddd, d mmmm yyyy", "sq"), "e shtunë, 7 mars 2026"); + assert_eq!(in_lang("ddd d mmm", "sq"), "sht 7 mar"); assert_eq!(date_language("PT-BR").map(|l| l.code), Some("pt-br")); assert!(date_language("xx").is_none()); for l in &DATE_LANGUAGES { diff --git a/crates/ui-egui/src/i18n/mod.rs b/crates/ui-egui/src/i18n/mod.rs index 18a0fc54b..118dee0e7 100644 --- a/crates/ui-egui/src/i18n/mod.rs +++ b/crates/ui-egui/src/i18n/mod.rs @@ -147,7 +147,7 @@ fn plural_sl(n: u64) -> usize { } /// The registry. English first: it is the fallback and the source language. -pub static LANGUAGES: [LangInfo; 22] = [ +pub static LANGUAGES: [LangInfo; 23] = [ LangInfo { code: "en", name: "English", source: "", plural: plural_one_other, rtl: false, catalog: OnceLock::new() }, LangInfo { code: "ja", name: "日本語", source: include_str!("ja.tsv"), plural: plural_none, rtl: false, catalog: OnceLock::new() }, // Simplified Chinese; `zh`, `zh-CN`, `zh-SG` and `zh-Hans-*` locales resolve here (see `candidates`). @@ -207,6 +207,8 @@ pub static LANGUAGES: [LangInfo; 22] = [ LangInfo { code: "tr", name: "Türkçe", source: include_str!("tr.tsv"), plural: plural_none, rtl: false, catalog: OnceLock::new() }, // Lithuanian; every `lt-*` locale (`lt-LT`, `lt_LT.UTF-8`) resolves here. Three plural forms (one, few, other). LangInfo { code: "lt", name: "Lietuvių", source: include_str!("lt.tsv"), plural: plural_lithuanian, rtl: false, catalog: OnceLock::new() }, + // Albanian; every `sq-*` locale (`sq-AL`, `sq_AL.UTF-8`, `sq-XK`) resolves here. One/other plural, like English. + LangInfo { code: "sq", name: "Shqip", source: include_str!("sq.tsv"), plural: plural_one_other, rtl: false, catalog: OnceLock::new() }, ]; impl LangInfo { @@ -2288,6 +2290,60 @@ mod tests { assert_eq!(restored.language, "sl"); } + #[test] + fn albanian_is_registered_and_persists() { + let sq = Lang::from_code("sq").expect("sq registered"); + assert_eq!(sq.name(), "Shqip"); + assert_eq!(normalize_pref("SQ"), Some("sq")); + for tag in ["sq", "sq-AL", "sq_AL.UTF-8", "SQ-xk", "sq_XK@variant"] { + assert_eq!(lang_from_tag(tag), Some(sq), "{tag}"); + } + assert_eq!(first_supported("sq-AL\r\nen-US"), Some(sq)); + assert_eq!(tr(sq, "File"), "Skedari"); + // one (1), other (0, 2+) + assert_eq!((0..=3).map(|n| (sq.0.plural)(n)).collect::>(), [1, 0, 1, 1]); + assert_eq!(trn(sq, 1, "{n} page", "{n} pages"), "1 faqe"); + assert_eq!(trn(sq, 0, "{n} page", "{n} pages"), "0 faqe"); + assert_eq!(trn(sq, 5, "{n} page", "{n} pages"), "5 faqe"); + let mut app = crate::PdfCraftApp::default(); + app.set_option("language", "SQ").unwrap(); + assert_eq!(app.language, "sq"); + let mut restored = crate::PdfCraftApp::default(); + restored.restore(&app.persist()); + assert_eq!(restored.language, "sq"); + assert!(restored.set_option("language", "xx").is_err()); + assert_eq!(restored.language, "sq"); + } + + /// Albanian translates every registered command and every All tools group, section and item. + #[test] + fn albanian_covers_commands_and_catalogue() { + let sq = Lang::from_code("sq").expect("sq registered"); + for command in pdfcraft_engine::commands::COMMANDS { + assert!(has(sq, command.label), "missing command: {}", command.label); + if let Some(menu) = command.menu { + assert!(has(sq, menu), "missing menu: {menu}"); + } + } + for group in pdfcraft_engine::catalog::TOOL_GROUPS { + assert!(has(sq, group.label), "missing group: {}", group.label); + for section in group.sections { + assert!(has(sq, section.title), "missing section: {}", section.title); + for item in section.items { + assert!(has(sq, item.label), "missing item: {}", item.label); + } + } + } + } + + /// New tl!("literal") labels must not silently fall back to English. + #[test] + fn albanian_covers_ui_literals() { + let sq = Lang::from_code("sq").expect("sq registered"); + let missing: Vec<_> = scan_ui_literals(false).into_iter().filter(|label| !has(sq, label)).collect(); + assert!(missing.is_empty(), "untranslated Albanian UI literals: {missing:#?}"); + } + #[test] fn slovene_plurals_cover_dual_few_teens_and_large_counts() { let sl = Lang::from_code("sl").expect("sl registered"); diff --git a/crates/ui-egui/src/i18n/sq.tsv b/crates/ui-egui/src/i18n/sq.tsv new file mode 100644 index 000000000..cbaf9b8e5 --- /dev/null +++ b/crates/ui-egui/src/i18n/sq.tsv @@ -0,0 +1,2354 @@ +# Albanian (sq) catalog. Format: see the header of ja.tsv +# (context source translation; @id, @plural and other contexts; escapes \n \t \\). +# Plural forms (see `plural_one_other` in i18n/mod.rs): one (1) | other (0, 2 and above). +# +# Clean-room: every entry was written from the plain meaning of the English label using ordinary +# Albanian computing vocabulary. No proprietary localisation resource, string table or product UI +# (Acrobat's included) was consulted or copied; add entries the same way. +# Product and technology names (PdfCraft, PDF, Acrobat JavaScript ...) are not translated; +# the trailing "…" of dialog commands is kept. + + Menu Menyja + File Skedari + Edit Redakto + Pages Faqet + View Pamja + Help Ndihma + Preferences Preferencat + Preferences… Preferencat… + Interface language Gjuha e ndërfaqes +@plural {n} page|{n} pages {n} faqe|{n} faqe + · not fixable here · nuk mund të rregullohet këtu + (page {p}) (faqja {p}) + (searching… {s} of {p} pages) (duke kërkuar… {s} nga {p} faqe) + ({s} not exported: {first}) ({s} nuk u eksportuan: {first}) + on page {p} në faqen {p} + · password-protected · e mbrojtur me fjalëkalim + % of all commits % e të gjitha commit-eve + (none) (asnjë) + +Bin +Bin + +LOC +LOC + , Expires: , Skadon: + 1 difference found U gjet 1 ndryshim + 1 file 1 skedar + 1 file done 1 skedar u krye + 1 file needs attention 1 skedar kërkon vëmendje + 1 instance 1 rast + 1 issue 1 problem + 1 mark 1 shenjë + 1 page 1 faqe + 1 page selected 1 faqe e zgjedhur + 1 page selected. 1 faqe e zgjedhur. + 180 degrees 180 gradë + 9 digit, A letter, O letter or digit, X any character 9 shifër, A shkronjë, O shkronjë ose shifër, X çdo karakter + ; 1 page already had text ; 1 faqe kishte tashmë tekst + ; failed: {list} ; dështoi: {list} + ; {n} pages already had text ; {n} faqe kishin tashmë tekst + ? of {n} ? nga {n} + @{login}: {prs} PRs, {commits} commits, +{added} / −{deleted} lines (Δ {delta}), +{bin_added} / −{bin_deleted} binary assets, {first} – {last} @{login}: {prs} PR, {commits} commit, +{added} / −{deleted} rreshta (Δ {delta}), +{bin_added} / −{bin_deleted} burime binare, {first} – {last} + A button Një buton + A clean-room, open-source PDF application written in Rust. MIT OR Apache-2.0. Një aplikacion PDF me kod të hapur, i zhvilluar në mënyrë clean-room dhe i shkruar në Rust. MIT OR Apache-2.0. + A diagonal CONFIDENTIAL watermark on every page. Një watermark diagonal CONFIDENTIAL në çdo faqe. + A document needs at least one page: copy instead Një dokument ka nevojë për të paktën një faqe: kopjoje në vend të kësaj + A form field has additional actions Një fushë formulari ka veprime shtesë + A link Një lidhje + A script Një skript + A stream refers to an external file Një rrjedhë i referohet një skedari të jashtëm + A stream uses LZW compression Një rrjedhë përdor kompresimin LZW + A summary describes the table's purpose and layout. Add a Summary attribute to each table. Një përmbledhje përshkruan qëllimin dhe strukturën e tabelës. Shtoni atributin Summary në çdo tabelë. + AI assistant Asistenti AI + About Rreth + About PdfCraft Rreth PdfCraft + Accepted Pranuar + Accessibility Qasshmëria + Accessibility Checker Kontrolluesi i qasshmërisë + Accessibility Checker Options Opsionet e kontrolluesit të qasshmërisë + Accessibility permission flag Flamuri i lejes së qasshmërisë + Accessibility permission flag is set Flamuri i lejes së qasshmërisë është vendosur + Acrobat 3.0 and later (40-bit RC4) Acrobat 3.0 e më vonë (RC4 40-bit) + Acrobat 5.0 and later (128-bit RC4) Acrobat 5.0 e më vonë (RC4 128-bit) + Acrobat 7.0 and later (128-bit AES) Acrobat 7.0 e më vonë (AES 128-bit) + Acrobat X and later (256-bit AES) Acrobat X e më vonë (AES 256-bit) + Action Wizard Asistenti i veprimeve + Action Wizard… Asistenti i veprimeve… + Action name: Emri i veprimit: + Actions Veprimet + Actions list Lista e veprimeve + Actual Size Madhësia aktuale + Actual size Madhësia aktuale + Add Shto + Add Bates numbering… Shto numërtimin Bates… + Add Page Numbers Shto numrat e faqeve + Add Step Shto hap + Add a button Shto një buton + Add a callout Shto një përmendje + Add a checkbox Shto një kuti zgjedhjeje + Add a comment Shto një koment + Add a date field Shto një fushë date + Add a digital signature field Shto një fushë nënshkrimi dixhital + Add a drop-down list Shto një listë zbritëse + Add a list box Shto një kuti liste + Add a radio button Shto një buton radio + Add a reply Shto një përgjigje + Add a stamp Shto një vulë + Add a sticky note Shto një shënim ngjitës + Add a sticky note here Shto një shënim ngjitës këtu + Add a text box Shto një kuti teksti + Add a text field Shto një fushë teksti + Add alternate text Shto tekst alternativ + Add alternate text… Shto tekst alternativ… + Add an Action Shto një veprim + Add an image field Shto një fushë imazhi + Add arrow Shto shigjetë + Add at least two files Shto të paktën dy skedarë + Add background Shto sfond + Add background… Shto sfond… + Add bookmark Shto libërshënues + Add callout Shto përmendje + Add checkmark Shto shenjë vlefshmërie + Add cloud Shto re + Add comments Shto komente + Add connected lines Shto vija të lidhura + Add content Shto përmbajtje + Add cross Shto kryq + Add dot Shto pikë + Add drawing Shto vizatim + Add field Shto fushë + Add file attachment Shto bashkëngjitje skedari + Add files to combine Shto skedarë për t'u bashkuar + Add files… Shto skedarë… + Add folder Shto dosje + Add folder and subfolders Shto dosjen dhe nëndosjet + Add folder and subfolders… Shto dosjen dhe nëndosjet… + Add folder… Shto dosje… + Add footer Shto fund faqeje + Add form components Shto komponentë formulari + Add header Shto krye faqeje + Add header & footer Shto krye dhe fund faqeje + Add header & footer… Shto krye dhe fund faqeje… + Add highlight Shto theksim + Add image Shto imazh + Add image… Shto imazh… + Add inserted text Shto tekst të futur + Add line Shto vijë + Add link Shto lidhje + Add open documents Shto dokumentet e hapura + Add or edit links Shto ose redakto lidhje + Add oval Shto oval + Add polygon Shto shumëkëndësh + Add printer marks Shto shenja shtypjeje + Add rectangle Shto drejtkëndësh + Add redaction mark Shto shenjë redaktimi + Add search index Shto indeks kërkimi + Add signature Shto nënshkrim + Add squiggly underline Shto nënvizim të valëzuar + Add stamp Shto vulë + Add sticky note Shto shënim ngjitës + Add strikethrough Shto vijëzim + Add text Shto tekst + Add text box Shto kuti teksti + Add the PDFs to combine Shto PDF-të për t'u bashkuar + Add the choices people pick from. Shto zgjedhjet nga të cilat zgjedhin përdoruesit. + Add the steps this action runs, in order. Shto hapat që ekzekuton ky veprim, sipas radhës. + Add to Trusted Certificates Shto te certifikatat e besuara + Add to trusted certificates Shto te certifikatat e besuara + Add underline Shto nënvizim + Add watermark Shto watermark + Add watermark… Shto watermark… + Add {what} Shto {what} + Added 1 comment U shtua 1 koment + Added more than once Shtuar më shumë se një herë + Added the first {n} PDFs in {folder} U shtuan {n} PDF-të e para në {folder} + Added {n} comments U shtuan {n} komente + Adding images arrives on the web with file pickers for images Shtimi i imazheve vjen në ueb me zgjedhës skedarësh për imazhe + Adds invisible text over each word; the page image is not changed Shton tekst të padukshëm mbi çdo fjalë; imazhi i faqes nuk ndryshon + Advanced Të avancuara + Advanced Options {chevron} Opsione të avancuara {chevron} + Advanced optimization Optimizim i avancuar + Advanced options Opsione të avancuara + Advanced search… Kërkim i avancuar… + Algorithm Algoritmi + Align Rreshto + Align fields Rreshto fushat + Align left Rreshto majtas + Align right Rreshto djathtas + Alignment: Rreshtimi: + All Të gjitha + All annotations are tagged Të gjitha shënimet janë të etiketuara + All document contents I gjithë përmbajtja e dokumentit + All document contents except metadata I gjithë përmbajtja e dokumentit përveç metadatave + All form fields are tagged Të gjitha fushat e formularit janë të etiketuara + All form fields have description Të gjitha fushat e formularit kanë përshkrim + All multimedia objects are tagged Të gjitha objektet multimediale janë të etiketuara + All open documents Të gjitha dokumentet e hapura + All page content is tagged I gjithë përmbajtja e faqes është e etiketuar + All pages Të gjitha faqet + All pages in document Të gjitha faqet në dokument + All pages in range Të gjitha faqet në interval + All tools Të gjitha mjetet + Allow Rich Text Formatting Lejo formatimin e tekstit të pasur + Allow user to enter custom text Lejo përdoruesin të shkruajë tekst të personalizuar + Allowed Lejuar + Alternate Text Tekst alternativ + Alternate text Tekst alternativ + Alternate text inside an element that already has alternate text is never read. Remove the inner alternate text. Teksti alternativ brenda një elementi që ka tashmë tekst alternativ nuk lexohet kurrë. Hiqni tekstin alternativ të brendshëm. + Alternate text must be associated with some content Teksti alternativ duhet të lidhet me një përmbajtje + Alternate text on an element that contains a link or field hides that annotation from assistive technology. Move the alternate text. Teksti alternativ në një element që përmban lidhje ose fushë e fsheh atë shënim nga teknologjia ndihmëse. Zhvendoseni tekstin alternativ. + Alternate text on an element without page content is never reached. Remove it or attach the element to content. Teksti alternativ në një element pa përmbajtje faqeje nuk arrihet kurrë. Hiqeni ose lidheni elementin me përmbajtje. + Alternate text should not hide annotation Teksti alternativ nuk duhet ta fshehë shënimin + Alternate text that will never be read Tekst alternativ që nuk do të lexohet kurrë + An action is already running Një veprim po ekzekutohet tashmë + An action with this name already exists. Ekziston tashmë një veprim me këtë emër. + An embedded file has no AFRelationship Një skedar i ngulitur nuk ka AFRelationship + An image asks to be interpolated Një imazh kërkon të interpolohet + An image has alternates or OPI information Një imazh ka alternativa ose informacion OPI + An open-source PDF workbench — local, private, and scriptable. Një hapësirë pune PDF me kod të hapur — lokale, private dhe e programueshme me skripte. + Angle Këndi + Animation that flashes can cause seizures. Check scripts and media for flicker. Animacioni që xixëllon mund të shkaktojë kriza. Kontrolloni skriptet dhe median për dridhje. + Annotations, form fill-in, and digital signatures Shënime, plotësim formularësh dhe nënshkrime dixhitale + Another file dialog is still open. Finish with it first. Një dialog tjetër skedari është ende i hapur. Përfundoni fillimisht me të. + Any Çfarëdo + Any except extracting pages Çfarëdo përveç nxjerrjes së faqeve + Anyone opening the document will need this password. It's applied when you save. Kushdo që hap dokumentin do të ketë nevojë për këtë fjalëkalim. Zbatohet kur ruani. + Appear behind page Shfaqet pas faqes + Appear on top of page Shfaqet mbi faqe + Appearance Pamja + Application Aplikacioni + Applied 1 redaction mark. Save to remove the content from the file. U zbatua 1 shenjë redaktimi. Ruani për ta hequr përmbajtjen nga skedari. + Applied {n} redaction marks. Save to remove the content from the file. U zbatuan {n} shenja redaktimi. Ruani për ta hequr përmbajtjen nga skedari. + Applies to 1 page Zbatohet në 1 faqe + Applies to {n} pages Zbatohet në {n} faqe + Apply Zbato + Apply PDF standards Zbato standardet PDF + Apply redactions Zbato redaktimet + Apply redactions… Zbato redaktimet… + Apply scale Zbato shkallën + Appropriate nesting Fole e përshtatshme + April Prill + Arbitrary Mask Maskë arbitrare + Archive documents Arkivo dokumentet + Area Sipërfaqja + Arrow Shigjetë + ArtCraft website Faqja e internetit e ArtCraft + Ask about this document Pyet për këtë dokument + Asks GitHub for the latest release. Nothing is downloaded or installed automatically. I kërkon GitHub-it versionin më të fundit. Asgjë nuk shkarkohet ose instalohet automatikisht. + Associated with content E lidhur me përmbajtjen + At least one signature has problems. Të paktën një nënshkrim ka probleme. + At least one signature is invalid. Të paktën një nënshkrim është i pavlefshëm. + At most Më së shumti + Attach a file Bashkëngjit një skedar + Attach file Bashkëngjit skedar + Attachment Bashkëngjitje + Attachments Bashkëngjitjet + Attachments Panel and Page Paneli i bashkëngjitjeve dhe faqja + Audit space usage Audito përdorimin e hapësirës + Audit space usage… Audito përdorimin e hapësirës… + August Gusht + Author Autori + Auto Automatik + Auto portrait/landscape Portret/peizazh automatik + Auto-rotate pages Rrotullo faqet automatikisht + Auto-size text to fit redaction region Përshtat madhësinë e tekstit automatikisht me zonën e redaktimit + Automatically tag PDF Etiketo PDF automatikisht + Available Në dispozicion + Back Mbrapa + Back side only Vetëm ana e pasme + Back to all tools Kthehu te të gjitha mjetet + Back to the document Kthehu te dokumenti + Background Sfondi + Basic constraints Kufizime bazë + Bates numbering Numërtim Bates + Before each selected page (select pages in Organize) Para çdo faqeje të zgjedhur (zgjidhni faqet te Organizo) + Before the number Para numrit + Beveled Me anë të pjerrëta + Bicubic downsampling to Ulje bikubike e mostrimit në + Binary assets added Burime binare të shtuara + Binary assets removed Burime binare të hequra + Binding Lidhja + Binding: Lidhja: + Black E zezë + Blank page Faqe boshe + Blue Blu + Bold Të trasha + Booklet Broshurë + Booklet subset: Nënbashkësia e broshurës: + Bookmark options Opsionet e libërshënuesit + Bookmarks Libërshënuesit + Bookmarks Panel and Page Paneli i libërshënuesve dhe faqja + Bookmarks are present in large documents Libërshënuesit ekzistojnë në dokumentet e mëdha + Border Color: Ngjyra e kornizës: + Borders and Colors Kornizat dhe ngjyrat + Both Të dyja + Both sides Të dyja anët + Bottom Poshtë + Bottom: Poshtë: + Box Kuti + Bring your own model (off by default) Sill modelin tënd (joaktiv si parazgjedhje) + Browse… Shfleto… + Button Buton + Button Properties Vetitë e butonit + Button Style: Stili i butonit: + Button is checked by default Butoni është i zgjedhur si parazgjedhje + Buttons with the same name and value are selected in unison Butonat me të njëjtin emër dhe vlerë zgjidhen së bashku + Bytes Bajte + Calculate Llogarit + Calibrate from two points Kalibro nga dy pika + Callout Përmendje + Can't be read: {e} Nuk mund të lexohet: {e} + Cancel Anulo + Cancelled Anuluar + Cancelling… Duke anuluar… + Case-sensitive Dallon shkronjat e mëdha + Category: Kategoria: + Center Qendër + Center Footer Text Teksti qendror i fundit të faqes + Center Header Text Teksti qendror i kreut të faqes + Center horizontally Qendro horizontalisht + Center vertically Qendro vertikalisht + Center window on screen Qendro dritaren në ekran + Centre Qendër + Certificate Viewer Shikuesi i certifikatave + Certificates Certifikatat + Certified by {by} Certifikuar nga {by} + Certify Certifiko + Certify (invisible signature) Certifiko (nënshkrim i padukshëm) + Certify (visible signature) Certifiko (nënshkrim i dukshëm) + Change comment properties Ndrysho vetitë e komentit + Change document properties Ndrysho vetitë e dokumentit + Change field properties Ndrysho vetitë e fushës + Change initial view Ndrysho pamjen fillestare + Change initials Ndrysho inicialet + Change link properties Ndrysho vetitë e lidhjes + Change reading options Ndrysho opsionet e leximit + Change reading options… Ndrysho opsionet e leximit… + Change settings… Ndrysho cilësimet… + Change signature Ndrysho nënshkrimin + Change {key} Ndrysho {key} + Change {what} Ndrysho {what} + Changes allowed Ndryshimet e lejuara + Changing the document Ndryshimi i dokumentit + Character encoding Kodimi i karaktereve + Character spacing Hapësira mes karaktereve + Check Kontrollo + Check Again Kontrollo përsëri + Check Box Properties Vetitë e kutisë së zgjedhjes + Check Box Style: Stili i kutisë së zgjedhjes: + Check again Kontrollo përsëri + Check box is checked by default Kutia e zgjedhjes është e zgjedhur si parazgjedhje + Check for accessibility Kontrollo qasshmërinë + Check for accessibility… Kontrollo qasshmërinë… + Check for updates Kontrollo për përditësime + Check for updates… Kontrollo për përditësime… + Check spelling Kontrollo drejtshkrimin + Check that the tags read in the order a sighted reader would. Use the Reading Order tool or the Tags panel to correct it. Kontrolloni që etiketat lexohen në radhën që do t'i lexonte një lexues që sheh. Përdorni mjetin e radhës së leximit ose panelin e etiketave për ta korrigjuar. + Check the pages of {name}: {why} Kontrolloni faqet e {name}: {why} + CheckBox Kuti zgjedhjeje + Checkbox Kuti zgjedhjeje + Checked E zgjedhur + Checking Options ({on} of 32 in all categories) Opsionet e kontrollit ({on} nga 32 në të gjitha kategoritë) + Checking for a newer version… Duke kontrolluar për një version më të ri… + Checkmark Shenjë vlefshmërie + Choose a PNG or JPEG image (up to 4 MiB). Transparency is preserved. Zgjidhni një imazh PNG ose JPEG (deri në 4 MiB). Transparenca ruhet. + Choose a folder for the exported files Zgjidhni një dosje për skedarët e eksportuar + Choose a folder for the extracted pages Zgjidhni një dosje për faqet e nxjerra + Choose a folder for the results Zgjidhni një dosje për rezultatet + Choose a folder for the searchable files Zgjidhni një dosje për skedarët e kërkueshëm + Choose a folder for the split files Zgjidhni një dosje për skedarët e ndarë + Choose a folder on this computer to pin Zgjidhni një dosje në këtë kompjuter për ta fiksuar + Choose a layout: Zgjidhni një paraqitje: + Choose a stamp, then click on the page to place it. Zgjidhni një vulë, pastaj klikoni në faqe për ta vendosur. + Choose an image Zgjidhni një imazh + Choose images Zgjidhni imazhe + Choose the digital ID that you want to use for signing: Zgjidhni identitetin dixhital që dëshironi të përdorni për nënshkrim: + Circle Rreth + Clean Up Pastro + Clear Pastro + Clear All Pastro të gjitha + Clear Recent Files Pastro skedarët e fundit + Clear all Pastro të gjitha + Clear form Pastro formularin + Clear redaction marks Pastro shenjat e redaktimit + Clear selection / close find Pastro përzgjedhjen / mbyll kërkimin + Click on the page to add a {tool}, or drag to set its size Klikoni në faqe për të shtuar {tool}, ose tërhiqni për të caktuar madhësinë + Click on the page to add text; each click starts a new box, and ✓ finishes. Drag items to move them, drag a corner to resize, double-click text to edit it. Klikoni në faqe për të shtuar tekst; çdo klikim nis një kuti të re dhe ✓ përfundon. Tërhiqni elementet për t'i lëvizur, tërhiqni një qoshe për të ndryshuar madhësinë, klikoni dyfish te teksti për ta redaktuar. + Click text or an image to edit it Klikoni një tekst ose një imazh për ta redaktuar + Click the first point to begin. Klikoni pikën e parë për të filluar. + Click to sort, drag to move the column. Drag its edge to resize it. Klikoni për të renditur, tërhiqni për të lëvizur kolonën. Tërhiqni skajin e saj për të ndryshuar madhësinë. + Click vertices. Enter or double-click finishes a perimeter or area. Click the first point to close an area. Klikoni kulmet. Enter ose klikimi dyfish përfundon një perimetër ose sipërfaqe. Klikoni pikën e parë për të mbyllur një sipërfaqe. + Clipboard Clipboard + Clockwise 90 degrees 90 gradë në drejtim orar + Close Mbyll + Close (Esc) Mbyll (Esc) + Close all Mbyll të gjitha + Close file Mbyll skedarin + Close panel Mbyll panelin + Cloud Re + Collapse Palos + Collapse all bookmarks Palos të gjithë libërshënuesit + Collate Rendit kopjet + Color Images Imazhe me ngjyra + Color Spaces Hapësirat e ngjyrave + Color contrast Kontrasti i ngjyrave + Color: Ngjyra: + Colour Ngjyra + Comb of Krehër me + Combine Bashko + Combine files Bashko skedarët + Combine files… Bashko skedarët… + Combined {n} files U bashkuan {n} skedarë + Combo Kombinim + Coming in milestone Vjen në etapën + Coming in milestone {m}. Items marked Ready work today. Vjen në etapën {m}. Elementët e shënuar Gati funksionojnë sot. + Command Komandë + Comment and form data Të dhënat e komenteve dhe formularëve + Comment list Lista e komenteve + Commenting Komentim + Commenting, filling in form fields, and signing existing signature fields Komentim, plotësim i fushave të formularit dhe nënshkrim i fushave ekzistuese të nënshkrimit + Comments Komente + Comments & Forms Komente dhe formularë + Comments and markups Komente dhe shënime + Comments only Vetëm komente + Comments panel Paneli i komenteve + Comments, links and fields must be in the tag tree to be announced. Tag the annotations. Komentet, lidhjet dhe fushat duhet të jenë në pemën e etiketave për t'u lexuar me zë. Etiketo shënimet. + Commit selected value immediately Konfirmo menjëherë vlerën e zgjedhur + Commits Ndryshimet + Common Properties Veti të përbashkëta + Company Kompania + Compare Krahaso + Compare Files Krahaso skedarët + Compare files Krahaso skedarët + Compare files… Krahaso skedarët… + Compare this file with an older version: Compare files… in All tools. Krahaso këtë skedar me një version më të vjetër: Krahaso skedarët… te Të gjitha mjetet. + Compatibility Përputhshmëria + Completed Përfunduar + Compress a PDF Ngjeshe një PDF + Compress document structure (object streams) Ngjeshe strukturën e dokumentit (rrjedhat e objekteve) + Compression Ngjeshja + Configure New Digital ID Konfiguro ID të re dixhitale + Configure a Digital ID for Signing Konfiguro një ID dixhitale për nënshkrim + Confirm Password Konfirmo fjalëkalimin + Conformance level: Niveli i përputhshmërisë: + Connected lines Vija të lidhura + Console Konsola + Content Streams Rrjedhat e përmbajtjes + Content copying Kopjimi i përmbajtjes + Content copying for accessibility Kopjimi i përmbajtjes për qasshmëri + Continue Vazhdo + Continuous scrolling Lëvizje e vazhdueshme + Contributors Kontribuesit + Convert Konverto + Convert colors Konverto ngjyrat + Copied {what} U kopjua {what} + Copies: Kopje: + Copy Kopjo + Copy or cut pages first Kopjo ose preji faqet së pari + Copy pages Kopjo faqet + Copy selected text Kopjo tekstin e zgjedhur + Copy text Kopjo tekstin + Correct recognized text Korrigjo tekstin e njohur + Could not save: {e} Nuk u ruajt: {e} + Couldn't add {name}: {e} Nuk u shtua {name}: {e} + Couldn't check for updates: {e} Nuk u kontrollua për përditësime: {e} + Couldn't combine files: {e} Nuk u bashkuan skedarët: {e} + Couldn't create a PDF: {e} Nuk u krijua dot një PDF: {e} + Couldn't download {name}: {e} Nuk u shkarkua {name}: {e} + Couldn't extract pages: {e} Nuk u nxorën faqet: {e} + Couldn't fit the visible content: {e} Nuk u përshtat përmbajtja e dukshme: {e} + Couldn't import the signature image: {e} Nuk u importua dot imazhi i nënshkrimit: {e} + Couldn't open revision {n}: {e} Nuk u hap rishikimi {n}: {e} + Couldn't open the result: {e} Nuk u hap dot rezultati: {e} + Couldn't open the signed version: {e} Nuk u hap dot versioni i nënshkruar: {e} + Couldn't open {name}: {e} Nuk u hap {name}: {e} + Couldn't optimize the file Nuk u optimizua dot skedari + Couldn't optimize the file: {e} Nuk u optimizua dot skedari: {e} + Couldn't read {name}: {e} Nuk u lexua {name}: {e} + Couldn't recover {name}: {e} Nuk u rikuperua {name}: {e} + Couldn't save the image: {e} Nuk u ruajt dot imazhi: {e} + Couldn't save {name}: {e} Nuk u ruajt {name}: {e} + Couldn't save: {e} Nuk u ruajt: {e} + Couldn't show the file picker. Please try again. Nuk u shfaq dot zgjedhësi i skedarëve. Provo përsëri. + Couldn't split: {e} Nuk u nda dot: {e} + Couldn't summarize comments: {e} Nuk u përmblodhën dot komentet: {e} + Couldn't take the snapshot: {e} Nuk u bë dot pamja e çastit: {e} + Couldn't use {name}: {e} Nuk u përdor dot {name}: {e} + Couldn't write {name}: {e} Nuk u shkrua {name}: {e} + Couldn't write {path}: {e} Nuk u shkrua {path}: {e} + Counterclockwise 90 degrees 90 gradë në të kundërt të akrepave të orës + Country/Region Shteti/Rajoni + Create Krijo + Create Custom Stamp Krijo vulë të personalizuar + Create Link Krijo lidhje + Create PDF Comment Summary Krijo përmbledhje komentesh të PDF + Create PDF comment summary… Krijo përmbledhje komentesh të PDF… + Create PDF from clipboard Krijo PDF nga clipboard + Create PDF from file… Krijo PDF nga skedari… + Create PDF from images Krijo PDF nga imazhet + Create PDF from images… Krijo PDF nga imazhet… + Create PDF from multiple files… Krijo PDF nga disa skedarë… + Create separate PDFs… Krijo PDF të veçanta… + Create a PDF Krijo një PDF + Create a new Digital ID (self-signed, saved to a password-protected file) Krijo një ID të re dixhitale (e vetënënshkruar, e ruajtur në një skedar të mbrojtur me fjalëkalim) + Create accessibility report Krijo raport qasshmërie + Create custom stamp… Krijo vulë të personalizuar… + Create from Krijo nga + Create link Krijo lidhje + Create links from URLs Krijo lidhje nga URL-të + Create {what} Krijo {what} + Created 1 link U krijua 1 lidhje + Created a PDF from the first {n} files U krijua një PDF nga {n} skedarët e parë + Created a PDF from {n} files U krijua një PDF nga {n} skedarë + Created a PDF from {n} files; left out: {names} U krijua një PDF nga {n} skedarë; të lënë jashtë: {names} + Created a comment summary U krijua një përmbledhje komentesh + Created {n} links U krijuan {n} lidhje + Creates 1 file from {n} pages. Krijon 1 skedar nga {n} faqe. + Creates {f} files from {n} pages. Krijon {f} skedarë nga {n} faqe. + Credit Cards Kartat e kreditit + Crop (% trimmed from each side) Prit (% e prerë nga secila anë) + Crop page Prit faqen + Crop pages Prit faqet + Cross Kryq + Currency symbol: Simboli i monedhës: + Current page Faqja aktuale + Current page ({n}) Faqja aktuale ({n}) + Current page — type a page number or label (such as iv) and press Enter Faqja aktuale — shkruaj një numër ose etiketë faqeje (p.sh. iv) dhe shtyp Enter + Custom E personalizuar + Custom scale: Shkallë e personalizuar: + Custom stamps arrive on the web with file pickers for images Vulat e personalizuara vijnë në uebin me zgjedhës skedarësh për imazhe + Custom text: Tekst i personalizuar: + Custom: E personalizuar: + Cut Preji + Cut and stack Preji dhe grumbulloji + Cut marks Shenja prerjeje + Cut pages Preji faqet + Cut {what} Preji {what} + DPI sets the printed page size without resampling the image. DPI cakton madhësinë e faqes së printuar pa e rimostruar imazhin. + Dark gray Gri e errët + Dark gray theme Tema gri e errët + Dashed Me vija të ndërprera + Date Data + Date field Fusha e datës + Dates Datat + December Dhjetor + Decimal places: Shifra dhjetore: + Decimals Dhjetore + Declared conformance: {shown} Përputhshmëria e deklaruar: {shown} + Decorative figure Figurë dekorative + Default Parazgjedhja + Default Value: Vlera e parazgjedhur: + Default page display Shfaqja e parazgjedhur e faqes + Default workspace mode Mënyra e parazgjedhur e hapësirës së punës + Default zoom Zmadhimi i parazgjedhur + Default: Parazgjedhja: + Delete Fshi + Delete bookmark Fshi libërshënuesin + Delete comment Fshi komentin + Delete content Fshi përmbajtjen + Delete document JavaScript Fshi JavaScript-in e dokumentit + Delete field Fshi fushën + Delete image Fshi imazhin + Delete link Fshi lidhjen + Delete page Fshi faqen + Delete pages Fshi faqet + Delete pages (Delete) Fshi faqet (Delete) + Delete pages after extracting Fshi faqet pas nxjerrjes + Delete selected fields Fshi fushat e zgjedhura + Delete selected pages (Organize) Fshi faqet e zgjedhura (Organizo) + Delete stamp Fshi vulën + Delete {o} Fshi {o} + Deleted U fshi + Describe the figure Përshkruaj figurën + Description Përshkrimi + Description: Përshkrimi: + Details Detajet + Detect form fields Zbulo fushat e formularit + Detected 1 form field U zbulua 1 fushë formulari + Detected {n} form fields U zbuluan {n} fusha formulari + Device colour is used, but there is no PDF/A output intent Përdoret ngjyra e pajisjes, por nuk ka synim dalje (output intent) PDF/A + DeviceCMYK is used: it needs a CMYK output intent (not added automatically) Përdoret DeviceCMYK: kërkon një synim dalje CMYK (nuk shtohet automatikisht) + Diagnostic details Detaje diagnostikimi + Diamond Romb + Digital ID ID dixhitale + Digital ID password Fjalëkalimi i ID-së dixhitale + Digital Signature Properties Vetitë e nënshkrimit dixhital + Digital signature Nënshkrim dixhital + Digitally sign Nënshkruaj dixhitalisht + Direction: Drejtimi: + Discard Hidhe tej + Discard Objects Hidh tej objektet + Discard User Data Hidh tej të dhënat e përdoruesit + Discard all comments, forms and multimedia Hidh tej të gjitha komentet, formularët dhe multimedian + Discard all links, actions and JavaScript Hidh tej të gjitha lidhjet, veprimet dhe JavaScript-in + Discard all object data (file attachments) Hidh tej të gjitha të dhënat e objekteve (bashkëngjitjet e skedarëve) + Discard alternate images Hidh tej imazhet alternative + Discard bookmarks Hidh tej libërshënuesit + Discard document information and metadata Hidh tej informacionin e dokumentit dhe metadatat + Discard document tags Hidh tej etiketat e dokumentit + Discard embedded page thumbnails Hidh tej miniaturat e faqeve të ngulitura + Discard embedded print settings Hidh tej cilësimet e printimit të ngulitura + Discard hidden layer content Hidh tej përmbajtjen e shtresave të fshehura + Discard hidden text Hidh tej tekstin e fshehur + Discard private data of other applications Hidh tej të dhënat private të aplikacioneve të tjera + Dismiss Mbylle + Display name Emri i shfaqur + Display theme Tema e shfaqjes + Distance Distanca + Distinguished name Emri dallues + Distribute Shpërndaj + Distribute fields Shpërndaj fushat + Document Dokumenti + Document JavaScripts JavaScript-et e dokumentit + Document JavaScripts… JavaScript-et e dokumentit… + Document Overhead Ngarkesa e dokumentit + Document Properties Vetitë e dokumentit + Document Title Titulli i dokumentit + Document actions Veprimet e dokumentit + Document and markups Dokumenti dhe shënimet + Document and stamps Dokumenti dhe vulat + Document assembly Montimi i dokumentit + Document has appropriate color contrast Dokumenti ka kontrast të përshtatshëm ngjyrash + Document is not image-only PDF Dokumenti nuk është PDF vetëm me imazhe + Document is tagged PDF Dokumenti është PDF i etiketuar + Document language Gjuha e dokumentit + Document properties (⌘D) Vetitë e dokumentit (⌘D) + Document properties… Vetitë e dokumentit… + Document sanitized. Save to finish: saving rewrites the whole file. Dokumenti u pastrua. Ruaje për ta përfunduar: ruajtja e rishkruan gjithë skedarin. + Document structure provides a logical reading order Struktura e dokumentit jep një rend logjik leximi + Document title is showing in title bar Titulli i dokumentit shfaqet në shiritin e titullit + Documents and view Dokumentet dhe pamja + Documents of more than 20 pages need bookmarks for navigation. Add bookmarks for the main sections. Dokumentet me më shumë se 20 faqe kanë nevojë për libërshënues për lundrim. Shto libërshënues për seksionet kryesore. + Don't save Mos e ruaj + Done U krye + Dot Pikë + Double-click Klikim i dyfishtë + Download Shkarko + Downloaded {name} U shkarkua {name} + Downloading attachments on the web arrives with M3.10 ({n} bytes ready) Shkarkimi i bashkëngjitjeve në ueb vjen me M3.10 ({n} bajte gati) + Downsample to Zvogëlo rezolucionin në + Also recognize pages that already have text Njih edhe faqet që kanë tashmë tekst + Pictures on those pages are recognized too; words already in the page's text are not added again Edhe figurat në ato faqe njihen; fjalët që ekzistojnë tashmë në tekstin e faqes nuk shtohen përsëri + Drag a rectangle around the area to copy Tërhiq një drejtkëndësh rreth zonës që do të kopjohet + Drag a rectangle on a page to crop it; double-click a page for Set Page Boxes Tërhiq një drejtkëndësh mbi një faqe për ta prerë; kliko dyfish një faqe për Cakto kutitë e faqes + Drag a rectangle to create a link; double-click a link to edit it Tërhiq një drejtkëndësh për të krijuar një lidhje; kliko dyfish një lidhje për ta ndryshuar + Drag to draw the area where the signature should appear. Tërhiq për të vizatuar zonën ku duhet të shfaqet nënshkrimi. + Drag to reorder Tërhiq për ta renditur + Draw Vizato + Draw a cloud Vizato një re + Draw a line Vizato një vijë + Draw a polygon Vizato një shumëkëndësh + Draw a rectangle Vizato një drejtkëndësh + Draw an arrow Vizato një shigjetë + Draw an oval Vizato një oval + Draw connected lines Vizato vija të lidhura + Draw freehand Vizato lirisht + Draw your {what} below. Vizato {what} më poshtë. + Drawing Vizatim + Drawing scale Shkalla e vizatimit + 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 + Duplicate "{name}" onto: Dyfisho "{name}" në: + Duplicate Field Dyfisho fushën + Duplicate field Dyfisho fushën + Duplicate page Dyfisho faqen + Duplicate pages Dyfisho faqet + Duplicate… Dyfisho… + Dynamic Dinamike + Dynamic XFA form laid out from its template: {pages}, {fields}. Formular dinamik XFA i ndërtuar nga shablloni i tij: {pages}, {fields}. + This form's scripts are turned off because one ran too long. Reopen the document to run them again. Skriptet e këtij formulari janë çaktivizuar sepse njëri u ekzekutua shumë gjatë. Rihape dokumentin për t'i ekzekutuar përsëri. + E-Sign Nënshkrim elektronik + Each field needs a tooltip that says what to enter. Add one in Field Properties > General > Tooltip. Çdo fushë ka nevojë për një këshillë që tregon çfarë të shkruhet. Shtoje te Vetitë e fushës > Të përgjithshme > Këshilla. + Each file holds as many of the {n} pages as fit. Çdo skedar mban aq nga {n} faqet sa përshtaten. + Each image is measured where pages draw it; an image is replaced only if the result is smaller. Çdo imazh matet aty ku e vizatojnë faqet; një imazh zëvendësohet vetëm nëse rezultati është më i vogël. + Each image once, named after the document and page. JPEG images are saved unchanged; others as PNG. Çdo imazh një herë, me emrin e dokumentit dhe të faqes. Imazhet JPEG ruhen të pandryshuara; të tjerat si PNG. + Earlier in tab order Më herët në rendin e tabit + Edit Action Ndrysho veprimin + Edit a PDF Redakto një PDF + Edit comment Ndrysho komentin + Edit content Ndrysho përmbajtjen + Edit document JavaScript Ndrysho JavaScript-in e dokumentit + Edit fields Ndrysho fushat + Edit image Ndrysho imazhin + Edit script of {name} Ndrysho skriptin e {name} + Edit text Ndrysho tekstin + Load document font Ngarko shkronjën e dokumentit + Edit text & images Ndrysho tekstin dhe imazhet + Edit text… Ndrysho tekstin… + Editing Redaktim + Edit… Ndrysho… + Email Address Adresa e email-it + Email Addresses Adresat e email-it + Embedded Files Skedarët e ngulitur + Embedded files must be PDF/A files themselves (use PDF/A-3 for others) Skedarët e ngulitur duhet të jenë vetë skedarë PDF/A (përdor PDF/A-3 për të tjerët) + Enable Acrobat JavaScript Aktivizo Acrobat JavaScript + Enable copying of text, images, and other content Lejo kopjimin e tekstit, imazheve dhe përmbajtjes tjetër + Enable text access for screen reader devices for the visually impaired Lejo qasjen në tekst për lexuesit e ekranit për personat me shikim të dobët + Encrypt Enkripto + Encrypt with certificate Enkripto me certifikatë + Encryption Enkriptimi + Endpoint Pika fundore + Endpoints Pikat fundore + Enhance scanned file Përmirëso skedarin e skanuar + Enter the password that opens it Shkruaj fjalëkalimin që e hap + Enter the permissions password to allow combining Shkruaj fjalëkalimin e lejeve për të lejuar bashkimin + Entire page Gjithë faqja + Erase Fshi + Erase drawings Fshi vizatimet + Eraser Gomë + Even Pages Only Vetëm faqet çifte + Even and Odd Pages Faqet çifte dhe tek + Even pages Faqet çifte + Even pages only Vetëm faqet çifte + Every PDF in the folder Çdo PDF në dosje + Every PDF in the folder and the folders inside it Çdo PDF në dosje dhe në nëndosjet e saj + Everything on a page must be tagged or marked as an artifact (decoration, headers, footers). Tag the untagged content. Gjithçka në një faqe duhet të jetë e etiketuar ose e shënuar si artefakt (dekor, kokë, fund faqeje). Etiketo përmbajtjen e paetiketuar. + Example: {sample} Shembull: {sample} + Exclude images smaller than Përjashto imazhet më të vogla se + Execute a menu item Ekzekuto një element menuje + Expand Zgjero + Expand all bookmarks Zgjero të gjithë libërshënuesit + Expand top-level bookmarks Zgjero libërshënuesit e nivelit të parë + Explain Shpjego + Export Eksporto + Export All Images Eksporto të gjitha imazhet + Export Value: {on} Vlera e eksportit: {on} + Export a PDF Eksporto një PDF + Export all comments to data file… Eksporto të gjitha komentet në skedar të dhënash… + Export all images Eksporto të gjitha imazhet + Export all images… Eksporto të gjitha imazhet… + Export all to data file… Eksporto gjithçka në skedar të dhënash… + Export certificate Eksporto certifikatën + Export certificate… Eksporto certifikatën… + Export comments Eksporto komentet + Export data Eksporto të dhënat + Export form data Eksporto të dhënat e formularit + Export form data… Eksporto të dhënat e formularit… + Export measurements Eksporto matjet + Export measurements as CSV Eksporto matjet si CSV + Export stopped: {e} Eksporti u ndal: {e} + Export to Eksporto në + Export to HTML… Eksporto në HTML… + Export to Image Eksporto si imazh + Export to RTF… Eksporto në RTF… + Export to Text Eksporto si tekst + Export to Word… Eksporto në Word… + Export to PowerPoint… Eksporto në PowerPoint… + Export to image… Eksporto si imazh… + Export to text… Eksporto si tekst… + Exported 1 image U eksportua 1 imazh + Exported the text of 1 page U eksportua teksti i 1 faqeje + Exported the text of {n} pages U eksportua teksti i {n} faqeve + Exported to {path} U eksportua te {path} + Exported {n} images U eksportuan {n} imazhe + Exporting… {d} of {t} Po eksportohet… {d} nga {t} + Export… Eksporto… + Extended Graphics States Gjendjet grafike të zgjeruara + Extract Nxirr + Extract pages Nxirr faqet + Extract pages as separate files Nxirr faqet si skedarë të veçantë + Extract pages to a new document Nxirr faqet në një dokument të ri + Extract pages… Nxirr faqet… + Extracted 1 page U nxor 1 faqe + Extracted {n} pages U nxorën {n} faqe + Failed Dështoi + February Shkurt + Field Fusha + Field descriptions Përshkrimet e fushave + Field is used for file selection Fusha përdoret për zgjedhjen e skedarit + Field list Lista e fushave + Field names (comma-separated) Emrat e fushave (të ndarë me presje) + Field names with + - * / and parentheses; put \\ before spaces in names. Emrat e fushave me + - * / dhe kllapa; vendos \\ para hapësirave në emra. + Field properties Vetitë e fushës + Field properties… Vetitë e fushës… + Field value is in range: Vlera e fushës është brenda intervalit: + Field value is not validated Vlera e fushës nuk vlerësohet + Field: {field} on page {p} Fusha: {field} në faqen {p} + Fields Fushat + Fields to reset (comma-separated; empty: all) Fushat që do të rivendosen (të ndara me presje; bosh: të gjitha) + Figure {i} of {n}{page} Figura {i} nga {n}{page} + Figures alternate text Teksti alternativ i figurave + Figures require alternate text Figurat kërkojnë tekst alternativ + File (.p12, .pfx) Skedar (.p12, .pfx) + File Name Emri i skedarit + File attachments Bashkëngjitjet e skedarëve + File name Emri i skedarit + File size Madhësia e skedarit + Files are combined from top to bottom. Leave Pages empty to take every page. Skedarët bashkohen nga lart poshtë. Lëre Faqet bosh për të marrë çdo faqe. + Files are combined in this order. Leave Pages empty to take every page. Skedarët bashkohen sipas këtij rendi. Lëre Faqet bosh për të marrë çdo faqe. + Files for {name} Skedarët për {name} + Files you open in PdfCraft appear here. Drop a PDF anywhere to open it. Skedarët që hap në PdfCraft shfaqen këtu. Hidh një PDF kudo për ta hapur. + Fill Plotëso + Fill & Sign Plotëso dhe nënshkruaj + Fill & Sign: add text Plotëso dhe nënshkruaj: shto tekst + Fill & Sign: change initials Plotëso dhe nënshkruaj: ndrysho inicialet + Fill & Sign: change signature Plotëso dhe nënshkruaj: ndrysho nënshkrimin + Fill & Sign: checkmark Plotëso dhe nënshkruaj: shenjë vlefshmërie + Fill & Sign: cross Plotëso dhe nënshkruaj: kryq + Fill & Sign: date Plotëso dhe nënshkruaj: data + Fill & Sign: dot Plotëso dhe nënshkruaj: pikë + Fill & Sign: initials Plotëso dhe nënshkruaj: inicialet + Fill & Sign: line Plotëso dhe nënshkruaj: vijë + Fill & Sign: remove saved initials Plotëso dhe nënshkruaj: hiq inicialet e ruajtura + Fill & Sign: remove saved signature Plotëso dhe nënshkruaj: hiq nënshkrimin e ruajtur + Fill & Sign: sign Plotëso dhe nënshkruaj: nënshkruaj + Fill Color: Ngjyra e mbushjes: + Fill in {name} Plotëso {name} + Filling in form fields and signing existing signature fields Plotësimi i fushave të formularit dhe nënshkrimi i fushave ekzistuese të nënshkrimit + Filling of form fields Plotësimi i fushave të formularit + Filter comments Filtro komentet + Find options Opsionet e kërkimit + Find text Gjej tekst + Find text and redact Gjej tekst dhe redakto + Find text and redact… Gjej tekst dhe redakto… + Find tools and commands Gjej mjete dhe komanda + Find tools and commands… Gjej mjete dhe komanda… + Find… Gjej… + First I pari + First / last page Faqja e parë / e fundit + First commit Commit-i i parë + Fit Përshtat + Fit Height Përshtat lartësinë + Fit Page Përshtat faqen + Fit Visible Përshtat pjesën e dukshme + Fit Width Përshtat gjerësinë + Fit one full page Përshtat një faqe të plotë + Fit to height Përshtat sipas lartësisë + Fit to page Përshtat sipas faqes + Fit to width Përshtat sipas gjerësisë + Fit to width scrolling Përshtat sipas gjerësisë me rrëshqitje + Fit visible Përshtat pjesën e dukshme + Fix Ndrysho + Fix hairlines Ndrysho vijat e holla + Fix reading order Ndrysho renditjen e leximit + Fixed what could be fixed; 1 problem remains U ndreqën ato që mund të ndreqeshin; mbetet 1 problem + Fixed what could be fixed; {n} problems remain U ndreqën ato që mund të ndreqeshin; mbeten {n} probleme + Flatten Rrafshoje + Flatten comments Rrafshoji komentet + Flatten form fields Rrafshoji fushat e formularit + Flip Horizontal Përmbys horizontalisht + Flip Vertical Përmbys vertikalisht + Flip horizontal Përmbys horizontalisht + Flip image Përmbys imazhin + Flip on long edge Përmbys sipas anës së gjatë + Flip on short edge Përmbys sipas anës së shkurtër + Flip vertical Përmbys vertikalisht + Folders Dosjet + Font Size: Madhësia e shkronjave: + Font colour: Ngjyra e shkronjave: + Font size: Madhësia e shkronjave: + Font: Shkronja: + Font: Helvetica Shkronja: Helvetica + Fonts Shkronjat + Fonts must map their characters to Unicode so text can be read and copied. Fix the fonts or recreate the PDF. Shkronjat duhet t'i lidhin karakteret me Unicode që teksti të mund të lexohet dhe kopjohet. Ndreqi shkronjat ose krijo PDF-në nga e para. + Form data and PDF forms Të dhënat e formularit dhe formularët PDF + Form fields Fushat e formularit + Form fields are flattened: their values stay visible. Saving rewrites the whole file. Fushat e formularit janë rrafshuar: vlerat e tyre mbeten të dukshme. Ruajtja rishkruan të gjithë skedarin. + Form fields must be in the tag tree (Form tags) to be announced. Tag the form fields. Fushat e formularit duhet të jenë në pemën e etiketave (etiketat Form) që të lexohen me zë. Etiketo fushat e formularit. + Form fields only Vetëm fushat e formularit + Form fields panel Paneli i fushave të formularit + Form fill-in and digital signatures Plotësimi i formularëve dhe nënshkrimet dixhitale + Format Formati + Finding document fonts… Po gjenden shkronjat e dokumentit… + Installed fonts… Shkronjat e instaluara… + Keep source fonts Mbaj shkronjat burimore + Load font… Ngarko shkronja… + No openly licensed document fonts found. Load a font file. Nuk u gjetën shkronja dokumenti me licencë të hapur. Ngarko një skedar shkronjash. + Format text Formato tekstin + Format: Formati: + Forms Formularët + Formulas and similar non-text elements need alternate text. Add alternate text to them. Formulat dhe elementët e ngjashëm jo tekst kanë nevojë për tekst alternativ. Shtoju tekst alternativ. + From Nga + From a PDF page or an image Nga një faqe PDF ose një imazh + From colour Nga ngjyra + From {file} Nga {file} + From: Nga: + Front side only Vetëm ana e përparme + Full screen mode Modaliteti me ekran të plotë + General Të përgjithshme + Geospatial location Vendndodhja gjeohapësinore + Get help, share feedback and follow development on Discord. Merr ndihmë, ndaj komente dhe ndiq zhvillimin në Discord. + Go to a page view Shko te një pamje faqeje + Go to page {p} Shko te faqja {p} + Go to page… Shko te faqja… + Go to the page Shko te faqja + Go to this result Shko te ky rezultat + Grab bag Të ndryshme + Gray Gri + Grayscale Images Imazhe në nuanca gri + Green Jeshile + H / Space (hold) H / Hapësira (mbaje shtypur) + HTML web page Faqe interneti HTML + Hand (H) Dora (H) + Has JavaScript actions (run in M6) Ka veprime JavaScript (ekzekutohen në M6) + Header and footer Koka dhe këmba e faqes + Header cells (TH) tell listeners what each column or row holds. Mark the header cells. Qelizat e kokës (TH) u tregojnë dëgjuesve çfarë përmban çdo kolonë ose rresht. Shëno qelizat e kokës. + Headers Kokat + Heading levels shouldn't skip (an H1 followed by an H3). Retag the headings. Nivelet e titujve nuk duhet të anashkalohen (një H1 i ndjekur nga një H3). Rietiketo titujt. + Headings Titujt + Height Lartësia + Height: Lartësia: + Hidden layers Shtresat e fshehura + Hidden text Teksti i fshehur + Hide a field Fshih një fushë + Hide all comments Fshih të gjitha komentet + Hide field highlights Fshih theksimet e fushave + Hide layer Fshih shtresën + Hide menu bar Fshih shiritin e menysë + Hide password Fshih fjalëkalimin + Hide toolbars Fshih shiritat e mjeteve + Hide window controls Fshih kontrollet e dritares + Hides annotation Fsheh shënimin + High E lartë + High Resolution Rezolucion i lartë + High resolution Rezolucion i lartë + Highlight Thekso + Highlight Style: Stili i theksimit: + Highlight fields Thekso fushat + Highlight text Thekso tekstin + Home Kreu + Home / End Home / End + Horizontal Horizontal + Horizontal reversed Horizontal i kundërt + Horizontal scale Shkalla horizontale + Horizontally Horizontalisht + Icon Ikona + Identity Identiteti + Image Imazh + Image (PNG) Imazh (PNG) + Image field Fushë imazhi + Image-only PDF PDF vetëm me imazhe + Images Imazhet + Images and text Imazhet dhe teksti + Images and text (converted to PDF) Imazhet dhe teksti (të konvertuara në PDF) + Import comments… Importo komente… + Import data Importo të dhëna + Import form data… Importo të dhënat e formularit… + Import {name} Importo {name} + Importing data arrives on the web with file pickers for data files Importimi i të dhënave në ueb vjen me zgjedhës skedarësh për skedarët e të dhënave + In multiple files Në disa skedarë + In this file Në këtë skedar + Includes unsaved changes Përfshin ndryshime të paruajtura + Incorrect password. Try again. Fjalëkalim i pasaktë. Provo përsëri. + Indent Zhvendos djathtas + Index Indeksi + Initial View Pamja fillestare + Initials Inicialet + Insert Fut + Insert Date Fut datën + Insert Page Number Fut numrin e faqes + Insert a blank page after the selection Fut një faqe bosh pas përzgjedhjes + Insert a file at the end Fut një skedar në fund + Insert a file before page {label} Fut një skedar para faqes {label} + Insert blank page Fut faqe bosh + Insert pages Fut faqe + Insert pages from a file… Fut faqe nga një skedar… + Insert pages from file… Fut faqe nga skedari… + Insert pages from {name} Fut faqe nga {name} + Insert pages from {name} — 1 field renamed Fut faqe nga {name} — 1 fushë u riemërua + Insert pages from {name} — fields renamed Fut faqe nga {name} — fushat u riemëruan + Insert text Fut tekst + Inserted Futur + Inserted text Teksti i futur + Inserting, deleting, and rotating pages Futja, fshirja dhe rrotullimi i faqeve + Inset Brendashkruaj + Intended usage Përdorimi i synuar + Intersection Prerja + Intersections Prerjet + Invert Përmbys ngjyrat + Invisible Rectangle Drejtkëndësh i padukshëm + Irregular tables confuse cell navigation. Give every row the same number of cells (counting spans). Tabelat e parregullta ngatërrojnë lëvizjen nëpër qeliza. Jepi çdo rreshti të njëjtin numër qelizash (duke numëruar edhe bashkimet). + Issued by Lëshuar nga + Issued by: Lëshuar nga: + Issued to Lëshuar për + Issuer Lëshuesi + Italic Zhdrejtë + Item List Lista e artikujve + Item: Artikulli: + Items marked Ready work today. Artikujt e shënuar Gati funksionojnë sot. + Its security settings don't allow copying pages Cilësimet e tij të sigurisë nuk lejojnë kopjimin e faqeve + January Janar + JavaScript JavaScript + JavaScript Console Konsola JavaScript + JavaScript console… Konsola JavaScript… + JavaScript is turned off (Preferences ▸ JavaScript). JavaScript është çaktivizuar (Preferencat > JavaScript). + JavaScript, e.g. getField("total").value JavaScript, p.sh. getField("total").value + Join our Discord Bashkohu me Discord-in tonë + Join the ArtCraft Discord Bashkohu me Discord-in e ArtCraft + Join the ArtCraft community Bashkohu me komunitetin e ArtCraft + July Korrik + June Qershor + Justify Drejto në të dyja anët + Keep tool selected Mbaje mjetin të zgjedhur + Keep tool selected: on Mbaje mjetin të zgjedhur: aktiv + Key Algorithm Algoritmi i çelësit + Key usage Përdorimi i çelësit + Keyboard shortcuts Shkurtoret e tastierës + Keychain · Zinxhiri i çelësave · + Keywords Fjalët kyçe + LI must be a child of L LI duhet të jetë fëmijë i L + Label Etiketa + Labels Etiketat + Labels: {preview}. Later pages keep their labels. Etiketat: {preview}. Faqet e mëvonshme i mbajnë etiketat e tyre. + Landscape Peizazh + Landscape Pages Faqe në peizazh + Landscape and Portrait Pages Faqe në peizazh dhe portret + Landscape pages Faqet në peizazh + Language Gjuha + Last E fundit + Last commit Commit-i i fundit + Later Më vonë + Later in tab order Më vonë në rendin e tabit + Layers Shtresat + Layers Panel and Page Paneli i shtresave dhe faqja + Layout and Magnification Faqosja dhe zmadhimi + Lbl and LBody Lbl dhe LBody + Lbl and LBody must be children of LI Lbl dhe LBody duhet të jenë fëmijë të LI + Left Majtas + Left Edge Skaji i majtë + Left Footer Text Teksti i këmbës majtas + Left Header Text Teksti i kokës majtas + Left: Majtas: + Light blue Blu e çelët + Light gray Gri e çelët + Light theme Tema e çelët + Limit of Kufiri i + Line Vijë + Line Style: Stili i vijës: + Line Thickness: Trashësia e vijës: + Line delta Ndryshimi i rreshtave + Line spacing Hapësira ndërmjet rreshtave + Line thickness Trashësia e vijës + Lines +/− Rreshta +/− + Lines added Rreshta të shtuar + Lines deleted Rreshta të fshirë + Link Lidhje + Link Action Veprimi i lidhjes + Link Appearance Pamja e lidhjes + Link Properties Vetitë e lidhjes + Link Type: Lloji i lidhjes: + Links, actions and JavaScripts Lidhjet, veprimet dhe JavaScript-et + List Listë + List Box Properties Vetitë e kutisë së listës + List box Kuti liste + List items Artikujt e listës + List items belong in a list. Fix the list's tags. Artikujt e listës i përkasin një liste. Ndreqi etiketat e listës. + List labels and bodies belong in a list item. Fix the list's tags. Etiketat dhe trupat e listës i përkasin një artikulli liste. Ndreqi etiketat e listës. + Lists Listat + Location Vendndodhja + Lock comment Blloko komentin + Locked E bllokuar + Logical Reading Order Renditja logjike e leximit + Looking for PDFs… Po kërkohen PDF… + Low E ulët + Low Resolution (150 dpi) Rezolucion i ulët (150 dpi) + Low resolution Rezolucion i ulët + Magnification Zmadhimi + Make Current Properties Default Bëje vetitë aktuale parazgjedhje + Make accessible Bëje të aksesueshëm + Make scans searchable, then make them smaller. Bëji skanimet të kërkueshme, pastaj zvogëloji. + Manage embedded index Menaxho indeksin e ngulitur + March Mars + Margins (in) Margjinat (in) + Mark Page Range Shëno intervalin e faqeve + Mark all Shëno të gjitha + Mark as Confidential Shëno si konfidenciale + Mark as comments Shëno si komente + Mark differences Shëno dallimet + Mark figure as decorative Shëno figurën si dekorative + Mark for redaction Shëno për redaktim + Mark pages for redaction Shëno faqet për redaktim + Mark with checkmark Shëno me shenjë vizë + Marked I shënuar + Markup Shënime + Marquee zoom Zmadhim me zgjedhje + Mask: Maska: + Match field sizes Përputh madhësitë e fushave + Maximum Maksimumi + May Maj + Measure Mat + Measure area Mat sipërfaqen + Measure distance Mat distancën + Measure objects Mat objektet + Measure perimeter Mat perimetrin + Measurement information Informacioni i matjes + Measurement snapping Kapja e matjes + Measuring tool Mjeti i matjes + Medium Mesatar + Merge data files into spreadsheet… Bashko skedarët e të dhënave në fletëllogaritëse… + Merged 1 file into {path} U bashkua 1 skedar në {path} + Merged PRs PR-të e bashkuara + Merged {n} files into {path} U bashkuan {n} skedarë në {path} + Merging data files needs the desktop app Bashkimi i skedarëve të të dhënave kërkon aplikacionin për desktop + Metadata Metadatat + Microsoft Word (.docx) Microsoft Word (.docx) + Midpoint Pika e mesit + Midpoints Pikat e mesit + Minimum Minimumi + Model Modeli + Models Modelet + Modified Ndryshuar + Modify page Modifiko faqen + More Më shumë + More options Më shumë opsione + More options: Më shumë opsione: + More ways to add files Më shumë mënyra për të shtuar skedarë + Mouse Down Maus poshtë + Mouse Enter Maus brenda + Mouse Exit Maus jashtë + Mouse Up Maus lart + Move bookmark Zhvendos libërshënuesin + Move comment Zhvendos komentin + Move down Zhvendos poshtë + Move earlier Zhvendos më herët + Move image Zhvendos imazhin + Move later Zhvendos më vonë + Move page Zhvendos faqen + Move pages Zhvendos faqet + Move up Zhvendos lart + Multi-line Shumë rreshta + Multiple Të shumëfishta + Multiple files Disa skedarë + Separate PDFs PDF të veçanta + Multiple selection Zgjedhje e shumëfishtë + Name Emri + Name (A–Z) Emri (A–Zh) + Name on new comments Emri në komentet e reja + Name: Emri: + Named Destinations Destinacionet me emër + Navigation links Lidhjet e navigimit + Navigation links are not repetitive Lidhjet e navigimit nuk përsëriten + Navigation tab Tabi i navigimit + Needs manual check Kërkon kontroll manual + Negative number style: Stili i numrave negativë: + Nested alternate text Tekst alternativ i brendshëm + New Action Veprim i ri + New Action… Veprim i ri… + New blank PDF PDF e re bosh + New bookmark Libërshënues i ri + New bookmark (⌘B) Libërshënues i ri (⌘B) + New file: Skedari i ri: + New {tool} comments will look like this one Komentet e reja {tool} do të duken si ky + Next (⌘G) Tjetri (⌘G) + Next / previous match Përputhja tjetër / e mëparshme + Next figure Figura tjetër + Next month Muaji tjetër + Next page Faqja tjetër + Next sheet Fleta tjetër + Next view Pamja tjetër + No Jo + No PDFs found in {folder} Nuk u gjetën PDF në {folder} + No PDFs in this folder yet Ende nuk ka PDF në këtë dosje + No actions Nuk ka veprime + No changes allowed Nuk lejohen ndryshime + No changes to save Nuk ka ndryshime për t'u ruajtur + No check has run yet. Ende nuk është ekzekutuar asnjë kontroll. + No color Pa ngjyrë + No colour Pa ngjyrë + No comments match. Asnjë koment nuk përputhet. + No comments yet. Ende nuk ka komente. + No contributor data was built into this copy. Në këtë kopje nuk u ndërtuan të dhëna kontribuesish. + No differences in the text. Nuk ka dallime në tekst. + No digital IDs yet. Ende nuk ka ID dixhitale. + No documents are open Nuk ka dokumente të hapura + No file chosen Nuk u zgjodh asnjë skedar + No fonts are referenced by the pages. Faqet nuk referojnë asnjë shkronjë. + No form fields were detected Nuk u zbuluan fusha formulari + No inaccessible scripts Nuk ka skripte të paaksesueshme + No issues found Nuk u gjetën probleme + No limit Pa kufi + No matches Nuk ka përputhje + No matches. Nuk ka përputhje. + No matching tools Nuk ka mjete që përputhen + No model credits were built into this copy. Në këtë kopje nuk u ndërtuan kredite modelesh. + No pages match those choices Asnjë faqe nuk përputhet me ato zgjedhje + No pages selected Nuk është zgjedhur asnjë faqe + No preview Pa pamje paraprake + No problems found: the document conforms to {level}. Nuk u gjetën probleme: dokumenti është në përputhje me {level}. + No recent files Nuk ka skedarë të fundit + No security Pa siguri + No sheets Nuk ka fletë + No status has been set. Nuk është caktuar asnjë status. + No unlinked web addresses were found in the text Në tekst nuk u gjetën adresa uebi pa lidhje + None Asnjë + None (prefix only) Asnjë (vetëm prefiks) + None found Nuk u gjet asnjë + None of those files can be made into a PDF; use PDFs, images or .txt files Asnjë nga ato skedarë nuk mund të bëhet PDF; përdor PDF, imazhe ose skedarë .txt + None — everything is allowed Asnjë — gjithçka lejohet + Not allowed Nuk lejohet + Not present Nuk ekziston + Note Shënim + Nothing to redo Nuk ka asgjë për ripërsëritje + Nothing to undo Nuk ka asgjë për zhbërje + November Nëntor + Number Numri + Number every page in the footer. Numëro çdo faqe në fund të faqes. + Number of pages Numri i faqeve + Number pages Numëro faqet + Number pages… Numëro faqet… + OK OK + October Tetor + Odd Pages Only Vetëm faqet tek + Odd pages Faqet tek + Odd pages only Vetëm faqet tek + Off Joaktiv + Old file: Skedari i vjetër: + On Blur Kur humbet fokusin + On Focus Kur merr fokusin + On the web, open or drop an image to convert it Në ueb, hap ose lësho një imazh për ta konvertuar + One {f} file per page, named after the document. Një skedar {f} për faqe, me emrin e dokumentit. + Only continue if you trust this document. An address can carry information from the document, such as what you typed into its form. Vazhdo vetëm nëse i beson këtij dokumenti. Një adresë mund të mbartë informacion nga dokumenti, si ajo që shkruatë në formularin e tij. + Only the document's owner can change its security (open it with the permissions password) Vetëm zotëruesi i dokumentit mund të ndryshojë sigurinë e tij (hape me fjalëkalimin e lejeve) + Only the page content changes: links, comments, form fields and bookmarks on the original pages stay. Ndryshon vetëm përmbajtja e faqes: lidhjet, komentet, fushat e formularit dhe libërshënuesit në faqet origjinale mbeten. + Opacity Tejdukshmëria + Open Hap + Open Recent Hap të fundit + Open a PDF (⌘O) Hap një PDF (⌘O) + Open a PDF to measure it. Hap një PDF për ta matur. + Open a document first Hap fillimisht një dokument + Open a web link Hap një lidhje ueb + Open a web page Hap një faqe ueb + Open accessibility report Hap raportin e aksesueshmërisë + Open email app Hap aplikacionin e emailit + Open file Hap skedarin + Open in Full Screen mode Hap në ekran të plotë + Open in a new tab Hap në një skedë të re + Open link Hap lidhjen + Open the file as it was saved then Hap skedarin siç ishte ruajtur atëherë + Open the older version first Hap fillimisht versionin më të vjetër + Open this web page? Të hapet kjo faqe ueb? + Open to page Hap te faqja + Opened with Hapur me + Opened, but its security settings don't allow combining. Enter the permissions password. U hap, por cilësimet e sigurisë së tij nuk lejojnë bashkimin. Fut fjalëkalimin e lejeve. + Open… Hap… + Optimization cancelled Optimizimi u anulua + Optimization is already running Optimizimi është tashmë në punë + Optimize Optimizo + Optimize PDF… Optimizo PDF… + Optimize Scanned Documents Optimizo dokumentet e skanuara + Optimize scanned documents Optimizo dokumentet e skanuara + Optimize scanned documents… Optimizo dokumentet e skanuara… + Optimizing… cleaning up Duke optimizuar… duke pastruar + Optimizing… image {d} of {t} Duke optimizuar… imazhi {d} nga {t} + Optimizing… merging identical objects Duke optimizuar… duke bashkuar objektet identike + Optimizing… removing user data Duke optimizuar… duke hequr të dhënat e përdoruesit + Optimizing… writing the copy Duke optimizuar… duke shkruar kopjen + Optional Opsionale + Optional: needs an AI provider you configure Opsionale: kërkon një ofrues IA që e konfiguron ti + Options Opsionet + Options… Opsionet… + Orange Portokalli + Organization Name Emri i organizatës + Organizational Unit Njësia organizative + Organize pages Organizo faqet + Orientation: Orientimi: + Original: replace pages Origjinali: zëvendëso faqet + Other elements alternate text Teksti alternativ i elementeve të tjerë + Other elements that require alternate text Elementet e tjerë që kërkojnë tekst alternativ + Outdent Zvogëlo identimin + Outline Strukturë + Output Dalja + Output appears here. Dalja shfaqet këtu. + Output intent: {list} Qëllimi i daljes: {list} + Output preview Pamja paraprake e daljes + Oval Ovale + Overlap: Mbivendosja: + Owner password (no restrictions apply) Fjalëkalimi i zotëruesit (pa kufizime) + PDF Optimizer Optimizuesi i PDF + PDF or image PDF ose imazh + PDF producer Prodhuesi i PDF + PDF version Versioni i PDF + PDF, images and text PDF, imazhe dhe tekst + PDF/A… PDF/A… + PRs PR-të + Page Faqja + Page Content Përmbajtja e faqes + Page Only Vetëm faqja + Page Range Intervali i faqeve + Page Range Options Opsionet e intervalit të faqeve + Page Sizing & Handling Madhësia dhe trajtimi i faqes + Page display Shfaqja e faqes + Page display: {layout} Shfaqja e faqes: {layout} + Page does not require timed responses Faqja nuk kërkon përgjigje me kohë të kufizuar + Page grid Rrjeta e faqes + Page labels Etiketat e faqeve + Page layout Paraqitja e faqes + Page navigation Navigimi i faqeve + Page number Numri i faqes + Page options Opsionet e faqes + Page order: Radha e faqeve: + Page size Madhësia e faqes + Page thumbnails Miniaturat e faqeve + Page transitions Kalimet mes faqeve + Page will not cause screen flicker Faqja nuk do të shkaktojë dridhje të ekranit + Page {label} Faqja {label} + Page {p} of {n} Faqja {p} nga {n} + Pages Panel and Page Paneli i faqeve dhe faqja + Pages from Faqet nga + Pages of {name} to combine, e.g. 1-3, 6 Faqet e {name} për t'u bashkuar, p.sh. 1-3, 6 + Pages per file Faqe për skedar + Pages per sheet: Faqe për fletë: + Pages that are only pictures of text can't be read aloud or searched. Recognize text (OCR) to add a text layer. Faqet që janë vetëm figura teksti nuk mund të lexohen me zë ose të kërkohen. Njih tekstin (OCR) për të shtuar një shtresë teksti. + Pages to Print Faqet për t'u printuar + Pages with links, comments or fields should tab in structure order. The fix sets each page's tab order to Use Document Structure. Faqet me lidhje, komente ose fusha duhet të kalojnë me tab sipas radhës së strukturës. Rregullimi vendos radhën e tab-it të çdo faqeje te Përdor strukturën e dokumentit. + Pages: Faqet: + Paper: Letra: + Part of Pjesë e + Passed Kaloi + Password Fjalëkalimi + Password protection will be applied when you save Mbrojtja me fjalëkalim do të zbatohet kur të ruash + Password required Kërkohet fjalëkalimi + Password security Siguria me fjalëkalim + Password-protected E mbrojtur me fjalëkalim + Paste after Ngjit pas + Paste pages Ngjit faqet + Path Rruga + Paths Rrugët + Patterns Modelet + Patterns (graphics objects) Modelet (objekte grafike) + PdfCraft didn't shut down normally. These documents had changes that were autosaved: PdfCraft nuk u mbyll normalisht. Këta dokumente kishin ndryshime të ruajtura automatikisht: + PdfCraft on GitHub PdfCraft në GitHub + PdfCraft web page Faqja ueb e PdfCraft + PdfCraft works offline. No telemetry, no account, and no cloud processing unless you add a provider. PdfCraft funksionon pa internet. Pa telemetri, pa llogari dhe pa përpunim në re, përveçse nëse shton një ofrues. + PdfCraft {c} is up to date. PdfCraft {c} është i përditësuar. + PdfCraft {v} is available. PdfCraft {v} është i disponueshëm. + People may need more time to respond. Check that nothing has a time limit. Njerëzit mund të kenë nevojë për më shumë kohë për të përgjigjur. Kontrollo që asgjë të mos ketë kufi kohe. + Percentage Përqindja + Perimeter Perimetri + Permitted actions after certifying Veprimet e lejuara pas certifikimit + Phone Number Numri i telefonit + Phone Numbers Numrat e telefonit + Pick a tool in the quick bar, or type above. Zgjidh një mjet te shiriti i shpejtë, ose shkruaj më sipër. + Pictures need alternate text that describes them, or must be marked decorative. Add alternate text to each figure. Fotografitë kanë nevojë për tekst alternativ që i përshkruan, ose duhen shënuar si dekorative. Shto tekst alternativ për çdo figurë. + Pin a folder to Home Fiksoje një dosje te Kreu + Pin a folder to list its newest PDFs here, such as where your scanner or a synced cloud drive saves them. Fikso një dosje për të listuar këtu PDF-të e saj më të reja, p.sh. ku ruan skaneri ose një disk i sinkronizuar në re. + Pin a folder… Fikso një dosje… + Pin folder to Home… Fikso dosjen te Kreu… + Pink Rozë + Pinned folders need the desktop app Dosjet e fiksuara kërkojnë aplikacionin për desktop + Pinned {folder} to Home U fiksua {folder} te Kreu + Place saved {what} Vendos {what} të ruajtur + Plain text in reading order; pages are separated by form feeds. Tekst i thjeshtë sipas radhës së leximit; faqet ndahen me ndërprerje formulari. + Planned Planifikuar + Planned for milestone Planifikuar për fazën + Planned for milestone {m} — open to see what it will include Planifikuar për fazën {m} — hape për të parë çfarë do të përfshijë + Planned · {m} Planifikuar · {m} + Points from the page's bottom-left corner. Pikë nga këndi i poshtëm majtas i faqes. + Polygon Shumëkëndësh + Polyline Vijë e thyer + Portable mode is off: {folder} can't be written ({error}). Settings are kept in your user folder instead. Modaliteti portativ është joaktiv: nuk mund të shkruhet në {folder} ({error}). Cilësimet ruhen në dosjen tënde të përdoruesit. + Portrait Portret + Portrait Pages Faqe portret + Portrait pages Faqe portret + Position Pozicioni + Post Posto + PostScript / EPS PostScript / EPS + PostScript XObjects aren't allowed Objektet XObject PostScript nuk lejohen + Poster Poster + Prefix Parashtesa + Preflight Preflight + Prepare a form Përgatit një formular + Prepare for Distribution Përgatit për shpërndarje + Prepare for accessibility Përgatit për aksesueshmëri + Prepare for distribution Përgatit për shpërndarje + Prepare for distribution… Përgatit për shpërndarje… + Presentation (.pptx) Prezantim (.pptx) + Preview Pamje paraprake + Preview: page {p} of {n} Pamje paraprake: faqja {p} nga {n} + Previous (⇧⌘G) E mëparshmja (⇧⌘G) + Previous / next page Faqja e mëparshme / tjetër + Previous figure Figura e mëparshme + Previous month Muaji i mëparshëm + Previous page Faqja e mëparshme + Previous sheet Fleta e mëparshme + Previous view Pamja e mëparshme + Primary language Gjuha kryesore + Print Printo + Print (⌘P) Printo (⌘P) + Print in grayscale Printo me tonet e grisë + Print page border Printo kornizën e faqes + Print production Prodhimi për shtyp + Print single-sided. Keep the sheets in order, cut at the marks, then stack the piles left to right, top to bottom. Printo vetëm nga njëra anë. Mbaji fletët në radhë, pri te shenjat, pastaj vendosi grumbujt nga e majta në të djathtë, nga lart poshtë. + Print, NextPage, PrevPage, FirstPage or LastPage Print, NextPage, PrevPage, FirstPage ose LastPage + Printer: Printeri: + Printing Printimi + Printing allowed Printimi lejohet + Print… Printo… + Privacy Privatësia + Private data of other applications Të dhënat private të aplikacioneve të tjera + Properties… Vetitë… + Protect Mbro + Protect Using Password Mbro me fjalëkalim + Protect a PDF Mbro një PDF + Protect using password… Mbro me fjalëkalim… + Protect with password Mbro me fjalëkalim + Protected: the combined file won't keep its security settings Mbrojtur: skedari i bashkuar nuk do t'i ruajë cilësimet e sigurisë + Public key Çelësi publik + Purple Vjollcë + PushButton PushButton + Quality Cilësia + Radio Radio + Radio Button Properties Vetitë e butonit radio + Radio button Butoni radio + Re-type Password Shkruaje sërish fjalëkalimin + Read Lexo + Read Only Vetëm lexim + Read mode Modaliteti i leximit + Ready Gati + Real name Emri real + Reason Arsyeja + Recent Të fundit + Recognize Text Njih tekstin + Recognize text Njih tekstin + Recognize text in multiple files… Njih tekstin në disa skedarë… + Recognize text… Njih tekstin… + Recognized 1 word U njoh 1 fjalë + Recognized {n} words U njohën {n} fjalë + Recognized {w} words in 1 file U njohën {w} fjalë në 1 skedar + Recognized {w} words in {n} files U njohën {w} fjalë në {n} skedarë + Recognizing text… file {d} of {t} Duke njohur tekstin… skedari {d} nga {t} + Recognizing text… page {d} of {t} Duke njohur tekstin… faqja {d} nga {t} + Recommended tools Mjetet e rekomanduara + Recover Rikupero + Recover unsaved documents? Të rikuperohen dokumentet e paruajtura? + Rectangle Drejtkëndësh + Red E kuqe + Redact Redakto + Redact a PDF Redakto një PDF + Redact all Redakto të gjitha + Redact pages Redakto faqet + Redact pages… Redakto faqet… + Redact text and images Redakto tekstin dhe imazhet + Redacted area fill colour: Ngjyra e mbushjes së zonës së redaktuar: + Redaction Tool Properties Vetitë e mjetit të redaktimit + Redaction properties… Vetitë e redaktimit… + Redid {label} U ribë {label} + Redo Ribëj + Redo {action} Ribëj {action} + Reduce file size Zvogëlo madhësinë e skedarit + Reduce file size… Zvogëlo madhësinë e skedarit… + Regularity Rregullsia + Rejected Refuzuar + Reliable character encoding is provided Ofrohet kodim i besueshëm i karaktereve + Remove Hiq + Remove all links Hiq të gjitha lidhjet + No links to remove Nuk ka lidhje për t'u hequr + Removed 1 link U hoq 1 lidhje + Removed {n} links U hoqën {n} lidhje + Remove background Hiq sfondin + Remove checkmark Hiq shenjën e zgjedhjes + Remove from Recent Hiq nga të fundit + Remove header & footer Hiq kokën dhe fundin e faqes + Remove hidden information Hiq informacionin e fshehur + Remove hidden information and flatten comments and form fields, so recipients see only the pages. Hiq informacionin e fshehur dhe sheshoji komentet e fushat e formularit, që marrësit të shohin vetëm faqet. + Remove hidden information, metadata, scripts and embedded content, and rewrite the files. Hiq informacionin e fshehur, metadatat, skriptet dhe përmbajtjen e ngulitur, dhe rishkruaj skedarët. + Remove hidden information… Hiq informacionin e fshehur… + Remove invalid links and bookmarks Hiq lidhjet dhe libërshënuesit e pavlefshëm + Remove redaction marks Hiq shenjat e redaktimit + Remove saved {what} Hiq {what} të ruajtur + Remove security Hiq sigurinë + Remove unreferenced named destinations Hiq destinacionet e emërtuara të pareferuara + Remove unused objects and merge identical ones Hiq objektet e papërdorura dhe bashko ato identike + Remove watermark Hiq filigranën + Remove {name} Hiq {name} + Remove {name} from Recent Hiq {name} nga të fundit + Remove {n} files Hiq {n} skedarë + Removed 1 hidden item. Save to remove them from the file. U hoq 1 element i fshehur. Ruaje për ta hequr nga skedari. + Removed {n} hidden items. Save to remove them from the file. U hoqën {n} elemente të fshehur. Ruaje për t'i hequr nga skedari. + Rename Riemërto + Rename bookmark Riemërto libërshënuesin + Rendering: hayro (bootstrap) · UI: egui · Icons: Lucide (ISC) · Fonts: Inter, JetBrains Mono, Dancing Script (OFL) Duke vizatuar: hayro (fillestar) · UI: egui · Ikonat: Lucide (ISC) · Shkronjat: Inter, JetBrains Mono, Dancing Script (OFL) + Reopen the files that were open when PdfCraft last closed Rihap skedarët që ishin hapur kur u mbyll PdfCraft për herë të fundit + Repair log Regjistri i riparimeve + Repairs Riparimet + Repeat overlay text Përsërit tekstin e mbivendosjes + Repeated navigation links should be skippable. Check links that appear on every page. Lidhjet e përsëritura të navigimit duhet të mund të anashkalohen. Kontrollo lidhjet që shfaqen në çdo faqe. + Replace Zëvendëso + Replace Image… Zëvendëso imazhin… + Replace Pages Zëvendëso faqet + Replace image Zëvendëso imazhin + Replace page Zëvendëso faqen + Replace pages Zëvendëso faqet + Replace pages… Zëvendëso faqet… + Replace text Zëvendëso tekstin + Replaced Zëvendësuar + Replacement text Teksti zëvendësues + Replacement: pages of {name} Zëvendësimi: faqet e {name} + Replaces the existing one on those pages. Zëvendëson atë ekzistues në ato faqe. + Replacing images arrives on the web with image file pickers Zëvendësimi i imazheve vjen në ueb me zgjedhësit e skedarëve të imazhit + Replacing images on page {p} arrives on the web with image pickers ({i}) Zëvendësimi i imazheve në faqen {p} vjen në ueb me zgjedhësit e imazhit ({i}) + Reply Përgjigju + Report Raporti + Report Options Opsionet e raportit + Report… Raporti… + Required E detyrueshme + Requires user to enter a password for: Kërkon që përdoruesi të fusë një fjalëkalim për: + Reset a form Rivendos një formular + Reset columns Rivendos kolonat + Resize comment Ndrysho madhësinë e komentit + Resize window to initial page Ndrysho madhësinë e dritares sipas faqes fillestare + Resolution Rezolucioni + Restrictions Kufizimet + Retain existing Mbaj ekzistueset + Reverse pages Ktheje radhën e faqeve + Reverse the order Ktheje radhën + Revert Rikthe + Revert to the previously saved version of “{name}”? Changes since then can't be undone afterwards. Të rikthehet te versioni i ruajtur më parë i “{name}”? Ndryshimet e bëra që atëherë nuk mund të zhbëhen më pas. + Reverted to the last saved version U rikthye te versioni i fundit i ruajtur + Review Rishiko + Review History Historiku i rishikimeve + Revisions Rishikimet + Rich Text Format (.rtf) Rich Text Format (.rtf) + Right Djathtas + Right Edge Skaji i djathtë + Right Footer Text Teksti i fundit të faqes djathtas + Right Header Text Teksti i kokës së faqes djathtas + Rotate Rrotullo + Rotate Clockwise Rrotullo në drejtim orar + Rotate Counterclockwise Rrotullo në drejtim kundërorar + Rotate Pages Rrotullo faqet + Rotate clockwise Rrotullo në drejtim orar + Rotate counterclockwise Rrotullo në drejtim kundërorar + Rotate image Rrotullo imazhin + Rotate page Rrotullo faqen + Rotate pages Rrotullo faqet + Rotate pages clockwise Rrotullo faqet në drejtim orar + Rotate pages counterclockwise Rrotullo faqet në drejtim kundërorar + Rotate pages… Rrotullo faqet… + Rotate view Rrotullo pamjen + Rotate view clockwise Rrotullo pamjen në drejtim orar + Rotate view clockwise (⇧⌘+) Rrotullo pamjen në drejtim orar (⇧⌘+) + Rotate view counterclockwise Rrotullo pamjen në drejtim kundërorar + Rotate: Rrotullo: + Rotation Rrotullimi + Rows Rreshtat + Run Ekzekuto + Run JavaScript Ekzekuto JavaScript + Run a JavaScript Ekzekuto një JavaScript + Run form script Ekzekuto skriptin e formularit + Running action… file {d} of {t} Duke ekzekutuar veprimin… skedari {d} nga {t} + SHA-1 digest Përmbledhja SHA-1 + SHA-256 digest Përmbledhja SHA-256 + Sanitize Pastro + Sanitize Documents Pastro dokumentet + Sanitize document Pastro dokumentin + Sanitize document… Pastro dokumentin… + Sanitizing removes hidden information from the document: metadata, file attachments, comments, form fields (flattened), hidden text and layers, bookmarks, links, actions and scripts, and private application data. Pastrimi heq nga dokumenti informacionin e fshehur: metadatat, bashkëngjitjet, komentet, fushat e formularit (të sheshuara), tekstin dhe shtresat e fshehura, libërshënuesit, lidhjet, veprimet dhe skriptet, si dhe të dhënat private të aplikacioneve. + Save Ruaj + Save & Close Ruaj dhe mbyll + Save (M4) Ruaj (M4) + Save Image As… Ruaj imazhin si… + Copy Image Kopjo imazhin + The image has been copied ({w} × {h} pixels) Imazhi u kopjua ({w} × {h} piksel) + Couldn't copy the image: {e} Imazhi nuk u kopjua: {e} + Copy Image in Original Format Kopjo imazhin në formatin origjinal + The image has been copied as a {ext} file Imazhi u kopjua si skedar {ext} + The page has changed; select the image again Faqja ka ndryshuar; zgjidh sërish imazhin + Save as PDF Ruaj si PDF + Save as PDF/A Ruaj si PDF/A + Save as PDF/A-1b Ruaj si PDF/A-1b + Save as PDF/A-2b Ruaj si PDF/A-2b + Save as PDF/A-3b Ruaj si PDF/A-3b + Save as PDF/UA Ruaj si PDF/UA + Save as PDF/X Ruaj si PDF/X + Save as… Ruaj si… + Save attachment… Ruaj bashkëngjitjen… + Save changes to “{name}” before closing? Të ruhen ndryshimet në “{name}” para mbylljes? + Save image Ruaj imazhin + Save pages Ruaj faqet + Save the accessibility report Ruaj raportin e aksesueshmërisë + Save the document afterwards: saving rewrites the whole file so no trace of the removed content stays in it. Ruaje dokumentin më pas: ruajtja rishkruan të gjithë skedarin, që të mos mbetet asnjë gjurmë e përmbajtjes së hequr. + Save the document afterwards; saving rewrites the whole file so nothing removed stays in it. Ruaje dokumentin më pas; ruajtja rishkruan të gjithë skedarin, që asgjë e hequr të mos mbetet në të. + Save the spreadsheet Ruaj fletëllogaritësen + Save these pages as one PDF Ruaj këto faqe si një PDF + Saved measurements Matjet e ruajtura + Saved measurements. Matjet e ruajtura. + Saved the print-ready PDF to {path} PDF-ja gati për shtyp u ruajt në {path} + Saved {name} U ruajt {name} + Saved {place}: {before} → {after} ({pct}% smaller){detail} U ruajt {place}: {before} → {after} ({pct}% më e vogël){detail} + Saved, but reopening failed: {e} U ruajt, por rihapja dështoi: {e} + Scale relative to target page Shkalla në raport me faqen e synuar + Scan & OCR Skanim dhe OCR + Screen flicker Dridhja e ekranit + Screen readers choose their voice from the document's language. Set it in Document Properties > Advanced > Language. Lexuesit e ekranit e zgjedhin zërin sipas gjuhës së dokumentit. Caktojeni te Veçoritë e dokumentit > Të avancuara > Gjuha. + Script Name: Emri i skriptit: + Script: Skripti: + Scripted content must be usable with a keyboard and assistive technology. Check the document's scripts. Përmbajtja me skripte duhet të jetë e përdorshme me tastierë dhe teknologji ndihmëse. Kontrolloni skriptet e dokumentit. + Scripts Skriptet + Scripts run in a sandbox without file or network access. A script that asks to open a web page needs your permission first. With JavaScript off, Acrobat's standard format, validate and calculate functions still work. Skriptet ekzekutohen në një ambient të izoluar, pa qasje te skedarët apo rrjeti. Një skript që kërkon të hapë një faqe web ka nevojë më parë për lejen tuaj. Me JavaScript të çaktivizuar, funksionet standarde të Acrobat për formatim, vlerësim dhe llogaritje vazhdojnë të punojnë. + Scripts run in a sandbox without file or network access. With JavaScript off, Acrobat's standard format, validate and calculate functions still work. Skriptet ekzekutohen në një ambient të izoluar, pa qasje te skedarët apo rrjeti. Me JavaScript të çaktivizuar, funksionet standarde të Acrobat për formatim, vlerësim dhe llogaritje vazhdojnë të punojnë. + Scroll long text Lëviz tekstin e gjatë + Search Kërko + Search comments Kërko te komentet + Search tools and commands… Kërko mjete dhe komanda… + Searchable Image (Exact) Imazh i kërkueshëm (i saktë) + Searching… {s} of {p} pages Po kërkohet… {s} nga {p} faqe + Searching… {s}/{p} Po kërkohet… {s}/{p} + Security Siguria + Security method Metoda e sigurisë + Security properties Veçoritë e sigurisë + Security properties… Veçoritë e sigurisë… + Security settings Cilësimet e sigurisë + Security settings must allow assistive technology to read the content ("Enable text access for screen reader devices"). Change the document's security to allow it. Cilësimet e sigurisë duhet t'i lejojnë teknologjisë ndihmëse ta lexojë përmbajtjen ("Enable text access for screen reader devices"). Ndryshoni sigurinë e dokumentit për ta lejuar. + Security will be removed when you save Siguria do të hiqet kur ta ruani + Select (V) Zgjidh (V) + Select Action: Zgjidh veprimin: + Select All Zgjidh të gjitha + Select Icon Zgjidh ikonën + Select Trigger: Zgjidh nxitësin: + Select a file first Zgjidhni fillimisht një skedar + Select a file for the stamp Zgjidhni një skedar për vulën + Select a password-protected file first Zgjidhni fillimisht një skedar të mbrojtur me fjalëkalim + Select a word Zgjidh një fjalë + Select all pages (Organize) Zgjidh të gjitha faqet (Organizo) + Select data files to merge Zgjidh skedarët e të dhënave për t'u bashkuar + Select files to compare Zgjidh skedarët për krahasim + Select format category: Zgjidh kategorinë e formatit: + Select pages Zgjidh faqet + Select the items to remove from this document. Zgjidhni elementët që do të hiqen nga ky dokument. + Selected image files: {count} Skedarë imazhi të zgjedhur: {count} + Selected pages Faqet e zgjedhura + Selection Përzgjedhja + Self-signed I vetënënshkruar + Sensitivity Ndjeshmëria + Sent to {printer} U dërgua te {printer} + Sent to {printer}: {msg} U dërgua te {printer}: {msg} + Separator style: Stili i ndarësit: + September Shtator + Serial number Numri serik + Set Alternate Text Cakto tekstin alternativ + Set Fields to Same Size Cakto fushat me madhësi të njëjtë + Set Page Boxes Cakto kutitë e faqes + Set alternate text Cakto tekstin alternativ + Set bookmark destination Cakto destinacionin e libërshënuesit + Set document title Cakto titullin e dokumentit + Set layer visibility Cakto dukshmërinë e shtresës + Set measurement scale Cakto shkallën e matjes + Set page boxes Cakto kutitë e faqes + Set page boxes… Cakto kutitë e faqes… + Set properties Cakto veçoritë + Set status Cakto statusin + Set status Accepted Cakto statusin Pranuar + Set status Cancelled Cakto statusin Anuluar + Set status Completed Cakto statusin Përfunduar + Set status None Cakto statusin Asnjë + Set status Rejected Cakto statusin Refuzuar + Set status Unmarked Cakto statusin Pa shënuar + Set tab order Cakto renditjen e tabit + Set the image of {name} Cakto imazhin e {name} + Set to current page ({n}) Cakto në faqen aktuale ({n}) + Set to zero Cakto në zero + Settings Cilësimet + Shadings Hijëzimet + Sheet {s} of {n} Fleta {s} nga {n} + Shift constrains to 45 degrees. Backspace removes a vertex. Escape cancels. Shift e kufizon në 45 gradë. Backspace heq një kulm. Escape anulon. + Show Shfaq + Show Report Shfaq raportin + Show a field Shfaq një fushë + Show all Shfaq të gjitha + Show all comments Shfaq të gjitha komentet + Show certificate… Shfaq certifikatën… + Show cover page in two-page view Shfaq faqen e kopertinës në pamjen me dy faqe + Show layer Shfaq shtresën + Show less Shfaq më pak + Show password Shfaq fjalëkalimin + Show the accessibility report Shfaq raportin e qasshmërisë + Show this dialog when the Checker starts Shfaq këtë dialog kur nis Kontrolluesi + Show {n} more Shfaq edhe {n} + Show: Shfaq: + Shrink oversized pages Zvogëlo faqet e mëdha + Side panels Panelet anësore + Sign Nënshkruaj + Sign Here Nënshkruani këtu + Sign this field… Nënshkruaj këtë fushë… + Sign with a Digital ID Nënshkruaj me një ID dixhitale + Sign yourself Nënshkruani vetë + Signature Nënshkrimi + Signature Details Detajet e nënshkrimit + Signature is INVALID: Nënshkrimi është i PAVLEFSHËM: + Signature is valid: Nënshkrimi është i vlefshëm: + Signature panel Paneli i nënshkrimit + Signature validity is UNKNOWN: Vlefshmëria e nënshkrimit është E PANJOHUR: + Signatures Nënshkrimet + Signatures panel Paneli i nënshkrimeve + Signed and all signatures are valid. Është nënshkruar dhe të gjitha nënshkrimet janë të vlefshme. + Signed and saved to {path} U nënshkrua dhe u ruajt te {path} + Signer Nënshkruesi + Signing time Koha e nënshkrimit + Simplified field notation: Shënimi i thjeshtuar i fushës: + Single Page Faqe e vetme + Single Page Continuous Faqe e vetme e vazhdueshme + Single file Skedar i vetëm + Single page Faqe e vetme + Single word or phrase Fjalë ose frazë e vetme + Size Madhësia + Skip Rule Kapërce rregullin + Skipped U kapërcye + Snap to drawing Ngjit te vizatimi + Snapping Ngjitja + Social Security Number Numri i sigurimeve shoqërore + Social Security Numbers Numrat e sigurimeve shoqërore + Solid I plotë + Some page content couldn't be read; snapping uses the rest. Një pjesë e përmbajtjes së faqes nuk u lexua; ngjitja përdor pjesën tjetër. + Sort Rendit + Sort by Rendit sipas + Sort comments by: Rendit komentet sipas: + Sort items Rendit elementët + Source Burimi + Space Audit Auditimi i hapësirës + Special Speciale + Split Ndaj + Split document Ndaj dokumentin + Split document… Ndaj dokumentin… + Split into files… Ndaj në skedarë… + Spreadsheet (.xlsx) Fletë llogaritjeje (.xlsx) + Square Katror + Squiggly Valëzuar + Squiggly underline Nënvizim i valëzuar + Squiggly underline text Nënvizo tekstin me valëzim + Stamp Vulë + Stamp palette Paleta e vulave + Stamps Vulat + Standard Business Biznes standard + Thai and Arabic use regular fallback fonts when available. Tajlandishtja dhe arabishtja përdorin shkronja rezervë të zakonshme kur ka të tilla. + Standards Standardet + Star Yll + Start Fillo + Start Checking Fillo kontrollin + Start page number Numri i faqes fillestare + Status Statusi + Steps Hapat + Sticky note Shënim ngjitës + Strength: {s} Fuqia: {s} + Strikethrough Vizë mbi tekst + Strikethrough text Tekst me vizë mbi të + Strong E fortë + Structure Info Info e strukturës + Style Stili + Subject Subjekti + Submit a form Dërgo një formular + Subset Nënbashkësi + Summarize Përmblidh + Summarize Options Opsionet e përmbledhjes + Summarize comments Përmblidh komentet + Summary Përmbledhje + Switch light / dark theme Ndërro temën e çelët / të errët + Switch to two-page view first to show the cover page Kaloni fillimisht te pamja me dy faqe për të shfaqur faqen e kopertinës + TH and TD TH dhe TD + TH and TD must be children of TR TH dhe TD duhet të jenë fëmijë të TR + TR must be a child of Table, THead, TBody, or TFoot TR duhet të jetë fëmijë i Table, THead, TBody ose TFoot + Tab order Renditja e tabit + Tab order by columns Renditja e tabit sipas kolonave + Tab order by rows Renditja e tabit sipas rreshtave + Tab order is consistent with structure order Renditja e tabit përputhet me renditjen e strukturës + Tab order: by columns Renditja e tabit: sipas kolonave + Tab order: by document structure Renditja e tabit: sipas strukturës së dokumentit + Tab order: by rows Renditja e tabit: sipas rreshtave + Tab order: move a field with its arrows. Renditja e tabit: lëvizni një fushë me shigjetat e saj. + Table Tabela + Table cells belong in a row. Fix the table's tags. Qelizat e tabelës duhet të jenë në një rresht. Rregulloni etiketat e tabelës. + Table rows belong directly in a table or its head, body or foot. Fix the table's tags. Rreshtat e tabelës duhet të jenë drejtpërdrejt në një tabelë ose në kokën, trupin ose fundin e saj. Rregulloni etiketat e tabelës. + Tables Tabelat + Tables must contain the same number of columns in each row and rows in each column Tabelat duhet të kenë të njëjtin numër kolonash në çdo rresht dhe rreshtash në çdo kolonë + Tables must have a summary Tabelat duhet të kenë një përmbledhje + Tables should have headers Tabelat duhet të kenë tituj + Tagged PDF PDF me etiketa + Tagged annotations Shënime me etiketa + Tagged content Përmbajtje me etiketa + Tagged form fields Fusha formulari me etiketa + Tagged multimedia Multimedia me etiketa + Tags give the document a logical structure that assistive technology follows. Tag the document (Automatically tag PDF). Etiketat i japin dokumentit një strukturë logjike që e ndjek teknologjia ndihmëse. Etiketoni dokumentin (Etiketo PDF automatikisht). + Take a snapshot Merr një pamje + Text Tekst + Text (plain) Tekst (i thjeshtë) + Text Color: Ngjyra e tekstit: + Text Field Properties Veçoritë e fushës së tekstit + Text alignment: Drejtimi i tekstit: + Text box Kuti teksti + Text field Fushë teksti + Text in images isn't found; recognise text (OCR) first. Teksti në imazhe nuk gjendet; njihni fillimisht tekstin (OCR). + Text is compared word by word; the differences are shown on the new file. Teksti krahasohet fjalë për fjalë; dallimet shfaqen te skedari i ri. + Text language is specified Gjuha e tekstit është caktuar + Text must contrast enough with its background for people with low vision. Check the colours by eye or with a contrast tool. Teksti duhet të kontrastojë mjaftueshëm me sfondin për personat me shikim të dobët. Kontrolloni ngjyrat me sy ose me një mjet kontrasti. + Text recognition is already running Njohja e tekstit është tashmë në punë + Text recognition isn't installed: its models are missing (run `cargo xtask models`, or set PDFCRAFT_MODELS). Njohja e tekstit nuk është e instaluar: mungojnë modelet e saj (ekzekutoni `cargo xtask models`, ose caktoni PDFCRAFT_MODELS). + Text to find Teksti për t'u gjetur + Text to insert Teksti për t'u futur + That didn't work: an internal error stopped it ({m}). Nuk funksionoi: një gabim i brendshëm e ndali ({m}). + That didn't work: an internal error stopped it ({m}). Your documents are unchanged. Nuk funksionoi: një gabim i brendshëm e ndali ({m}). Dokumentet tuaja nuk janë ndryshuar. + The Keychain's digital IDs couldn't be listed: {e} ID-të dixhitale të Keychain nuk u listuan dot: {e} + The Windows store's digital IDs couldn't be listed: {e} ID-të dixhitale të depos së Windows nuk u listuan dot: {e} + The checker found 1 problem which may prevent the document from being fully accessible. Kontrolluesi gjeti 1 problem që mund ta pengojë dokumentin të jetë plotësisht i qasshëm. + The checker found no problems in this document. Kontrolluesi nuk gjeti probleme në këtë dokument. + The checker found {n} problems which may prevent the document from being fully accessible. Kontrolluesi gjeti {n} probleme që mund ta pengojnë dokumentin të jetë plotësisht i qasshëm. + The clipboard has no image or text Kujtesa e fragmenteve nuk ka imazh apo tekst + The document changed while you were choosing a file, so nothing was changed. Dokumenti ndryshoi ndërsa zgjidhnit një skedar, ndaj nuk u ndryshua asgjë. + The document has additional actions (/AA) Dokumenti ka veprime shtesë (/AA) + The document has document-level JavaScript Dokumenti ka JavaScript në nivel dokumenti + The document has no XMP metadata Dokumenti nuk ka metadata XMP + The document is encrypted Dokumenti është i enkriptuar + The document now conforms to {level}; save it to keep the changes Dokumenti tani është në përputhje me {level}; ruajeni për t'i mbajtur ndryshimet + The document opens without a password; this password is needed to change the restrictions. It's applied when you save. Dokumenti hapet pa fjalëkalim; ky fjalëkalim nevojitet për të ndryshuar kufizimet. Zbatohet kur ruani. + The document was closed before it could be saved. Dokumenti u mbyll para se të ruhej. + The document's security settings don't allow filling in form fields Cilësimet e sigurisë së dokumentit nuk lejojnë plotësimin e fushave të formularit + The document's security settings don't allow this change Cilësimet e sigurisë së dokumentit nuk e lejojnë këtë ndryshim + The form asks to be submitted to {u}; PdfCraft doesn't send form data. Save the document to keep your entries. Formulari kërkon të dërgohet te {u}; PdfCraft nuk dërgon të dhëna formulari. Ruajeni dokumentin për të mbajtur të dhënat tuaja. + The form asks viewers to make appearances (NeedAppearances) Formulari u kërkon shikuesve të krijojnë pamjet (NeedAppearances) + The key is in the Windows certificate store, which may ask to allow PdfCraft to use it. Çelësi është në depon e certifikatave të Windows, e cila mund të kërkojë të lejohet PdfCraft ta përdorë. + The key is in the macOS Keychain, which may ask to allow PdfCraft to use it. Çelësi është në Keychain të macOS, i cili mund të kërkojë të lejohet PdfCraft ta përdorë. + The newest {n} of {total} PDFs {n} PDF-të më të reja nga {total} + The operation failed. Veprimi dështoi. + The pages were extracted but not deleted, because the document changed while you were choosing a folder. Faqet u nxorën por nuk u fshinë, sepse dokumenti ndryshoi ndërsa zgjidhnit një dosje. + The password is only used to read the file; it isn't saved. Fjalëkalimi përdoret vetëm për të lexuar skedarin; nuk ruhet. + The passwords don't match. Fjalëkalimet nuk përputhen. + The replacement file doesn't have that many pages. Skedari zëvendësues nuk ka kaq shumë faqe. + The same password is tried on each file. I njëjti fjalëkalim provohet te çdo skedar. + The selected area has been copied ({w} × {h} pixels) Zona e zgjedhur u kopjua ({w} × {h} piksel) + The signature will be invisible. Nënshkrimi do të jetë i padukshëm. + The existing action will be preserved. Veprimi ekzistues do të ruhet. + The text is the same Teksti është i njëjtë + The title in the metadata and the document information differ Titulli te metadata dhe te informacioni i dokumentit ndryshojnë + The value is shown as typed. Vlera shfaqet siç është shkruar. + The window should show a meaningful title rather than the file name. Set a title and Initial View > Show: Document Title. Dritarja duhet të shfaqë një titull kuptimplotë në vend të emrit të skedarit. Caktoni një titull dhe Pamja fillestare > Shfaq: Titulli i dokumentit. + There are no redaction marks (mark text, areas or pages first) Nuk ka shenja redaktimi (shënoni fillimisht tekst, zona ose faqe) + There are no redaction marks to apply Nuk ka shenja redaktimi për t'u zbatuar + Thick E trashë + Thickness Trashësia + Thin E hollë + This area has too many overlapping paths; intersection snapping is limited. Kjo zonë ka shumë shtigje që mbivendosen; ngjitja te prerjet është e kufizuar. + This certificate is in your list of trusted certificates. Kjo certifikatë është në listën tuaj të certifikatave të besuara. + This certificate is not trusted. Signatures made with it show an unknown identity. Kjo certifikatë nuk është e besuar. Nënshkrimet e bëra me të shfaqin një identitet të panjohur. + This certificate is trusted through a certificate above it in the chain. Kjo certifikatë besohet nëpërmjet një certifikate mbi të në zinxhir. + This comment's appearance can't be changed yet. Pamja e këtij komenti nuk mund të ndryshohet ende. + This compatibility level supports only plain ASCII passwords. Ky nivel përputhshmërie mbështet vetëm fjalëkalime të thjeshta ASCII. + This dialog shows the details of a certificate and its chain. Ky dialog shfaq detajet e një certifikate dhe të zinxhirit të saj. + This document can't be checked: it couldn't be read for editing Ky dokument nuk mund të kontrollohet: nuk u lexua dot për redaktim + This document contains {n} interactive form fields. Ky dokument përmban {n} fusha interaktive formulari. + This document has no attachments. Ky dokument nuk ka bashkëngjitje. + This document has no bookmarks. Ky dokument nuk ka libërshënues. + This document has no comments to flatten Ky dokument nuk ka komente për t'u sheshuar + This document has no document-level scripts. Ky dokument nuk ka skripte në nivel dokumenti. + This document has no form fields to flatten Ky dokument nuk ka fusha formulari për t'u sheshuar + This document has no form fields you can fill in Ky dokument nuk ka fusha formulari që mund të plotësoni + This document has no form fields. Ky dokument nuk ka fusha formulari. + This document has no layers. Ky dokument nuk ka shtresa. + This document has no pages. Ky dokument nuk ka faqe. + This document has no signatures. Ky dokument nuk ka nënshkrime. + This document has no tagged figures. Ky dokument nuk ka figura me etiketa. + This document has no {kind} to change Ky dokument nuk ka {kind} për t'u ndryshuar + This document hasn't been checked yet. Ky dokument nuk është kontrolluar ende. + This document is secured. Some changes are restricted by its security settings. Ky dokument është i siguruar. Disa ndryshime kufizohen nga cilësimet e sigurisë së tij. + This document isn't password-protected Ky dokument nuk është i mbrojtur me fjalëkalim + This drawing exceeds the snapping limit; only the first paths are used. Ky vizatim e tejkalon kufirin e ngjitjes; përdoren vetëm shtigjet e para. + This field is locked. Unlock it to change its properties. Kjo fushë është e kyçur. Shkyçeni për të ndryshuar veçoritë e saj. + This file was damaged and has been repaired. Saving keeps the repaired version. Ky skedar ishte i dëmtuar dhe u riparua. Ruajtja mban versionin e riparuar. + This folder isn't available right now. It may have moved, or its drive or cloud sync is offline. Kjo dosje nuk është e disponueshme tani. Mund të jetë zhvendosur, ose disku apo sinkronizimi i saj në re është jashtë linje. + This form also contains XFA data, which PdfCraft doesn't read yet. You can fill its fields, but Acrobat may show the XFA values instead. Ky formular përmban edhe të dhëna XFA, të cilat PdfCraft ende nuk i lexon. Mund t'i plotësoni fushat e tij, por Acrobat mund të shfaqë në vend të tyre vlerat XFA. + This is a dynamic XFA form, which PdfCraft can't display yet. What you see is the file's placeholder page. Ky është një formular dinamik XFA, të cilin PdfCraft ende nuk mund ta shfaqë. Ajo që shihni është faqja zëvendësuese e skedarit. + This measurement needs at least {n} points. Kjo matje kërkon të paktën {n} pika. + This page couldn't be displayed.\n{e} Kjo faqe nuk u shfaq dot.\n{e} + This web address mixes letters from different alphabets, a common way to imitate another site's name. Kjo adresë web përzien shkronja nga alfabete të ndryshme, një mënyrë e zakonshme për të imituar emrin e një faqeje tjetër. + This web address uses letters from another alphabet, which can look like familiar ones. Kjo adresë web përdor shkronja nga një alfabet tjetër, të cilat mund të duken si ato të njohurat. + Thumbnails Miniaturat + Tile scale: Shkalla e pllakave: + Time Ora + Timed responses Përgjigje të kohëzuara + Timestamp Vula kohore + Title Titulli + To: Për: + Toggle fit page / fit width Ndërro përshtatjen e faqes / gjerësisë + Tool Mjeti + Tooltip: Këshilla e mjetit: + Top Sipër + Top-level bookmarks ({n}) Libërshënuesit e nivelit të parë ({n}) + Total Totali + Translate Përkthe + Trust Besim + Try the form as people filling it in will see it Provoni formularin siç do ta shohin ata që e plotësojnë + Two-Up (Cover Page) Dy faqe (me kopertinë) + Two-Up (Facing) Dy faqe (përballë) + Two-Up Continuous (Cover Page) Dy faqe të vazhdueshme (me kopertinë) + Two-Up Continuous (Facing) Dy faqe të vazhdueshme (përballë) + Two-page view Pamja me dy faqe + Two-sided: Dyanëshe: + Type Lloji + Type Password Shkruaj fjalëkalimin + Type a password. Shkruani një fjalëkalim. + Type text Shkruaj tekst + Type the web address. Shkruani adresën web. + Type your {what}. Shkruani {what} tuaj. + Typewriter Makinë shkrimi + URL to submit to URL-ja ku do të dërgohet + Unchecked Pa shënuar + Underline Nënvizim + Underline text Nënvizo tekstin + Undid {label} U zhbë {label} + Undo Zhbëj + Undo {action} Zhbëj {action} + Unit Njësia + Units Njësitë + Unknown E panjohur + Unknown author Autor i panjohur + Unlock Shkyç + Unlock comment Shkyç komentin + Unlock {name} Shkyç {name} + Unlock {n} files Shkyç {n} skedarë + Unlocked {n} of {m} files U shkyçën {n} nga {m} skedarë + Unlocked: the combined file won't be password-protected Shkyçur: skedari i bashkuar nuk do të mbrohet me fjalëkalim + Unlock… Shkyç… + Unpin Hiq gozhdimin + Unpin {folder} Hiq gozhdimin e {folder} + Unplaced I paplasuar + Unsupported measurements Matje të pambështetura + Up Lart + Update Përditëso + Update background Përditëso sfondin + Update background… Përditëso sfondin… + Update header & footer Përditëso kokën & fundin + Update header & footer… Përditëso kokën & fundin… + Update watermark Përditëso filigranin + Update watermark… Përditëso filigranin… + Use 72 DPI (one point per pixel) Përdor 72 DPI (një pikë për piksel) + Use Flate to encode streams that are not encoded Përdor Flate për të koduar rrjedhat që nuk janë të koduara + Use JavaScript Përdor JavaScript + Use a Digital ID from a file Përdor një ID dixhitale nga një skedar + Use a certificate Përdor një certifikatë + Use custom DPI Përdor DPI të personalizuar + Use each image's embedded DPI; use 72 DPI when it is absent. Përdor DPI-në e ngulitur të çdo imazhi; përdor 72 DPI kur mungon. + Use guided actions Përdor veprime të udhëzuara + Use image resolution Përdor rezolucionin e imazhit + Use now Përdor tani + Use overlay text Përdor tekst mbivendosës + Use print production Përdor prodhimin e shtypit + Use system setting Përdor cilësimin e sistemit + Use {what} Përdor {what} + Used when a PDF doesn't ask for a layout or zoom. Continuous scrolling never snaps between pages. Përdoret kur një PDF nuk kërkon paraqitje apo zmadhim. Lëvizja e vazhdueshme nuk ngjitet kurrë mes faqeve. + Used when opening PDFs. An explicit launch or control mode takes precedence for the session. Përdoret kur hapen PDF-të. Një nisje e qartë ose mënyra e kontrollit ka përparësi gjatë sesionit. + User Interface Options Opsionet e ndërfaqes së përdoruesit + User password Fjalëkalimi i përdoruesit + Username Emri i përdoruesit + Valid I vlefshëm + Valid for 5 years, for digital signatures. Self-signed IDs are usually not trusted by others. E vlefshme për 5 vjet, për nënshkrime dixhitale. ID-të e vetënënshkruara zakonisht nuk besohen nga të tjerët. + Valid from E vlefshme nga + Valid to E vlefshme deri + Validate Vlerëso + Validate all Vlerëso të gjitha + Validate all signatures Vlerëso të gjitha nënshkrimet + Validity ends Vlefshmëria mbaron + Validity starts Vlefshmëria fillon + Value is not calculated Vlera nuk llogaritet + Value is the Vlera është + Value: Vlera: + Verify Verifiko + Verify to see what the document needs. Verifikoni për të parë çfarë i nevojitet dokumentit. + Version Versioni + Version {v} Versioni {v} + Vertical Vertikale + Vertical reversed Vertikale e kthyer + Vertically Vertikalisht + Video, sound and rich media must be tagged to be announced. Tag the multimedia annotations. Videoja, zëri dhe media e pasur duhet të etiketohen për t'u lexuar. Etiketoni shënimet e multimedias. + View less Shiko më pak + View more Shiko më shumë + View revision {n} Shiko rishikimin {n} + View signed version Shiko versionin e nënshkruar + Viewing Shikimi + Viewport Dritarja e pamjes + Viewport rectangle in page points (x, y, width, height) Drejtkëndëshi i dritares së pamjes në pika faqeje (x, y, gjerësia, lartësia) + Visible Rectangle Drejtkëndësh i dukshëm + Visual Pamor + Warnings Paralajmërimet + Watermark Filigran + Weak E dobët + Welcome to PdfCraft Mirë se vini në PdfCraft + What word or phrase would you like to search for? Çfarë fjale ose fraze do të kërkoni? + Whole words only Vetëm fjalë të plota + Width Gjerësia + Width: Gjerësia: + Window Options Opsionet e dritares + Windows store · Dyqani i Windows · + Write this email? Ta shkruani këtë email? + Wrong password Fjalëkalim i gabuar + Wrote 1 file to {dir} U shkrua 1 skedar te {dir} + Wrote {n} files to {dir} U shkruan {n} skedarë te {dir} + X Object Forms Forma X Object + XFA form: its fields and its XFA data are kept in step, so other viewers show what you fill in. Formular XFA: fushat dhe të dhënat XFA mbahen në përputhje, kështu që shfletuesit e tjerë shfaqin atë që plotësoni. + Yellow E verdhë + Yes Po + You are about to apply 1 redaction mark. Text, images and drawings under the marks, and comments and form fields that overlap them, are removed permanently. Jeni gati të zbatoni 1 shenjë redaktimi. Teksti, imazhet dhe vizatimet nën shenjat, si dhe komentet dhe fushat e formularit që mbivendosen me to, hiqen përgjithmonë. + You are about to apply {n} redaction marks. Text, images and drawings under the marks, and comments and form fields that overlap them, are removed permanently. Jeni gati të zbatoni {n} shenja redaktimi. Teksti, imazhet dhe vizatimet nën shenjat, si dhe komentet dhe fushat e formularit që mbivendosen me to, hiqen përgjithmonë. + You can pin up to {n} folders. Unpin one first. Mund të fiksoni deri në {n} dosje. Hiqni fiksimin e njërës më parë. + You have version {c}. All releases are listed at {page}. Keni versionin {c}. Të gjitha botimet janë të listuara te {page}. + You have version {c}. Download the new version from its release page. Keni versionin {c}. Shkarkoni versionin e ri nga faqja e botimit. + Your changes will be lost if you don't save them. Ndryshimet tuaja do të humbasin nëse nuk i ruani. + Your name Emri juaj + ZIP ZIP + Zip Code Kodi postar + Zip Code + 4 Kodi postar + 4 + Zoom Zmadhimi + Zoom in Zmadho + Zoom in (⌘+) Zmadho (⌘+) + Zoom in / out (also pinch or ⌘-scroll) Zmadho / zvogëlo (edhe me pinch ose ⌘-rrotullim) + Zoom out Zvogëlo + Zoom out (⌘−) Zvogëlo (⌘−) + Zoom to page level Zmadho në nivelin e faqes + `{command}` {when} `{command}` {when} + a bookmark cannot be moved inside itself një libërshënues nuk mund të zhvendoset brenda vetes + a document must keep at least one page një dokument duhet të mbajë të paktën një faqe + average mesatarja + background sfondi + characters karaktere + e.g. My stamps p.sh. Pullat e mia + e.g. en-US p.sh. en-US + for images above për imazhet mbi + header or footer koka ose këmba + initials inicialet + is available është i disponueshëm + is not available yet nuk është ende i disponueshëm + just now pikërisht tani + maximum maksimumi + minimum minimumi + needs an AI provider (off by default) kërkon një ofrues IA (i çaktivizuar si parazgjedhje) + no such document nuk ka dokument të tillë + none asnjë + nothing in the file matches this document asgjë në skedar nuk përputhet me këtë dokument + nothing to redo asgjë për ta ribërë + nothing to undo asgjë për ta zhbërë + of the following fields: e fushave të mëposhtme: + of {name} e {name} + of {pages} e {pages} + on page {label} në faqen {label} + open to see what it will include hapeni për të parë çfarë do të përfshijë + pages faqe + product (x) prodhimi (x) + ships in milestone {m} vjen në fazën {m} + signature nënshkrimi + sorted ascending renditur në rritje + sorted descending renditur në zbritje + sum (+) shuma (+) + the document has no form fields dokumenti nuk ka fusha formulari + the document has no page tree dokumenti nuk ka pemë faqesh + the document has no tags dokumenti nuk ka etiketa + the document is protected by a password dokumenti është i mbrojtur me fjalëkalim + the image is empty imazhi është bosh + the password is incorrect fjalëkalimi është i pasaktë + the title must not be empty titulli nuk duhet të jetë bosh + there are no pages to print nuk ka faqe për t'u printuar + there are no redaction marks to apply nuk ka shenja redaktimi për t'u zbatuar + this document is signed: rewriting it would invalidate its signatures (save it incrementally instead) ky dokument është i nënshkruar: rishkrimi i tij do të bënte të pavlefshme nënshkrimet (ruajeni në mënyrë inkrementale) + this file isn't XFDF, FDF, XML or text form data ky skedar nuk është të dhëna formulari XFDF, FDF, XML ose tekst + to deri në + to {n} deri në {n} + watermark filigrami + yesterday dje + {0}: {1} {0}: {1} + {c} of {n}{more} {c} nga {n}{more} + {dpi} pixels/inch {dpi} piksele/inç + {field}: {e} {field}: {e} + {file} is too large for a stamp (at most {n} MB) {file} është shumë i madh për një pullë (më së shumti {n} MB) + {folder} is already pinned to Home {folder} është tashmë i fiksuar te Kreu + {kind} Properties Vetitë e {kind} + {kind} field Fusha {kind} + {kind} · page {p} {kind} · faqja {p} + {kind} — click to show it on the page {kind} — klikoni për ta shfaqur në faqe + {k} of {n} {k} nga {n} + {label} (1 issue) {label} (1 problem) + {label} ({n} issues) {label} ({n} probleme) + {label} failed: {e} {label} dështoi: {e} + {month} {day}, {y} {day} {month}, {y} + {month} {y} {month} {y} + {msg} to {dir} {msg} te {dir} + {name} (default) {name} (parazgjedhja) + {name} can't be combined: {why} {name} nuk mund të kombinohet: {why} + {name} has no action {name} nuk ka veprim + {name} is read-only {name} është vetëm për lexim + {name} submits the form to {url}; PdfCraft doesn't send form data. Save the document to keep your entries. {name} dërgon formularin te {url}; PdfCraft nuk dërgon të dhëna formulari. Ruajeni dokumentin për të mbajtur të dhënat tuaja. + {name} — unsaved changes {name} — ndryshime të paruajtura + {name}: choosing images arrives on the web with file pickers for images {name}: zgjedhja e imazheve vjen në ueb me zgjedhës skedarësh për imazhe + {name}: the {other} action isn't supported yet {name}: veprimi {other} nuk mbështetet ende + {n} contributors · {c} commits {n} kontribues · {c} commit + {n} days ago {n} ditë më parë + {n} differences found U gjetën {n} dallime + {n} files {n} skedarë + {n} files done {n} skedarë përfunduan + {n} files need attention {n} skedarë kërkojnë vëmendje + {n} h ago {n} orë më parë + {n} instances {n} instanca + {n} issues {n} probleme + {n} marks {n} shenja + {n} match(es) marked for redaction. {n} përputhje u shënuan për redaktim. + {n} measurements use an unsupported format and are left out. {n} matje përdorin një format të pambështetur dhe janë lënë jashtë. + {n} min ago {n} min më parë + {n} pages {n} faqe + {n} pages selected {n} faqe të zgjedhura + {n} pages selected. {n} faqe të zgjedhura. + {n} selected {n} të zgjedhura + {n} {kind} {n} {kind} + {rule} - {status} {rule} - {status} + {s} action Veprimi {s} + This PDF uses the unsupported {s} action. Ky PDF përdor veprimin e pambështetur {s}. + {verb} Background {verb} sfondin + {verb} Header and Footer {verb} kokën dhe këmbën + {verb} Watermark {verb} filigranin + {verb} as "{name}" {verb} si "{name}" + {who} in this document tried to open an address PdfCraft won't open: {e}. {who} në këtë dokument u përpoq të hapte një adresë që PdfCraft nuk e hap: {e}. + {who} in this document tried to open an address PdfCraft won't open: {e}. Only web (http, https) and email (mailto) links open from documents. {who} në këtë dokument u përpoq të hapte një adresë që PdfCraft nuk e hap: {e}. Nga dokumentet hapen vetëm lidhjet e uebit (http, https) dhe të emailit (mailto). + {who} in this document wants to open this address in your browser: {who} në këtë dokument dëshiron ta hapë këtë adresë në shfletuesin tuaj: + {who} in this document wants to open your email app with this address: {who} në këtë dokument dëshiron të hapë aplikacionin tuaj të emailit me këtë adresë: + {words} on {pages} {words} në {pages} + ΔLOC ΔLOC + — (protection is applied when you save) — (mbrojtja zbatohet kur ruani) + “{name}” is protected. Enter a password to open it. “{name}” është i mbrojtur. Vendosni një fjalëkalim për ta hapur. + −Bin −Bin + −LOC −LOC +action wizard Start Fillo +certificate Subject Subjekti +comment menu Edit Redakto +signature pad Type Shkruaj +@plural {n} field|{n} fields {n} fushë|{n} fusha + ({n} at {dpi} dpi, the largest size they can be drawn at) ({n} në {dpi} dpi, madhësia më e madhe në të cilën mund të vizatohen) + A selected field has no widget on any page, so the fields can't be edited together. Një fushë e zgjedhur nuk ka widget në asnjë faqe, kështu që fushat nuk mund të redaktohen së bashku. + Butt Skaj i sheshtë + Character limit 0 means no limit. A comb of characters needs a limit. Kufiri 0 i karaktereve do të thotë pa kufi. Një krehër karakteresh kërkon një kufi. + Character limit: Kufiri i karaktereve: + Closed arrow Shigjetë e mbyllur + Comb of characters Krehër karakteresh + Couldn't open the printer's preferences: {e} Nuk u hapën preferencat e printerit: {e} + Custom font Font i personalizuar + Date format Formati i datës + Document properties ({key}) Vetitë e dokumentit ({key}) + Fill & Sign dates Datat e Fill & Sign + Flatten Fill & Sign when saving Sheshoje Fill & Sign gjatë ruajtjes + Font size 0 uses automatic sizing. Madhësia 0 e fontit përdor përmasim automatik. + Import list… Importo listën… + Larger pages Faqe më të mëdha + Line ending Fundi i vijës + Mixed E përzier + Multiple words or phrases Fjalë ose fraza të shumta + New bookmark ({key}) Libërshënues i ri ({key}) + New bookmarks from structure Libërshënues të rinj nga struktura + Next ({key}) Tjetra ({key}) + One word or phrase per line Një fjalë ose frazë për rresht + Only checked properties will change. Mixed means the selected fields have different values. Vetëm vetitë e shënuara do të ndryshojnë. E përzier do të thotë se fushat e zgjedhura kanë vlera të ndryshme. + Open a PDF ({key}) Hap një PDF ({key}) + Open arrow Shigjetë e hapur + Opens the printer driver's preferences. They are saved for every print from this computer; the copies, two-sided, grayscale and paper chosen here still apply. Hap preferencat e drajverit të printerit. Ato ruhen për çdo printim nga ky kompjuter; kopjet, dyanshmi, nuanca gri dhe letra e zgjedhur këtu vlejnë prapë. + Pattern Modeli + PdfCraft is drawing without a graphics processor, so it may be slow. Updating the graphics driver may help. PdfCraft po vizaton pa procesor grafik, ndaj mund të jetë i ngadaltë. Përditësimi i drajverit grafik mund të ndihmojë. + Previous ({key}) E mëparshmja ({key}) + Print ({key}) Printo ({key}) + Printer properties Vetitë e printerit + Redaction code: Kodi i redaktimit: + Reset page size Rivendos madhësinë e faqes + Reset to printer defaults Rivendos te parazgjedhjet e printerit + Reverse closed arrow Shigjetë e mbyllur e kundërt + Reverse open arrow Shigjetë e hapur e kundërt + Rotate view clockwise ({key}) Rrotullo pamjen në drejtim orar ({key}) + Rotation: Rrotullimi: + Same as interface ({language}) Njësoj si ndërfaqja ({language}) + Scroll tabs left Lëviz skedat majtas + Scroll tabs right Lëviz skedat djathtas + Shared Field Properties Vetitë e përbashkëta të fushës + Shift- or Ctrl/Command-click to select several fields. Shift- ose Ctrl/Command-klikoni për të zgjedhur disa fusha. + Slash Vijë e pjerrët + Smaller pages Faqe më të vogla + Text recognition isn't installed: its model files are missing. Reinstall PdfCraft, or set PDFCRAFT_MODELS to the folder that holds them. Njohja e tekstit nuk është e instaluar: mungojnë skedarët e modelit. Instaloni përsëri PdfCraft, ose vendosni PDFCRAFT_MODELS te dosja që i përmban. + Text, marks and signatures become part of the page. Other comments stay editable. Teksti, shenjat dhe nënshkrimet bëhen pjesë e faqes. Komentet e tjera mbeten të redaktueshme. + The document changed while you were editing field properties. Dokumenti ndryshoi ndërsa po redaktonit vetitë e fushës. + The document is no longer open. Dokumenti nuk është më i hapur. + The field properties could not be changed. Vetitë e fushës nuk mund të ndryshoheshin. + The field properties dialog is no longer open. Dialogu i vetive të fushës nuk është më i hapur. + The field {name} no longer exists. Fusha {name} nuk ekziston më. + The printer driver's own settings for this print: paper tray, paper type, finishing and more. Cilësimet e vetë drajverit të printerit për këtë printim: tabaka e letrës, lloji i letrës, përfundimi e më shumë. + The selected fields could not be found. Select them again. Fushat e zgjedhura nuk u gjetën. Zgjidhni ato përsëri. + The PDF text fonts can't draw “{c}” ({code}). Choose supported text. Fontet e tekstit PDF nuk mund të vizatojnë “{c}” ({code}). Zgjidhni tekst të mbështetur. + This printer offers no settings of its own. Ky printer nuk ofron cilësime të veta. + To change locked fields, also set Locked to No. Për të ndryshuar fushat e kyçura, vendosni edhe Kyçur në Jo. + Today: {date} Sot: {date} + Zoom in ({key}) Zmadho ({key}) + Zoom in / out (also pinch or {key}-scroll) Zmadho / zvogëlo (edhe me pinch ose {key}-rrotullim) + Zoom out ({key}) Zvogëlo ({key}) + the text recognition models are not installed (reinstall PdfCraft, or set PDFCRAFT_MODELS to the folder that holds them) modelet e njohjes së tekstit nuk janë të instaluara (instaloni përsëri PdfCraft, ose vendosni PDFCRAFT_MODELS te dosja që i përmban) + yyyy or yy year · m or mm month · mmm or mmmm month name · d or dd day · ddd or dddd weekday. H, h, M, s and t are time letters and can't be used on their own: put {escape} before a letter to show it as is. yyyy ose yy vit · m ose mm muaj · mmm ose mmmm emri i muajit · d ose dd ditë · ddd ose dddd ditë e javës. H, h, M, s dhe t janë shkronja ore dhe nuk mund të përdoren vetëm: vendosni {escape} para një shkronje për ta shfaqur siç është. + {chars} can't be written into the PDF yet: Fill & Sign text is Western European only. Pick a numeric format such as dd.mm.yyyy. {chars} nuk mund të shkruhet ende në PDF: teksti i Fill & Sign është vetëm evropianoperëndimor. Zgjidhni një format numerik si dd.mm.yyyy. + {name} is too large for a word list (at most 1 MB). {name} është shumë i madh për një listë fjalësh (më së shumti 1 MB). + {n} fields selected {n} fusha të zgjedhura + {n} word(s) or phrase(s) {n} fjalë ose frazë + Auto ({percent}%) Auto ({percent}%) + Auto follows the system's text size. Pages always render at the display's full resolution. Auto ndjek madhësinë e tekstit të sistemit. Faqet vizatohen gjithmonë në rezolucionin e plotë të ekranit. + Check the pages Kontrollo faqet + Collapse all Palos të gjitha + Column select Zgjedhje kolone + Drag the selection to move it. Esc clears the selection. Zvarrit zgjedhjen për ta lëvizur. Esc e pastron zgjedhjen. + Expand all Zgjero të gjitha + Files are combined in the order shown. Drag them to change it. Skedarët kombinohen sipas rendit të treguar. Zvarritini për ta ndryshuar. + Fill colour Ngjyra e mbushjes + Fill colour: none Ngjyra e mbushjes: asnjë + Finish or discard the text being edited before selecting several objects. Përfundoni ose hidhni tekstin që po redaktohet para se të zgjidhni disa objekte. + Grid view Pamja me rrjetë + Interface size Madhësia e ndërfaqes + List view Pamja me listë + Move object Lëviz objektin + Move objects Lëviz objektet + No fill Pa mbushje + Pages: {k} of {n} Faqet: {k} nga {n} + Preview unavailable: {e} Pamja paraprake nuk është e disponueshme: {e} + Remove page Hiq faqen + Remove {n} pages Hiq {n} faqe + Saved {place}: {before} → {after} (not smaller){detail} U ruajt {place}: {before} → {after} (jo më i vogël){detail} + Select at most 1000 objects at a time. Zgjidhni më së shumti 1000 objekte njëherësh. + Shift-click to select several objects. Drag empty space to select an area. Shift-klikoni për të zgjedhur disa objekte. Zvarrisni mbi hapësirë të zbrazët për të zgjedhur një zonë. + Some bookmarks are not shown here: the panel lists a limited number, nested a limited depth. Disa libërshënues nuk shfaqen këtu: paneli liston një numër të kufizuar, të ndërthurur në një thellësi të kufizuar. + Switch to List view to change the pages it takes. Kaloni te pamja me listë për të ndryshuar faqet që merr. + Text used as a clipping path cannot be moved with this selection. Teksti i përdorur si shteg prerjeje nuk mund të lëvizet me këtë zgjedhje. + These objects could not be moved. Select them again and try a smaller move. Këto objekte nuk mund të lëviznin. Zgjidhni ato përsëri dhe provoni një lëvizje më të vogël. + This file is already as small as it can be made ({size}). No copy was saved. Ky skedar është tashmë sa më i vogël që mund të bëhet ({size}). Nuk u ruajt asnjë kopje. + This page contains objects that cannot be selected together. Kjo faqe përmban objekte që nuk mund të zgjidhen së bashku. + Vertical text cannot be moved with this selection. Teksti vertikal nuk mund të lëvizet me këtë zgjedhje. +key Ctrl Ctrl +key Delete Fshi +key End End +key Esc Esc +key Home Home +key Shift Shift +key Space Hapësirë +@plural {n} object selected|{n} objects selected {n} objekt i zgjedhur|{n} objekte të zgjedhura + Looking for printers… Po kërkohen printerë… + Sending to {printer}… Po dërgohet te {printer}… + Float panel Shkëput panelin + Inspector Inspektori + Move to group Zhvendos te grupi + Panels Panelet + Reset panel layout Rivendos strukturën e paneleve + Resize panel window Ndrysho madhësinë e dritares së panelit + Resize panels Ndrysho madhësinë e paneleve + Tools Veglat + Appearance mode Mënyra e pamjes + Light E çelët + Dark E errët + Active Aktive + Dark theme Tema e errët + Appearance settings… Cilësimet e pamjes… + Save ({key}) Ruaj ({key}) + Select page {label} Zgjidh faqen {label} + Rotate page {label} counterclockwise Rrotullo faqen {label} në drejtim kundërorar + Rotate page {label} clockwise Rrotullo faqen {label} në drejtim orar + Delete page {label} Fshi faqen {label} + Offset from centre Zhvendosja nga qendra + Graphic Grafik + Signer's name Emri i nënshkruesit + Fill & Sign signature Nënshkrimi Fill & Sign + Choose image… Zgjidh imazhin… + Enter permissions password… Vendos fjalëkalimin e lejeve… + Permissions password Fjalëkalimi i lejeve + “{name}” has security restrictions. Enter its permissions password to lift them. “{name}” ka kufizime sigurie. Vendosni fjalëkalimin e lejeve për t'i hequr. + Restrictions lifted Kufizimet u hoqën + Couldn't unlock {name}: {e} Nuk u zhbllokua {name}: {e} + This document has no restrictions to lift Ky dokument nuk ka kufizime për t'u hequr + The document's security settings don't allow copying text and images Cilësimet e sigurisë së dokumentit nuk lejojnë kopjimin e tekstit dhe imazheve + Add the files to combine Shtoni skedarët për t'u kombinuar + Leave out files that can't be read? Të lihen jashtë skedarët që nuk lexohen? + These files can't be read, so they won't be in the combined PDF: Këta skedarë nuk lexohen, ndaj nuk do të jenë në PDF-në e kombinuar: + Combine the rest Kombino pjesën tjetër + and {n} more dhe {n} të tjerë + Drop PDFs, images, text files or folders here, or choose them. Hidhni këtu PDF, imazhe, skedarë teksti ose dosje, ose zgjidhini. + Every PDF, image and text file in the folder Çdo skedar PDF, imazh dhe teksti në dosje + Every PDF, image and text file in the folder and the folders inside it Çdo skedar PDF, imazh dhe teksti në dosje dhe në dosjet brenda saj + No PDFs, images or text files found in {folder} Nuk u gjetën PDF, imazhe ose skedarë teksti në {folder} + Added the first {n} files in {folder} U shtuan {n} skedarët e parë në {folder} + Margins Margjinat + For page sizes and margins. Për madhësitë e faqeve dhe margjinat. + PDF page: {size} Faqja PDF: {size} + Match page at 100% Përputh faqen në 100% + PDF scale: {scale}% Shkalla e PDF: {scale}% + Printer paper and scaling may differ. Check driver settings. Letra dhe shkallëzimi i printerit mund të ndryshojnë. Kontrolloni cilësimet e drajverit. + Drawing scale changes. Use Actual size for full-scale plans. Shkalla e vizatimit ndryshon. Përdorni Madhësinë aktuale për planet në shkallë të plotë. + Reload documents when their files change on disk Ringarko dokumentet kur skedarët e tyre ndryshojnë në disk + This file changed on disk. Reload it to see the new version; your unsaved changes will be lost. Ky skedar ndryshoi në disk. Ringarkojeni për të parë versionin e ri; ndryshimet tuaja të paruajtura do të humbasin. + Reload Ringarko + Couldn't reload {name}: {e} Nuk u ringarkua {name}: {e} + Mouse wheel scroll speed Shpejtësia e lëvizjes me rrotëzën e miut +scroll speed Slow Ngadalë +scroll speed Normal Normale +scroll speed Fast Shpejt + Animation effects Efektet e animacionit +animation effects On Aktiv +animation effects Off Joaktiv + Enhance camera image Përmirëso imazhin e kamerës + Drag the corners onto the document's edges, then choose Enhance page. Zvarrisni qoshet te skajet e dokumentit, pastaj zgjidhni Përmirëso faqen. + Enhance page Përmirëso faqen + Done adding text Përfundoi shtimi i tekstit + Discard this text (Esc) Hidhe këtë tekst (Esc) + Clean-up Pastrimi + Original Origjinali + Greyscale Nuanca gri + Black and white Bardhë e zi + Reading colours Ngjyrat e leximit + Replace document colours Zëvendëso ngjyrat e dokumentit + Black on white E zezë mbi të bardhë + White on black E bardhë mbi të zezë + Yellow on black E verdhë mbi të zezë + Green on black E gjelbër mbi të zezë + Page background Sfondi i faqes + Only change the colour of black text or line art Ndrysho vetëm ngjyrën e tekstit të zi ose të vijave + Change the colour of line art as well as text Ndrysho ngjyrën e vijave si dhe të tekstit + Colours are remapped while rendering; the document itself never changes. Ngjyrat ripërcaktohen gjatë vizatimit; vetë dokumenti nuk ndryshon kurrë. + This printer's driver doesn't take two-sided settings from other programs, so its own setting applies. Change it in Properties… Drajveri i këtij printeri nuk i merr cilësimet dyanshe nga programet e tjera, ndaj zbatohet cilësimi i tij. Ndryshojeni te Vetitë… + This field's font can't draw “{c}” ({code}), so PdfCraft shows ? in its place. The value is saved, and other PDF viewers redraw the field from it. Fonti i kësaj fushe nuk mund të vizatojë “{c}” ({code}), ndaj PdfCraft shfaq ? në vend të tij. Vlera ruhet dhe shfaqësit e tjerë PDF e vizatojnë fushën nga ajo. + The fonts PdfCraft writes with can't draw “{c}” ({code}), so it shows as ? in every PDF viewer. The text is saved. Fontet me të cilat shkruan PdfCraft nuk mund të vizatojnë “{c}” ({code}), ndaj shfaqet si ? në çdo shfaqës PDF. Teksti ruhet. + Browser's print dialog Dialogu i printimit të shfletuesit + Copies, two-sided printing and colour are chosen in the browser's print dialog. Kopjet, printimi dyanësh dhe ngjyra zgjidhen në dialogun e printimit të shfletuesit. + Preparing {n} sheets for printing… Po përgatiten {n} fletë për printim… + Preparing sheet {done} of {total} for printing… Po përgatitet fleta {done} nga {total} për printim… + Opening the browser's print dialog… Po hapet dialogu i printimit të shfletuesit… + Couldn't print from the browser ({e}); downloaded {name} to print instead Nuk u printua nga shfletuesi ({e}); u shkarkua {name} për ta printuar + Tools panel side Ana e panelit të veglave + Add comment Shto koment + Change tag properties Ndrysho vetitë e etiketës + Tags panel Paneli i etiketave + Tags Etiketat + Tag type Lloji i etiketës + Actual text Teksti aktual + Find a tag Gjej një etiketë + Collapse tag Palos etiketën + Expand tag Zgjero etiketën + Revert changes Ktheji ndryshimet + Save tag properties Ruaj vetitë e etiketës + This document has no editable structure tags. Ky dokument nuk ka etiketa strukture të redaktueshme. + {n} tags {n} etiketa + Save or revert changes before selecting another tag. Ruani ose ktheni ndryshimet para se të zgjidhni një etiketë tjetër. + Left out: {names} Lënë jashtë: {names} + already a PDF tashmë një PDF + no unused output name nuk ka emër të papërdorur dalës + no output folder was chosen nuk u zgjodh dosje dalëse +@plural Downloaded {n} PDF|Downloaded {n} PDFs U shkarkua {n} PDF|U shkarkuan {n} PDF +@plural {n} field name collides with earlier files and will be renamed: {list}|{n} field names collide with earlier files and will be renamed: {list} {n} emër fushe përplaset me skedarët e mëparshëm dhe do të riemërtohet: {list}|{n} emra fushash përplasen me skedarët e mëparshëm dhe do të riemërtohen: {list} + Scan Skano + Sign a sheet of white paper and take a photo of it in bright, even light (use the flash). Choose the photo or drop it here: PdfCraft finds the signature and removes the paper. Nënshkruani një fletë letre të bardhë dhe bëni një foto në dritë të fortë e të njëtrajtshme (përdorni blicin). Zgjidhni foton ose hidheni këtu: PdfCraft gjen nënshkrimin dhe heq letrën. + Choose photo… Zgjidh foton… + No photo chosen Nuk u zgjodh foto + Photo Foto + Ink sensitivity Ndjeshmëria e bojës + No signature was found in the frame. Move the frame over the signature or raise the ink sensitivity. Nuk u gjet nënshkrim në kornizë. Lëvizeni kornizën mbi nënshkrim ose rritni ndjeshmërinë e bojës. + Couldn't use the photo: {e} Nuk u përdor dot fotoja: {e} + Close Tab Mbyll skedën + Reopen Closed Tab Rihap skedën e mbyllur + Reveal in Finder Shfaq në Finder + Reveal in File Explorer Shfaq në File Explorer + Other colour… Ngjyrë tjetër… + Recent colours Ngjyrat e fundit + Couldn't follow linked PDF: {reason} Nuk u ndoq dot PDF-ja e lidhur: {reason} + The linked PDF opened, but its named destination was not applied. PDF-ja e lidhur u hap, por destinacioni i saj i emërtuar nuk u zbatua. + The linked PDF opened, but its page destination was out of range. PDF-ja e lidhur u hap, por destinacioni i faqes ishte jashtë kufijve. + Local cross-PDF links require the desktop app Lidhjet e brendshme midis PDF-ve lokale kërkojnë aplikacionin desktop + Next tab Skeda tjetër + Minimize Minimizo + Maximize Maksimizo + Restore Rikthe + Use system title bar Përdor shiritin e titullit të sistemit + Show a basic title bar for the window buttons instead of the tab strip. GNOME doesn't draw title bars for apps, so this one doesn't follow its theme. Shfaq një shirit bazë titulli për butonat e dritares në vend të shiritit të skedave. GNOME nuk vizaton shirita titulli për aplikacionet, prandaj ky nuk e ndjek temën e tij. + Allow Lejo + Only allow this if you trust the source document. Lejoje vetëm nëse i beson dokumentit burimor. + Open this local PDF? Të hapet ky PDF lokal? + This document is trying to open a local file: Ky dokument po përpiqet të hapë një skedar lokal: + Move tag earlier Zhvendose etiketën më herët + Move tag later Zhvendose etiketën më vonë + Remove "{name}" from this list? The file itself is not deleted. Të hiqet «{name}» nga kjo listë? Vetë skedari nuk fshihet. + Previous tab Skeda e mëparshme diff --git a/crates/ui-egui/tests/fonts.rs b/crates/ui-egui/tests/fonts.rs index 63a31d4cf..3251377ba 100644 --- a/crates/ui-egui/tests/fonts.rs +++ b/crates/ui-egui/tests/fonts.rs @@ -264,7 +264,7 @@ fn ui_fonts_work_without_craft_fonts() { theme::install_fonts(&ctx); } -/// Latin- and Cyrillic-script catalogs (Czech, Brazilian Portuguese, German, Spanish, French, Russian, Bulgarian, Hungarian, Ukrainian, Italian, Slovene) are drawn entirely by the app's own faces +/// Latin- and Cyrillic-script catalogs (Czech, Brazilian Portuguese, German, Spanish, French, Russian, Bulgarian, Hungarian, Ukrainian, Italian, Slovene, Albanian) are drawn entirely by the app's own faces /// (Inter, JetBrains Mono): no letter falls through to egui's defaults or a CJK fallback. (egui's /// `has_glyphs` can't answer this: with only the primary face it is also the replacement face.) #[test] @@ -287,6 +287,7 @@ fn primary_ui_fonts_cover_latin_and_cyrillic_catalogs() { ("tr", include_str!("../src/i18n/tr.tsv")), ("sl", include_str!("../src/i18n/sl.tsv")), ("lt", include_str!("../src/i18n/lt.tsv")), + ("sq", include_str!("../src/i18n/sq.tsv")), ] { let mut text = String::from("áčďéěíňóřšťúůýžÁČĎÉĚÍŇÓŘŠŤÚŮÝŽãõçâêôàÃÕÇÂÊÔÀñÑüÜäÄöÖőűß„“¿¡«»…ґҐєЄіІїЇәғқңөұүһӘҒҚҢӨҰҮҺ"); for line in catalog.lines().filter(|l| !l.starts_with('#')) { diff --git a/docs/localization-parity.md b/docs/localization-parity.md index ccd5f88b9..ccfd19e78 100644 --- a/docs/localization-parity.md +++ b/docs/localization-parity.md @@ -66,8 +66,9 @@ none has translated help. | Greek | `el` | 2,341 entries | partial | no | | Turkish | `tr` | 2,313 entries | partial | yes | | Lithuanian | `lt` | 2,578 entries | partial; community native-speaker review ([#1401](https://github.com/storytold/pdfcraft/pull/1401)) | no | +| Albanian | `sq` | 2,344 entries | partial; not yet reviewed by a native speaker | no | -**14 other languages** ship (21 catalogs plus English, 22 interface languages in Preferences). +**15 other languages** ship (22 catalogs plus English, 23 interface languages in Preferences). The entry counts without percentages were measured on 2026-10-12; they are not percentages of the older 2,143-key snapshot above. Their presence does not imply a detailed linguistic or runtime review. Acrobat languages PdfCraft lacks: Danish, Dutch, Finnish, Norwegian, Swedish, Hebrew. @@ -75,5 +76,6 @@ Acrobat languages PdfCraft lacks: Danish, Dutch, Finnish, Norwegian, Swedish, He | Date | Change | Summary | |---|---|---| +| 2026-10-12 | minor | Added Albanian (`sq`): catalog, date names, Preferences entry | | 2026-10-12 | minor | Added current counts for Kazakh, Polish, Slovenian, Greek, Turkish and Lithuanian; retained existing language assessments and the original percentage snapshot | | 2026-10-10 | major | Created. Catalog counts measured from `crates/ui-egui/src/i18n/*.tsv` against the 2,143-key union; Acrobat's localizations from its bundle's `.lproj` and Sequences folder names | diff --git a/docs/localization.md b/docs/localization.md index 05240cafb..b45b2cbb3 100644 --- a/docs/localization.md +++ b/docs/localization.md @@ -1,10 +1,10 @@ # Interface language -Choose **Menu > Edit > Preferences…** (Command-comma on macOS, Ctrl-comma elsewhere) **> Interface language** and select **Auto**, **English**, **日本語**, **简体中文**, **繁體中文**, **Čeština**, **Português (Brasil)**, **Deutsch**, **Español**, **Français**, **Русский**, **Қазақша**, **Български**, **తెలుగు**, **Magyar**, **Українська**, **Italiano**, **العربية**, **Polski**, **Slovenščina**, **Ελληνικά**, **Türkçe** or **Lietuvių**. The change applies immediately and persists between launches. Command ids, document contents and file names are unchanged. +Choose **Menu > Edit > Preferences…** (Command-comma on macOS, Ctrl-comma elsewhere) **> Interface language** and select **Auto**, **English**, **日本語**, **简体中文**, **繁體中文**, **Čeština**, **Português (Brasil)**, **Deutsch**, **Español**, **Français**, **Русский**, **Қазақша**, **Български**, **తెలుగు**, **Magyar**, **Українська**, **Italiano**, **العربية**, **Polski**, **Slovenščina**, **Ελληνικά**, **Türkçe**, **Lietuvių** or **Shqip**. The change applies immediately and persists between launches. Command ids, document contents and file names are unchanged. Displayed keyboard shortcuts use the same active interface language. For example, German shows `Strg+K` and `Strg+Umschalt+S` in the toolbar, menus, command palette, tooltips and Keyboard shortcuts dialog; macOS keeps its modifier symbols (`⌘`, `⇧`, `⌃`). Key names have their own `key` catalog context, so the Delete key can read `Entf` while the command remains `Löschen`. A missing key-name entry falls back to the English key name. Actual bindings and machine-facing command ids remain stable. -**Auto** (the default) follows the system language: `LC_ALL`, `LC_MESSAGES` or `LANG`, then the preferred-languages list on macOS. Any Portuguese locale (`pt_BR`, `pt_PT`) uses the Brazilian catalog, any French locale (`fr`, `fr_FR`, `fr_CA`, `fr_BE`) the French one, any German locale (`de`, `de_DE`, `de_AT`, `de_CH`) the German one, and Chinese locales for Taiwan, Hong Kong and Macau (`zh_TW`, `zh_HK`, `zh_MO`, `zh-Hant`) the Traditional Chinese one; other Chinese locales (`zh`, `zh_CN`, `zh_SG`, `zh-Hans`) the Simplified Chinese one. Telugu locales (`te`, `te_IN`) use the Telugu catalog, Bulgarian locales (`bg`, `bg_BG`) the Bulgarian one, and Hungarian locales (`hu`, `hu_HU`) the Hungarian one, and Ukrainian locales (`uk`, `uk_UA`) the Ukrainian one, and Italian locales (`it`, `it_IT`, `it_CH`) the Italian one, and Arabic locales (`ar`, `ar_MA`, `ar_EG`, `ar_SA`, …) the Arabic one, and Turkish locales (`tr`, `tr_TR`) the Turkish one, and Slovenian locales (`sl`, `sl_SI`) the Slovenian one. A system language without a catalog shows English. On Windows, **Auto** uses the Windows display languages, in preference order, when no supported locale is selected by those environment variables. Neutral `C`/`POSIX` locale values (including `C.UTF-8`) inherited from a launcher do not override the Windows display language; explicitly named supported locales such as `fr_FR.UTF-8` still do. The query asks Windows directly (`GetUserPreferredUILanguages`, through the `sys-locale` crate) without starting a process, and is cached for the process. If detection fails or the display language has no catalog, PdfCraft shows English. +**Auto** (the default) follows the system language: `LC_ALL`, `LC_MESSAGES` or `LANG`, then the preferred-languages list on macOS. Any Portuguese locale (`pt_BR`, `pt_PT`) uses the Brazilian catalog, any French locale (`fr`, `fr_FR`, `fr_CA`, `fr_BE`) the French one, any German locale (`de`, `de_DE`, `de_AT`, `de_CH`) the German one, and Chinese locales for Taiwan, Hong Kong and Macau (`zh_TW`, `zh_HK`, `zh_MO`, `zh-Hant`) the Traditional Chinese one; other Chinese locales (`zh`, `zh_CN`, `zh_SG`, `zh-Hans`) the Simplified Chinese one. Telugu locales (`te`, `te_IN`) use the Telugu catalog, Bulgarian locales (`bg`, `bg_BG`) the Bulgarian one, and Hungarian locales (`hu`, `hu_HU`) the Hungarian one, and Ukrainian locales (`uk`, `uk_UA`) the Ukrainian one, and Italian locales (`it`, `it_IT`, `it_CH`) the Italian one, and Arabic locales (`ar`, `ar_MA`, `ar_EG`, `ar_SA`, …) the Arabic one, and Turkish locales (`tr`, `tr_TR`) the Turkish one, and Slovenian locales (`sl`, `sl_SI`) the Slovenian one, and Albanian locales (`sq`, `sq_AL`, `sq_XK`, …) the Albanian one. A system language without a catalog shows English. On Windows, **Auto** uses the Windows display languages, in preference order, when no supported locale is selected by those environment variables. Neutral `C`/`POSIX` locale values (including `C.UTF-8`) inherited from a launcher do not override the Windows display language; explicitly named supported locales such as `fr_FR.UTF-8` still do. The query asks Windows directly (`GetUserPreferredUILanguages`, through the `sys-locale` crate) without starting a process, and is cached for the process. If detection fails or the display language has no catalog, PdfCraft shows English. The control channel exposes the setting through `ui.set`: @@ -12,10 +12,10 @@ The control channel exposes the setting through `ui.set`: {"method":"ui.set","params":{"key":"language","value":"ja"}} ``` -The value is `auto` or a language code (`en`, `ja`, `zh-hans`, `zh-hant`, `cs`, `pt-br`, `de`, `es`, `fr`, `ru`, `kk`, `bg`, `te`, `hu`, `uk`, `it`, `ar`, `pl`, `sl`, `el`, `tr`, `lt`), in any case. `ui.state` reports `language` as written in the preferences (`auto`, `en`, `ja`, `zh-hans`, `zh-hant`, `cs`, `pt-br`, `de`, `es`, `fr`, `ru`, `kk`, `bg`, `te`, `hu`, `uk`, `it`, `ar`, `pl`, `sl`, `el`, `tr` or `lt`). Unknown values return an error without changing the current setting. Preferences saved before this setting existed follow the system language. +The value is `auto` or a language code (`en`, `ja`, `zh-hans`, `zh-hant`, `cs`, `pt-br`, `de`, `es`, `fr`, `ru`, `kk`, `bg`, `te`, `hu`, `uk`, `it`, `ar`, `pl`, `sl`, `el`, `tr`, `lt`, `sq`), in any case. `ui.state` reports `language` as written in the preferences (`auto`, `en`, `ja`, `zh-hans`, `zh-hant`, `cs`, `pt-br`, `de`, `es`, `fr`, `ru`, `kk`, `bg`, `te`, `hu`, `uk`, `it`, `ar`, `pl`, `sl`, `el`, `tr`, `lt` or `sq`). Unknown values return an error without changing the current setting. Preferences saved before this setting existed follow the system language. -Dialogs, panels, menus, notices and history labels go through the catalog (`tl!`). Japanese, Traditional Chinese, Simplified Chinese, Russian, Bulgarian, German, Spanish, French, Telugu, Hungarian, Ukrainian, Italian, Brazilian Portuguese and Arabic translate them (about 2,000–2,140 entries each); Czech and Turkish cover the menus so far. Untranslated labels use English. Error details that come from the engine or the operating system are shown as they are, inside a translated frame ("操作「…」に失敗しました: …"). The command palette matches the translated label, the English label and the command id. Vertical Japanese PDF rendering is an existing viewer feature; this change does not add vertical text editing. Per-language coverage, script support and what each language still needs are in [localization-parity.md](localization-parity.md). -Dialogs, panels, menus, notices and history labels go through the catalog (`tl!`). Japanese, Traditional Chinese, Simplified Chinese, Russian, Bulgarian, German, Spanish, French, Telugu, Hungarian, Ukrainian, Italian, Brazilian Portuguese, Arabic and Slovenian translate them (about 2,000–2,190 entries each); Czech covers the menus so far. Untranslated labels use English. Error details that come from the engine or the operating system are shown as they are, inside a translated frame ("操作「…」に失敗しました: …"). The command palette matches the translated label, the English label and the command id. Vertical Japanese PDF rendering is an existing viewer feature; this change does not add vertical text editing. Per-language coverage, script support and what each language still needs are in [localization-parity.md](localization-parity.md). +Dialogs, panels, menus, notices and history labels go through the catalog (`tl!`). Japanese, Traditional Chinese, Simplified Chinese, Russian, Bulgarian, German, Spanish, French, Telugu, Hungarian, Ukrainian, Italian, Brazilian Portuguese, Arabic and Albanian translate them (about 2,000–2,140 entries each); Czech and Turkish cover the menus so far. Untranslated labels use English. Error details that come from the engine or the operating system are shown as they are, inside a translated frame ("操作「…」に失敗しました: …"). The command palette matches the translated label, the English label and the command id. Vertical Japanese PDF rendering is an existing viewer feature; this change does not add vertical text editing. Per-language coverage, script support and what each language still needs are in [localization-parity.md](localization-parity.md). +Dialogs, panels, menus, notices and history labels go through the catalog (`tl!`). Japanese, Traditional Chinese, Simplified Chinese, Russian, Bulgarian, German, Spanish, French, Telugu, Hungarian, Ukrainian, Italian, Brazilian Portuguese, Arabic, Slovenian and Albanian translate them (about 2,000–2,190 entries each); Czech covers the menus so far. Untranslated labels use English. Error details that come from the engine or the operating system are shown as they are, inside a translated frame ("操作「…」に失敗しました: …"). The command palette matches the translated label, the English label and the command id. Vertical Japanese PDF rendering is an existing viewer feature; this change does not add vertical text editing. Per-language coverage, script support and what each language still needs are in [localization-parity.md](localization-parity.md). Whole sentences that the layers below word — what the accessibility checker found, what the PDF/A verifier reports, what a signature's details say, what is wrong with the pages to print, what an edit is called in the history — are translated too, because those layers hand the sentence over apart from the document's own words. See [Sentences the engine words](#sentences-the-engine-words). @@ -25,12 +25,14 @@ The Lithuanian catalog has 2,578 entries and three integer plural forms. Calenda Edit text reads Hebrew lines in typing order and writes them back in drawing order (`crates/edit/src/bidi.rs`); letters the page's own font lacks are drawn with the craft-fonts `Hebr` face (Noto Sans Hebrew) as Type 3 glyphs, and a build without one says so. Hebrew points (niqqud) can't be written yet. The craft-fonts revision pinned for CI and releases has no `Hebr` face yet, so until one is added releases report that error instead of drawing the missing letters. -Japanese interface text uses BIZ UDPGothic from [craft-fonts](https://github.com/storytold/craft-fonts), an optional build input that every release includes (`CRAFT_FONTS_DIR`; see the README). A build made without it has no Japanese face, so Japanese labels show replacement boxes. Chinese is drawn with the same craft-fonts CJK faces (in Simplified Chinese the `Hans` faces come first, so a line never mixes faces with different baselines), so a character none of them has shows a replacement box (and every Chinese character does in a build without craft-fonts). Russian, Bulgarian, Czech, Brazilian Portuguese, German, Spanish, French, Hungarian, Italian, Turkish and Lithuanian need only the bundled Latin faces (tested in `tests/fonts.rs`). Hungarian uses the same one/other plural rule as English: 1 is singular, and every other count — including 0 — is the other form. After a numeral the noun stays singular (`1 oldal`, `2 oldal`). Telugu is drawn with a craft-fonts `Telu` face (Noto Sans Telugu, kept in the web build too), whose conjuncts egui shapes; a build without one shows Telugu labels as replacement boxes, and the release-pinned craft-fonts input has no Telugu face yet. -Japanese interface text uses BIZ UDPGothic from [craft-fonts](https://github.com/storytold/craft-fonts), an optional build input that every release includes (`CRAFT_FONTS_DIR`; see the README). A build made without it has no Japanese face, so Japanese labels show replacement boxes. Chinese is drawn with the same craft-fonts CJK faces (in Simplified Chinese the `Hans` faces come first, so a line never mixes faces with different baselines), so a character none of them has shows a replacement box (and every Chinese character does in a build without craft-fonts). Russian, Bulgarian, Czech, Brazilian Portuguese, German, Spanish, French, Hungarian, Italian and Slovenian need only the bundled Latin faces (tested in `tests/fonts.rs`). Slovenian has four plural forms: one (1, 101, 201…), two (2, 102…), few (3, 4, 103…) and other (everything else, including 0, 5–20 and 21+), so `@plural` entries list four forms (`1 stran`, `2 strani`, `3 strani`, `5 strani`). Hungarian uses the same one/other plural rule as English: 1 is singular, and every other count — including 0 — is the other form. After a numeral the noun stays singular (`1 oldal`, `2 oldal`). Telugu is drawn with a craft-fonts `Telu` face (Noto Sans Telugu, kept in the web build too), whose conjuncts egui shapes; a build without one shows Telugu labels as replacement boxes, and the release-pinned craft-fonts input has no Telugu face yet. -Japanese interface text uses BIZ UDPGothic from [craft-fonts](https://github.com/storytold/craft-fonts), an optional build input that every release includes (`CRAFT_FONTS_DIR`; see the README). A build made without it has no Japanese face, so Japanese labels show replacement boxes. Chinese is drawn with the same craft-fonts CJK faces (in Simplified Chinese the `Hans` faces come first, so a line never mixes faces with different baselines), so a character none of them has shows a replacement box (and every Chinese character does in a build without craft-fonts). Until craft-fonts has an allowed `Hans` face, the desktop app draws a Chinese interface with a Chinese face already installed on the machine (Microsoft YaHei or JhengHei on Windows, PingFang, Hiragino Sans GB or STHeiti on macOS, WenQuanYi or Droid Sans Fallback on Linux; never Noto CJK or Source Han), placed before the Japanese faces so a line keeps one face (#826). The web build has no installed fonts to fall back on. Russian, Bulgarian, Czech, Brazilian Portuguese, German, Spanish, French, Hungarian and Italian need only the bundled Latin faces (tested in `tests/fonts.rs`). Hungarian uses the same one/other plural rule as English: 1 is singular, and every other count — including 0 — is the other form. After a numeral the noun stays singular (`1 oldal`, `2 oldal`). Telugu is drawn with a craft-fonts `Telu` face (Noto Sans Telugu, kept in the web build too), whose conjuncts egui shapes; a build without one shows Telugu labels as replacement boxes, and the release-pinned craft-fonts input has no Telugu face yet. +Japanese interface text uses BIZ UDPGothic from [craft-fonts](https://github.com/storytold/craft-fonts), an optional build input that every release includes (`CRAFT_FONTS_DIR`; see the README). A build made without it has no Japanese face, so Japanese labels show replacement boxes. Chinese is drawn with the same craft-fonts CJK faces (in Simplified Chinese the `Hans` faces come first, so a line never mixes faces with different baselines), so a character none of them has shows a replacement box (and every Chinese character does in a build without craft-fonts). Russian, Bulgarian, Czech, Brazilian Portuguese, German, Spanish, French, Hungarian, Italian, Turkish, Lithuanian and Albanian need only the bundled Latin faces (tested in `tests/fonts.rs`). Hungarian uses the same one/other plural rule as English: 1 is singular, and every other count — including 0 — is the other form. After a numeral the noun stays singular (`1 oldal`, `2 oldal`). Telugu is drawn with a craft-fonts `Telu` face (Noto Sans Telugu, kept in the web build too), whose conjuncts egui shapes; a build without one shows Telugu labels as replacement boxes, and the release-pinned craft-fonts input has no Telugu face yet. +Japanese interface text uses BIZ UDPGothic from [craft-fonts](https://github.com/storytold/craft-fonts), an optional build input that every release includes (`CRAFT_FONTS_DIR`; see the README). A build made without it has no Japanese face, so Japanese labels show replacement boxes. Chinese is drawn with the same craft-fonts CJK faces (in Simplified Chinese the `Hans` faces come first, so a line never mixes faces with different baselines), so a character none of them has shows a replacement box (and every Chinese character does in a build without craft-fonts). Russian, Bulgarian, Czech, Brazilian Portuguese, German, Spanish, French, Hungarian, Italian, Slovenian and Albanian need only the bundled Latin faces (tested in `tests/fonts.rs`). Slovenian has four plural forms: one (1, 101, 201…), two (2, 102…), few (3, 4, 103…) and other (everything else, including 0, 5–20 and 21+), so `@plural` entries list four forms (`1 stran`, `2 strani`, `3 strani`, `5 strani`). Hungarian uses the same one/other plural rule as English: 1 is singular, and every other count — including 0 — is the other form. After a numeral the noun stays singular (`1 oldal`, `2 oldal`). Telugu is drawn with a craft-fonts `Telu` face (Noto Sans Telugu, kept in the web build too), whose conjuncts egui shapes; a build without one shows Telugu labels as replacement boxes, and the release-pinned craft-fonts input has no Telugu face yet. +Japanese interface text uses BIZ UDPGothic from [craft-fonts](https://github.com/storytold/craft-fonts), an optional build input that every release includes (`CRAFT_FONTS_DIR`; see the README). A build made without it has no Japanese face, so Japanese labels show replacement boxes. Chinese is drawn with the same craft-fonts CJK faces (in Simplified Chinese the `Hans` faces come first, so a line never mixes faces with different baselines), so a character none of them has shows a replacement box (and every Chinese character does in a build without craft-fonts). Until craft-fonts has an allowed `Hans` face, the desktop app draws a Chinese interface with a Chinese face already installed on the machine (Microsoft YaHei or JhengHei on Windows, PingFang, Hiragino Sans GB or STHeiti on macOS, WenQuanYi or Droid Sans Fallback on Linux; never Noto CJK or Source Han), placed before the Japanese faces so a line keeps one face (#826). The web build has no installed fonts to fall back on. Russian, Bulgarian, Czech, Brazilian Portuguese, German, Spanish, French, Hungarian, Italian and Albanian need only the bundled Latin faces (tested in `tests/fonts.rs`). Hungarian uses the same one/other plural rule as English: 1 is singular, and every other count — including 0 — is the other form. After a numeral the noun stays singular (`1 oldal`, `2 oldal`). Telugu is drawn with a craft-fonts `Telu` face (Noto Sans Telugu, kept in the web build too), whose conjuncts egui shapes; a build without one shows Telugu labels as replacement boxes, and the release-pinned craft-fonts input has no Telugu face yet. The Brazilian Portuguese catalog has 2,000 entries: the ~1,826-entry gist André Cardoso posted in [#288](https://github.com/storytold/pdfcraft/issues/288), the labels added since, and a review of the existing wording. Portuguese, like French, treats 0 and 1 as singular (`1 página`, `2 páginas`). +The Albanian catalog (`sq.tsv`, interface name **Shqip**) is written in Standard Albanian with the imperative for commands (`Ruaj`, `Hap`, `Fshi`). Albanian uses two plural forms like English: 1 is singular and every other count, including 0, is plural (`1 faqe`, `2 faqe`). Month and weekday names are lowercase (`mars`, `e shtunë`), and the letters `ë` and `ç` are covered by the bundled Latin faces. It has not been reviewed by a native Albanian speaker yet. + ## Arabic and right-to-left text The Arabic catalog has 2,137 entries in Modern Standard Arabic with Western digits. Counts use the six [CLDR Arabic forms](https://www.unicode.org/cldr/charts/48/supplemental/language_plural_rules.html#ar) (`0`, `1`, `2`, `3–10`, `11–99`, the rest), and dates use the Arabic names of the Gregorian months. From 9d31cf9f99fa0f4a9819bc22caac42dc769bef7d Mon Sep 17 00:00:00 2001 From: arpan-star Date: Wed, 14 Oct 2026 20:28:02 +0530 Subject: [PATCH 020/498] fix(docs): correct spelling of "Formatting" in comments --- vendor/lopdf/examples/merge.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vendor/lopdf/examples/merge.rs b/vendor/lopdf/examples/merge.rs index 151440c84..0fee85b51 100644 --- a/vendor/lopdf/examples/merge.rs +++ b/vendor/lopdf/examples/merge.rs @@ -92,7 +92,7 @@ fn main() { )); // Can set bookmark formatting and color per report bookmark added. - // Formating is 1 for italic 2 for bold 3 for bold and italic + // Formatting is 1 for italic 2 for bold 3 for bold and italic // Color is RGB 0.0..255.0 for (layer, mut doc) in documents { let color = [0.0, 0.0, 0.0]; From a1acf5283c999c34c5a6d8861ee1f6df3887a344 Mon Sep 17 00:00:00 2001 From: srt8hellcat2-ui <225485253+srt8hellcat2-ui@users.noreply.github.com> Date: Wed, 14 Oct 2026 14:58:41 +0000 Subject: [PATCH 021/498] Print: remember selected paper size across restarts (#2156) --- ROADMAP.md | 3 + crates/print/README.md | 6 ++ crates/ui-egui/src/lib.rs | 16 ++++- crates/ui-egui/tests/print.rs | 131 +++++++++++++++++++++++++++++++++- docs/roadmap.md | 3 +- parity/acrobat-features.toml | 4 +- 6 files changed, 156 insertions(+), 7 deletions(-) diff --git a/ROADMAP.md b/ROADMAP.md index b4ab4ea8a..72ce62f9c 100644 --- a/ROADMAP.md +++ b/ROADMAP.md @@ -2,6 +2,7 @@ **Stage: alpha** · next: beta, ~26% (ready for real work 49% → 75%) and ~400–700 h away +> **Last reviewed:** 2026-10-14 · **Last updated:** 2026-10-14 · **Change:** minor (M10 #2156 candidate: remember selected print paper by canonical name; estimates unchanged) > **Last reviewed:** 2026-10-13 · **Last updated:** 2026-10-13 · **Change:** minor (M3 candidate: native opens retain chosen tools through password retries and defer startup intake while preparation is pending; estimates unchanged) · **Target:** Adobe Acrobat Pro (Acrobat DC, continuous track 26.002.21931, macOS) > **Last reviewed:** 2026-10-12 · **Last updated:** 2026-10-12 · **Change:** minor (M13: CLI check visits each directory once through aliases and cycles; estimates unchanged) · **Target:** Adobe Acrobat Pro (Acrobat DC, continuous track 26.002.21931, macOS) > **Last reviewed:** 2026-10-12 · **Last updated:** 2026-10-12 · **Change:** minor (M4: Extract and Split preserve shared Type 3 glyph resources; estimates unchanged) · **Target:** Adobe Acrobat Pro (Acrobat DC, continuous track 26.002.21931, macOS) @@ -149,6 +150,8 @@ Ranked; detail and the full milestone table in [docs/roadmap.md](docs/roadmap.md ## Progress log +- **2026-10-14 (M10 #2156 candidate):** Print paper selection survives Cancel and settings restoration; canonical names avoid preset-index dependence. Other print preferences and estimates unchanged. + - **2026-10-13 (M3, native-opening candidate):** Chosen tools survive preparation, conversion and password retries; startup intake waits for pending preparation. Regression tests cover completion, cancellation and document identity. Estimates unchanged. - **2026-10-12 (M10, Windows printing without PowerShell, #1107):** craft-print now prints on Windows in-process: printers from EnumPrinters/GetDefaultPrinter, jobs drawn as vectors by Windows.Data.Pdf into the XPS print API with a driver-validated PrintTicket (exact paper, orientation, no scaling), so printing works where App Control for Business or AppLocker run PowerShell in Constrained Language Mode. Portrait and landscape sheets still print as one job (turned with /Rotate); a sheet size the driver lacks is refused rather than shrunk. Pins craft-libs f03ec27 (craft-libs#28); deny.toml allows the storytold/winprint.rs fork and adds a webpki-root-certs licence exception and a RUSTSEC-2024-0370 ignore for winprint's build-dependencies. An earlier craft-print revision was checked in Windows Sandbox under enforced WDAC: printers listed, CLI and desktop jobs spooled, and no powershell.exe in the 4688 audit. The final pinned revision passed craft-libs Windows CI, including a real paused-queue job; that Sandbox run has not been repeated. Estimates unchanged. - **2026-10-12 (M13, CLI robustness scans):** `pdfcraft-cli check` visits a directory once even when input roots overlap or directory symlinks lead back into the tree. PDFs reached through file symlinks remain accepted. Three real CLI regressions cover overlapping roots, a directory cycle and directory/file aliases. Estimates unchanged. diff --git a/crates/print/README.md b/crates/print/README.md index 6a489977d..d938e81c9 100644 --- a/crates/print/README.md +++ b/crates/print/README.md @@ -32,6 +32,12 @@ Each source page becomes a Form XObject (its content wrapped in q/Q, plus the pr annotations); sheets place them with a clip. The result is a fresh, unencrypted, garbage-collected file (callers check the print permission). +The GUI Print dialog remembers its last selected paper size across application sessions, +including when Print is cancelled. The preference stores a canonical name such as `A4`; +unrecognized saved values retain the current selection (US Letter on a fresh app). +This change does not alter persistence of other print preferences. +Headless `doc_print` defaults are unchanged. + `spool` delegates discovery, driver options, preferences and submission to [`craft-print`](https://github.com/storytold/craft-libs/tree/main/crates/print). PdfCraft retains page selection, imposition, annotations and print-permission checks. diff --git a/crates/ui-egui/src/lib.rs b/crates/ui-egui/src/lib.rs index f800ad6a0..7e67b9cc7 100644 --- a/crates/ui-egui/src/lib.rs +++ b/crates/ui-egui/src/lib.rs @@ -2096,7 +2096,7 @@ impl PdfCraftApp { /// Serialize the user's persistent state (recent files, theme). Local only. pub fn persist(&self) -> String { let trusted: Vec = self.session.trusted_certificates().iter().map(pdfcraft_engine::sign::x509::to_pem).collect(); - serde_json::json!({ + let mut settings = serde_json::json!({ "docking": self.docking, "docking_left_open": self.left_open, "docking_right": self.right, @@ -2155,8 +2155,11 @@ impl PdfCraftApp { "combine_zoom": self.combine_zoom, "comments_panel_closed": self.comments_panel_closed, "right_panel_closed": self.right_panel_closed, - }) - .to_string() + }); + // Add separately to avoid growing the large settings macro. The literal above is an object. + // Canonical names survive changes to the order of PAPERS and do not depend on UI language. + settings["print_paper"] = serde_json::json!(pdfcraft_engine::print::PAPERS.get(self.print_draft.paper).map(|(name, _)| *name)); + settings.to_string() } /// Restore state written by `persist`. Unknown or malformed data is ignored. @@ -2213,6 +2216,13 @@ impl PdfCraftApp { if let Ok(units) = serde_json::from_value::(v["units"].clone()) { self.units = units; } + if let Some(paper) = v + .get("print_paper") + .and_then(serde_json::Value::as_str) + .and_then(|name| pdfcraft_engine::print::PAPERS.iter().position(|(canonical, _)| *canonical == name)) + { + self.print_draft.paper = paper; + } if let Some(on) = v["highlight_fields"].as_bool() { self.view_defaults.highlight_fields = on; } diff --git a/crates/ui-egui/tests/print.rs b/crates/ui-egui/tests/print.rs index 739c04ee9..0999023bf 100644 --- a/crates/ui-egui/tests/print.rs +++ b/crates/ui-egui/tests/print.rs @@ -5,9 +5,16 @@ use egui_kittest::kittest::{NodeT, Queryable}; use pdfcraft_ui_egui::{Dialog, PdfCraftApp}; fn harness() -> Harness<'static, PdfCraftApp> { - let mut h = Harness::builder().with_size(egui::vec2(1400.0, 900.0)).build_eframe(|_cc| { + harness_with_settings(None) +} + +fn harness_with_settings(settings: Option) -> Harness<'static, PdfCraftApp> { + let mut h = Harness::builder().with_size(egui::vec2(1400.0, 900.0)).build_eframe(move |_cc| { let mut app = PdfCraftApp::new(); app.set_option("language", "en").unwrap(); + if let Some(json) = &settings { + app.restore(json); + } app.open_bytes("form.pdf", None, include_bytes!("data/form.pdf").to_vec()).unwrap(); app }); @@ -373,3 +380,125 @@ fn a_printer_without_two_sided_printing_points_to_its_properties() { h.run_steps(2); h.get_by_label_contains(note); } + +#[test] +fn paper_choice_survives_cancel_and_settings_restore() { + use pdfcraft_engine::print::{Orientation, PAPERS}; + let a4 = PAPERS.iter().position(|(name, _)| *name == "A4").unwrap(); + let letter = PAPERS.iter().position(|(name, _)| *name == "US Letter").unwrap(); + let mut h = harness(); + assert!(h.state_mut().execute("print.dialog")); + h.run_steps(3); + h.get_by_value("US Letter").click(); + h.run_steps(2); + h.get_by_label("A4").click(); + h.run_steps(2); + assert_eq!(h.state().print_draft.paper, a4); + // Only paper should be added to persistence; these choices still belong to this session. + let draft = &mut h.state_mut().print_draft; + draft.copies = 5; + draft.which = pdfcraft_ui_egui::PrintWhich::Range; + draft.range = "1".into(); + draft.orientation = Orientation::Landscape; + draft.grayscale = true; + let before_cancel = draft.clone(); + h.get_by_label("Cancel").click(); + h.run_steps(2); + assert_eq!(h.state().dialog, None); + assert_eq!(h.state().print_draft, before_cancel, "cancel keeps the existing draft behavior"); + let saved = h.state().persist(); + let json: serde_json::Value = serde_json::from_str(&saved).unwrap(); + assert_eq!(json["print_paper"], "A4", "store the canonical name, not its position"); + let mut app = PdfCraftApp::new(); + app.restore(&saved); + let expected = pdfcraft_ui_egui::PrintDraft { paper: a4, ..Default::default() }; + assert_eq!(app.print_draft, expected, "no other print preference becomes persistent"); + let mut restarted = harness_with_settings(Some(saved)); + assert!(restarted.state_mut().execute("print.dialog")); + restarted.run_steps(3); + restarted.get_by_value("A4"); + assert_eq!(restarted.state().print_draft.paper, a4); + restarted.get_by_value("A4").click(); + restarted.run_steps(2); + restarted.get_by_label("US Letter").click(); + restarted.run_steps(2); + restarted.get_by_label("Cancel").click(); + restarted.run_steps(2); + let saved = restarted.state().persist(); + assert_eq!(serde_json::from_str::(&saved).unwrap()["print_paper"], "US Letter"); + let mut again = harness_with_settings(Some(saved)); + assert!(again.state_mut().execute("print.dialog")); + again.run_steps(3); + again.get_by_value("US Letter"); + assert_eq!(again.state().print_draft.paper, letter); +} + +#[test] +fn paper_restore_accepts_canonical_names_and_ignores_invalid_settings() { + use pdfcraft_engine::print::PAPERS; + for (index, (name, _)) in PAPERS.iter().enumerate() { + let mut app = PdfCraftApp::new(); + app.restore(&serde_json::json!({"print_paper": name}).to_string()); + assert_eq!(app.print_draft.paper, index); + assert_eq!(serde_json::from_str::(&app.persist()).unwrap()["print_paper"], *name); + } + for invalid in [ + "not JSON", + "{}", + r#"{"print_paper":null}"#, + r#"{"print_paper":true}"#, + r#"{"print_paper":[]}"#, + r#"{"print_paper":{}}"#, + r#"{"print_paper":"unknown"}"#, + r#"{"print_paper":"a4"}"#, + r#"{"print_paper":4}"#, + r#"{"print_paper":-1}"#, + r#"{"print_paper":4294967296}"#, + r#"{"print_paper":18446744073709551615}"#, + r#"{"print_paper":1e100}"#, + ] { + let mut app = PdfCraftApp::new(); + let factory = app.print_draft.paper; + app.restore(invalid); + assert_eq!(app.print_draft.paper, factory, "{invalid}"); + app.restore(r#"{"print_paper":"A4"}"#); + let selected = app.print_draft.paper; + app.restore(invalid); + assert_eq!(app.print_draft.paper, selected, "invalid input must not replace a valid choice: {invalid}"); + } + let mut app = PdfCraftApp::new(); + app.print_draft.paper = usize::MAX; + assert_eq!(serde_json::from_str::(&app.persist()).unwrap()["print_paper"], serde_json::Value::Null); +} + +#[test] +fn restored_paper_keeps_preview_and_saved_sheet_dimensions() { + use pdfcraft_engine::print::{self, PAPERS}; + let a4 = PAPERS.iter().find(|(name, _)| *name == "A4").unwrap().1; + let mut h = harness_with_settings(Some(r#"{"print_paper":"A4"}"#.into())); + assert!(h.state_mut().execute("print.dialog")); + h.run_steps(3); + h.get_by_value("A4"); + h.get_by_label("Sheet 1 of 1"); + let id = h.state().views[h.state().active.unwrap()].id; + let doc = h.state().session.get(id).unwrap(); + let sizes: Vec<_> = doc.info.pages.iter().map(|p| (f64::from(p.width), f64::from(p.height))).collect(); + let labels: Vec<_> = doc.info.pages.iter().map(|p| p.label.clone()).collect(); + let settings = h.state().print_draft.settings(sizes.len(), &labels).unwrap(); + assert_eq!(settings.paper, a4); + let sheets = print::layout(&sizes, &settings).unwrap(); + assert_eq!(sheets.len(), 1); + assert_eq!(sheets[0].size, a4, "preview uses the restored paper"); + let out = std::env::temp_dir().join(format!("pdfcraft-restored-paper-{}.pdf", std::process::id())); + h.state_mut().print_draft.printer = None; + h.state_mut().save_override = Some(out.to_string_lossy().into_owned()); + h.get_by_label("Save as PDF").click(); + h.run_steps(3); + assert_eq!(h.state().dialog, None); + let printed = pdfcraft_cos::Document::open(std::sync::Arc::new(std::fs::read(&out).unwrap())).unwrap(); + let pages = pdfcraft_model::pages(&printed); + assert_eq!(pages.len(), sheets.len()); + let size = pages[0].display_size(&printed); + assert!((size.0 - a4.0).abs() < 0.01 && (size.1 - a4.1).abs() < 0.01, "saved sheet: {size:?}"); + std::fs::remove_file(out).unwrap(); +} diff --git a/docs/roadmap.md b/docs/roadmap.md index fabb5e603..ec21c9c23 100644 --- a/docs/roadmap.md +++ b/docs/roadmap.md @@ -1,5 +1,6 @@ # PdfCraft roadmap: milestones and what's next +> **Last reviewed:** 2026-10-14 · **Last updated:** 2026-10-14 · **Change:** minor (M10 #2156 candidate: remember selected print paper by canonical name; estimates unchanged) > **Last reviewed:** 2026-10-13 · **Last updated:** 2026-10-13 · **Change:** minor (M3 candidate: native opens retain chosen tools through password retries and defer startup intake while preparation is pending; estimates unchanged) · **Target:** Adobe Acrobat Pro (Acrobat DC, continuous track 26.002.21931, macOS) > **Last reviewed:** 2026-10-12 · **Last updated:** 2026-10-12 · **Change:** minor (M13: CLI check visits each directory once through aliases and cycles; estimates unchanged) · **Target:** Adobe Acrobat Pro (Acrobat DC, continuous track 26.002.21931, macOS) > **Last reviewed:** 2026-10-12 · **Last updated:** 2026-10-12 · **Change:** minor (M4: Extract and Split preserve shared Type 3 glyph resources; estimates unchanged) · **Target:** Adobe Acrobat Pro (Acrobat DC, continuous track 26.002.21931, macOS) @@ -110,7 +111,7 @@ total matches the parity estimate. | M8 | Security + redaction | 100–180 | 68% | 15–30 | Done: opening protected documents, permissions, Protect Using Password, Remove security; redaction (mark text/areas/pages, Search & Redact with patterns, apply removing glyphs, image pixels, vectors, XObject content, annotations and fields, verification, full rewrite on save); Remove hidden information and Sanitize.
Done since: redaction codes (U.S. FOIA and Privacy Act sets as overlay text, in Redaction properties and `redact_mark`). Redaction cleans indirect and form structure references, preserving surviving form tags. Vertical-writing text is still refused, and the error no longer claims the text was under the mark (#1340). Missing: certificate security, custom redaction code sets and pattern locales, DCT re-encoding | | M8 | Security + redaction | 100–180 | 68% | 15–30 | Done: opening protected documents, permissions, Protect Using Password, Remove security; redaction (mark text/areas/pages, Search & Redact with patterns, apply removing glyphs, image pixels, vectors, XObject content, annotations and fields, verification, full rewrite on save); Remove hidden information and Sanitize.
Done since: redaction codes (U.S. FOIA and Privacy Act sets as overlay text, in Redaction properties and `redact_mark`). Redaction cleans indirect and form structure references, preserving surviving form tags. Redaction retires inherited resource dictionaries, so a parent `/Pages` can't keep a removed XObject reachable; unredacted pages are left untouched. Missing: certificate security, custom redaction code sets and pattern locales, DCT re-encoding | | M9 | Signatures (PAdES, validation) | 160–280 | 60% | 40–70 | Done: new `sign` crate (DER, X.509, CMS, PKCS #12 on RustCrypto; aws-lc-rs for RSA private keys); PAdES B-B signing (visible, invisible, existing fields, certification with DocMDP); validation with trust store and changes-after-signing classification; self-signed digital IDs; Signatures panel, message bar, sign dialogs; agent tools. Checked with pdfsig and OpenSSL.
Done since: macOS Keychain and Windows Current User Personal store signing (software-backed CNG keys), certificate viewer, signed documents protected from rewrites. Missing: timestamps (B-T), LTV (DSS, OCSP, CRL), FieldMDP, smart cards, PKCS #11 | -| M10 | OCR, create, export, print | 200–350 | 33% | 120–215 | Done: create from blank/text/PNG/JPEG/TIFF (multi-page)/GIF/BMP; export PNG/JPEG/TIFF and text; Print (Acrobat's sizing, n-up, booklet, poster, comments & forms, preview, the CUPS and Windows spoolers, print-ready PDF).
Done since: embedded/72/custom DPI choices for image imports; export all images; OCR (searchable image for pages, ranges and multiple files); single-sided cut-and-stack imposition with cut marks, through Print and doc_print; architectural/ANSI/large ISO sheet presets, Match page at 100% and PDF-scale preview (#599 follow-up); Create PDF from multiple files (PDFs, images and text, edited as pages in the grid); OCR can also read pictures on pages that have text, without adding that text twice (#1028). Done since: Word invoice export uses borderless inferred tables, floating positioned text/artwork only where text overlaps an image or is rotated, and per-page sizes, covered by synthetic invoice automation regressions (#773); printing on the web through the browser's print dialog, sheets drawn by PdfCraft (gap 4). Missing: OCR languages beyond Latin, editable-text OCR output, full Office layout fidelity/import | +| M10 | OCR, create, export, print | 200–350 | 33% | 120–215 | Done: create from blank/text/PNG/JPEG/TIFF (multi-page)/GIF/BMP; export PNG/JPEG/TIFF and text; Print (Acrobat's sizing, n-up, booklet, poster, comments & forms, preview, the CUPS and Windows spoolers, print-ready PDF).
Done since: embedded/72/custom DPI choices for image imports; export all images; OCR (searchable image for pages, ranges and multiple files); single-sided cut-and-stack imposition with cut marks, through Print and doc_print; architectural/ANSI/large ISO sheet presets, Match page at 100% and PDF-scale preview (#599 follow-up); Create PDF from multiple files (PDFs, images and text, edited as pages in the grid); OCR can also read pictures on pages that have text, without adding that text twice (#1028). Done since: Word invoice export uses borderless inferred tables, floating positioned text/artwork only where text overlaps an image or is rotated, and per-page sizes, covered by synthetic invoice automation regressions (#773); printing on the web through the browser's print dialog, sheets drawn by PdfCraft (gap 4). Missing: OCR languages beyond Latin, editable-text OCR output, full Office layout fidelity/import #2156 candidate: last selected print paper persists across sessions; other print preferences unchanged. | | M11 | Optimize, preflight, PDF/A/X/UA, print production | 200–350 | 18% | 80–140 | Done: new `optimize` crate: Reduce File Size and the PDF Optimizer (images measured where drawn, bicubic downsampling, JPEG/ZIP recompression only when smaller, discard objects and user data, Flate clean-up, resource merging, object streams). Missing: fonts and transparency panels, space audit, preflight, PDF/A/X/UA | | M12 | Accessibility, compare, measure, search, XFA | 200–380 | 30% | 90–160 | Done: new `a11y` crate with the Accessibility Checker (all 32 rules, report, Fix/Skip/Explain, options dialog and results panel, agent tools). Locatable figure, annotation and form findings highlight their page bounds.
Done since: 2D distance, perimeter and area measurements with persistent viewport calibration, snapping, live information and CSV export; a bounded, text-only auto-tag proposal tool for one page. Missing: writing proposed tags and parent tree, field autotag, visual Tags/Order/Content panels, Reading Order tool, compare, geospatial/3D measurement, search index, XFA | | M13 | Automation (MCP, Action Wizard, CLI) + AI providers | 60–120 | 45% | 25–45 | Done: MCP resources (document info, text, page images); headless tool table (123 tools incl. signing, optimizing, initial view, links, stamps, data exchange, comment review, forms authoring and scripts, redaction, sanitize, print, add content), opt-in MCP server over stdio, CLI `run`/`tools` (closed stdout pipes exit cleanly), UI control channel with drag. Missing: Action Wizard, AI providers
Done since: CLI run and MCP reject missing, empty, repeated and option-valued --root arguments before any tool/script execution or MCP initialization. A single-hyphen directory name remains valid; synthetic CLI regressions preserve a would-be overwritten file. `text_find` also caps the per-page match ranges it materializes at the remaining result limit plus one continuation match. CLI robustness scans visit each directory once through overlapping roots and symlink aliases. | diff --git a/parity/acrobat-features.toml b/parity/acrobat-features.toml index 359a71e9a..77015d26e 100644 --- a/parity/acrobat-features.toml +++ b/parity/acrobat-features.toml @@ -7912,8 +7912,8 @@ milestone = "M10" status = "shipped" commands = ["print.dialog"] tools = ["doc_print", "printers"] -evidence = ["crates/ui-egui/tests/print.rs::print_dialog_lays_out_sheets_and_saves_a_pdf", "crates/engine/src/tests.rs::printing_lays_out_sheets_that_render", "crates/ui-egui/src/web_print.rs::a_job_draws_every_sheet_at_its_planned_resolution_then_builds_the_page", "crates/ui-egui/src/web_print.rs::the_print_page_turns_sideways_sheets_names_other_sizes_and_ends_without_a_blank_page"] -notes = "⌘P; settings and live sheet preview; on the web the same dialog prints through the browser's print dialog" +evidence = ["crates/ui-egui/tests/print.rs::paper_choice_survives_cancel_and_settings_restore", "crates/ui-egui/tests/print.rs::restored_paper_keeps_preview_and_saved_sheet_dimensions", "crates/ui-egui/tests/print.rs::print_dialog_lays_out_sheets_and_saves_a_pdf", "crates/engine/src/tests.rs::printing_lays_out_sheets_that_render", "crates/ui-egui/src/web_print.rs::a_job_draws_every_sheet_at_its_planned_resolution_then_builds_the_page", "crates/ui-egui/src/web_print.rs::the_print_page_turns_sideways_sheets_names_other_sizes_and_ends_without_a_blank_page"] +notes = "⌘P; settings and live sheet preview; on the web the same dialog prints through the browser's print dialog; last paper selection, including cancelled Print dialogs, persists by canonical name; this change does not alter persistence of other print preferences" [[feature]] id = "print.printer-selection" From 3a1c02933eb38ed97cfd0abe7d32b5629961d42e Mon Sep 17 00:00:00 2001 From: sanches Date: Wed, 14 Oct 2026 19:37:29 +0300 Subject: [PATCH 022/498] ko: unify redaction-mark, flatten, Verify and Collapse terminology MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Applies the rest of the native-speaker review on #1976 on top of the merged redaction redesign (fork PR 1): redaction marks read 제거 대상 표시 in all ten entries (not 수정 표시), every Flatten label uses 평탄화 (not 병합, which reads as merging documents, or 평면화), Verify is 검증 so it no longer collides with OK (확인), and Collapse is 접기 so it no longer collides with Zoom out (축소). ATTRIBUTION.toml hash updated. --- ATTRIBUTION.toml | 2 +- crates/ui-egui/src/i18n/ko.tsv | 30 +++++++++++++++--------------- 2 files changed, 16 insertions(+), 16 deletions(-) diff --git a/ATTRIBUTION.toml b/ATTRIBUTION.toml index ded830833..58d05857b 100644 --- a/ATTRIBUTION.toml +++ b/ATTRIBUTION.toml @@ -272,7 +272,7 @@ licence = "MIT OR Apache-2.0" licence_file = "LICENSE-MIT" kind = "translation" usage = "Korean UI strings, compiled in by crates/ui-egui/src/i18n/mod.rs" -sha256 = "b570144be1a0296fa4a95648611709641420efbff44de7845344c1cbe2c37004" +sha256 = "c59ead567704ee3840c7da88fa06edf3b7315c6609eb2038384001c7ad0c1054" [[asset]] path = "assets/icons/accessibility.svg" diff --git a/crates/ui-egui/src/i18n/ko.tsv b/crates/ui-egui/src/i18n/ko.tsv index dec60f1d9..ac9210122 100644 --- a/crates/ui-egui/src/i18n/ko.tsv +++ b/crates/ui-egui/src/i18n/ko.tsv @@ -182,7 +182,7 @@ Replace text 텍스트 바꾸기 Attach a file 파일 첨부 Erase drawings 그림 지우기 - Flatten comments 주석 병합 + Flatten comments 주석 평탄화 Import comments… 주석 가져오기… Add a stamp 스탬프 추가 Export all comments to data file… 모든 주석을 데이터 파일로 내보내기… @@ -763,7 +763,7 @@ No problems found: the document conforms to {level}. 발견된 문제가 없습니다. 문서가 {level}을(를) 준수합니다. (page {p}) (페이지 {p}) · not fixable here · 여기서는 수정할 수 없음 - Verify 확인 + Verify 검증 Box 박스 Units 단위 Set to zero 0으로 설정 @@ -918,7 +918,7 @@ Set document title 문서 제목 설정 Run a JavaScript JavaScript 실행 Prepare for Distribution 배포 준비 - Remove hidden information and flatten comments and form fields, so recipients see only the pages. 숨겨진 정보를 제거하고 주석과 양식 필드를 병합하여 받는 사람이 페이지만 보도록 합니다. + Remove hidden information and flatten comments and form fields, so recipients see only the pages. 숨겨진 정보를 제거하고 주석과 양식 필드를 평탄화하여 받는 사람이 페이지만 보도록 합니다. Optimize Scanned Documents 스캔한 문서 최적화 Make scans searchable, then make them smaller. 스캔본을 검색 가능하게 만든 다음 크기를 줄입니다. Add Page Numbers 페이지 번호 추가 @@ -986,7 +986,7 @@ Check again 다시 검사 Report 보고서 Show the accessibility report 접근성 보고서 표시 - Collapse 축소 + Collapse 접기 Expand 확장 {rule} - {status} {rule} - {status} Passed 통과 @@ -1140,9 +1140,9 @@ Links, actions and JavaScripts 링크, 동작, JavaScript Private data of other applications 다른 응용 프로그램의 개인 데이터 None found 발견된 항목 없음 - Form fields are flattened: their values stay visible. Saving rewrites the whole file. 양식 필드가 병합되어 값은 계속 표시됩니다. 저장하면 파일 전체가 다시 쓰여집니다. + Form fields are flattened: their values stay visible. Saving rewrites the whole file. 양식 필드가 평탄화되어 값은 계속 표시됩니다. 저장하면 파일 전체가 다시 쓰여집니다. Remove 제거 - Sanitizing removes hidden information from the document: metadata, file attachments, comments, form fields (flattened), hidden text and layers, bookmarks, links, actions and scripts, and private application data. 정리는 문서에서 숨겨진 정보를 제거합니다: 메타데이터, 파일 첨부, 주석, 양식 필드(병합됨), 숨겨진 텍스트와 레이어, 책갈피, 링크, 동작과 스크립트, 응용 프로그램 개인 데이터 등입니다. + Sanitizing removes hidden information from the document: metadata, file attachments, comments, form fields (flattened), hidden text and layers, bookmarks, links, actions and scripts, and private application data. 정리는 문서에서 숨겨진 정보를 제거합니다: 메타데이터, 파일 첨부, 주석, 양식 필드(평탄화됨), 숨겨진 텍스트와 레이어, 책갈피, 링크, 동작과 스크립트, 응용 프로그램 개인 데이터 등입니다. Save the document afterwards; saving rewrites the whole file so nothing removed stays in it. 그 후 문서를 저장하세요. 저장하면 파일 전체가 다시 쓰여져 제거된 항목이 남지 않습니다. Printer: 프린터: Save as PDF PDF로 저장 @@ -1203,8 +1203,8 @@ Removed 1 hidden item. Save to remove them from the file. 숨겨진 항목 1개를 제거했습니다. 파일에서 완전히 제거하려면 저장하세요. Removed {n} hidden items. Save to remove them from the file. 숨겨진 항목 {n}개를 제거했습니다. 파일에서 완전히 제거하려면 저장하세요. Document sanitized. Save to finish: saving rewrites the whole file. 문서가 정리되었습니다. 완료하려면 저장하세요: 저장하면 파일 전체가 다시 작성됩니다. - Applied 1 redaction mark. Save to remove the content from the file. 수정 표시 1개가 적용되었습니다. 파일에서 콘텐츠를 제거하려면 저장하세요. - Applied {n} redaction marks. Save to remove the content from the file. 수정 표시 {n}개가 적용되었습니다. 파일에서 콘텐츠를 제거하려면 저장하세요. + Applied 1 redaction mark. Save to remove the content from the file. 제거 대상 표시 1개가 적용되었습니다. 파일에서 콘텐츠를 제거하려면 저장하세요. + Applied {n} redaction marks. Save to remove the content from the file. 제거 대상 표시 {n}개가 적용되었습니다. 파일에서 콘텐츠를 제거하려면 저장하세요. JavaScript Console JavaScript 콘솔 JavaScript is turned off (Preferences ▸ JavaScript). JavaScript가 꺼져 있습니다(기본 설정 ▸ JavaScript). Output appears here. 출력이 여기에 표시됩니다. @@ -1706,9 +1706,9 @@ Nothing to undo 취소할 작업이 없습니다 Nothing to redo 다시 실행할 작업이 없습니다 This document has no form fields you can fill in 이 문서에는 채울 수 있는 양식 필드가 없습니다 - This document has no comments to flatten 이 문서에는 평면화할 주석이 없습니다 - This document has no form fields to flatten 이 문서에는 평면화할 양식 필드가 없습니다 - There are no redaction marks (mark text, areas or pages first) 수정 표시가 없습니다(먼저 텍스트, 영역 또는 페이지를 표시하세요) + This document has no comments to flatten 이 문서에는 평탄화할 주석이 없습니다 + This document has no form fields to flatten 이 문서에는 평탄화할 양식 필드가 없습니다 + There are no redaction marks (mark text, areas or pages first) 제거 대상 표시가 없습니다(먼저 텍스트, 영역 또는 페이지를 표시하세요) This document has no {kind} to change 이 문서에는 변경할 {kind}이(가) 없습니다 header or footer 머리글 또는 바닥글 watermark 워터마크 @@ -1726,7 +1726,7 @@ Security will be removed when you save 저장할 때 보안이 제거됩니다 Click text or an image to edit it 텍스트나 이미지를 클릭하여 편집하세요 Drag a rectangle to create a link; double-click a link to edit it 드래그하여 사각형을 그려 링크를 만들고, 링크를 두 번 클릭하여 편집하세요 - There are no redaction marks to apply 적용할 수정 표시가 없습니다 + There are no redaction marks to apply 적용할 제거 대상 표시가 없습니다 Drag to draw the area where the signature should appear. 서명이 표시될 영역을 드래그하여 그리세요. Couldn't fit the visible content: {e} 보이는 콘텐츠를 맞출 수 없습니다: {e} Drag a rectangle around the area to copy 복사할 영역 주위에 사각형을 드래그하세요 @@ -1910,7 +1910,7 @@ Change link properties 링크 속성 변경 Delete link 링크 삭제 Create link 링크 만들기 - Flatten 병합 + Flatten 평탄화 Add sticky note 스티커 메모 추가 Add highlight 형광펜 추가 Add underline 밑줄 추가 @@ -2165,7 +2165,7 @@ calendar date December 12월 Larger pages 더 큰 페이지 Smaller pages 더 작은 페이지 Reset page size 페이지 크기 재설정 - Flatten Fill & Sign when saving 저장 시 입력 내용과 서명을 페이지에 고정 + Flatten Fill & Sign when saving 저장 시 채우기 및 서명 평탄화 Text, marks and signatures become part of the page. Other comments stay editable. 텍스트, 표시 및 서명이 페이지의 일부가 됩니다. 다른 주석은 계속 편집할 수 있습니다. Date format 날짜 형식 Fill & Sign dates 채우기 및 서명 날짜 @@ -2407,7 +2407,7 @@ animation effects Off 끄기 Every PDF in the folder and the folders inside it 폴더와 그 안의 폴더에 있는 모든 PDF Field "{}" on page {p} has no description (tooltip) {p}페이지의 필드 "{}"에 설명(도구 설명)이 없습니다 Filename 파일 이름 - Flatten Fill & Sign 채우기 및 서명 병합 + Flatten Fill & Sign 채우기 및 서명 평탄화 Font (unnamed) on page {p} doesn't map its characters to Unicode {p}페이지의 글꼴(이름 없음)이 문자를 유니코드에 매핑하지 않습니다 Font {} on page {p} doesn't map its characters to Unicode {p}페이지의 글꼴 {}이(가) 문자를 유니코드에 매핑하지 않습니다 Form field on page {p} isn't tagged {p}페이지의 양식 필드에 태그가 없습니다 From 580ef9f94c505d7966b995c8cd6f6bb9dcc24aec Mon Sep 17 00:00:00 2001 From: sanches Date: Wed, 14 Oct 2026 19:37:53 +0300 Subject: [PATCH 023/498] docs: drop the Korean review notes from the tree The terminology rationale lives in the review discussion (fork PR 1 on pechnikov2026-star/pdfcraft and the #1976 thread); docs/ holds the project's reference documents, not contribution-process notes. --- docs/korean-localization-review.md | 69 ------------------------------ 1 file changed, 69 deletions(-) delete mode 100644 docs/korean-localization-review.md diff --git a/docs/korean-localization-review.md b/docs/korean-localization-review.md deleted file mode 100644 index 249152951..000000000 --- a/docs/korean-localization-review.md +++ /dev/null @@ -1,69 +0,0 @@ -# Korean UI terminology review — draft follow-up to #1976 - -This is a code-grounded review draft, NOT evidence of completed native-speaker or runtime QA. Only -Korean UI labels change; English lookup keys, stable command IDs, PDF contents and automation -protocols remain unchanged. - -## Redaction has three separate operations - -The initial Korean catalog used the word "검열" (censorship) for all redaction actions. -The project source has three distinct stages: - -| Stage | Relevant code | Korean meaning | -| --- | --- | --- | -| Mark | crates/ui-egui/src/redact_ui.rs (RedactPrefs::mark), crates/engine/src/commands.rs (redact.mark/pages/search) | Mark a future removal area; content is not yet permanently removed | -| Apply | crates/ui-egui/src/commands.rs (redact.apply), crates/ui-egui/src/redact_ui.rs (confirmation), crates/redact/src/lib.rs (apply) | Confirm and remove covered content permanently | -| Clear | crates/ui-egui/src/commands.rs (redact.clear -> Edit::ClearRedactions) | Clear pending marks WITHOUT deleting the underlying content | - -Terminology chosen from these behaviors: - -- Tool (Redact): 민감 정보 제거 -- Mark for redaction: 제거할 영역 표시 -- Apply redactions: 표시된 정보 영구 제거 -- Clear redaction marks: 제거 대상 표시 지우기 -- Redaction code: 제거 사유 코드 (reason/exemption code sets: crates/redact/src/codes.rs) - -"Clear all" is a generic English lookup key used in other contexts and intentionally -is NOT changed to "clear redaction marks" globally. - -## Additional terminology improvements - -| English | Previous | Proposed | Source | -| --- | --- | --- | --- | -| Sanitize document… | 문서 정리… | 문서에서 숨겨진 정보 제거… | crates/redact/src/sanitize.rs | -| Flatten form fields | 양식 필드 병합 | 양식 필드 평탄화 | crates/ui-egui/src/optimize_ui.rs | -| Flatten Fill & Sign when saving | 저장할 때 채우기 및 서명 병합 | 저장 시 입력 내용과 서명을 페이지에 고정 | crates/ui-egui/src/editing.rs | -| Add printer marks | 프린터 표시 추가 | 인쇄용 표시 추가 | printer marks are printed on pages, not on devices | - -This review does not change acceptable variations such as 확인란/체크박스 or -Bates/베이츠 simply for stylistic reasons. Certificate and digital-signature -language requires separate code-context review. - -## Verification and remaining gates - -- Tested: catalog key coverage, TSV structural rules, placeholder preservation, - ellipsis preservation, old-vs-new textual regression assertions. -- Added a Rust regression test for the distinct redaction stage labels. This test - had failing baseline strings before the terminology changes. -- NOT YET EXECUTED: cargo fmt, Rust unit tests, real Windows UI, font glyph coverage, - PDF save/reopen, OCR, permanent-redaction behavior on a synthetic PDF. - These gates are necessary before calling the translation production-ready. - -## UI acceptance test matrix (synthetic data only) - -1. With an English UI, open a sample PDF called 한글_검수.pdf containing Hangul bookmark - and comment text. Verify that tab, bookmark, search and dialogs render Hangul rather - than replacement boxes, regardless of interface language. -2. Select 한국어 under Preferences and check persistence; separately test Auto on ko-KR. -3. Draw a redaction mark on TEST-REDACT-UNIQUE. Before Apply, the UI must say - "marked" rather than implying permanent removal. Clear must remove only marks. -4. On a separate synthetic document, Apply redactions, save and reopen; inspect - extracted text and rendered output for the removed token (source-byte/fidelity - checks belong in the engine suite as well). -5. Flatten an AcroForm field and reopen: the visible value should remain on the - page without the interactive field being editable as before. -6. Test 100/125/150% Windows display scaling for Korean text overflow and truncation. -7. Test web build font delivery separately once Hangul font PR #1484 lands. - -The translations were written from intended source-code behavior. Do not copy other -products' localization files, proprietary Adobe assets, fonts or real users' PDFs. From c73eb76e920ac052bb51310aeb6145e8ef6395d9 Mon Sep 17 00:00:00 2001 From: Earl Co Date: Wed, 14 Oct 2026 23:03:26 +0200 Subject: [PATCH 024/498] fix(forms): draw the widget border inside /Tx BMC so Acrobat keeps it on focus changes (#1613) --- crates/forms/src/appearance.rs | 28 ++++++++++++------------- crates/forms/src/tests.rs | 38 ++++++++++++++++++++++++++++++++++ 2 files changed, 52 insertions(+), 14 deletions(-) diff --git a/crates/forms/src/appearance.rs b/crates/forms/src/appearance.rs index dc5ffcef1..a9558bbe0 100644 --- a/crates/forms/src/appearance.rs +++ b/crates/forms/src/appearance.rs @@ -426,20 +426,20 @@ pub fn field_appearance_drawn(doc: &Document, f: &Field, w: &Widget, values: &[S } } } - let mut content = c.into_bytes(); - content.extend( - format!( - "/Tx BMC\nq\n{} {} {} {} re W n\nBT\n/{} {} Tf\n{}\n", - n(bw), - n(bw), - n(width - 2.0 * bw), - n(height - 2.0 * bw), - font_name, - n(size), - da.color - ) - .bytes(), - ); + // Acrobat regenerates only what is inside /Tx BMC when it redraws a field (e.g. on focus + // changes), discarding what came before it (issues #1613, #633). The background and border + // therefore go inside the marked-content block too, so a redraw keeps them with the text. + let mut content = format!( + "/Tx BMC\nq\n{c}{} {} {} {} re W n\nBT\n/{} {} Tf\n{}\n", + n(bw), + n(bw), + n(width - 2.0 * bw), + n(height - 2.0 * bw), + font_name, + n(size), + da.color + ) + .into_bytes(); content.extend(body); content.extend_from_slice(b"ET\nQ\nEMC\n"); let mut fonts = Dict::new(); diff --git a/crates/forms/src/tests.rs b/crates/forms/src/tests.rs index 0256bfafb..23691aa17 100644 --- a/crates/forms/src/tests.rs +++ b/crates/forms/src/tests.rs @@ -277,6 +277,44 @@ fn text_fields_get_new_appearances() { assert!(raw.windows(8).any(|x| x == b"(Z\xfcrich)")); } +/// Acrobat regenerates only the `/Tx BMC` block when it redraws a text field, so background and +/// border must live inside it rather than immediately before it (#1613). +fn marked_content_borders_field(appearance: &str, label: &str) { + let start = appearance.find("/Tx BMC").expect("no /Tx BMC"); + let marked = appearance[start..].split_once("EMC").expect("no matching EMC").0; + assert!(marked.contains("1 1 0.9 rg"), "background inside /Tx BMC: {appearance} {label}"); + assert!(marked.contains("0 0 0 RG\n1 w\n0.5 0.5 199 19 re S"), "border inside /Tx BMC: {appearance} {label}"); +} + +#[test] +fn text_and_date_fields_keep_background_and_border_inside_marked_content() { + let mut doc = one_page(); + add_field(&mut doc, 0, [50.0, 700.0, 250.0, 720.0], &NewField::Text { multiline: false }, Some("name")).unwrap(); + add_field(&mut doc, 0, [50.0, 660.0, 250.0, 680.0], &NewField::Date, Some("due")).unwrap(); + let props = || FieldProps { + look: Some(Look { + border: Some([0.0; 3]), + fill: Some([1.0, 1.0, 0.9]), + width: 1.0, + style: BorderStyle::Solid, + text: [0.0, 0.0, 0.0], + font: FieldFont::Helvetica, + }), + ..FieldProps::default() + }; + set_props(&mut doc, "name", &props()).unwrap(); + set_props(&mut doc, "due", &props()).unwrap(); + set_value(&mut doc, "name", &FieldValue::Text("Ada".into())).unwrap(); + set_value(&mut doc, "due", &FieldValue::Text("10/14/2026".into())).unwrap(); + let name_ap = ap(&doc, &field(&fields(&doc), "name").widgets[0]); + let due_ap = ap(&doc, &field(&fields(&doc), "due").widgets[0]); + marked_content_borders_field(&name_ap, "text field"); + marked_content_borders_field(&due_ap, "date field"); + assert!(name_ap.contains("(Ada) Tj"), "{name_ap}"); + assert!(due_ap.contains("(10/14/2026) Tj"), "{due_ap}"); + assert!(!need_appearances(&doc), "drawable ASCII fields do not ask other viewers to redraw"); +} + #[test] fn existing_field_font_encoding_keeps_italian_punctuation_visible() { // ReportLab-style Helvetica: an indirect encoding dictionary with PDFDoc-like Differences. From 2f208a289b28059660fe88c5404cb0f24ecbda82 Mon Sep 17 00:00:00 2001 From: NetterSilver <133535268+Silvertree2010@users.noreply.github.com> Date: Wed, 14 Oct 2026 21:40:11 +0000 Subject: [PATCH 025/498] Keep Auto font size in the field properties Appearance tab Fixes #2250 Co-Authored-By: Claude Haiku 5.5 Co-Authored-By: Claude Sonnet 5.5 --- crates/ui-egui/src/prepare.rs | 5 ++++- crates/ui-egui/tests/prepare.rs | 14 ++++++++++++++ 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/crates/ui-egui/src/prepare.rs b/crates/ui-egui/src/prepare.rs index 37747f14c..d4e20f254 100644 --- a/crates/ui-egui/src/prepare.rs +++ b/crates/ui-egui/src/prepare.rs @@ -977,7 +977,10 @@ pub(crate) fn body(ui: &mut egui::Ui, d: &mut FieldDraft, t: &crate::theme::Toke if ui.add(widgets::checkbox(&mut auto, tl!("Auto"))).changed() { d.font_size = if auto { 0.0 } else { 12.0 }; } - ui.add_enabled(!auto, egui::DragValue::new(&mut d.font_size).range(2.0..=100.0).speed(0.25).suffix(" pt")); + ui.add_enabled( + !auto, + egui::DragValue::new(&mut d.font_size).range(2.0..=100.0).clamp_existing_to_range(false).speed(0.25).suffix(" pt"), + ); }); ui.end_row(); if let Some(l) = d.look.as_mut() { diff --git a/crates/ui-egui/tests/prepare.rs b/crates/ui-egui/tests/prepare.rs index b23f1a9f8..ea006911d 100644 --- a/crates/ui-egui/tests/prepare.rs +++ b/crates/ui-egui/tests/prepare.rs @@ -193,6 +193,20 @@ fn appearance_tab_restyles_the_field() { assert_eq!((l.style, l.font, l.fill), (BorderStyle::Dashed, FieldFont::Courier, Some([1.0, 1.0, 0.8]))); } +#[test] +fn appearance_tab_keeps_auto_font_size() { + let mut h = harness(); + h.state_mut().execute("form.prepare"); + h.run_steps(2); + h.state_mut().open_field_props("city", 0); + h.run_steps(2); + h.get_by_label("Appearance").click(); + h.run_steps(2); + h.state_mut().field_props.as_mut().unwrap().font_size = 0.0; + h.run_steps(3); + assert_eq!(h.state().field_props.as_ref().unwrap().font_size, 0.0, "Auto (0) must survive a frame"); +} + #[test] fn position_tab_rotates_a_field() { let mut h = harness(); From 2e4d9a400e6ada3a8b70388a8152998aa1d97a66 Mon Sep 17 00:00:00 2001 From: Earl Co Date: Thu, 15 Oct 2026 01:00:04 +0200 Subject: [PATCH 026/498] chore(deps): update rustls to 0.23.46 Clear the RUSTSEC-2026-0348 dependency advisory for PR 2280. --- Cargo.lock | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index f2acd78dc..0bae7d4f9 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1861,7 +1861,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "39cab71617ae0d63f51a36d69f866391735b51691dbda63cf6f96d042b63efeb" dependencies = [ "libc", - "windows-sys 0.52.0", + "windows-sys 0.60.2", ] [[package]] @@ -4843,7 +4843,7 @@ dependencies = [ "once_cell", "socket2", "tracing", - "windows-sys 0.52.0", + "windows-sys 0.60.2", ] [[package]] @@ -5393,14 +5393,14 @@ dependencies = [ "errno", "libc", "linux-raw-sys 0.12.1", - "windows-sys 0.52.0", + "windows-sys 0.60.2", ] [[package]] name = "rustls" -version = "0.23.45" +version = "0.23.46" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0d41d731c7d2f962d1ccc364cec258de3c0e93b38c2fb3ba97ac74513048d634" +checksum = "48e13bd8c0e9365c43cfa5c9e8f9ad49d3c8444926c9aac819e0e4dc503c8fdf" dependencies = [ "aws-lc-rs", "log", @@ -5463,7 +5463,7 @@ dependencies = [ "security-framework", "security-framework-sys", "webpki-root-certs", - "windows-sys 0.52.0", + "windows-sys 0.60.2", ] [[package]] @@ -6340,7 +6340,7 @@ dependencies = [ "getrandom 0.3.4", "once_cell", "rustix 1.1.5", - "windows-sys 0.52.0", + "windows-sys 0.60.2", ] [[package]] @@ -7425,7 +7425,7 @@ version = "0.1.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c2a7b1c03c876122aa43f3020e6c3c3ee5c05081c9a00739faf7503aeba10d22" dependencies = [ - "windows-sys 0.52.0", + "windows-sys 0.60.2", ] [[package]] From b57e2f688436164ef4c24919761a248e9284316f Mon Sep 17 00:00:00 2001 From: sanches Date: Thu, 15 Oct 2026 04:28:50 +0300 Subject: [PATCH 027/498] fix(oracle): chunks_exact with a constant size trips clippy 1.99 as_chunks::<4>() gives the pixel array directly; upstream main fails the new chunks_exact_to_as_chunks lint here, which made every pull request red under rust-clippy 1.99.0. --- crates/oracle/src/pixels.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/crates/oracle/src/pixels.rs b/crates/oracle/src/pixels.rs index 7365e37ea..b74d07c06 100644 --- a/crates/oracle/src/pixels.rs +++ b/crates/oracle/src/pixels.rs @@ -186,8 +186,8 @@ pub fn decode_pam_gray(bytes: &[u8]) -> Option<(usize, usize, Vec)> { return None; } let mut out = Vec::with_capacity(width.checked_mul(height)?); - for px in data.get(..wanted)?.chunks_exact(4) { - let (&r, &g, &b, &a) = (px.first()?, px.get(1)?, px.get(2)?, px.get(3)?); + for px in data.get(..wanted)?.as_chunks::<4>().0 { + let [r, g, b, a] = *px; // Composite premultiplied RGB over white, in integer arithmetic that cannot overflow: // each term is at most 255, and the sum is at most 255. let over_white = |c: u8| u32::from(c).saturating_add(255u32.saturating_sub(u32::from(a))).min(255); From d2fc6c1be38ef39f7e7fd254d8736abcb61ce926 Mon Sep 17 00:00:00 2001 From: marcintrojnacki Date: Thu, 15 Oct 2026 09:53:00 +0200 Subject: [PATCH 028/498] M14: Polish says what a signature says, and the rest of the interface MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit A Polish signature panel headed "Ważność podpisu jest NIEZNANA" and listed its details in English: the catalog had none of the engine's signature wordings (sign::pdf::WORDINGS, 57) or the changes after signing they name (kind::ALL, 10), and lacked 34 UI literals besides. All 101 are translated, and two tests keep them so: - polish_covers_ui_literals, every tl!() literal (as Japanese has); - polish_says_what_a_signature_says, the signature wordings and change kinds with their {} holes. Both fail on the previous catalog. ATTRIBUTION.toml carries the new hash. Co-Authored-By: Claude Opus 5.5 --- ATTRIBUTION.toml | 2 +- ROADMAP.md | 1 + crates/ui-egui/src/i18n/mod.rs | 20 +++++++ crates/ui-egui/src/i18n/pl.tsv | 106 +++++++++++++++++++++++++++++++++ parity/acrobat-features.toml | 4 +- 5 files changed, 130 insertions(+), 3 deletions(-) diff --git a/ATTRIBUTION.toml b/ATTRIBUTION.toml index 3f3791f71..a26ab23c0 100644 --- a/ATTRIBUTION.toml +++ b/ATTRIBUTION.toml @@ -129,7 +129,7 @@ licence = "MIT OR Apache-2.0" licence_file = "LICENSE-MIT" kind = "translation" usage = "Polish UI strings, compiled in by crates/ui-egui/src/i18n/mod.rs" -sha256 = "988bcf2e0322a46c0464ff7b91ab5d90193b0ea7f454812d12595eb843de6fc7" +sha256 = "b0661ac2cceb945d244eff959505b77077816708ae90c8a97184c03b1cee0915" [[asset]] path = "crates/ui-egui/src/i18n/ru.tsv" diff --git a/ROADMAP.md b/ROADMAP.md index fe9723fdf..8c01e47f7 100644 --- a/ROADMAP.md +++ b/ROADMAP.md @@ -201,6 +201,7 @@ Ranked; detail and the full milestone table in [docs/roadmap.md](docs/roadmap.md - **2026-10-14 (M3, control-click candidate):** Coordinate clicks retain hover warmup and pair press/release in one input pass so slow frames do not turn a click into a hold. Text multi-click selection accepts the actual press event when egui has already cleared its origin. Regression cases cover slow-frame button activation, disabled controls and coalesced text selection; estimates unchanged. - **2026-10-14 (community, M7, #128 Hebrew in Add text):** Add text and `page_add_text` draw Hebrew with the craft-fonts Hebr face (Noto Sans Hebrew), through the same shaped path as Arabic and Thai: right-to-left display order with numbers and Latin in place, points and cantillation kept on their letter as one Type 3 glyph, ToUnicode and per-line ActualText so extraction, search and the editor get typing order. Builds without the face refuse Hebrew rather than write `?`. Regular style only. Estimates unchanged. - **2026-10-14 (M9, #1787):** Changes after signing are judged by the role an object held when signed for a page's resources too: a rewritten font, XObject, graphics state or resources dictionary is page content however its new version is labelled, so a `/FT` or `/Subtype /Widget` added by the attacker no longer reads as a permitted form fill. A category dictionary that only gained a name is judged as before. +- **2026-10-15 (community, M14, Polish signature panel):** A Polish signature panel listed its details in English: the catalog lacked every signature wording, the changes after signing they name and 34 UI literals. All 101 are translated; `polish_covers_ui_literals` and `polish_says_what_a_signature_says` keep them so. Estimates unchanged. - **2026-10-13 (M3, native-opening candidate):** Chosen tools survive preparation, conversion and password retries; startup intake waits for pending preparation. Regression tests cover completion, cancellation and document identity. Estimates unchanged. - **2026-10-13 (community, M3, #531 touchpad momentum):** On Wayland a two-finger swipe keeps gliding after the fingers lift and slows to a stop, measured from the gesture's last 0.1 s and decaying with a 0.35 s time constant through the #759 1:1 path. Any wheel input, click, key, zoom or edge ends it (fingers resting on the touchpad don't yet: the vendored winit binds no Wayland hold gestures); single-page paging, macOS (which sends its own momentum), the web, and Animation effects Off never glide. Unit tests for the physics and two headless view tests. Estimates unchanged. - **2026-10-13 (M3, native-open admission):** Later prepared replies stay queued while a modal or native picker owns the foreground. Picker completion, cancellation and abandonment wake retained opens. Regressions cover recipient ownership, exactly-once admission, source/history preservation and one-shot repaint requests. Estimates unchanged. diff --git a/crates/ui-egui/src/i18n/mod.rs b/crates/ui-egui/src/i18n/mod.rs index 5bb2889c9..dec85f5ec 100644 --- a/crates/ui-egui/src/i18n/mod.rs +++ b/crates/ui-egui/src/i18n/mod.rs @@ -961,6 +961,26 @@ mod tests { } } + /// Polish translates every `tl!("…")` literal in the UI source, as Japanese does. + #[test] + fn polish_covers_ui_literals() { + let pl = Lang::from_code("pl").expect("pl registered"); + let missing: Vec<_> = ui_literals().into_iter().filter(|label| !has(pl, label)).collect(); + assert!(missing.is_empty(), "untranslated Polish UI literals: {missing:#?}"); + } + + /// Polish says everything a signature's validation says, and the changes after signing it + /// names, keeping each sentence's holes: a Polish signature panel listed these in English. + #[test] + fn polish_says_what_a_signature_says() { + let pl = Lang::from_code("pl").expect("pl registered"); + for wording in pdfcraft_engine::sign::pdf::WORDINGS.iter().chain(pdfcraft_engine::sign::pdf::kind::ALL) { + assert!(has(pl, wording), "missing signature wording: {wording}"); + let said = tr(pl, wording); + assert_eq!(wording.matches("{}").count(), said.matches("{}").count(), "the Polish of {wording:?} loses a hole: {said:?}"); + } + } + /// Japanese translates every `tl!("…")` literal in the UI source, so a new string can't ship in /// English by accident (the same check French, German, Russian and Simplified Chinese have). #[test] diff --git a/crates/ui-egui/src/i18n/pl.tsv b/crates/ui-egui/src/i18n/pl.tsv index 3dbb24705..d07329979 100644 --- a/crates/ui-egui/src/i18n/pl.tsv +++ b/crates/ui-egui/src/i18n/pl.tsv @@ -2408,3 +2408,109 @@ animation effects Off Wyłączone Make properties default Ustaw właściwości jako domyślne Pages selected Zaznaczone strony Page properties Właściwości strony + +# Signature validation: what a signature's details say and the changes after signing they name +# (pdfcraft_engine::sign::pdf::WORDINGS and kind::ALL). + The signature has no valid byte range. Podpis nie ma prawidłowego zakresu bajtów. + The signature's byte range does not match the file. Zakres bajtów podpisu nie odpowiada plikowi. + The signature's byte range does not exclude exactly its contents. Zakres bajtów podpisu nie pomija dokładnie jego zawartości. + The signature contents are not hexadecimal. Zawartość podpisu nie jest zapisana szesnastkowo. + The signature could not be read ({}). Nie udało się odczytać podpisu ({}). + PdfCraft can't check this signature yet: {}. PdfCraft nie potrafi jeszcze sprawdzić tego podpisu: {}. + The signature uses the legacy adbe.x509.rsa_sha1 format. Podpis używa przestarzałego formatu adbe.x509.rsa_sha1. + The signature is BER-encoded (indefinite lengths) rather than DER; it was read leniently. Podpis jest zakodowany w BER (długości nieokreślone), a nie w DER; odczytano go z tolerancją. + The signed content is a constructed (segmented) OCTET STRING, as BER allows; it was read anyway. Podpisana treść jest złożonym (segmentowanym) OCTET STRING, na co pozwala BER; mimo to ją odczytano. + The RSA signature value does not have the length of the key's modulus (leading zero bytes dropped or added); it was read anyway. Wartość podpisu RSA nie ma długości modułu klucza (pominięte lub dodane początkowe bajty zerowe); mimo to ją odczytano. + The RSA signature's DigestInfo has no NULL parameter (older signers write it so); it was read anyway. DigestInfo podpisu RSA nie ma parametru NULL (tak zapisują go starsze programy); mimo to go odczytano. + The ECDSA signature is not in canonical DER (trailing bytes, padding or a missing sign byte); it was read anyway. Podpis ECDSA nie jest w kanonicznym DER (nadmiarowe bajty końcowe, dopełnienie lub brak bajtu znaku); mimo to go odczytano. + The ECDSA signature is the raw r and s values instead of a DER sequence; it was read anyway. Podpis ECDSA zawiera surowe wartości r i s zamiast sekwencji DER; mimo to go odczytano. + The signature algorithm and the SignerInfo's digest algorithm name different hashes; the signature was made with the SignerInfo's. Algorytm podpisu i algorytm skrótu w SignerInfo wskazują różne funkcje skrótu; podpis złożono funkcją wskazaną w SignerInfo. + This signature uses SHA-1, a weak hash algorithm: collisions in it have been demonstrated. It still validates because many documents signed years ago use it, but it should not be relied on. Ten podpis używa SHA-1, słabej funkcji skrótu, dla której wykazano kolizje. Podpis nadal przechodzi weryfikację, bo używa jej wiele dokumentów podpisanych przed laty, ale nie należy na nim polegać. + This signature uses RIPEMD-160, a legacy 160-bit hash algorithm that is no longer recommended for signatures. It still validates, but it should not be relied on. Ten podpis używa RIPEMD-160, przestarzałej 160-bitowej funkcji skrótu, której nie zaleca się już do podpisów. Podpis nadal przechodzi weryfikację, ale nie należy na nim polegać. + The document has been altered or corrupted since the signature was applied. Dokument został zmieniony lub uszkodzony po złożeniu podpisu. + The signer's certificate is not in the signature. Podpis nie zawiera certyfikatu podpisującego. + The signature value does not match the signer's certificate: the signature is corrupt. Wartość podpisu nie pasuje do certyfikatu podpisującego: podpis jest uszkodzony. + The signature could not be checked ({}). Nie udało się sprawdzić podpisu ({}). + The signature could not be verified ({}). Nie udało się zweryfikować podpisu ({}). + This document has not been modified since this signature was applied. Dokument nie był modyfikowany od złożenia tego podpisu. + The document has been modified since this signature was applied, but the changes are permitted ({}). Dokument zmodyfikowano po złożeniu tego podpisu, ale zmiany są dozwolone ({}). + The document has been altered since this signature was applied in ways it does not permit ({}). Dokument zmieniono po złożeniu tego podpisu w sposób, na który podpis nie pozwala ({}). + The signer's certificate was not valid at the time of signing. Certyfikat podpisującego nie był ważny w chwili podpisania. + The signer's certificate does not allow digital signatures (its key usage has neither digital signature nor non-repudiation). Certyfikat podpisującego nie pozwala na podpisy cyfrowe (jego użycie klucza nie obejmuje ani podpisu cyfrowego, ani niezaprzeczalności). + The signer's certificate is not issued for signing documents (its extended key usage has no document-signing purpose). Certyfikat podpisującego nie jest wystawiony do podpisywania dokumentów (jego rozszerzone użycie klucza nie obejmuje podpisywania dokumentów). + The signer's certificate has critical extensions PdfCraft does not recognize ({}). Certyfikat podpisującego ma rozszerzenia krytyczne, których PdfCraft nie rozpoznaje ({}). + The certificate of {} is not a CA certificate that may issue certificates, so it is not used to vouch for {}. Certyfikat podmiotu {} nie jest certyfikatem urzędu certyfikacji, który może wystawiać certyfikaty, dlatego nie poświadcza certyfikatu {}. + The certificate of {} does not allow this many CA certificates below it (path length), so it is not used to vouch for {}. Certyfikat podmiotu {} nie dopuszcza tylu certyfikatów urzędów certyfikacji poniżej siebie (długość ścieżki), dlatego nie poświadcza certyfikatu {}. + The certificate of {} was not valid at the time of signing, so it is not used to vouch for {}. Certyfikat podmiotu {} nie był ważny w chwili podpisania, dlatego nie poświadcza certyfikatu {}. + The signer's identity is unknown because it has not been included in your list of trusted certificates and none of its parent certificates are trusted certificates. Tożsamość podpisującego jest nieznana, ponieważ jego certyfikatu nie ma na liście zaufanych certyfikatów i żaden z certyfikatów nadrzędnych nie jest zaufany. + The signer's identity is valid. Tożsamość podpisującego jest prawidłowa. + The signature includes an embedded timestamp. Podpis zawiera osadzony znacznik czasu. + Signing time is from the clock on the signer's computer. Czas podpisania pochodzi z zegara komputera podpisującego. + The signature's timestamp token does not cover the signature value. Token znacznika czasu nie obejmuje wartości podpisu. + The signature's timestamp token could not be verified ({}). Nie udało się zweryfikować tokenu znacznika czasu podpisu ({}). + The embedded timestamp token is valid and its authority is trusted; trusted time is {}. Osadzony token znacznika czasu jest prawidłowy, a jego urząd jest zaufany; zaufany czas to {}. + The signature carries an unverified timestamp ({}): the timestamp authority is not in your list of trusted certificates, so the signing time claimed by the signer is used instead. Podpis zawiera niezweryfikowany znacznik czasu ({}): urzędu znacznika czasu nie ma na liście zaufanych certyfikatów, dlatego użyto czasu podpisania podanego przez podpisującego. + The signer's certificate has been revoked ({}). Certyfikat podpisującego został unieważniony ({}). + The document's embedded revocation information shows that the signer's certificate has not been revoked. Osadzone w dokumencie informacje o unieważnieniach potwierdzają, że certyfikat podpisującego nie został unieważniony. + The timestamp has no valid byte range. Znacznik czasu nie ma prawidłowego zakresu bajtów. + The timestamp's byte range does not match the file. Zakres bajtów znacznika czasu nie odpowiada plikowi. + The timestamp's byte range does not exclude exactly its contents. Zakres bajtów znacznika czasu nie pomija dokładnie jego zawartości. + The timestamp contents are not hexadecimal. Zawartość znacznika czasu nie jest zapisana szesnastkowo. + The timestamp token could not be read ({}). Nie udało się odczytać tokenu znacznika czasu ({}). + The document has been altered or corrupted since the timestamp was applied. Dokument został zmieniony lub uszkodzony po dodaniu znacznika czasu. + The timestamp authority's certificate was not valid at the time of timestamping. Certyfikat urzędu znacznika czasu nie był ważny w chwili oznaczania czasem. + This document has not been modified since this timestamp was applied. Dokument nie był modyfikowany od dodania tego znacznika czasu. + The document has been modified since this timestamp was applied, but the changes are permitted ({}). Dokument zmodyfikowano po dodaniu tego znacznika czasu, ale zmiany są dozwolone ({}). + The document has been altered since this timestamp was applied in ways it does not permit ({}). Dokument zmieniono po dodaniu tego znacznika czasu w sposób, na który znacznik nie pozwala ({}). + The timestamp token is valid and its authority is trusted. Token znacznika czasu jest prawidłowy, a jego urząd jest zaufany. + The timestamp token is valid, but the timestamp authority is not in your list of trusted certificates. Token znacznika czasu jest prawidłowy, ale urzędu znacznika czasu nie ma na liście zaufanych certyfikatów. + Unsigned signature field Niepodpisane pole podpisu + Signature is valid Podpis jest prawidłowy + Signature validity is unknown Ważność podpisu jest nieznana + Signature is invalid Podpis jest nieprawidłowy + page content zawartość stron + form fill wypełnianie formularzy + comments komentarze + document security store magazyn zabezpieczeń dokumentu + metadata metadane + links łącza + document structure struktura dokumentu + pages added or removed dodane lub usunięte strony + other changes inne zmiany + the signed version could not be read nie udało się odczytać podpisanej wersji + +# The rest of the interface the Polish catalog lacked. + Auto ({percent}%) Automatycznie ({percent}%) + Auto follows the system's text size. Pages always render at the display's full resolution. Tryb automatyczny dopasowuje się do rozmiaru tekstu w systemie. Strony są zawsze renderowane w pełnej rozdzielczości ekranu. + Check the pages Sprawdź strony + Collapse all Zwiń wszystko + Discard this text (Esc) Odrzuć ten tekst (Esc) + Done adding text Zakończ dodawanie tekstu + Drawing scale changes. Use Actual size for full-scale plans. Skala rysunku się zmieni. Do planów w pełnej skali użyj opcji Rzeczywisty rozmiar. + Expand all Rozwiń wszystko + Files are combined in the order shown. Drag them to change it. Pliki są łączone w pokazanej kolejności. Przeciągnij je, aby ją zmienić. + Fill colour Kolor wypełnienia + Fill colour: none Kolor wypełnienia: brak + For page sizes and margins. Dotyczy rozmiarów stron i marginesów. + Grid view Widok siatki + Import list… Importuj listę… + Interface size Rozmiar interfejsu + List view Widok listy + Margins Marginesy + Match page at 100% Dopasuj stronę w skali 100% + Multiple words or phrases Wiele słów lub fraz + New bookmarks from structure Nowe zakładki ze struktury + No fill Bez wypełnienia + Offset from centre Przesunięcie od środka + One word or phrase per line Jedno słowo lub fraza w wierszu + PDF page: {size} Strona PDF: {size} + PDF scale: {scale}% Skala PDF: {scale}% + Pages: {k} of {n} Strony: {k} z {n} + Preview unavailable: {e} Podgląd niedostępny: {e} + Printer paper and scaling may differ. Check driver settings. Papier i skalowanie w drukarce mogą się różnić. Sprawdź ustawienia sterownika. + Remove page Usuń stronę + Remove {n} pages Usuń strony ({n}) + Some bookmarks are not shown here: the panel lists a limited number, nested a limited depth. Niektóre zakładki nie są tu widoczne: panel pokazuje ograniczoną ich liczbę i ograniczoną głębokość zagnieżdżenia. + Switch to List view to change the pages it takes. Przełącz na widok listy, aby zmienić strony, które obejmuje. + The document's security settings don't allow copying text and images Ustawienia zabezpieczeń dokumentu nie pozwalają kopiować tekstu i obrazów + {n} word(s) or phrase(s) Słowa lub frazy: {n} diff --git a/parity/acrobat-features.toml b/parity/acrobat-features.toml index e841dec08..380da6318 100644 --- a/parity/acrobat-features.toml +++ b/parity/acrobat-features.toml @@ -9952,9 +9952,9 @@ status = "partial" commands = ["app.preferences"] tools = [] evidence = ["crates/ui-egui/src/commands.rs::localized_shortcut_labels_follow_language_and_platform", "crates/ui-egui/src/i18n/mod.rs::keyboard_key_names_have_a_separate_context_and_english_fallback", "crates/ui-egui/tests/commands.rs::localized_shortcuts_update_immediately_and_keep_command_ids_and_key_bindings", "crates/ui-egui/src/i18n/mod.rs::windows_display_language_resolves_chinese_scripts", "crates/ui-egui/src/i18n/mod.rs::neutral_locale_does_not_override_display_language", "crates/ui-egui/src/i18n/mod.rs::windows_display_language_query_returns_a_locale_tag", "crates/ui-egui/src/i18n/mod.rs::language_persists_and_invalid_input_keeps_current_language", "crates/ui-egui/src/i18n/mod.rs::bundled_catalogs_are_consistent", "crates/ui-egui/src/i18n/mod.rs::arabic_is_registered_and_persists", "crates/ui-egui/src/i18n/mod.rs::arabic_lookups_are_in_display_order", "crates/ui-egui/src/i18n/mod.rs::arabic_plurals_follow_the_six_cldr_forms", "crates/ui-egui/src/i18n/mod.rs::arabic_covers_commands_and_catalogue", "crates/ui-egui/src/i18n/mod.rs::arabic_covers_ui_literals", "crates/ui-egui/src/i18n/mod.rs::arabic_labels_have_glyphs", "crates/ui-egui/src/bidi.rs::rtl_labels_keep_placeholders_whole", "crates/ui-egui/src/i18n/mod.rs::japanese_covers_commands_and_catalogue", "crates/ui-egui/src/i18n/mod.rs::simplified_chinese_covers_commands_and_catalogue", "crates/ui-egui/src/i18n/mod.rs::simplified_chinese_covers_ui_literals", "crates/ui-egui/src/i18n/mod.rs::simplified_chinese_history_and_diagnostics_preserve_user_values", "crates/ui-egui/tests/control.rs::simplified_chinese_signature_prompts_and_errors_keep_document_state", "crates/ui-egui/tests/control.rs::language_switch_preserves_document_and_command_ids", "crates/ui-egui/tests/control.rs::japanese_controls_and_search_keep_command_ids", "crates/ui-egui/tests/control.rs::japanese_dialogs_errors_and_custom_action_names", "crates/ui-egui/src/i18n/mod.rs::french_is_registered", "crates/ui-egui/src/i18n/mod.rs::french_covers_commands_and_catalogue", "crates/ui-egui/src/i18n/mod.rs::french_covers_ui_literals", "crates/ui-egui/src/i18n/mod.rs::french_history_and_diagnostics_preserve_user_values", "crates/ui-egui/src/i18n/mod.rs::german_certificate_subject_has_a_distinct_context", "crates/ui-egui/src/widgets.rs::search_placeholder_never_overlaps_the_shortcut", "crates/ui-egui/src/home.rs::translated_card_description_leaves_room_for_the_action", "crates/ui-egui/tests/control.rs::german_preferences_and_search_keep_command_ids", "crates/ui-egui/src/i18n/mod.rs::telugu_covers_commands_and_catalogue", "crates/ui-egui/src/i18n/mod.rs::telugu_labels_have_glyphs", "crates/ui-egui/src/i18n/mod.rs::hungarian_is_registered", "crates/ui-egui/src/i18n/mod.rs::hungarian_covers_commands_and_catalogue", "crates/ui-egui/src/i18n/mod.rs::hungarian_covers_ui_literals", "crates/ui-egui/src/i18n/mod.rs::hungarian_history_and_diagnostics_preserve_user_values", "crates/ui-egui/src/i18n/mod.rs::ukrainian_is_registered_and_persists", "crates/ui-egui/src/i18n/mod.rs::ukrainian_integer_plurals_cover_teens_and_large_counts", "crates/ui-egui/src/i18n/mod.rs::ukrainian_calendar_uses_month_case_for_dates", "crates/ui-egui/src/i18n/mod.rs::ukrainian_catalog_does_not_leave_english_ui_text", "crates/ui-egui/src/i18n/mod.rs::ukrainian_covers_commands_and_catalogue", "crates/ui-egui/src/i18n/mod.rs::ukrainian_covers_ui_literals", "crates/ui-egui/src/i18n/mod.rs::ukrainian_history_and_diagnostics_preserve_user_values", "crates/ui-egui/src/i18n/mod.rs::spanish_covers_ui_literals", "crates/ui-egui/src/i18n/mod.rs::spanish_covers_what_the_engine_says", "crates/ui-egui/src/i18n/mod.rs::spanish_keeps_the_holes_in_what_the_engine_says", "crates/print/src/tests.rs::wordings_are_said"] -notes = "Shortcut modifiers and key names use a dedicated catalog context across toolbar, menus, palette, Help and tooltips, with English fallback and macOS symbols preserved. Preferences switches Auto (system language)/English/Japanese/Simplified Chinese/Traditional Chinese/Czech/Brazilian Portuguese/German/Spanish/French/Telugu/Hungarian/Ukrainian/Italian/Arabic and persists; ui.set language auto|en|ja|zh-hans|zh-hant|cs|pt-br|de|es|fr|te|hu|uk|it|ar and ui.state expose it. TSV catalogs per language (same system as PhotoCraft); every dialog, panel and notice goes through tl!. Japanese, Traditional Chinese, Simplified Chinese, German, Spanish, French and Hungarian cover commands, dialogs, panels, shortcuts and history labels; Czech and Brazilian Portuguese the menus. French locales (fr, fr_FR, fr_CA, fr_BE) select the French catalog, German locales (de, de_DE, de_AT, de_CH) the German one, Hungarian locales (hu, hu_HU) the Hungarian one. German search hints reserve shortcut space, Home cards bound translated text, certificate Subject has its own context, and inserted tool names keep their capitalization. The sentences the layers below word for themselves (accessibility findings and the saved report, PDF/A problems, signature details, page-range mistakes, edit labels) are handed over apart from the document's own values and go through the catalog too, through said(&i18n::words); Spanish translates them and the other catalogs fall back to English. OS error details, and faults rather than mistakes, stay as they are. Auto detects the Windows display language after explicitly named supported locale overrides; neutral C/POSIX launcher locales are skipped on Windows, with Chinese script/region mapping and English fallback. Arabic (ar and every ar-* locale) covers commands, dialogs and panels with the six CLDR plural forms; its labels are put into display order when the catalog loads, because egui joins Arabic letters but lays words out left to right. Missing: a right-to-left layout (Arabic labels sit in the left-to-right layout, a wrapped Arabic paragraph breaks at the wrong end, and text typed into a field is not reordered), Czech and Brazilian Portuguese dialogs, Chinese and Telugu font delivery in releases (the pinned craft-fonts revision has an Arabic face; its Noto Sans CJK SC is never embedded, AGENTS.md §1.1), the engine's sentences in the other catalogs, a full localization audit." +notes = "Shortcut modifiers and key names use a dedicated catalog context across toolbar, menus, palette, Help and tooltips, with English fallback and macOS symbols preserved. Preferences switches Auto (system language)/English/Japanese/Simplified Chinese/Traditional Chinese/Czech/Brazilian Portuguese/German/Spanish/French/Telugu/Hungarian/Ukrainian/Italian/Arabic and persists; ui.set language auto|en|ja|zh-hans|zh-hant|cs|pt-br|de|es|fr|te|hu|uk|it|ar and ui.state expose it. TSV catalogs per language (same system as PhotoCraft); every dialog, panel and notice goes through tl!. Japanese, Traditional Chinese, Simplified Chinese, German, Spanish, French and Hungarian cover commands, dialogs, panels, shortcuts and history labels; Czech and Brazilian Portuguese the menus. French locales (fr, fr_FR, fr_CA, fr_BE) select the French catalog, German locales (de, de_DE, de_AT, de_CH) the German one, Hungarian locales (hu, hu_HU) the Hungarian one. German search hints reserve shortcut space, Home cards bound translated text, certificate Subject has its own context, and inserted tool names keep their capitalization. The sentences the layers below word for themselves (accessibility findings and the saved report, PDF/A problems, signature details, page-range mistakes, edit labels) are handed over apart from the document's own values and go through the catalog too, through said(&i18n::words); Spanish translates them, Polish the signature details and the changes after signing, and the other catalogs fall back to English. OS error details, and faults rather than mistakes, stay as they are. Auto detects the Windows display language after explicitly named supported locale overrides; neutral C/POSIX launcher locales are skipped on Windows, with Chinese script/region mapping and English fallback. Arabic (ar and every ar-* locale) covers commands, dialogs and panels with the six CLDR plural forms; its labels are put into display order when the catalog loads, because egui joins Arabic letters but lays words out left to right. Missing: a right-to-left layout (Arabic labels sit in the left-to-right layout, a wrapped Arabic paragraph breaks at the wrong end, and text typed into a field is not reordered), Czech and Brazilian Portuguese dialogs, Chinese and Telugu font delivery in releases (the pinned craft-fonts revision has an Arabic face; its Noto Sans CJK SC is never embedded, AGENTS.md §1.1), the engine's sentences in the other catalogs, a full localization audit." evidence = ["crates/ui-egui/src/commands.rs::localized_shortcut_labels_follow_language_and_platform", "crates/ui-egui/src/i18n/mod.rs::keyboard_key_names_have_a_separate_context_and_english_fallback", "crates/ui-egui/tests/commands.rs::localized_shortcuts_update_immediately_and_keep_command_ids_and_key_bindings", "crates/ui-egui/src/i18n/mod.rs::windows_display_language_resolves_chinese_scripts", "crates/ui-egui/src/i18n/mod.rs::neutral_locale_does_not_override_display_language", "crates/ui-egui/src/i18n/mod.rs::windows_display_language_query_returns_a_locale_tag", "crates/ui-egui/src/i18n/mod.rs::language_persists_and_invalid_input_keeps_current_language", "crates/ui-egui/src/i18n/mod.rs::bundled_catalogs_are_consistent", "crates/ui-egui/src/i18n/mod.rs::arabic_is_registered_and_persists", "crates/ui-egui/src/i18n/mod.rs::arabic_lookups_are_in_display_order", "crates/ui-egui/src/i18n/mod.rs::arabic_plurals_follow_the_six_cldr_forms", "crates/ui-egui/src/i18n/mod.rs::arabic_covers_commands_and_catalogue", "crates/ui-egui/src/i18n/mod.rs::arabic_covers_ui_literals", "crates/ui-egui/src/i18n/mod.rs::arabic_labels_have_glyphs", "crates/ui-egui/src/bidi.rs::rtl_labels_keep_placeholders_whole", "crates/ui-egui/src/i18n/mod.rs::japanese_covers_commands_and_catalogue", "crates/ui-egui/src/i18n/mod.rs::simplified_chinese_covers_commands_and_catalogue", "crates/ui-egui/src/i18n/mod.rs::simplified_chinese_covers_ui_literals", "crates/ui-egui/src/i18n/mod.rs::simplified_chinese_history_and_diagnostics_preserve_user_values", "crates/ui-egui/tests/control.rs::simplified_chinese_signature_prompts_and_errors_keep_document_state", "crates/ui-egui/tests/control.rs::language_switch_preserves_document_and_command_ids", "crates/ui-egui/tests/control.rs::japanese_controls_and_search_keep_command_ids", "crates/ui-egui/tests/control.rs::japanese_dialogs_errors_and_custom_action_names", "crates/ui-egui/src/i18n/mod.rs::french_is_registered", "crates/ui-egui/src/i18n/mod.rs::french_covers_commands_and_catalogue", "crates/ui-egui/src/i18n/mod.rs::french_covers_ui_literals", "crates/ui-egui/src/i18n/mod.rs::french_history_and_diagnostics_preserve_user_values", "crates/ui-egui/src/i18n/mod.rs::german_certificate_subject_has_a_distinct_context", "crates/ui-egui/src/widgets.rs::search_placeholder_never_overlaps_the_shortcut", "crates/ui-egui/src/home.rs::translated_card_description_leaves_room_for_the_action", "crates/ui-egui/tests/control.rs::german_preferences_and_search_keep_command_ids", "crates/ui-egui/src/i18n/mod.rs::telugu_covers_commands_and_catalogue", "crates/ui-egui/src/i18n/mod.rs::telugu_labels_have_glyphs", "crates/ui-egui/src/i18n/mod.rs::hungarian_is_registered", "crates/ui-egui/src/i18n/mod.rs::hungarian_covers_commands_and_catalogue", "crates/ui-egui/src/i18n/mod.rs::hungarian_covers_ui_literals", "crates/ui-egui/src/i18n/mod.rs::hungarian_history_and_diagnostics_preserve_user_values", "crates/ui-egui/src/i18n/mod.rs::ukrainian_is_registered_and_persists", "crates/ui-egui/src/i18n/mod.rs::ukrainian_integer_plurals_cover_teens_and_large_counts", "crates/ui-egui/src/i18n/mod.rs::ukrainian_calendar_uses_month_case_for_dates", "crates/ui-egui/src/i18n/mod.rs::ukrainian_catalog_does_not_leave_english_ui_text", "crates/ui-egui/src/i18n/mod.rs::ukrainian_covers_commands_and_catalogue", "crates/ui-egui/src/i18n/mod.rs::ukrainian_covers_ui_literals", "crates/ui-egui/src/i18n/mod.rs::ukrainian_history_and_diagnostics_preserve_user_values", "crates/ui-egui/src/i18n/mod.rs::spanish_covers_what_the_engine_says", "crates/ui-egui/src/i18n/mod.rs::spanish_keeps_the_holes_in_what_the_engine_says", "crates/print/src/tests.rs::wordings_are_said"] -notes = "Shortcut modifiers and key names use a dedicated catalog context across toolbar, menus, palette, Help and tooltips, with English fallback and macOS symbols preserved. Preferences switches Auto (system language)/English/Japanese/Simplified Chinese/Traditional Chinese/Czech/Brazilian Portuguese/German/Spanish/French/Telugu/Hungarian/Ukrainian/Italian/Arabic and persists; ui.set language auto|en|ja|zh-hans|zh-hant|cs|pt-br|de|es|fr|te|hu|uk|it|ar and ui.state expose it. TSV catalogs per language (same system as PhotoCraft); every dialog, panel and notice goes through tl!. Japanese, Traditional Chinese, Simplified Chinese, German, Spanish, French and Hungarian cover commands, dialogs, panels, shortcuts and history labels; Czech and Brazilian Portuguese the menus. French locales (fr, fr_FR, fr_CA, fr_BE) select the French catalog, German locales (de, de_DE, de_AT, de_CH) the German one, Hungarian locales (hu, hu_HU) the Hungarian one. German search hints reserve shortcut space, Home cards bound translated text, certificate Subject has its own context, and inserted tool names keep their capitalization. The sentences the layers below word for themselves (accessibility findings and the saved report, PDF/A problems, signature details, page-range mistakes, edit labels) are handed over apart from the document's own values and go through the catalog too, through said(&i18n::words); Spanish and Italian translate them and the other catalogs fall back to English. OS error details, and faults rather than mistakes, stay as they are. Auto detects the Windows display language after explicitly named supported locale overrides; neutral C/POSIX launcher locales are skipped on Windows, with Chinese script/region mapping and English fallback. Arabic (ar and every ar-* locale) covers commands, dialogs and panels with the six CLDR plural forms; its labels are put into display order when the catalog loads, because egui joins Arabic letters but lays words out left to right. Missing: a right-to-left layout (Arabic labels sit in the left-to-right layout, a wrapped Arabic paragraph breaks at the wrong end, and text typed into a field is not reordered), Czech and Brazilian Portuguese dialogs, Chinese and Telugu font delivery in releases (the pinned craft-fonts revision has an Arabic face; its Noto Sans CJK SC is never embedded, AGENTS.md §1.1), the engine's sentences in the other catalogs, a full localization audit." +notes = "Shortcut modifiers and key names use a dedicated catalog context across toolbar, menus, palette, Help and tooltips, with English fallback and macOS symbols preserved. Preferences switches Auto (system language)/English/Japanese/Simplified Chinese/Traditional Chinese/Czech/Brazilian Portuguese/German/Spanish/French/Telugu/Hungarian/Ukrainian/Italian/Arabic and persists; ui.set language auto|en|ja|zh-hans|zh-hant|cs|pt-br|de|es|fr|te|hu|uk|it|ar and ui.state expose it. TSV catalogs per language (same system as PhotoCraft); every dialog, panel and notice goes through tl!. Japanese, Traditional Chinese, Simplified Chinese, German, Spanish, French and Hungarian cover commands, dialogs, panels, shortcuts and history labels; Czech and Brazilian Portuguese the menus. French locales (fr, fr_FR, fr_CA, fr_BE) select the French catalog, German locales (de, de_DE, de_AT, de_CH) the German one, Hungarian locales (hu, hu_HU) the Hungarian one. German search hints reserve shortcut space, Home cards bound translated text, certificate Subject has its own context, and inserted tool names keep their capitalization. The sentences the layers below word for themselves (accessibility findings and the saved report, PDF/A problems, signature details, page-range mistakes, edit labels) are handed over apart from the document's own values and go through the catalog too, through said(&i18n::words); Spanish and Italian translate them, Polish the signature details and the changes after signing, and the other catalogs fall back to English. OS error details, and faults rather than mistakes, stay as they are. Auto detects the Windows display language after explicitly named supported locale overrides; neutral C/POSIX launcher locales are skipped on Windows, with Chinese script/region mapping and English fallback. Arabic (ar and every ar-* locale) covers commands, dialogs and panels with the six CLDR plural forms; its labels are put into display order when the catalog loads, because egui joins Arabic letters but lays words out left to right. Missing: a right-to-left layout (Arabic labels sit in the left-to-right layout, a wrapped Arabic paragraph breaks at the wrong end, and text typed into a field is not reordered), Czech and Brazilian Portuguese dialogs, Chinese and Telugu font delivery in releases (the pinned craft-fonts revision has an Arabic face; its Noto Sans CJK SC is never embedded, AGENTS.md §1.1), the engine's sentences in the other catalogs, a full localization audit." [[feature]] id = "misc.prefs-reading" From 2109c6785e8d32ce0e5b5c6ce600210258854820 Mon Sep 17 00:00:00 2001 From: komo1iddin <45395275+komo1iddin@users.noreply.github.com> Date: Thu, 15 Oct 2026 14:58:24 +0500 Subject: [PATCH 029/498] M7: show a shaped run in one text object instead of one per glyph Shaped text (Arabic, Indic, combining marks) was written as one text object per glyph: BT, the whole text state (Tf Tc Tw Tz TL Ts and the colour), Tm, Tj and ET. A 15-glyph row took 15 text objects and 392 tokens (the whole stream), a long Arabic paragraph thousands of operators, and other viewers saw every glyph as a separate piece of text. Each run is now one text object: the state once, one Tm, and the glyphs in TJ arrays. A glyph's adjustment moves it from where the glyph before it ends (its width in the embedded font) to where shaping put it, and a mark shaped above or below its letter is raised with Ts, then reset (ISO 32000-1 9.4.3, 9.3.7). Character and word spacing are part of those positions, so Tc and Tw are 0 in the run. The same row is now 1 text object (90 tokens for the stream), and renders the same at 300 dpi (138 of 33 million bytes differ, by 1 level, from rounding). The new test shapes marks beside and above their letters with Inter, reads each glyph's origin back from the TJ displacements and checks it against the shaped position. It fails without this change (15 text objects in the run against 1). Co-Authored-By: Claude Opus 5.5 --- crates/edit/src/tests.rs | 54 ++++++++++++++++++++++++++ crates/edit/src/text_regions.rs | 67 +++++++++++++++++++++++++-------- docs/editing-existing-text.md | 4 +- 3 files changed, 108 insertions(+), 17 deletions(-) diff --git a/crates/edit/src/tests.rs b/crates/edit/src/tests.rs index b542142df..3ba5ce5eb 100644 --- a/crates/edit/src/tests.rs +++ b/crates/edit/src/tests.rs @@ -4184,6 +4184,60 @@ fn a_new_character_comes_from_the_source_fonts_own_embedded_program() { } } +#[test] +fn a_shaped_run_is_one_text_object_with_each_glyph_where_shaping_put_it() { + let inter = include_bytes!("../../../assets/fonts/Inter-Regular.ttf"); + let mut doc = text_page("BT /F1 12 Tf 72 700 Td (Stable text) Tj ET"); + let resource = text::register_text_font(&mut doc, 0, inter).unwrap(); + // Marks shaped beside their letters (q́, x̣) and one stacked above another (ñ̄). + let typed = "q\u{301}x\u{323} n\u{303}\u{304} Cafe\u{301}"; + let style = text::BlockStyle { width: Some(400.0), resource: Some(resource), ..Default::default() }; + text::rewrite_block(&mut doc, 0, 0, Some(typed), &style).unwrap(); + assert_eq!(text::text_blocks(&reopen(&doc), 0).unwrap()[0].editor_text, typed); + let ops = pdfcraft_content::parse(&page_content_bytes(&doc, 0)).ops; + let start = ops.iter().position(|o| o.is("BDC")).unwrap(); + let end = start + ops[start..].iter().position(|o| o.is("EMC")).unwrap(); + let run = &ops[start..end]; + let count = |name: &str| run.iter().filter(|o| o.is(name)).count(); + assert_eq!((count("BT"), count("Tm"), count("Tj")), (1, 1, 0), "{run:?}"); + // Each glyph's origin, read back with the text-space displacements of ISO 32000-1 §9.4.4. + let font = run.iter().find(|o| o.is("Tf")).unwrap(); + let (resource, size) = (font.operands[0].as_name().unwrap().to_vec(), font.operands[1].as_f64().unwrap()); + let page = pdfcraft_model::pages(&doc).remove(0); + let resources = doc.resolve(page.dict.get(b"Resources").unwrap()).as_dict().unwrap().clone(); + let fonts = doc.resolve(resources.get(b"Font").unwrap()).as_dict().unwrap().clone(); + let metrics = pdfcraft_fonts::pdf::Metrics::from_dict(&doc, doc.resolve(fonts.get(&resource).unwrap()).as_dict().unwrap()); + let (mut x, mut rise, mut drawn) = (0.0, 0.0, Vec::new()); + for op in run { + match op.op.as_slice() { + b"Ts" => rise = op.operands[0].as_f64().unwrap(), + b"Tc" | b"Tw" => assert_eq!(op.operands[0].as_f64(), Some(0.0), "{run:?}"), + b"Tz" => assert_eq!(op.operands[0].as_f64(), Some(100.0), "{run:?}"), + b"TJ" => { + for item in op.operands[0].as_array().unwrap() { + match item.as_string() { + Some(s) => { + for code in s.bytes.chunks(2) { + drawn.push((x, rise)); + x += metrics.width(u32::from(u16::from_be_bytes([code[0], code[1]]))) * size; + } + } + None => x -= item.as_f64().unwrap() / 1000.0 * size, + } + } + } + _ => {} + } + } + let shaped = pdfcraft_fonts::source_shaping::shape(inter, typed).unwrap(); + assert_eq!(drawn.len(), shaped.glyphs.len()); + assert!(shaped.glyphs.iter().any(|g| g.position[1] != 0.0), "a mark is raised"); + for (glyph, (x, y)) in shaped.glyphs.iter().zip(&drawn) { + assert!((glyph.position[0] * size - x).abs() < 1e-3 && (glyph.position[1] * size - y).abs() < 1e-3, "{glyph:?} at {x}, {y}"); + } + assert_eq!(rise, 0.0, "the rise is reset after the run"); +} + #[test] fn a_subset_program_is_not_trusted_for_new_characters_and_the_error_names_the_character() { let mut doc = embedded_program_page("BT /F1 12 Tf 72 700 Td (Stable text) Tj ET", "ABCDEF+Inter-Regular"); diff --git a/crates/edit/src/text_regions.rs b/crates/edit/src/text_regions.rs index 2d7baf519..d4915e00d 100644 --- a/crates/edit/src/text_regions.rs +++ b/crates/edit/src/text_regions.rs @@ -753,24 +753,59 @@ pub(super) fn rewrite_styled_block( properties.set(b"ActualText".to_vec(), Object::String(PdfString::text(&string))); block_ops.push(Op::new("BDC", vec![Object::name("Span"), Object::Dict(properties)])); state.font = Some((resource.clone(), size_of(source, item.1))); - // Absolute glyph matrices preserve marks and contextual positions; font-program - // codes are separate from Unicode and ToUnicode/ActualText keep logical text. + // One text object for the run: each glyph is placed where shaping put it by a TJ + // adjustment from where the glyph before it ends (its advance in the embedded + // font's widths), and raised by the text rise for a mark set above or below + // (ISO 32000-1 §9.4.3, §9.3.7). Font-program codes are separate from Unicode; + // ToUnicode and ActualText keep the logical text. let size = size_of(source, item.1); - let mut extra = 0.0; - for (i, glyph) in shaped.glyphs.iter().enumerate() { - let mut matrix = tm; - let x = (glyph.position[0] * size + extra) * state.scale; - let y = glyph.position[1] * size; - matrix[4] += matrix[0] * x + matrix[2] * y; - matrix[5] += matrix[1] * x + matrix[3] * y; - let code = u16::try_from(i + 1).map_err(|_| EditError::Invalid("shaped glyph limit".into()))?; - block_ops.push(Op::new("BT", vec![])); - block_ops.extend(state.ops()); - block_ops.push(Op::new("Tm", matrix.map(n).to_vec())); - block_ops.push(Op::new("Tj", vec![Object::String(PdfString::literal(code.to_be_bytes().to_vec()))])); - block_ops.push(Op::new("ET", vec![])); - extra += state.char_spacing * glyph.text.chars().count() as f64 + state.word_spacing * glyph.text.matches(' ').count() as f64; + let per_unit = 1000.0 / size; + if !per_unit.is_finite() { + return Err(EditError::Invalid("the shaped text has no size".into())); } + let shown = fonts + .get(resource.as_bytes()) + .and_then(|f| doc.resolve(f).as_dict().cloned()) + .map(|d| Metrics::from_dict(doc, &d)) + .ok_or_else(|| EditError::Invalid("shaped font is missing".into()))?; + // Spacing is part of each glyph's position, so the run itself has none. + let (char_spacing, word_spacing, rise) = (state.char_spacing, state.word_spacing, state.rise); + state.char_spacing = 0.0; + state.word_spacing = 0.0; + block_ops.push(Op::new("BT", vec![])); + block_ops.extend(state.ops()); + block_ops.push(Op::new("Tm", tm.iter().map(|v| n(*v)).collect())); + // `pen`: where the next glyph would start, in thousandths of the font size. + let (mut pen, mut extra, mut raised) = (0.0, 0.0, rise); + let mut shown_glyphs: Vec = Vec::new(); + for (i, glyph) in shaped.glyphs.iter().enumerate() { + let target = (glyph.position[0] * size + extra) * per_unit; + let glyph_rise = rise + glyph.position[1] * size; + if (glyph_rise - raised).abs() > 1e-9 || shown_glyphs.len() >= 4096 { + if !shown_glyphs.is_empty() { + block_ops.push(Op::new("TJ", vec![Object::Array(std::mem::take(&mut shown_glyphs))])); + } + if (glyph_rise - raised).abs() > 1e-9 { + block_ops.push(Op::new("Ts", vec![n(glyph_rise)])); + raised = glyph_rise; + } + } + if (target - pen).abs() > 1e-6 { + shown_glyphs.push(n(pen - target)); + } + let code = u16::try_from(i + 1).map_err(|_| EditError::Invalid("shaped glyph limit".into()))?; + shown_glyphs.push(Object::String(PdfString::literal(code.to_be_bytes().to_vec()))); + pen = target + shown.width(u32::from(code)) * 1000.0; + extra += char_spacing * glyph.text.chars().count() as f64 + word_spacing * glyph.text.matches(' ').count() as f64; + } + if !shown_glyphs.is_empty() { + block_ops.push(Op::new("TJ", vec![Object::Array(shown_glyphs)])); + } + if (raised - rise).abs() > 1e-9 { + block_ops.push(Op::new("Ts", vec![n(rise)])); + } + block_ops.push(Op::new("ET", vec![])); + (state.char_spacing, state.word_spacing) = (char_spacing, word_spacing); block_ops.push(Op::new("EMC", vec![])); segment_width = (shaped.advance * size + extra) * state.scale * source.origin.k; } else { diff --git a/docs/editing-existing-text.md b/docs/editing-existing-text.md index e8bb03b9a..db589996d 100644 --- a/docs/editing-existing-text.md +++ b/docs/editing-existing-text.md @@ -49,7 +49,9 @@ format that selection. Automation supports up to 1024 disjoint UTF-8 byte ranges same properties; invalid or overlapping ranges fail atomically. Untouched source formatting survives. OpenType shaping uses the selected/source face's substitution and positioning rules, preserves marks and ligatures, and applies Unicode bidi ordering for a single face. -Logical text remains available after save/reopen through ToUnicode and ActualText. +Each shaped run is one text object: its glyphs are shown in one `TJ` array whose adjustments +place each glyph where shaping put it, and a mark set above or below its letter is raised +with the text rise. Logical text remains available after save/reopen through ToUnicode and ActualText. Added Arabic text records ActualText per shaped line for copying and searching in typing order. ActualText already supplies typing order, so the editor preserves it without applying a second bidi reversal; adjacent visual glyph runs still recover their own reading order. From e0ef098381f6e99a2ea02b21289c58a768668480 Mon Sep 17 00:00:00 2001 From: komo1iddin <45395275+komo1iddin@users.noreply.github.com> Date: Thu, 15 Oct 2026 15:13:34 +0500 Subject: [PATCH 030/498] M7: drop the fallback fonts a text edit leaves unused Each edit that draws Japanese or Hebrew characters the page's fonts lack generates new Type 3 fonts with the outlines of every character it draws. Editing the paragraph again generated new ones and left the old ones in the page's resources, so every edit added a set of glyph outlines to the file. After replace_line and rewrite_block, the page's generated fallback fonts (Type 3, /Name /PCJapanese or /PCHebrew) that no Tf selects any more are removed from its own font dictionary. The content read for this is the page's streams, every form XObject it can reach that has no resources of its own (those use the page's, ISO 32000-1 7.8.3), and the glyph procedures of Type 3 fonts without resources. If any of those can't be decoded strictly, nothing is removed. Registered fonts (PCFull) and the file's own fonts are never touched. Tests: a page with an unused generated font, one its content selects, one only a resource-less form selects and a file's Type 3 font that only shares the name prefix keeps all but the first after a rewrite, and keeps everything when such a form can't be read. Rewriting Japanese text twice (with craft-fonts) leaves only the second rewrite's fonts. The first test fails without this change. Co-Authored-By: Claude Opus 5.5 --- crates/edit/src/tests.rs | 81 +++++++++++++++++++++++++++++++ crates/edit/src/text.rs | 91 ++++++++++++++++++++++++++++++++++- docs/editing-existing-text.md | 5 +- 3 files changed, 174 insertions(+), 3 deletions(-) diff --git a/crates/edit/src/tests.rs b/crates/edit/src/tests.rs index b542142df..00832082f 100644 --- a/crates/edit/src/tests.rs +++ b/crates/edit/src/tests.rs @@ -1109,6 +1109,87 @@ fn covered_japanese_chars(n: usize) -> String { .collect() } +#[test] +fn fallback_fonts_nothing_shows_any_more_leave_with_a_rewrite() { + // `PCJp1` is selected by the page, `PCJp2` only by a form that uses the page's resources, `PCJp` + // by nothing; `PCJpOther` is a Type 3 font of the file's own that only shares the prefix. + let mut doc = text_page("BT /F1 12 Tf 72 700 Td (Some text) Tj ET BT /PCJp1 12 Tf ET q /Fm0 Do Q"); + let generated = |doc: &mut Document, name: &str| { + doc.add(Object::Dict(Dict::from_iter([ + (b"Type".to_vec(), Object::name("Font")), + (b"Subtype".to_vec(), Object::name("Type3")), + (b"Name".to_vec(), Object::name(name)), + ]))) + }; + let (unused, page_shown, form_shown, own) = + (generated(&mut doc, "PCJapanese"), generated(&mut doc, "PCJapanese"), generated(&mut doc, "PCJapanese"), generated(&mut doc, "Other")); + let form = doc.add(Object::Stream(Stream::from_raw( + Dict::from_iter([(b"Subtype".to_vec(), Object::name("Form")), (b"BBox".to_vec(), Object::Array(vec![Object::Int(0); 4]))]), + b"BT /PCJp2 12 Tf ET".to_vec(), + ))); + let p = pdfcraft_model::pages(&doc)[0].obj; + let mut fonts = Dict::from_iter([(b"F1".to_vec(), Object::Ref(pdfcraft_cos::ObjRef::new(5, 0)))]); + for (name, font) in [("PCJp", unused), ("PCJp1", page_shown), ("PCJp2", form_shown), ("PCJpOther", own)] { + fonts.set(name.as_bytes().to_vec(), Object::Ref(font)); + } + let resources = Dict::from_iter([ + (b"Font".to_vec(), Object::Dict(fonts)), + (b"XObject".to_vec(), Object::Dict(Dict::from_iter([(b"Fm0".to_vec(), Object::Ref(form))]))), + ]); + doc.update_dict(p, |d| d.set(b"Resources".to_vec(), Object::Dict(resources.clone()))).unwrap(); + let names = |doc: &Document| { + let page = pdfcraft_model::pages(doc).remove(0); + let res = doc.resolve(page.dict.get(b"Resources").unwrap()).as_dict().unwrap().clone(); + let mut names: Vec = + doc.resolve(res.get(b"Font").unwrap()).as_dict().unwrap().iter().map(|(n, _)| String::from_utf8_lossy(n).into_owned()).collect(); + names.sort(); + names + }; + // A rewrite that doesn't reach the fallback fonts still drops the one nothing shows. + text::rewrite_block(&mut doc, 0, 0, Some("Other text"), &text::BlockStyle::default()).unwrap(); + assert_eq!(names(&reopen(&doc)), ["F1", "PCJp1", "PCJp2", "PCJpOther"]); + + // A form using the page's resources whose content can't be read might show any of them: they + // all stay. + let mut doc = text_page("BT /F1 12 Tf 72 700 Td (Some text) Tj ET q /Fm0 Do Q"); + let unused = generated(&mut doc, "PCJapanese"); + let broken = doc.add(Object::Stream(Stream::from_raw( + Dict::from_iter([ + (b"Subtype".to_vec(), Object::name("Form")), + (b"BBox".to_vec(), Object::Array(vec![Object::Int(0); 4])), + (b"Filter".to_vec(), Object::name("FlateDecode")), + ]), + b"not deflate data".to_vec(), + ))); + let p = pdfcraft_model::pages(&doc)[0].obj; + let fonts = Dict::from_iter([(b"F1".to_vec(), Object::Ref(pdfcraft_cos::ObjRef::new(5, 0))), (b"PCJp".to_vec(), Object::Ref(unused))]); + let resources = Dict::from_iter([ + (b"Font".to_vec(), Object::Dict(fonts)), + (b"XObject".to_vec(), Object::Dict(Dict::from_iter([(b"Fm0".to_vec(), Object::Ref(broken))]))), + ]); + doc.update_dict(p, |d| d.set(b"Resources".to_vec(), Object::Dict(resources))).unwrap(); + text::rewrite_block(&mut doc, 0, 0, Some("Other text"), &text::BlockStyle::default()).unwrap(); + assert_eq!(names(&doc), ["F1", "PCJp"]); +} + +#[test] +fn rewriting_japanese_twice_keeps_only_the_fallback_fonts_it_shows() { + let mut doc = text_page("BT /F1 12 Tf 72 700 Td (Hello) Tj ET"); + if text::rewrite_block(&mut doc, 0, 0, Some("日本語の文章"), &text::BlockStyle::default()).is_err() { + assert!(pdfcraft_fonts::document_japanese_font().is_none()); + eprintln!("built without a craft-fonts Japanese face: the Type 3 path is checked with CRAFT_FONTS_DIR"); + return; + } + let first: Vec<_> = fallback_fonts(&doc).into_iter().map(|(_, f)| f).collect(); + text::rewrite_block(&mut doc, 0, 0, Some("別の文章です"), &text::BlockStyle::default()).unwrap(); + let doc = reopen(&doc); + let after = fallback_fonts(&doc); + assert!(!after.is_empty()); + assert!(after.iter().all(|(_, f)| !first.contains(f)), "the first rewrite's fonts are gone"); + let content = String::from_utf8_lossy(&page_content_bytes(&doc, 0)).into_owned(); + assert!(after.iter().all(|(name, _)| content.contains(&format!("/{} ", String::from_utf8_lossy(name)))), "{content}"); +} + /// The page's Type 3 fallback fonts (`PCJp`, `PCJp1`, ...) by resource name. fn fallback_fonts(doc: &Document) -> Vec<(Vec, Dict)> { let p = pdfcraft_model::pages(doc).swap_remove(0); diff --git a/crates/edit/src/text.rs b/crates/edit/src/text.rs index 9c83cf9a3..883051d02 100644 --- a/crates/edit/src/text.rs +++ b/crates/edit/src/text.rs @@ -1311,6 +1311,89 @@ fn is_type3_fallback(font: &Dict) -> bool { && font.name(b"Name").is_some_and(|n| n == JAPANESE_FONT_NAME.as_bytes() || n == HEBREW_FONT_NAME.as_bytes()) } +/// Drops the generated fallback fonts ([`is_type3_fallback`]) that nothing on `page` shows any more. +/// Each rewrite generates its own, with the outlines of every character it draws, so without this +/// an earlier rewrite's fonts stay in the page's resources and the file. Only a font dictionary the +/// page owns is changed (a rewrite gives the page its own), and nothing is dropped unless every +/// content stream that may name the page's fonts can be read: the page's own, and those of form +/// XObjects and Type 3 glyphs that have no resources of their own and so use the page's. +fn drop_unused_fallback_fonts(doc: &mut Document, page: usize) { + let Ok(p) = page_dict(doc, page) else { return }; + let Some(Object::Dict(mut resources)) = p.dict.get(b"Resources").cloned() else { return }; + let Some(mut fonts) = resources.get(b"Font").and_then(|f| doc.dict(f)) else { return }; + let generated: Vec> = + fonts.iter().filter(|(_, f)| doc.dict(f).is_some_and(|d| is_type3_fallback(&d))).map(|(name, _)| name.clone()).collect(); + if generated.is_empty() { + return; + } + let Some(shown) = fonts_shown(doc, &p.dict, &resources) else { return }; + let unused: Vec<&Vec> = generated.iter().filter(|name| !shown.contains(*name)).collect(); + if unused.is_empty() { + return; + } + for name in unused { + fonts.remove(name); + } + resources.set(b"Font".to_vec(), Object::Dict(fonts)); + // Nothing is lost if this fails: the fonts just stay. + let _ = doc.update_dict(p.obj, |d| d.set(b"Resources".to_vec(), Object::Dict(resources))); +} + +/// The font resource names `Tf` selects in the page's content and in the content that uses the +/// page's resources (see [`drop_unused_fallback_fonts`]), or `None` if any of it can't be read. +fn fonts_shown(doc: &Document, page: &Dict, resources: &Dict) -> Option>> { + let mut streams: Vec = match page.get(b"Contents") { + None => Vec::new(), + Some(c) => match &*doc.resolve(c) { + Object::Array(a) => a.clone(), + _ => vec![c.clone()], + }, + }; + // Form XObjects without their own resources use the page's, however deeply they are nested + // (ISO 32000-1 §7.8.3), so every form the page can reach is visited. + let mut pending: Vec = vec![resources.clone()]; + let mut seen = std::collections::HashSet::new(); + while let Some(res) = pending.pop() { + for (_, x) in res.get(b"XObject").and_then(|x| doc.dict(x)).unwrap_or_default().iter() { + let Some(r) = x.as_ref() else { continue }; + if !seen.insert(r) { + continue; + } + if seen.len() > 4096 { + return None; + } + let Object::Stream(s) = &*doc.get(r) else { continue }; + if s.dict.name(b"Subtype") != Some(b"Form") { + continue; + } + match s.dict.get(b"Resources").and_then(|r| doc.dict(r)) { + Some(own) => pending.push(own), + None => streams.push(x.clone()), + } + } + } + // And so do Type 3 glyph procedures without their own (the generated fonts' are outlines only). + for (_, f) in resources.get(b"Font").and_then(|f| doc.dict(f)).unwrap_or_default().iter() { + if let Some(font) = doc.dict(f).filter(|d| d.name(b"Subtype") == Some(b"Type3") && !d.contains(b"Resources") && !is_type3_fallback(d)) { + streams.extend(font.get(b"CharProcs").and_then(|c| doc.dict(c)).unwrap_or_default().iter().map(|(_, proc)| proc.clone())); + } + } + let mut shown = std::collections::HashSet::new(); + for stream in streams { + let Object::Stream(s) = &*doc.resolve(&stream) else { return None }; + // Strict: a stream only partly read might name a font in the part that wasn't. + let data = s.decoded_strict().ok()?; + for op in parse(&data).ops { + if op.is("Tf") + && let Some(name) = op.operands.first().and_then(|n| n.as_name()) + { + shown.insert(name.to_vec()); + } + } + } + Some(shown) +} + /// Whether a run shown in `font` (a resource name, and the Japanese or Hebrew fallback face it subsets, if /// any) continues `line`: the same font resource, or another subset of the same face. fn same_font(line: &TextLine, font: &[u8], face: Option<&str>) -> bool { @@ -1689,7 +1772,9 @@ fn source_show(metrics: &Metrics, text: &str, size: f64, space: f64, char_spacin /// Replace the text of line `line` (an index into [`text_lines`]) on `page` with `text`. pub fn replace_line(doc: &mut Document, page: usize, line: usize, text: &str) -> Result { - replace_line_with_limit(doc, page, line, text, MAX_TYPE3_GLYPHS) + let edit = replace_line_with_limit(doc, page, line, text, MAX_TYPE3_GLYPHS)?; + drop_unused_fallback_fonts(doc, page); + Ok(edit) } /// [`replace_line`] with the most unique characters one generated font may hold (tests lower it). @@ -1980,7 +2065,9 @@ pub struct RangeStyle { /// Rewrite paragraph `block` with new text (or its own) and formatting, rewrapped to its width. pub fn rewrite_block(doc: &mut Document, page: usize, block: usize, text: Option<&str>, style: &BlockStyle) -> Result { - rewrite_block_with_limit(doc, page, block, text, style, MAX_TYPE3_GLYPHS) + let edit = rewrite_block_with_limit(doc, page, block, text, style, MAX_TYPE3_GLYPHS)?; + drop_unused_fallback_fonts(doc, page); + Ok(edit) } /// [`rewrite_block`] with the most unique characters one generated font may hold (tests lower it). diff --git a/docs/editing-existing-text.md b/docs/editing-existing-text.md index e8bb03b9a..6f348b99f 100644 --- a/docs/editing-existing-text.md +++ b/docs/editing-existing-text.md @@ -31,7 +31,10 @@ no open-licence declaration are refused. Interface fallback fonts are never expo The full selected program, glyph mappings, widths and Unicode text are embedded in the PDF. Saving and reopening therefore needs no locally installed font. Editing the same text again reuses the font resource the page already has, and every resource made from one program -shares a single copy of it. Original subset bytes are +shares a single copy of it. The Type 3 fonts generated for Japanese or Hebrew characters the +page's fonts lack are made anew by each edit; after an edit, those nothing on the page shows any +more leave the page's resources, unless some content that could name them can't be read. +Original subset bytes are preserved. Optional matching faces from `CRAFT_FONTS_DIR` can also complete source subsets; this works only when that build input actually contains the full face. This change does not add a font binary or change the release font pin. Fonts shared by releases belong in From 6882ce3436999b8ddcb23c8f489edf259c8c91e9 Mon Sep 17 00:00:00 2001 From: Marco Arnulfo Date: Thu, 15 Oct 2026 12:46:19 +0200 Subject: [PATCH 031/498] Ctrl+V pastes a picture from the system clipboard onto the page (fixes #2494) --- crates/ui-egui/src/content_ui.rs | 39 ++++++++++++++++++++++ crates/ui-egui/src/create_ui.rs | 4 +-- crates/ui-egui/src/lib.rs | 8 +++++ crates/ui-egui/tests/content.rs | 55 ++++++++++++++++++++++++++++++++ parity/acrobat-features.toml | 4 +-- 5 files changed, 106 insertions(+), 4 deletions(-) diff --git a/crates/ui-egui/src/content_ui.rs b/crates/ui-egui/src/content_ui.rs index 5f5ef32f7..44d4f08c4 100644 --- a/crates/ui-egui/src/content_ui.rs +++ b/crates/ui-egui/src/content_ui.rs @@ -838,6 +838,45 @@ impl crate::PdfCraftApp { self.left_open = true; } } + + /// Whether ⌘V / Ctrl+V was let go this frame. egui-winit swallows that press (with a Paste + /// event only if the clipboard holds text), while a plain V press always comes through: a + /// release of V with no press of V since the last one is the shortcut, even when ⌘ or Ctrl + /// was let go first. Read every frame, dialogs or not, so a press is never missed. + pub(crate) fn paste_key_released(&mut self, ctx: &egui::Context) -> bool { + let mut released = false; + ctx.input(|inp| { + for e in &inp.events { + if let egui::Event::Key { key: egui::Key::V, pressed, .. } = e { + released |= !*pressed && !self.v_pressed; + self.v_pressed = *pressed; + } + } + }); + released + } + + /// ⌘V / Ctrl+V with a picture on the system clipboard (a screenshot, a picture copied in a + /// browser) places it on the current page, as Add Image does. + /// Organize Pages keeps ⌘V for pages, and text fields for text. + pub(crate) fn paste_image_key(&mut self, i: usize, ctx: &egui::Context, pasted: bool) { + let free = self.dialog.is_none() && !self.palette_open && !ctx.egui_wants_keyboard_input(); + let Some(view) = self.views.get(i) else { return }; + if !pasted || !free || view.organize || view.forms.focus.is_some() { + return; + } + let clip = match self.clipboard_override.clone() { + Some(c) => Some(c), + #[cfg(not(target_arch = "wasm32"))] + None if self.system_clipboard => crate::create_ui::read_clipboard(), + None => None, + }; + let Some(crate::create_ui::Clip::Image { width, height, rgba }) = clip else { return }; + match crate::create_ui::png_from_rgba(width, height, &rgba) { + Ok(png) => self.add_image("Pasted image.png".into(), png), + Err(e) => self.notify_fmt("Couldn't read {name}: {e}", &[("name", tl!("Clipboard")), ("e", &e)]), + } + } } /// What the image tools ask for. diff --git a/crates/ui-egui/src/create_ui.rs b/crates/ui-egui/src/create_ui.rs index 63f803525..cdd783a62 100644 --- a/crates/ui-egui/src/create_ui.rs +++ b/crates/ui-egui/src/create_ui.rs @@ -58,7 +58,7 @@ pub enum Clip { /// An image on the system clipboard, or else its text. #[cfg(not(target_arch = "wasm32"))] -fn read_clipboard() -> Option { +pub(crate) fn read_clipboard() -> Option { let mut cb = arboard::Clipboard::new().ok()?; if let Ok(img) = cb.get_image() { return Some(Clip::Image { width: img.width, height: img.height, rgba: img.bytes.into_owned() }); @@ -66,7 +66,7 @@ fn read_clipboard() -> Option { cb.get_text().ok().filter(|t| !t.trim().is_empty()).map(Clip::Text) } -fn png_from_rgba(width: usize, height: usize, rgba: &[u8]) -> Result, String> { +pub(crate) fn png_from_rgba(width: usize, height: usize, rgba: &[u8]) -> Result, String> { let (w, h) = (u32::try_from(width).map_err(|e| e.to_string())?, u32::try_from(height).map_err(|e| e.to_string())?); if w == 0 || h == 0 || rgba.len() != width * height * 4 { return Err("the clipboard image is empty or malformed".into()); diff --git a/crates/ui-egui/src/lib.rs b/crates/ui-egui/src/lib.rs index d101d812e..bd435f375 100644 --- a/crates/ui-egui/src/lib.rs +++ b/crates/ui-egui/src/lib.rs @@ -722,6 +722,10 @@ pub struct PdfCraftApp { /// system clipboard as a file when `system_clipboard` is on. pub last_copied_file: Option<(String, Vec)>, pub system_clipboard: bool, + /// What ⌘V reads instead of the system clipboard (tests). + pub clipboard_override: Option, + /// V is down as a plain key press (see [`Self::paste_key_released`]). + v_pressed: bool, /// Attach file: the file to attach instead of asking (tests, automation). pub attach_override: Option<(String, Vec)>, /// Duplicate Field: which field and onto which pages. @@ -1020,6 +1024,8 @@ impl PdfCraftApp { last_copied_image: None, last_copied_file: None, system_clipboard: true, + clipboard_override: None, + v_pressed: false, attach_override: None, duplicate_draft: None, form_preview: false, @@ -2767,6 +2773,7 @@ impl PdfCraftApp { fn shortcuts(&mut self, ctx: &egui::Context) { use egui::Key; + let pasted = self.paste_key_released(ctx); // "Save changes?" is modal: its keys are its own (⌘D is Don't save there, not Document // properties; Escape cancels it rather than clearing a selection), and nothing may run // underneath it. They are read here, before the canvas can consume them. @@ -2815,6 +2822,7 @@ impl PdfCraftApp { } canvas::shortcuts(&mut self.views[i], ctx, self.scroll_speed); self.copy_key(i, ctx); + self.paste_image_key(i, ctx, pasted); self.image_pick_keys(i, ctx); } } diff --git a/crates/ui-egui/tests/content.rs b/crates/ui-egui/tests/content.rs index dd2c032ef..c8f5270a1 100644 --- a/crates/ui-egui/tests/content.rs +++ b/crates/ui-egui/tests/content.rs @@ -275,6 +275,61 @@ fn typing_moving_styling_and_deleting_added_content() { assert!(img.flip_h); } +/// #2494: ⌘V / Ctrl+V with a picture on the system clipboard (a screenshot, a picture copied in a +/// browser) places it on the current page, as Add Image does. +#[test] +fn a_picture_on_the_clipboard_is_pasted_onto_the_page() { + use pdfcraft_ui_egui::Clip; + let mut h = harness(); + let v = |pressed, modifiers| egui::Event::Key { key: egui::Key::V, physical_key: None, pressed, repeat: false, modifiers }; + let images = |h: &Harness<'static, PdfCraftApp>| added(h).iter().filter(|a| matches!(a.content, pdfcraft_engine::AddedContent::Image(_))).count(); + // Text on the clipboard: egui gets a Paste event instead of the press; nothing lands on the page. + h.state_mut().clipboard_override = Some(Clip::Text("hello".into())); + h.event(egui::Event::Paste("hello".into())); + h.event(v(false, egui::Modifiers::COMMAND)); + h.run_steps(3); + assert_eq!(images(&h), 0); + h.state_mut().clipboard_override = Some(Clip::Image { width: 30, height: 20, rgba: [90u8, 90, 90, 255].repeat(30 * 20) }); + // A plain V comes through pressed and released: it picks the Select tool, it doesn't paste. + h.event(v(true, egui::Modifiers::NONE)); + h.run_steps(1); + h.event(v(false, egui::Modifiers::NONE)); + h.run_steps(3); + assert_eq!(images(&h), 0, "a plain V doesn't paste"); + // A picture alone: egui-winit sends no Paste event and swallows the press, so only the + // release of V arrives. + h.event(v(false, egui::Modifiers::COMMAND)); + h.run_steps(3); + let a = added(&h); + assert_eq!(a.len(), 1); + let pdfcraft_engine::AddedContent::Image(img) = &a[0].content else { panic!("an image was added") }; + assert_eq!(img.rect, [135.0, 190.0, 165.0, 210.0], "in the middle of the page, at its own size"); + assert_eq!(h.state().views[0].content.selected, Some((0, 0))); + { + let s = h.state(); + assert_eq!(s.session.get(s.views[0].id).unwrap().can_undo(), Some("Add image")); + } + // Ctrl let go a moment before V: the release comes without the modifier, and still pastes. + h.event(v(false, egui::Modifiers::NONE)); + h.run_steps(3); + assert_eq!(images(&h), 2, "Ctrl released first"); + // A text field with the keyboard keeps ⌘V for itself. + assert!(h.state_mut().execute("edit.find")); + h.run_steps(3); + h.event(v(false, egui::Modifiers::COMMAND)); + h.run_steps(3); + assert_eq!(images(&h), 2, "the Find field has the keyboard"); + h.key_press(egui::Key::Escape); + h.run_steps(3); + // Organize Pages keeps ⌘V for pages. + assert!(h.state_mut().execute("page.organize")); + h.run_steps(4); + assert!(h.state().views[0].organize); + h.event(v(false, egui::Modifiers::COMMAND)); + h.run_steps(3); + assert_eq!(images(&h), 2, "Organize Pages pastes pages"); +} + /// #125: text the standard fonts can't draw stays in the editor with a warning instead of being /// written to the page as `?` (or lost). #[test] diff --git a/parity/acrobat-features.toml b/parity/acrobat-features.toml index e841dec08..f5602c698 100644 --- a/parity/acrobat-features.toml +++ b/parity/acrobat-features.toml @@ -2070,8 +2070,8 @@ milestone = "M7" status = "shipped" commands = ["edit.image"] tools = ["page_add_image"] -evidence = ["crates/ui-egui/tests/content.rs::typing_moving_styling_and_deleting_added_content", "crates/automation/tests/automation.rs::adding_content_through_tools", "crates/edit/src/tests.rs::added_text_and_images_are_page_content_that_stays_editable", "crates/engine/src/tests.rs::added_text_and_images_render_and_stay_editable"] -notes = "PNG, JPEG, TIFF, GIF, BMP; centred at natural size or in a rect" +evidence = ["crates/ui-egui/tests/content.rs::typing_moving_styling_and_deleting_added_content", "crates/ui-egui/tests/content.rs::a_picture_on_the_clipboard_is_pasted_onto_the_page", "crates/automation/tests/automation.rs::adding_content_through_tools", "crates/edit/src/tests.rs::added_text_and_images_are_page_content_that_stays_editable", "crates/engine/src/tests.rs::added_text_and_images_render_and_stay_editable"] +notes = "PNG, JPEG, TIFF, GIF, BMP; centred at natural size or in a rect. ⌘V / Ctrl+V pastes a picture from the system clipboard onto the current page the same way (desktop only)" [[feature]] id = "edit.image-replace" From b248dffdff3c60260585df3eb71e8ceeaa11586f Mon Sep 17 00:00:00 2001 From: Marco Arnulfo Date: Tue, 13 Oct 2026 01:04:22 +0200 Subject: [PATCH 032/498] Hebrew file names: draw them with an installed Hebrew face when the build has none (part of #586) --- crates/ui-egui/src/system_fonts.rs | 44 ++++++++++++++++++++++++++---- crates/ui-egui/src/theme.rs | 9 ++++-- crates/ui-egui/tests/fonts.rs | 24 ++++++++++++++++ 3 files changed, 69 insertions(+), 8 deletions(-) diff --git a/crates/ui-egui/src/system_fonts.rs b/crates/ui-egui/src/system_fonts.rs index 606fa923d..8531ccd67 100644 --- a/crates/ui-egui/src/system_fonts.rs +++ b/crates/ui-egui/src/system_fonts.rs @@ -3,10 +3,10 @@ //! The embedded faces (Inter, egui's defaults, craft-fonts) come first in every family; this one //! only draws characters none of them has, such as an Arabic file name in a build without //! craft-fonts, or the Simplified Chinese interface in a build without a `Hans` face (#826). A -//! few more installed faces, [`devanagari_fallback`], [`telugu_fallback`], [`sinhala_fallback`] -//! and [`tamil_fallback`], draw Hindi, Telugu, Sinhala and Tamil when one is installed. It is -//! read at runtime and never embedded or shipped (AGENTS.md §1.4), and `PDFCRAFT_SYSTEM_FONTS=0` -//! turns it off (published screenshots do). +//! few more installed faces, [`devanagari_fallback`], [`telugu_fallback`], [`sinhala_fallback`], +//! [`tamil_fallback`] and [`hebrew_fallback`], draw Hindi, Telugu, Sinhala, Tamil and Hebrew when +//! one is installed. It is read at runtime and never embedded or shipped (AGENTS.md §1.4), and +//! `PDFCRAFT_SYSTEM_FONTS=0` turns it off (published screenshots do). use std::path::{Path, PathBuf}; use std::sync::{Arc, OnceLock}; @@ -32,6 +32,8 @@ const TELUGU_PROBE: char = '\u{0C15}'; const SINHALA_PROBE: char = '\u{0D9A}'; /// Tamil letter ka (க): the face must have it to cover Tamil. const TAMIL_PROBE: char = '\u{0B95}'; +/// Hebrew letter alef: the face must have it to cover Hebrew. +const HEBREW_PROBE: char = '\u{05D0}'; /// 欢 (U+6B22): Simplified only, absent from the Japanese craft-fonts faces. const HANS_PROBE: char = '\u{6B22}'; /// 說 (U+8AAA): Traditional only, absent from the Japanese craft-fonts faces. @@ -103,6 +105,13 @@ pub fn tamil_fallback() -> Option> { CACHE.get_or_init(|| script_fallback(&tamil_candidates(), TAMIL_PROBE)).clone() } +/// The installed fallback face for Hebrew, read once. `None` when it is turned off or no +/// candidate is installed; the interface then draws what the embedded faces can. +pub fn hebrew_fallback() -> Option> { + static CACHE: OnceLock>> = OnceLock::new(); + CACHE.get_or_init(|| script_fallback(&hebrew_candidates(), HEBREW_PROBE)).clone() +} + fn script_fallback(candidates: &[PathBuf], probe: char) -> Option> { if std::env::var_os("PDFCRAFT_SYSTEM_FONTS").is_some_and(|v| v == "0") { return None; @@ -227,6 +236,30 @@ fn tamil_candidates() -> Vec { } } +/// Well-known locations of Hebrew faces, best first. The general fallback does not cover it: +/// SF Arabic, Geeza Pro and Noto Sans Arabic have no Hebrew. +fn hebrew_candidates() -> Vec { + if cfg!(windows) { + ["segoeui.ttf", "arial.ttf", "tahoma.ttf", "david.ttf"].iter().map(|f| windows_fonts().join(f)).collect() + } else if cfg!(target_os = "macos") { + ["/System/Library/Fonts/SFHebrew.ttf", "/System/Library/Fonts/ArialHB.ttc", "/Library/Fonts/Arial Unicode.ttf"] + .iter() + .map(PathBuf::from) + .collect() + } else { + unix_fonts(&[ + "google-noto/NotoSansHebrew-Regular.ttf", + "google-noto-vf/NotoSansHebrew[wght].ttf", + "truetype/noto/NotoSansHebrew-Regular.ttf", + "noto/NotoSansHebrew-Regular.ttf", + "truetype/dejavu/DejaVuSans.ttf", + "TTF/DejaVuSans.ttf", + "dejavu/DejaVuSans.ttf", + "dejavu-sans-fonts/DejaVuSans.ttf", + ]) + } +} + /// Well-known locations of faces with broad script coverage, best first. fn candidates(need: Need) -> Vec { match need { @@ -407,11 +440,12 @@ mod tests { assert!(script_fallback(&candidates, DEVANAGARI_PROBE).is_none()); assert!(script_fallback(&candidates, SINHALA_PROBE).is_none()); assert!(script_fallback(&candidates, TAMIL_PROBE).is_none()); + assert!(script_fallback(&candidates, HEBREW_PROBE).is_none()); } #[test] fn script_candidates_are_absolute_font_files() { - for list in [devanagari_candidates(), telugu_candidates(), sinhala_candidates(), tamil_candidates()] { + for list in [devanagari_candidates(), telugu_candidates(), sinhala_candidates(), tamil_candidates(), hebrew_candidates()] { assert!(!list.is_empty()); assert!(list.iter().all(|p| p.is_absolute() || cfg!(windows)), "{list:?}"); assert!(list.iter().all(|p| p.extension().is_some_and(|e| e == "ttf" || e == "ttc")), "{list:?}"); diff --git a/crates/ui-egui/src/theme.rs b/crates/ui-egui/src/theme.rs index d28a7b658..783737847 100644 --- a/crates/ui-egui/src/theme.rs +++ b/crates/ui-egui/src/theme.rs @@ -224,6 +224,8 @@ pub const SYSTEM_TELUGU_FALLBACK: &str = "system-telugu-fallback"; pub const SYSTEM_SINHALA_FALLBACK: &str = "system-sinhala-fallback"; /// The name of the installed Tamil face [`installed_font_definitions`] may add. pub const SYSTEM_TAMIL_FALLBACK: &str = "system-tamil-fallback"; +/// The name of the installed Hebrew face [`installed_font_definitions`] may add. +pub const SYSTEM_HEBREW_FALLBACK: &str = "system-hebrew-fallback"; /// What [`install_fonts_for`] installs: [`font_definitions_for`], then, on desktop, one face /// already installed on this machine. It only draws characters no embedded face has. @@ -236,9 +238,9 @@ pub const SYSTEM_TAMIL_FALLBACK: &str = "system-tamil-fallback"; /// - Otherwise it is the last fallback of every family (an Arabic file name in a build without /// craft-fonts). /// -/// Installed Devanagari, Telugu, Sinhala and Tamil faces, when there are, end every family just -/// before that one, so Hindi, Telugu (#1531), Sinhala and Tamil (#1688) text, such as a file -/// name, draws in a build without such faces. +/// Installed Devanagari, Telugu, Sinhala, Tamil and Hebrew faces, when there are, end every +/// family just before that one, so Hindi, Telugu (#1531), Sinhala and Tamil (#1688) text, such as +/// a file name, and Hebrew file names (#586) draw in a build without such faces. /// /// `PDFCRAFT_SYSTEM_FONTS=0` leaves them out. pub fn installed_font_definitions(cjk: CjkPreference) -> FontDefinitions { @@ -253,6 +255,7 @@ pub fn installed_font_definitions(cjk: CjkPreference) -> FontDefinitions { (SYSTEM_TELUGU_FALLBACK, crate::system_fonts::telugu_fallback()), (SYSTEM_SINHALA_FALLBACK, crate::system_fonts::sinhala_fallback()), (SYSTEM_TAMIL_FALLBACK, crate::system_fonts::tamil_fallback()), + (SYSTEM_HEBREW_FALLBACK, crate::system_fonts::hebrew_fallback()), ] { let Some(data) = data else { continue }; fonts.font_data.insert(name.to_owned(), data); diff --git a/crates/ui-egui/tests/fonts.rs b/crates/ui-egui/tests/fonts.rs index 258abe89c..402ad4539 100644 --- a/crates/ui-egui/tests/fonts.rs +++ b/crates/ui-egui/tests/fonts.rs @@ -8,6 +8,7 @@ const JAPANESE: &str = "日本語の文字"; const CHINESE: &str = "简体中文欢迎"; const ARABIC: &str = "واحد اثنين"; const TELUGU: &str = "తెలుగు ఫైల్"; +const HEBREW: &str = "ייפוי כח.pdf"; fn families() -> Vec { vec![FontId::proportional(13.0), FontId::monospace(13.0), theme::medium(13.0), theme::semibold(17.0)] @@ -219,6 +220,29 @@ fn system_fallback_covers_sinhala_and_tamil() { } } +/// On a machine with an installed Hebrew font, the installed definitions include it and a +/// Hebrew file name has glyphs in the document tab and the recent files (#586). macOS always +/// ships Arial Hebrew and SF Hebrew, so there the test never skips. +#[test] +fn system_fallback_covers_hebrew() { + assert!(!theme::font_definitions().font_data.contains_key(theme::SYSTEM_HEBREW_FALLBACK)); + let defs = theme::installed_font_definitions(theme::CjkPreference::Default); + let off = std::env::var_os("PDFCRAFT_SYSTEM_FONTS").is_some_and(|v| v == "0"); + if !defs.font_data.contains_key(theme::SYSTEM_HEBREW_FALLBACK) && (off || !cfg!(target_os = "macos")) { + eprintln!("skipping system_fallback_covers_hebrew: no installed Hebrew fallback font (or PDFCRAFT_SYSTEM_FONTS=0)"); + assert!(defs.families.values().all(|stack| !stack.iter().any(|n| n == theme::SYSTEM_HEBREW_FALLBACK))); + return; + } + for (family, stack) in &defs.families { + assert_eq!(stack.iter().filter(|n| *n == theme::SYSTEM_HEBREW_FALLBACK).count(), 1, "{family:?}: {stack:?}"); + } + let mut fonts = Fonts::new(TextOptions::default(), defs); + for id in families() { + assert!(fonts.has_glyphs(&id, HEBREW), "{id:?} lacks {HEBREW}"); + } + assert!(layout_widths(&mut fonts, HEBREW).iter().all(|w| w.is_finite() && *w > 0.0)); +} + /// The Han characters of a catalog's translations. fn catalog_han(catalog: &str) -> String { let mut han: Vec = catalog From d5bde67e74f7a2828bc96fe0cd39c1275b7ae551 Mon Sep 17 00:00:00 2001 From: Marco Arnulfo Date: Thu, 15 Oct 2026 14:41:59 +0200 Subject: [PATCH 033/498] Ctrl+V doesn't paste a picture while preparing a form --- crates/ui-egui/src/content_ui.rs | 4 ++-- crates/ui-egui/tests/content.rs | 9 +++++++++ 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/crates/ui-egui/src/content_ui.rs b/crates/ui-egui/src/content_ui.rs index 44d4f08c4..54223a221 100644 --- a/crates/ui-egui/src/content_ui.rs +++ b/crates/ui-egui/src/content_ui.rs @@ -858,11 +858,11 @@ impl crate::PdfCraftApp { /// ⌘V / Ctrl+V with a picture on the system clipboard (a screenshot, a picture copied in a /// browser) places it on the current page, as Add Image does. - /// Organize Pages keeps ⌘V for pages, and text fields for text. + /// Organize Pages keeps ⌘V for pages, Prepare Form for fields, and text fields for text. pub(crate) fn paste_image_key(&mut self, i: usize, ctx: &egui::Context, pasted: bool) { let free = self.dialog.is_none() && !self.palette_open && !ctx.egui_wants_keyboard_input(); let Some(view) = self.views.get(i) else { return }; - if !pasted || !free || view.organize || view.forms.focus.is_some() { + if !pasted || !free || view.organize || view.forms.focus.is_some() || self.is_preparing() { return; } let clip = match self.clipboard_override.clone() { diff --git a/crates/ui-egui/tests/content.rs b/crates/ui-egui/tests/content.rs index c8f5270a1..6be7c4f56 100644 --- a/crates/ui-egui/tests/content.rs +++ b/crates/ui-egui/tests/content.rs @@ -328,6 +328,15 @@ fn a_picture_on_the_clipboard_is_pasted_onto_the_page() { h.event(v(false, egui::Modifiers::COMMAND)); h.run_steps(3); assert_eq!(images(&h), 2, "Organize Pages pastes pages"); + h.state_mut().views[0].organize = false; + h.run_steps(3); + // Prepare Form keeps ⌘V for form fields. + assert!(h.state_mut().execute("form.prepare")); + h.run_steps(3); + assert!(h.state().is_preparing()); + h.event(v(false, egui::Modifiers::COMMAND)); + h.run_steps(3); + assert_eq!(images(&h), 2, "Prepare Form pastes fields"); } /// #125: text the standard fonts can't draw stays in the editor with a warning instead of being From aad803caae022f0f160d063722bf064ebfac9952 Mon Sep 17 00:00:00 2001 From: Guillem Vela Date: Wed, 14 Oct 2026 19:26:06 +0200 Subject: [PATCH 034/498] M14: add Catalan interface and date localization MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Register Catalan (`ca`) as an interface and date language with a 2,592-entry contributor-original catalog written from the meaning of the English labels. Plurals use the one/other rule; every `ca-*` locale, including Valencian (`ca_ES@valencia`), resolves to this catalog. Tests cover registration and persistence, every command, menu, tool group and section, every `tl!` literal in the UI source, and every key in the other bundled catalogs. The Latin-script glyph test in tests/fonts.rs now includes Catalan (the interpunct of l·l is covered by the bundled faces). Catalan dates elide the preposition before a vowel (7 de març, 7 d'abril, 8 d'octubre), so the date language sets months_with_day, as Czech and Russian do; a unit test pins it. Update localization docs, the parity table and the roadmap log, and add the ATTRIBUTION.toml entry (ATTRIBUTION.md regenerated). The contributor, a native Catalan speaker, has reviewed the translation. Validation: cargo fmt --check; clippy -D warnings and tests on pdfcraft-ui-egui (i18n, fonts); pdfcraft-engine dates tests; cargo xtask assets; cargo xtask layers. Co-Authored-By: Claude Sonnet 5.5 --- ATTRIBUTION.md | 3 +- ATTRIBUTION.toml | 11 + ROADMAP.md | 1 + crates/engine/src/dates.rs | 36 +- crates/ui-egui/src/i18n/ca.tsv | 2681 ++++++++++++++++++++++++++++++++ crates/ui-egui/src/i18n/mod.rs | 87 +- crates/ui-egui/tests/fonts.rs | 3 +- docs/localization-parity.md | 9 +- docs/localization.md | 8 +- docs/roadmap.md | 1 + 10 files changed, 2828 insertions(+), 12 deletions(-) create mode 100644 crates/ui-egui/src/i18n/ca.tsv diff --git a/ATTRIBUTION.md b/ATTRIBUTION.md index c9acb0512..1181cf727 100644 --- a/ATTRIBUTION.md +++ b/ATTRIBUTION.md @@ -4,7 +4,7 @@ Every asset PdfCraft includes, bundles or uses to build its published material, with its author, source and licence. The policy is in [AGENTS.md](AGENTS.md) §1. The machine-readable list, with SHA-256 hashes, is [ATTRIBUTION.toml](ATTRIBUTION.toml). Licence texts are kept beside the assets and summarised in [NOTICE](NOTICE). -## In this repository (272) +## In this repository (273) | Asset | Title | Author | Licence | Source | Used for | |---|---|---|---|---|---| @@ -280,6 +280,7 @@ Every asset PdfCraft includes, bundles or uses to build its published material, | `assets/icons/monitor.svg` | Lucide icon "monitor" | Lucide Contributors (portions Cole Bemis, Feather) | ISC | https://github.com/lucide-icons/lucide (npm lucide-static 1.49.0, icons/monitor.svg) | UI icon, embedded via crates/ui-egui/src/icon_data.rs | | `crates/ui-egui/src/i18n/sl.tsv` | Slovene interface translation catalog | PdfCraft contributors | MIT OR Apache-2.0 | Contributor-original: clean-room translations of PdfCraft's English UI labels, no proprietary localisation resources | Slovene UI strings, compiled in by crates/ui-egui/src/i18n/mod.rs | | `vendor/vello_common/assets/probe.png` | vello_common probe reference image (rendered from probe.rgba) | Linebender vello contributors | MIT OR Apache-2.0 | vello_common 0.0.8 (crates.io), vendored in vendor/vello_common; regenerated by its vello_sparse_tests regenerate_probe_reference binary | Reference picture of the vendored vello_common probe module, for people only; the build reads probe.rgba, not this file | +| `crates/ui-egui/src/i18n/ca.tsv` | Catalan interface translation catalog | PdfCraft contributors | MIT OR Apache-2.0 | Contributor-original: clean-room translations of PdfCraft's English UI labels, written from their meaning; no proprietary localisation resources | Catalan UI strings, compiled in by crates/ui-egui/src/i18n/mod.rs | ## Compiled in through dependencies (6) diff --git a/ATTRIBUTION.toml b/ATTRIBUTION.toml index 3f3791f71..4b6f553fa 100644 --- a/ATTRIBUTION.toml +++ b/ATTRIBUTION.toml @@ -3375,3 +3375,14 @@ licence_file = "vendor/vello_common/LICENSE-MIT" kind = "image" usage = "Reference picture of the vendored vello_common probe module, for people only; the build reads probe.rgba, not this file" sha256 = "78c59a0cfd2c829909d77006f94e34dac1ae5d1f90e7f10f72e84de541fef697" + +[[asset]] +path = "crates/ui-egui/src/i18n/ca.tsv" +title = "Catalan interface translation catalog" +author = "PdfCraft contributors" +source = "Contributor-original: clean-room translations of PdfCraft's English UI labels, written from their meaning; no proprietary localisation resources" +licence = "MIT OR Apache-2.0" +licence_file = "LICENSE-MIT" +kind = "translation" +usage = "Catalan UI strings, compiled in by crates/ui-egui/src/i18n/mod.rs" +sha256 = "0988fff524d2b76e21a977d078e92da67ea927c9422ac5b67a9ac476c0f441d5" diff --git a/ROADMAP.md b/ROADMAP.md index fe9723fdf..488c3c8a9 100644 --- a/ROADMAP.md +++ b/ROADMAP.md @@ -201,6 +201,7 @@ Ranked; detail and the full milestone table in [docs/roadmap.md](docs/roadmap.md - **2026-10-14 (M3, control-click candidate):** Coordinate clicks retain hover warmup and pair press/release in one input pass so slow frames do not turn a click into a hold. Text multi-click selection accepts the actual press event when egui has already cleared its origin. Regression cases cover slow-frame button activation, disabled controls and coalesced text selection; estimates unchanged. - **2026-10-14 (community, M7, #128 Hebrew in Add text):** Add text and `page_add_text` draw Hebrew with the craft-fonts Hebr face (Noto Sans Hebrew), through the same shaped path as Arabic and Thai: right-to-left display order with numbers and Latin in place, points and cantillation kept on their letter as one Type 3 glyph, ToUnicode and per-line ActualText so extraction, search and the editor get typing order. Builds without the face refuse Hebrew rather than write `?`. Regular style only. Estimates unchanged. - **2026-10-14 (M9, #1787):** Changes after signing are judged by the role an object held when signed for a page's resources too: a rewritten font, XObject, graphics state or resources dictionary is page content however its new version is labelled, so a `/FT` or `/Subtype /Widget` added by the attacker no longer reads as a permitted form fill. A category dictionary that only gained a name is judged as before. +- **2026-10-14 (M14, Catalan localization):** Added Catalan as another interface and date language, with a 2,592-entry clean-room catalog, one/other plurals and coverage tests for commands, tools, UI literals and every key in the other catalogs. A native Catalan speaker (the contributor) has reviewed the translation. Estimates unchanged. - **2026-10-13 (M3, native-opening candidate):** Chosen tools survive preparation, conversion and password retries; startup intake waits for pending preparation. Regression tests cover completion, cancellation and document identity. Estimates unchanged. - **2026-10-13 (community, M3, #531 touchpad momentum):** On Wayland a two-finger swipe keeps gliding after the fingers lift and slows to a stop, measured from the gesture's last 0.1 s and decaying with a 0.35 s time constant through the #759 1:1 path. Any wheel input, click, key, zoom or edge ends it (fingers resting on the touchpad don't yet: the vendored winit binds no Wayland hold gestures); single-page paging, macOS (which sends its own momentum), the web, and Animation effects Off never glide. Unit tests for the physics and two headless view tests. Estimates unchanged. - **2026-10-13 (M3, native-open admission):** Later prepared replies stay queued while a modal or native picker owns the foreground. Picker completion, cancellation and abandonment wake retained opens. Regressions cover recipient ownership, exactly-once admission, source/history preservation and one-shot repaint requests. Estimates unchanged. diff --git a/crates/engine/src/dates.rs b/crates/engine/src/dates.rs index 8c14a5b1b..7d7da5711 100644 --- a/crates/engine/src/dates.rs +++ b/crates/engine/src/dates.rs @@ -56,7 +56,7 @@ const AR_DAYS: [&str; 7] = ["الأحد", "الاثنين", "الثلاثاء", /// The languages month and weekday names can be written in (Preferences ▸ Date format ▸ Language): /// the interface languages, in the same order and with the same names. -pub static DATE_LANGUAGES: [DateLanguage; 23] = [ +pub static DATE_LANGUAGES: [DateLanguage; 24] = [ DateLanguage { code: "en", name: "English", @@ -398,6 +398,29 @@ pub static DATE_LANGUAGES: [DateLanguage; 23] = [ days: ["Chủ Nhật", "Thứ Hai", "Thứ Ba", "Thứ Tư", "Thứ Năm", "Thứ Sáu", "Thứ Bảy"], days_short: ["CN", "T2", "T3", "T4", "T5", "T6", "T7"], }, + DateLanguage { + code: "ca", + name: "Català", + months: ["gener", "febrer", "març", "abril", "maig", "juny", "juliol", "agost", "setembre", "octubre", "novembre", "desembre"], + // After a day the month carries its own preposition, elided before a vowel: `7 d'abril`. + months_with_day: Some([ + "de gener", + "de febrer", + "de març", + "d'abril", + "de maig", + "de juny", + "de juliol", + "d'agost", + "de setembre", + "d'octubre", + "de novembre", + "de desembre", + ]), + months_short: ["gen.", "febr.", "març", "abr.", "maig", "juny", "jul.", "ag.", "set.", "oct.", "nov.", "des."], + days: ["diumenge", "dilluns", "dimarts", "dimecres", "dijous", "divendres", "dissabte"], + days_short: ["dg.", "dl.", "dt.", "dx.", "dj.", "dv.", "ds."], + }, ]; /// The date language for `code` (any case), or `None` when there's none. @@ -718,6 +741,17 @@ mod tests { assert_eq!(in_lang("dddd, mmmm", "cs"), "sobota, březen"); } + #[test] + fn catalan_months_elide_the_preposition_after_a_day() { + assert_eq!(in_lang("dddd d mmmm \\de yyyy", "ca"), "dissabte 7 de març de 2026"); + assert_eq!(in_lang("mmmm yyyy", "ca"), "març 2026"); + let ca = date_language("ca").unwrap(); + assert_eq!(format_day("d mmmm \\de yyyy", (2026, 4, 23), ca), "23 d'abril de 2026"); + assert_eq!(format_day("d mmmm", (2026, 8, 1), ca), "1 d'agost"); + assert_eq!(format_day("d mmmm", (2026, 10, 8), ca), "8 d'octubre"); + assert_eq!(format_day("mmmm", (2026, 10, 8), ca), "octubre", "no preposition without a day"); + } + #[test] fn the_session_writes_names_in_its_date_language() { let mut s = Session::new().with_clock(|| 1_700_000_000); diff --git a/crates/ui-egui/src/i18n/ca.tsv b/crates/ui-egui/src/i18n/ca.tsv new file mode 100644 index 000000000..dcaec4d48 --- /dev/null +++ b/crates/ui-egui/src/i18n/ca.tsv @@ -0,0 +1,2681 @@ +# Catalan (ca) catalog. Format: see the header of ja.tsv +# (context source translation; @id, @plural and other contexts; escapes \n \t \\). +# Plural forms (see `plural_one_other` in i18n/mod.rs): one (1) | other. +# +# Clean-room: every entry was written from the plain meaning of the English label using ordinary +# Catalan computing vocabulary (standard Catalan, commands in the second-person imperative, informal +# "tu" or impersonal wording in notices). No proprietary localisation resource, string table or +# product UI (Acrobat's included) was consulted or copied; add entries the same way. +# Product and technology names (PdfCraft, PDF, Acrobat JavaScript ...) are not translated; +# the trailing "…" of dialog commands is kept. + + Menu Menú + File Fitxer + Edit Edita + Pages Pàgines + View Visualitza + Help Ajuda + Preferences Preferències + Preferences… Preferències… + Interface language Idioma de la interfície + Interface size Mida de la interfície + Auto ({percent}%) Automàtica ({percent} %) + Auto follows the system's text size. Pages always render at the display's full resolution. L'opció automàtica segueix la mida del text del sistema. Les pàgines sempre es renderitzen a la resolució completa de la pantalla. + Identity Identitat + Name on new comments Nom als comentaris nous + Open… Obre… + Open Recent Obre un recent + Clear Recent Files Esborra els fitxers recents + Remove from Recent Elimina dels recents + Remove {name} from Recent Elimina {name} dels recents + Pin folder to Home… Fixa la carpeta a l'inici… + Folders Carpetes + Pin a folder… Fixa una carpeta… + Pin a folder to Home Fixa una carpeta a l'inici + Pin a folder to list its newest PDFs here, such as where your scanner or a synced cloud drive saves them. Fixa una carpeta per llistar-hi els PDF més recents, com ara on els desa l'escàner o una unitat al núvol sincronitzada. + Unpin Deixa de fixar + Unpin {folder} Deixa de fixar {folder} + Looking for PDFs… Cercant PDF… + This folder isn't available right now. It may have moved, or its drive or cloud sync is offline. Aquesta carpeta no està disponible ara mateix. Pot haver-se mogut, o la seva unitat o la sincronització al núvol no té connexió. + No PDFs in this folder yet Encara no hi ha cap PDF en aquesta carpeta + Show less Mostra'n menys + Show {n} more Mostra'n {n} més + The newest {n} of {total} PDFs Els {n} més recents de {total} PDF + Pinned folders need the desktop app Les carpetes fixades requereixen l'aplicació d'escriptori + Choose a folder on this computer to pin Tria una carpeta d'aquest ordinador per fixar-la + {folder} is already pinned to Home {folder} ja està fixada a l'inici + You can pin up to {n} folders. Unpin one first. Es poden fixar fins a {n} carpetes. Primer deixa'n de fixar una. + Pinned {folder} to Home S'ha fixat {folder} a l'inici + No recent files No hi ha fitxers recents + New blank PDF Nou PDF en blanc + Create PDF from file… Crea un PDF des d'un fitxer… + Create PDF from images… Crea un PDF des d'imatges… + Create PDF from multiple files… Crea un PDF des de diversos fitxers… + Create separate PDFs… Crea PDF separats… + Create PDF from clipboard Crea un PDF des del porta-retalls + Combine files… Combina fitxers… + Save Desa + Save as… Anomena i desa… + Close file Tanca el fitxer + Close all Tanca-ho tot + Revert Reverteix + Print… Imprimeix… + Document properties… Propietats del document… + Undo Desfés + Redo Refés + Find… Cerca… + Advanced search… Cerca avançada… + Copy pages Copia pàgines + Cut pages Retalla pàgines + Paste pages Enganxa pàgines + Fit visible Ajusta a l'àrea visible + Marquee zoom Zoom de marc + Take a snapshot Fes una captura + Column select Selecció per columnes + Full screen mode Mode de pantalla completa + Read mode Mode de lectura + Next tab Pestanya següent + Previous tab Pestanya anterior + Switch light / dark theme Canvia el tema clar / fosc + Comments panel Tauler de comentaris + Form fields panel Tauler de camps de formulari + Clear form Neteja el formulari + Find tools and commands… Cerca eines i ordres… + Zoom Zoom + Actual size Mida real + Zoom to page level Zoom a nivell de pàgina + Fit to width Ajusta a l'amplada + Display theme Tema de visualització + Side panels Taulers laterals + Enable Acrobat JavaScript Activa Acrobat JavaScript + Flatten Fill & Sign when saving Aplana Omple i signa en desar + Text, marks and signatures become part of the page. Other comments stay editable. El text, les marques i les signatures passen a formar part de la pàgina. Els altres comentaris continuen sent editables. + OK D'acord + Join our Discord Uneix-te al nostre Discord + Close Tanca + Next / previous match Coincidència següent / anterior + Copy selected text Copia el text seleccionat + Double-click Doble clic + Select a word Selecciona una paraula + Clear selection / close find Esborra la selecció / tanca la cerca + Zoom in / out (also pinch or {key}-scroll) Apropa / allunya (també amb pessic o {key} i desplaçament) + Rotate view Gira la visualització + First / last page Primera / última pàgina + Previous / next page Pàgina anterior / següent + Delete selected pages (Organize) Suprimeix les pàgines seleccionades (Organitza) + Select all pages (Organize) Selecciona totes les pàgines (Organitza) + Home Inici + Open Obre + Open a PDF ({key}) Obre un PDF ({key}) + Dark gray theme Tema gris fosc + Light theme Tema clar + Appearance mode Mode d'aparença + Light Clar + Dark Fosc + Active Actiu + Dark theme Tema fosc + Appearance settings… Configuració de l'aparença… + All tools Totes les eines + Read Llegeix + Convert Converteix + E-Sign Signatura electrònica + Print ({key}) Imprimeix ({key}) + Save ({key}) Desa ({key}) + Document properties ({key}) Propietats del document ({key}) + Find tools and commands Cerca eines i ordres + Fit to height Ajusta a l'alçada + Zoom in Apropa + Zoom out Allunya + Rotate view clockwise Gira la visualització en sentit horari + Rotate view counterclockwise Gira la visualització en sentit antihorari + Page navigation Navegació per pàgines + Previous view Visualització anterior + Next view Visualització següent + Page display Visualització de pàgines + Continuous scrolling Desplaçament continu + Two-page view Visualització de dues pàgines + Single page Pàgina única + Show cover page in two-page view Mostra la portada en la visualització de dues pàgines + Use system setting Usa la configuració del sistema + Light gray Gris clar + Dark gray Gris fosc + Comments Comentaris + Bookmarks Marcadors + Fields Camps + Layers Capes + Attachments Adjunts + Signatures Signatures + Accessibility Checker Verificador d'accessibilitat + Search Cerca + Compare Compara + Page thumbnails Miniatures de pàgina + Form fields Camps de formulari + Zoom out ({key}) Allunya ({key}) + Zoom in ({key}) Apropa ({key}) + Rotate view clockwise ({key}) Gira la visualització en sentit horari ({key}) + Toggle fit page / fit width Alterna entre ajustar a la pàgina / a l'amplada + Next page Pàgina següent + Previous page Pàgina anterior + Current page — type a page number or label (such as iv) and press Enter Pàgina actual — escriu un número o una etiqueta de pàgina (com ara iv) i prem Retorn + Welcome to PdfCraft Et donem la benvinguda a PdfCraft + An open-source PDF workbench — local, private, and scriptable. Un banc de treball de PDF de codi obert — local, privat i programable. + Join the ArtCraft community Uneix-te a la comunitat d'ArtCraft + Get help, share feedback and follow development on Discord. Obtén ajuda, comparteix comentaris i segueix el desenvolupament a Discord. + Recommended tools Eines recomanades + Use now Utilitza-ho ara + Open file Obre el fitxer + Recent Recents + Files you open in PdfCraft appear here. Drop a PDF anywhere to open it. Els fitxers que obris a PdfCraft apareixen aquí. Deixa anar un PDF en qualsevol lloc per obrir-lo. + Privacy Privadesa + PdfCraft works offline. No telemetry, no account, and no cloud processing unless you add a provider. PdfCraft funciona sense connexió. Sense telemetria, sense compte i sense processament al núvol tret que afegeixis un proveïdor. + Scripts run in a sandbox without file or network access. With JavaScript off, Acrobat's standard format, validate and calculate functions still work. Els scripts s'executen en un entorn aïllat sense accés a fitxers ni a la xarxa. Amb JavaScript desactivat, les funcions estàndard de format, validació i càlcul d'Acrobat continuen funcionant. + Back to all tools Torna a totes les eines + Close panel Tanca el tauler + View less Mostra'n menys + View more Mostra'n més + Available Disponible + Ready Llest + Search tools and commands… Cerca eines i ordres… + No matching tools Cap eina coincident + Tool Eina + Command Ordre + Add a sticky note Afegeix una nota adhesiva + Add a text box Afegeix un quadre de text + Highlight text Ressalta el text + Underline text Subratlla el text + Strikethrough text Ratlla el text + Squiggly underline text Subratlla el text amb ondulació + Draw freehand Dibuixa a mà alçada + Draw a line Dibuixa una línia + Draw an arrow Dibuixa una fletxa + Draw a rectangle Dibuixa un rectangle + Draw an oval Dibuixa un oval + Draw a polygon Dibuixa un polígon + Draw connected lines Dibuixa línies connectades + Draw a cloud Dibuixa un núvol + Add a callout Afegeix una llegenda + Insert text Insereix text + Replace text Substitueix el text + Attach a file Adjunta un fitxer + Erase drawings Esborra els dibuixos + Flatten comments Aplana els comentaris + Import comments… Importa comentaris… + Add a stamp Afegeix un segell + Export all comments to data file… Exporta tots els comentaris a un fitxer de dades… + Hide all comments Amaga tots els comentaris + Summarize comments Resumeix els comentaris + Import form data… Importa dades de formulari… + Export form data… Exporta dades de formulari… + PDF/A… PDF/A… + Action Wizard… Assistent d'accions… + Prepare for distribution… Prepara per a la distribució… + Optimize scanned documents… Optimitza documents escanejats… + Compare files… Compara fitxers… + Detect form fields Detecta camps de formulari + Merge data files into spreadsheet… Combina fitxers de dades en un full de càlcul… + Flatten form fields Aplana els camps de formulari + Prepare a form Prepara un formulari + Tab order: by rows Ordre de tabulació: per files + Tab order: by columns Ordre de tabulació: per columnes + Tab order: by document structure Ordre de tabulació: per estructura del document + Add text Afegeix text + Edit text & images Edita text i imatges + Add or edit links Afegeix o edita enllaços + Create links from URLs Crea enllaços a partir d'URL + Remove all links Elimina tots els enllaços + No links to remove No hi ha enllaços per eliminar + Removed 1 link S'ha eliminat 1 enllaç + Removed {n} links S'han eliminat {n} enllaços + Add Bates numbering… Afegeix numeració Bates… + Add image… Afegeix una imatge… + Redact text and images Censura text i imatges + Redact pages… Censura pàgines… + Find text and redact… Cerca text i censura… + Redaction properties… Propietats de la censura… + Apply redactions… Aplica les censures… + Clear redaction marks Esborra les marques de censura + Remove hidden information… Elimina la informació oculta… + Sanitize document… Neteja el document… + Field properties… Propietats del camp… + Add a text field Afegeix un camp de text + Add a checkbox Afegeix una casella de selecció + Add a radio button Afegeix un botó d'opció + Add a drop-down list Afegeix una llista desplegable + Add a list box Afegeix un quadre de llista + Add a button Afegeix un botó + Add an image field Afegeix un camp d'imatge + Add a date field Afegeix un camp de data + Add a digital signature field Afegeix un camp de signatura digital + Digitally sign Signa digitalment + Certify (visible signature) Certifica (signatura visible) + Certify (invisible signature) Certifica (signatura invisible) + Validate all signatures Valida totes les signatures + Signatures panel Tauler de signatures + Fill & Sign: add text Omple i signa: afegeix text + Fill & Sign: checkmark Omple i signa: marca de verificació + Fill & Sign: cross Omple i signa: creu + Fill & Sign: dot Omple i signa: punt + Fill & Sign: line Omple i signa: línia + Fill & Sign: date Omple i signa: data + Fill & Sign: sign Omple i signa: signa + Fill & Sign: initials Omple i signa: inicials + Export to image… Exporta a imatge… + Reduce file size… Redueix la mida del fitxer… + Optimize PDF… Optimitza el PDF… + Export to text… Exporta a text… + Export to Word… Exporta a Word… + Export to PowerPoint… Exporta a PowerPoint… + Export to HTML… Exporta a HTML… + Export to RTF… Exporta a RTF… + JavaScript console… Consola de JavaScript… + Document JavaScripts… JavaScripts del document… + Recognize text… Reconeix el text… + Recognize text in multiple files… Reconeix el text en diversos fitxers… + Check for accessibility… Comprova l'accessibilitat… + Open accessibility report Obre l'informe d'accessibilitat + Change reading options… Canvia les opcions de lectura… + Add alternate text… Afegeix text alternatiu… + Export all images… Exporta totes les imatges… + Add header & footer… Afegeix capçalera i peu de pàgina… + Update header & footer… Actualitza la capçalera i el peu de pàgina… + Remove header & footer Elimina la capçalera i el peu de pàgina + Add watermark… Afegeix una marca d'aigua… + Update watermark… Actualitza la marca d'aigua… + Remove watermark Elimina la marca d'aigua + Add background… Afegeix un fons… + Update background… Actualitza el fons… + Remove background Elimina el fons + Protect using password… Protegeix amb contrasenya… + Remove security Elimina la seguretat + Security properties… Propietats de seguretat… + Organize pages Organitza pàgines + New bookmark Marcador nou + New bookmarks from structure Marcadors nous a partir de l'estructura + Rotate pages clockwise Gira les pàgines en sentit horari + Rotate pages counterclockwise Gira les pàgines en sentit antihorari + Delete pages Suprimeix pàgines + Insert blank page Insereix una pàgina en blanc + Rotate pages… Gira pàgines… + Duplicate pages Duplica pàgines + Crop pages Escapça pàgines + Set page boxes… Defineix els quadres de pàgina… + Insert pages from file… Insereix pàgines des d'un fitxer… + Replace pages… Substitueix pàgines… + Extract pages… Extreu pàgines… + Split document… Divideix el document… + Number pages… Numera les pàgines… + Keyboard shortcuts Dreceres de teclat + Join the ArtCraft Discord Uneix-te al Discord d'ArtCraft + PdfCraft web page Pàgina web de PdfCraft + PdfCraft on GitHub PdfCraft a GitHub + ArtCraft website Lloc web d'ArtCraft + Check for updates… Cerca actualitzacions… + About PdfCraft Quant a PdfCraft + Export a PDF Exporta un PDF + Export to Exporta a + Microsoft Word (.docx) Microsoft Word (.docx) + Spreadsheet (.xlsx) Full de càlcul (.xlsx) + Presentation (.pptx) Presentació (.pptx) + Image (PNG) Imatge (PNG) + Export all images Exporta totes les imatges + HTML web page Pàgina web HTML + Rich Text Format (.rtf) Format de text enriquit (.rtf) + Text (plain) Text (net) + PostScript / EPS PostScript / EPS + Fill & Sign Omple i signa + Fill Omple + Checkmark Marca de verificació + Cross Creu + Dot Punt + Line Línia + Date Data + Signature Signatura + Initials Inicials + Edit a PDF Edita un PDF + Modify page Modifica la pàgina + Rotate pages Gira pàgines + Insert pages Insereix pàgines + Extract pages Extreu pàgines + Add content Afegeix contingut + Text Text + Image Imatge + Header and footer Capçalera i peu de pàgina + Watermark Marca d'aigua + Link Enllaç + Bates numbering Numeració Bates + Background Fons + Attach file Adjunta un fitxer + Create a PDF Crea un PDF + Create from Crea des de + Single file Fitxer únic + Multiple files Diversos fitxers + Separate PDFs PDF separats + Images Imatges + Clipboard Porta-retalls + Blank page Pàgina en blanc + Combine files Combina fitxers + Combine Combina + Add files to combine Afegeix fitxers per combinar + Page options Opcions de pàgina + Page grid Quadrícula de pàgines + Rotate Gira + Delete Suprimeix + Extract Extreu + Insert Insereix + Replace Substitueix + Split Divideix + More Més + Set page boxes Defineix els quadres de pàgina + Page labels Etiquetes de pàgina + Page transitions Transicions de pàgina + Add comments Afegeix comentaris + Markup Marcatge + Sticky note Nota adhesiva + Underline Subratlla + Strikethrough Ratllat + Squiggly underline Subratllat ondulat + Text box Quadre de text + Drawing Dibuix + Rectangle Rectangle + Oval Oval + Arrow Fletxa + Cloud Núvol + Stamp Segell + Review Revisa + Comment list Llista de comentaris + Scan & OCR Escaneig i OCR + Recognize text Reconeixement de text + In this file En aquest fitxer + In multiple files En diversos fitxers + Enhance scanned file Millora el fitxer escanejat + Correct recognized text Corregeix el text reconegut + Protect a PDF Protegeix un PDF + Protect Protegeix + Protect with password Protegeix amb contrasenya + Remove hidden information Elimina la informació oculta + Advanced options Opcions avançades + Encrypt with certificate Xifra amb certificat + Security properties Propietats de seguretat + Redact a PDF Censura un PDF + Redact Censura + Redact pages Censura pàgines + Find text and redact Cerca text i censura + Set properties Defineix les propietats + Sanitize document Neteja el document + Compress a PDF Comprimeix un PDF + Optimize Optimitza + Reduce file size Redueix la mida del fitxer + Advanced optimization Optimització avançada + Audit space usage Audita l'ús d'espai + Field list Llista de camps + Field properties Propietats del camp + Tab order by rows Ordre de tabulació per files + Tab order by columns Ordre de tabulació per columnes + Import data Importa dades + Export data Exporta dades + Add form components Afegeix components de formulari + Text field Camp de text + Checkbox Casella de selecció + Radio button Botó d'opció + Drop-down list Llista desplegable + List box Quadre de llista + Button Botó + Image field Camp d'imatge + Date field Camp de data + Digital signature Signatura digital + Stamps Segells + Stamp palette Paleta de segells + Use a certificate Utilitza un certificat + Certificates Certificats + Timestamp Marca de temps + Use print production Utilitza la producció d'impressió + Print production Producció d'impressió + Output preview Previsualització de sortida + Preflight Verificació prèvia (preflight) + Convert colors Converteix els colors + Add printer marks Afegeix marques d'impressora + Fix hairlines Corregeix les línies fines + Measure objects Mesura objectes + Measure Mesura + Measuring tool Eina de mesura + Geospatial location Ubicació geoespacial + Compare files Compara fitxers + Select files to compare Selecciona els fitxers per comparar + Use guided actions Utilitza accions guiades + Actions list Llista d'accions + Action Wizard Assistent d'accions + Make accessible Fes-lo accessible + Prepare for distribution Prepara per a la distribució + Optimize scanned documents Optimitza documents escanejats + Archive documents Arxiva documents + Prepare for accessibility Prepara per a l'accessibilitat + Accessibility Accessibilitat + Automatically tag PDF Etiqueta el PDF automàticament + Change reading options Canvia les opcions de lectura + Check for accessibility Comprova l'accessibilitat + Add alternate text Afegeix text alternatiu + Fix reading order Corregeix l'ordre de lectura + Apply PDF standards Aplica estàndards PDF + Standards Estàndards + Save as PDF/A Anomena i desa com a PDF/A + Save as PDF/X Anomena i desa com a PDF/X + Save as PDF/UA Anomena i desa com a PDF/UA + Add search index Afegeix un índex de cerca + Index Índex + Manage embedded index Gestiona l'índex incrustat + Use JavaScript Utilitza JavaScript + JavaScript JavaScript + Console Consola + Document JavaScripts JavaScripts del document + Document actions Accions del document + AI assistant Assistent d'IA + Bring your own model (off by default) Porta el teu propi model (desactivat per defecte) + Summarize Resumeix + Ask about this document Pregunta sobre aquest document + Translate Tradueix + pages pàgines + Planned Planificat + Planned for milestone Planificat per a la fita + open to see what it will include obre per veure què inclourà + Optional: needs an AI provider you configure Opcional: requereix un proveïdor d'IA que configuris + Coming in milestone Arribarà a la fita + Items marked Ready work today. Les opcions marcades com a Llest ja funcionen. + Preview Previsualitza + Edit fields Edita els camps + Try the form as people filling it in will see it Prova el formulari tal com el veuran les persones que l'ompliran + Redact all Censura-ho tot + Clear all Esborra-ho tot + Rotate page Gira la pàgina + Delete page Suprimeix la pàgina + Move page Mou la pàgina + Move pages Mou les pàgines + Duplicate page Duplica la pàgina + Replace page Substitueix la pàgina + Replace pages Substitueix les pàgines + Crop page Escapça la pàgina + Cancel Cancel·la + Don't save No desis + Apply Aplica + Run Executa + Clear Esborra + Sanitize Neteja + Mark all Marca-ho tot + Save changes to “{name}” before closing? Vols desar els canvis a “{name}” abans de tancar? + Your changes will be lost if you don't save them. Els canvis es perdran si no els deses. + Password required Cal una contrasenya + “{name}” is protected. Enter a password to open it. “{name}” està protegit. Introdueix una contrasenya per obrir-lo. + Password Contrasenya + Incorrect password. Try again. Contrasenya incorrecta. Torna-ho a provar. + Recognize Text Reconeixement de text + Password protection will be applied when you save La protecció amb contrasenya s'aplicarà en desar + Saved the print-ready PDF to {path} S'ha desat el PDF llest per imprimir a {path} + Could not save: {e} No s'ha pogut desar: {e} + Earlier in tab order Abans en l'ordre de tabulació + Later in tab order Després en l'ordre de tabulació + From: De: + To: A: + High Resolution Alta resolució + Print Imprimeix + Verify to see what the document needs. Verifica per veure què necessita el document. + Set Page Boxes Defineix els quadres de pàgina + Signature panel Tauler de signatures + {month} {day}, {y} {day} de {month} de {y} + The document's security settings don't allow filling in form fields La configuració de seguretat del document no permet omplir camps de formulari + {name} is read-only {name} és de només lectura + {name} has no action {name} no té cap acció + Previous month Mes anterior + Next month Mes següent + January gener + February febrer + March març + April abril + May maig + June juny + July juliol + August agost + September setembre + October octubre + November novembre + December desembre + Done Fet + This certificate is in your list of trusted certificates. Aquest certificat és a la teva llista de certificats de confiança. + This certificate is trusted through a certificate above it in the chain. Aquest certificat és de confiança mitjançant un certificat superior de la cadena. + This certificate is not trusted. Signatures made with it show an unknown identity. Aquest certificat no és de confiança. Les signatures fetes amb ell mostren una identitat desconeguda. + Add to Trusted Certificates Afegeix als certificats de confiança + Export… Exporta… + PDF Optimizer Optimitzador de PDF + Discard Objects Descarta objectes + Discard User Data Descarta dades d'usuari + Clean Up Neteja + Color Images Imatges en color + Grayscale Images Imatges en escala de grisos + Bicubic downsampling to Reducció bicúbica de resolució a + for images above per a imatges de més de + Compression Compressió + ZIP ZIP + Retain existing Conserva l'existent + Minimum Mínima + Low Baixa + High Alta + Maximum Màxima + Each image is measured where pages draw it; an image is replaced only if the result is smaller. Cada imatge es mesura allà on les pàgines la dibuixen; una imatge només se substitueix si el resultat és més petit. + Discard all links, actions and JavaScript Descarta tots els enllaços, accions i JavaScript + Discard alternate images Descarta les imatges alternatives + Discard embedded page thumbnails Descarta les miniatures de pàgina incrustades + Discard document tags Descarta les etiquetes del document + Discard embedded print settings Descarta la configuració d'impressió incrustada + Discard bookmarks Descarta els marcadors + Discard hidden layer content Descarta el contingut de capes ocultes + Discard all comments, forms and multimedia Descarta tots els comentaris, formularis i multimèdia + Discard document information and metadata Descarta la informació i les metadades del document + Discard all object data (file attachments) Descarta totes les dades d'objecte (fitxers adjunts) + Discard private data of other applications Descarta les dades privades d'altres aplicacions + Discard hidden text Descarta el text ocult + Use Flate to encode streams that are not encoded Utilitza Flate per codificar els fluxos que no estan codificats + Remove invalid links and bookmarks Elimina els enllaços i marcadors no vàlids + Remove unreferenced named destinations Elimina les destinacions amb nom sense referència + Compress document structure (object streams) Comprimeix l'estructura del document (fluxos d'objectes) + Remove unused objects and merge identical ones Elimina els objectes no utilitzats i combina els idèntics + Audit space usage… Auditoria de l'espai utilitzat… + Space Audit Auditoria d'espai + Bytes Bytes + Content Streams Fluxos de contingut + X Object Forms Formularis X Object + Structure Info Informació d'estructura + Thumbnails Miniatures + Named Destinations Destinacions amb nom + Color Spaces Espais de color + Shadings Degradats + Patterns (graphics objects) Patrons (objectes gràfics) + Extended Graphics States Estats gràfics ampliats + Embedded Files Fitxers incrustats + Document Overhead Sobrecàrrega del document + Total Total + Text Field Properties Propietats del camp de text + Check Box Properties Propietats de la casella de selecció + Radio Button Properties Propietats del botó d'opció + Dropdown Properties Propietats de la llista desplegable + List Box Properties Propietats del quadre de llista + Button Properties Propietats del botó + Digital Signature Properties Propietats de la signatura digital + Position Posició + Options Opcions + Validate Valida + Calculate Calcula + Actions Accions + This field is locked. Unlock it to change its properties. Aquest camp està bloquejat. Desbloqueja'l per canviar-ne les propietats. + Tooltip: Suggeriment: + Common Properties Propietats comunes + Read Only Només lectura + Required Obligatori + Font Size: Mida del tipus de lletra: + Auto Automàtica + Text Color: Color del text: + Borders and Colors Vores i colors + Border Color: Color de la vora: + Fill Color: Color de farciment: + No color Sense color + Beveled Bisellat + Left: Esquerra: + Bottom: Inferior: + Width: Amplada: + Height: Alçada: + Rotation: Rotació: + Points from the page's bottom-left corner. Punts des de la cantonada inferior esquerra de la pàgina. + Alignment: Alineació: + Default Value: Valor per defecte: + Multi-line Diverses línies + Scroll long text Desplaça el text llarg + Allow Rich Text Formatting Permet el format de text enriquit + Limit of Límit de + characters caràcters + Field is used for file selection El camp s'utilitza per seleccionar fitxers + Check spelling Revisa l'ortografia + Comb of Pentinat de + Export Value: {on} Valor d'exportació: {on} + Check box is checked by default La casella de selecció està marcada per defecte + Button is checked by default El botó està marcat per defecte + Buttons with the same name and value are selected in unison Els botons amb el mateix nom i valor se seleccionen alhora + Item: Element: + Item List Llista d'elements + Up Amunt + Delete {o} Suprimeix {o} + Add the choices people pick from. Afegeix les opcions entre les quals es pot triar. + Default: Per defecte: + (none) (cap) + Sort items Ordena els elements + Allow user to enter custom text Permet introduir text personalitzat + Multiple selection Selecció múltiple + Commit selected value immediately Confirma immediatament el valor seleccionat + Number Número + Percentage Percentatge + Time Hora + Special Especial + Select format category: Selecciona la categoria de format: + The value is shown as typed. El valor es mostra tal com s'ha escrit. + Decimal places: Posicions decimals: + Separator style: Estil del separador: + Currency symbol: Símbol de moneda: + Before the number Abans del número + Negative number style: Estil dels números negatius: + Format: Format: + Custom: Personalitzat: + Zip Code Codi postal + Zip Code + 4 Codi postal + 4 + Phone Number Número de telèfon + Social Security Number Número de la seguretat social + Arbitrary Mask Màscara arbitrària + Mask: Màscara: + 9 digit, A letter, O letter or digit, X any character 9 dígit, A lletra, O lletra o dígit, X qualsevol caràcter + Example: {sample} Exemple: {sample} + Field value is not validated El valor del camp no es valida + Field value is in range: El valor del camp és dins de l'interval: + Add an Action Afegeix una acció + Select Trigger: Selecciona l'activador: + Mouse Up Ratolí amunt + Mouse Down Ratolí avall + Mouse Enter El ratolí entra + Mouse Exit El ratolí surt + On Focus En rebre el focus + On Blur En perdre el focus + Select Action: Selecciona l'acció: + Open a web link Obre un enllaç web + Reset a form Restableix un formulari + Execute a menu item Executa un element de menú + Show a field Mostra un camp + Hide a field Amaga un camp + Submit a form Envia un formulari + Fields to reset (comma-separated; empty: all) Camps per restablir (separats per comes; buit: tots) + Print, NextPage, PrevPage, FirstPage or LastPage Print, NextPage, PrevPage, FirstPage o LastPage + Field names (comma-separated) Noms dels camps (separats per comes) + URL to submit to URL on enviar + Script: Script: + Value: Valor: + No actions Cap acció + Value is not calculated El valor no es calcula + Value is the El valor és + sum (+) suma (+) + product (x) producte (x) + average mitjana + minimum mínim + maximum màxim + of the following fields: dels camps següents: + Simplified field notation: Notació simplificada de camps: + Field names with + - * / and parentheses; put \\ before spaces in names. Noms de camps amb + - * / i parèntesis; posa \\ abans dels espais als noms. + Finding document fonts… Cerca de tipus de lletra del document… + Installed fonts… Tipus de lletra instal·lats… + Keep source fonts Conserva els tipus de lletra d'origen + Load font… Carrega un tipus de lletra… + No openly licensed document fonts found. Load a font file. No s'ha trobat cap tipus de lletra de document amb llicència oberta. Carrega un fitxer de tipus de lletra. + Format text Dona format al text + Bold Negreta + Italic Cursiva + Align left Alinea a l'esquerra + Centre Centra + Align right Alinea a la dreta + Justify Justifica + Thai and Arabic use regular fallback fonts when available. El tailandès i l'àrab utilitzen tipus de lletra alternatius normals quan estan disponibles. + Edit image Edita la imatge + Rotate counterclockwise Gira en sentit antihorari + Rotate clockwise Gira en sentit horari + Flip horizontal Capgira horitzontalment + Flip vertical Capgira verticalment + Replace image Substitueix la imatge + Crop (% trimmed from each side) Escapça (% escapçat de cada costat) + Click on the page to add text; each click starts a new box, and ✓ finishes. Drag items to move them, drag a corner to resize, double-click text to edit it. Fes clic a la pàgina per afegir text; cada clic comença un quadre nou i ✓ finalitza. Arrossega els elements per moure'ls, arrossega una cantonada per canviar-ne la mida i fes doble clic al text per editar-lo. + Choose an image Tria una imatge + Export to Image Exporta a imatge + Export to Text Exporta a text + Export All Images Exporta totes les imatges + Resolution Resolució + Format Format + Quality Qualitat + One {f} file per page, named after the document. Un fitxer {f} per pàgina, amb el nom del document. + Exclude images smaller than Exclou les imatges més petites de + No limit Sense límit + Each image once, named after the document and page. JPEG images are saved unchanged; others as PNG. Cada imatge una sola vegada, amb el nom del document i la pàgina. Les imatges JPEG es desen sense canvis; les altres com a PNG. + Plain text in reading order; pages are separated by form feeds. Text sense format en ordre de lectura; les pàgines se separen amb salts de pàgina. + Create {what} Crea {what} + initials inicials + signature signatura + Create Custom Stamp Crea un segell personalitzat + From {file} Des de {file} + Category: Categoria: + e.g. My stamps p. ex. Els meus segells + Name: Nom: + Custom Personalitzat + Delete stamp Suprimeix el segell + Create custom stamp… Crea un segell personalitzat… + From a PDF page or an image Des d'una pàgina PDF o una imatge + Line spacing Interlineat + Character spacing Espaiat de caràcters + Horizontal scale Escala horitzontal + Rotate Clockwise Gira en sentit horari + Rotate Counterclockwise Gira en sentit antihorari + Flip Horizontal Capgira horitzontalment + Flip Vertical Capgira verticalment + Replace Image… Substitueix la imatge… + Save Image As… Anomena i desa la imatge… + Copy Image Copia la imatge + The image has been copied ({w} × {h} pixels) S'ha copiat la imatge ({w} × {h} píxels) + Couldn't copy the image: {e} No s'ha pogut copiar la imatge: {e} + Copy Image in Original Format Copia la imatge en el format original + The image has been copied as a {ext} file S'ha copiat la imatge com a fitxer {ext} + The page has changed; select the image again La pàgina ha canviat; torna a seleccionar la imatge + Check for updates Cerca actualitzacions + No check has run yet. Encara no s'ha fet cap comprovació. + Checking for a newer version… S'està cercant una versió més recent… + PdfCraft {v} is available. PdfCraft {v} està disponible. + You have version {c}. Download the new version from its release page. Tens la versió {c}. Baixa la versió nova des de la seva pàgina de publicació. + PdfCraft {c} is up to date. PdfCraft {c} està actualitzat. + Couldn't check for updates: {e} No s'han pogut cercar actualitzacions: {e} + You have version {c}. All releases are listed at {page}. Tens la versió {c}. Totes les versions es llisten a {page}. + Asks GitHub for the latest release. Nothing is downloaded or installed automatically. Consulta a GitHub la darrera versió. No es baixa ni s'instal·la res automàticament. + Download Baixa + Later Més tard + none cap + Declared conformance: {shown} Conformitat declarada: {shown} + Output intent: {list} Intenció de sortida: {list} + Conformance level: Nivell de conformitat: + No problems found: the document conforms to {level}. No s'ha trobat cap problema: el document és conforme a {level}. + (page {p}) (pàgina {p}) + · not fixable here · no es pot corregir aquí + Verify Verifica + Box Quadre + Units Unitats + Set to zero Posa a zero + Current page ({n}) Pàgina actual ({n}) + Subset Subconjunt + Update Actualitza + Add Afegeix + {verb} Header and Footer {verb} capçalera i peu de pàgina + {verb} Watermark {verb} marca d'aigua + {verb} Background {verb} fons + Margins Marges + Left Header Text Text de la capçalera esquerra + Center Header Text Text de la capçalera central + Right Header Text Text de la capçalera dreta + Left Footer Text Text del peu de pàgina esquerre + Center Footer Text Text del peu de pàgina central + Right Footer Text Text del peu de pàgina dret + Insert Page Number Insereix el número de pàgina + Insert Date Insereix la data + Start page number Número de pàgina inicial + Source Origen + Fit to page Ajusta a la pàgina + Rotation Rotació + Appear behind page Apareix darrere de la pàgina + Appear on top of page Apareix sobre la pàgina + Offset from centre Desplaçament des del centre + From colour Des del color + Page Range Options Opcions de l'interval de pàgines + Preview: page {p} of {n} Previsualització: pàgina {p} de {n} + Applies to 1 page S'aplica a 1 pàgina + Applies to {n} pages S'aplica a {n} pàgines + Replaces the existing one on those pages. Substitueix l'existent en aquestes pàgines. + PDF or image PDF o imatge + No file chosen Cap fitxer triat + Page number Número de pàgina + Scale relative to target page Escala relativa a la pàgina de destinació + Link Properties Propietats de l'enllaç + Create Link Crea un enllaç + Link Appearance Aparença de l'enllaç + Link Type: Tipus d'enllaç: + Visible Rectangle Rectangle visible + Invisible Rectangle Rectangle invisible + Highlight Style: Estil de ressaltat: + Invert Inverteix + Outline Contorn + Inset Enfonsat + Line Thickness: Gruix de línia: + Thin Fina + Thick Gruixuda + Line Style: Estil de línia: + Solid Contínua + Dashed Discontínua + Color: Color: + Link Action Acció de l'enllaç + Open a web page Obre una pàgina web + Go to a page view Ves a una vista de pàgina + Type the web address. Escriu l'adreça web. + This document has no signatures. Aquest document no té signatures. + The Keychain's digital IDs couldn't be listed: {e} No s'han pogut llistar els identificadors digitals del Clauer: {e} + Signed and saved to {path} Signat i desat a {path} + Couldn't open revision {n}: {e} No s'ha pogut obrir la revisió {n}: {e} + Couldn't open the signed version: {e} No s'ha pogut obrir la versió signada: {e} + Sign with a Digital ID Signa amb un identificador digital + Choose the digital ID that you want to use for signing: Tria l'identificador digital que vols utilitzar per signar: + Keychain · Clauer · + Windows store · Magatzem de Windows · + Issued by: Emès per: + , Expires: , caduca: + No digital IDs yet. Encara no hi ha cap identificador digital. + Configure New Digital ID Configura un identificador digital nou + Remove "{name}" from this list? The file itself is not deleted. Vols eliminar "{name}" d'aquesta llista? El fitxer en si no se suprimeix. + Continue Continua + Configure a Digital ID for Signing Configura un identificador digital per signar + Use a Digital ID from a file Utilitza un identificador digital d'un fitxer + Create a new Digital ID (self-signed, saved to a password-protected file) Crea un identificador digital nou (autosignat, desat en un fitxer protegit amb contrasenya) + Name Nom + Organizational Unit Unitat organitzativa + Organization Name Nom de l'organització + Email Address Adreça electrònica + Country/Region País/regió + Key Algorithm Algorisme de clau + Confirm Password Confirma la contrasenya + Valid for 5 years, for digital signatures. Self-signed IDs are usually not trusted by others. Vàlid durant 5 anys, per a signatures digitals. Els identificadors autosignats normalment no són de confiança per a altres persones. + File (.p12, .pfx) Fitxer (.p12, .pfx) + Digital ID Identificador digital + Browse… Navega… + {verb} as "{name}" {verb} com a "{name}" + Certify Certifica + The signature will be invisible. La signatura serà invisible. + Distinguished name Nom distingit + Labels Etiquetes + Graphic Gràfic + Signer's name Nom del signant + Fill & Sign signature Signatura d'Omple i signa + Choose image… Tria una imatge… + Permitted actions after certifying Accions permeses després de certificar + No changes allowed No es permet cap canvi + Annotations, form fill-in, and digital signatures Anotacions, emplenament de formularis i signatures digitals + Form fill-in and digital signatures Emplenament de formularis i signatures digitals + The key is in the macOS Keychain, which may ask to allow PdfCraft to use it. La clau és al clauer de macOS, que pot demanar permís perquè PdfCraft la utilitzi. + The key is in the Windows certificate store, which may ask to allow PdfCraft to use it. La clau és al magatzem de certificats de Windows, que pot demanar permís perquè PdfCraft la utilitzi. + Digital ID password Contrasenya de l'identificador digital + Back Enrere + Validate all Valida-ho tot + Sign this field… Signa aquest camp… + Signature is valid: La signatura és vàlida: + Signature validity is UNKNOWN: La validesa de la signatura és DESCONEGUDA: + Signature is INVALID: La signatura NO és vàlida: + Signature Details Detalls de la signatura + Reason Motiu + Signing time Hora de signatura + Algorithm Algorisme + Signer Signant + Issued by Emès per + Valid Vàlid + Field Camp + Field: {field} on page {p} Camp: {field} a la pàgina {p} + Add to trusted certificates Afegeix als certificats de confiança + View signed version Mostra la versió signada + Show certificate… Mostra el certificat… + Export certificate… Exporta el certificat… + Certificate Viewer Visor de certificats + This dialog shows the details of a certificate and its chain. Aquest diàleg mostra els detalls d'un certificat i la seva cadena. + Trust Confia + Issued to Emès per a + Valid from Vàlid des de + Valid to Vàlid fins a + Intended usage Ús previst + Any Qualsevol + Version Versió + Serial number Número de sèrie + Issuer Emissor + Validity starts La validesa comença + Validity ends La validesa acaba + Public key Clau pública + Key usage Ús de la clau + Not present No present + Self-signed Autosignat + Edit Action Edita l'acció + New Action Acció nova + Action name: Nom de l'acció: + Description: Descripció: + Steps Passos + Add the steps this action runs, in order. Afegeix els passos que executa aquesta acció, per ordre. + Add Step Afegeix un pas + An action with this name already exists. Ja existeix una acció amb aquest nom. + New Action… Acció nova… + Edit… Edita… + Add watermark Afegeix una marca d'aigua + Add header Afegeix una capçalera + Add footer Afegeix un peu de pàgina + Set document title Defineix el títol del document + Run a JavaScript Executa un JavaScript + Prepare for Distribution Prepara per a la distribució + Remove hidden information and flatten comments and form fields, so recipients see only the pages. Elimina la informació oculta i aplana els comentaris i els camps de formulari, de manera que els destinataris només vegin les pàgines. + Optimize Scanned Documents Optimitza els documents escanejats + Make scans searchable, then make them smaller. Fes que els escanejats siguin cercables i després redueix-ne la mida. + Add Page Numbers Afegeix números de pàgina + Number every page in the footer. Numera cada pàgina al peu de pàgina. + Mark as Confidential Marca com a confidencial + A diagonal CONFIDENTIAL watermark on every page. Una marca d'aigua diagonal CONFIDENCIAL a cada pàgina. + Sanitize Documents Neteja els documents + Remove hidden information, metadata, scripts and embedded content, and rewrite the files. Elimina la informació oculta, les metadades, els scripts i el contingut incrustat, i reescriu els fitxers. + Type text Escriu text + Text to insert Text per inserir + Inserted text Text inserit + Replacement text Text de substitució + Edit text… Edita el text… + Add a sticky note here Afegeix aquí una nota adhesiva + {kind} Properties Propietats de {kind} + Appearance Aparença + General General + Review History Historial de revisió + This comment's appearance can't be changed yet. L'aparença d'aquest comentari encara no es pot canviar. + Icon Icona + Thickness Gruix + Line ending Final de línia + Modified Modificat + No status has been set. No s'ha definit cap estat. + Compare Files Compara fitxers + Old file: Fitxer antic: + Open the older version first Obre primer la versió més antiga + New file: Fitxer nou: + Text is compared word by word; the differences are shown on the new file. El text es compara paraula per paraula; les diferències es mostren al fitxer nou. + Compare this file with an older version: Compare files… in All tools. Compara aquest fitxer amb una versió més antiga: Compara fitxers… a Totes les eines. + No differences in the text. No hi ha diferències al text. + {n} {kind} {n} {kind} + Inserted Inserit + Deleted Suprimit + Replaced Substituït + Visual Visual + Mark as comments Marca com a comentaris + Report… Informe… + {kind} · page {p} {kind} · pàgina {p} + Set Alternate Text Defineix el text alternatiu + This document has no tagged figures. Aquest document no té figures etiquetades. + on page {p} a la pàgina {p} + Figure {i} of {n}{page} Figura {i} de {n}{page} + No preview Sense previsualització + Alternate text Text alternatiu + Describe the figure Descriu la figura + Decorative figure Figura decorativa + Previous figure Figura anterior + Next figure Figura següent + Save & Close Desa i tanca + Accessibility Checker Options Opcions del verificador d'accessibilitat + Report Options Opcions de l'informe + Create accessibility report Crea un informe d'accessibilitat + Page Range Interval de pàgines + All pages in document Totes les pàgines del document + Checking Options ({on} of 32 in all categories) Opcions de comprovació ({on} de 32 en totes les categories) + Show this dialog when the Checker starts Mostra aquest diàleg quan s'iniciï el verificador + Select All Selecciona-ho tot + Clear All Esborra-ho tot + Start Checking Inicia la comprovació + This document hasn't been checked yet. Aquest document encara no s'ha comprovat. + No issues found No s'ha trobat cap problema + 1 issue 1 problema + {n} issues {n} problemes + {label} (1 issue) {label} (1 problema) + {label} ({n} issues) {label} ({n} problemes) + Check again Torna a comprovar + Report Informe + Show the accessibility report Mostra l'informe d'accessibilitat + Collapse Replega + Expand Desplega + {rule} - {status} {rule} - {status} + Passed Superada + Failed Fallida + Needs manual check Cal comprovació manual + Skipped Omesa + Fix Corregeix + Skip Rule Omet la regla + Explain Explica + Check Again Torna a comprovar + Show Report Mostra l'informe + Options… Opcions… + Go to the page Ves a la pàgina + Page Content Contingut de la pàgina + Forms Formularis + Alternate Text Text alternatiu + Tables Taules + Lists Llistes + Headings Encapçalaments + Accessibility permission flag Indicador de permís d'accessibilitat + Accessibility permission flag is set L'indicador de permís d'accessibilitat està activat + Security settings must allow assistive technology to read the content ("Enable text access for screen reader devices"). Change the document's security to allow it. La configuració de seguretat ha de permetre que la tecnologia d'assistència llegeixi el contingut ("Enable text access for screen reader devices"). Canvia la seguretat del document per permetre-ho. + Image-only PDF PDF només d'imatge + Document is not image-only PDF El document no és un PDF només d'imatge + Pages that are only pictures of text can't be read aloud or searched. Recognize text (OCR) to add a text layer. Les pàgines que només són imatges de text no es poden llegir en veu alta ni cercar. Reconeix el text (OCR) per afegir-hi una capa de text. + Document is tagged PDF El document és un PDF etiquetat + Tags give the document a logical structure that assistive technology follows. Tag the document (Automatically tag PDF). Les etiquetes donen al document una estructura lògica que segueix la tecnologia d'assistència. Etiqueta el document (Automatically tag PDF). + Logical Reading Order Ordre de lectura lògic + Document structure provides a logical reading order L'estructura del document proporciona un ordre de lectura lògic + Check that the tags read in the order a sighted reader would. Use the Reading Order tool or the Tags panel to correct it. Comprova que les etiquetes es llegeixin en l'ordre en què ho faria un lector amb visió. Utilitza l'eina d'ordre de lectura o el tauler d'etiquetes per corregir-lo. + Primary language Idioma principal + Text language is specified S'ha especificat l'idioma del text + Screen readers choose their voice from the document's language. Set it in Document Properties > Advanced > Language. Els lectors de pantalla trien la veu segons l'idioma del document. Defineix-lo a Propietats del document > Avançat > Idioma. + Document title is showing in title bar El títol del document es mostra a la barra de títol + The window should show a meaningful title rather than the file name. Set a title and Initial View > Show: Document Title. La finestra hauria de mostrar un títol significatiu en lloc del nom del fitxer. Defineix un títol i Visualització inicial > Mostra: Títol del document. + Bookmarks are present in large documents Hi ha marcadors en documents grans + Documents of more than 20 pages need bookmarks for navigation. Add bookmarks for the main sections. Els documents de més de 20 pàgines necessiten marcadors per navegar-hi. Afegeix marcadors per a les seccions principals. + Color contrast Contrast de color + Document has appropriate color contrast El document té un contrast de color adequat + Text must contrast enough with its background for people with low vision. Check the colours by eye or with a contrast tool. El text ha de contrastar prou amb el fons per a les persones amb baixa visió. Comprova els colors a ull o amb una eina de contrast. + Tagged content Contingut etiquetat + All page content is tagged Tot el contingut de la pàgina està etiquetat + Everything on a page must be tagged or marked as an artifact (decoration, headers, footers). Tag the untagged content. Tot el que hi ha en una pàgina ha d'estar etiquetat o marcat com a artefacte (decoració, capçaleres, peus de pàgina). Etiqueta el contingut sense etiquetar. + Tagged annotations Anotacions etiquetades + All annotations are tagged Totes les anotacions estan etiquetades + Comments, links and fields must be in the tag tree to be announced. Tag the annotations. Els comentaris, els enllaços i els camps han de ser a l'arbre d'etiquetes perquè es puguin anunciar. Etiqueta les anotacions. + Tab order Ordre de tabulació + Tab order is consistent with structure order L'ordre de tabulació coincideix amb l'ordre de l'estructura + Pages with links, comments or fields should tab in structure order. The fix sets each page's tab order to Use Document Structure. Les pàgines amb enllaços, comentaris o camps haurien de tabular segons l'ordre de l'estructura. La correcció estableix l'ordre de tabulació de cada pàgina a Utilitza l'estructura del document. + Character encoding Codificació de caràcters + Reliable character encoding is provided Es proporciona una codificació de caràcters fiable + Fonts must map their characters to Unicode so text can be read and copied. Fix the fonts or recreate the PDF. Els tipus de lletra han d'associar els seus caràcters a Unicode perquè el text es pugui llegir i copiar. Corregeix els tipus de lletra o torna a crear el PDF. + Tagged multimedia Multimèdia etiquetada + All multimedia objects are tagged Tots els objectes multimèdia estan etiquetats + Video, sound and rich media must be tagged to be announced. Tag the multimedia annotations. El vídeo, el so i el contingut multimèdia enriquit han d'estar etiquetats per ser anunciats. Etiqueta les anotacions multimèdia. + Screen flicker Parpelleig de pantalla + Page will not cause screen flicker La pàgina no provocarà parpelleig de pantalla + Animation that flashes can cause seizures. Check scripts and media for flicker. Les animacions amb llampecs poden provocar convulsions. Revisa els scripts i el contingut multimèdia per detectar parpelleig. + Scripts Scripts + No inaccessible scripts Cap script inaccessible + Timed responses Respostes cronometrades + Page does not require timed responses La pàgina no requereix respostes cronometrades + People may need more time to respond. Check that nothing has a time limit. És possible que les persones necessitin més temps per respondre. Comprova que res tingui un límit de temps. + Navigation links Enllaços de navegació + Navigation links are not repetitive Els enllaços de navegació no són repetitius + Repeated navigation links should be skippable. Check links that appear on every page. Els enllaços de navegació repetits haurien de poder-se ometre. Revisa els enllaços que apareixen a totes les pàgines. + Tagged form fields Camps de formulari etiquetats + All form fields are tagged Tots els camps de formulari estan etiquetats + Form fields must be in the tag tree (Form tags) to be announced. Tag the form fields. Els camps de formulari han de ser a l'arbre d'etiquetes (etiquetes Form) per ser anunciats. Etiqueta els camps de formulari. + Field descriptions Descripcions dels camps + All form fields have description Tots els camps de formulari tenen descripció + Each field needs a tooltip that says what to enter. Add one in Field Properties > General > Tooltip. Cada camp necessita un suggeriment que digui què cal introduir. Afegeix-ne un a Propietats del camp > General > Suggeriment. + Figures alternate text Text alternatiu de les figures + Figures require alternate text Les figures requereixen text alternatiu + Pictures need alternate text that describes them, or must be marked decorative. Add alternate text to each figure. Les imatges necessiten un text alternatiu que les descrigui, o s'han de marcar com a decoratives. Afegeix text alternatiu a cada figura. + Nested alternate text Text alternatiu imbricat + Alternate text that will never be read Text alternatiu que mai es llegirà + Alternate text inside an element that already has alternate text is never read. Remove the inner alternate text. El text alternatiu dins d'un element que ja en té mai es llegeix. Elimina el text alternatiu interior. + Associated with content Associat amb contingut + Alternate text must be associated with some content El text alternatiu ha d'estar associat amb algun contingut + Alternate text on an element without page content is never reached. Remove it or attach the element to content. El text alternatiu d'un element sense contingut de pàgina mai s'assoleix. Elimina'l o vincula l'element a contingut. + Hides annotation Amaga l'anotació + Alternate text should not hide annotation El text alternatiu no hauria d'amagar l'anotació + Alternate text on an element that contains a link or field hides that annotation from assistive technology. Move the alternate text. El text alternatiu d'un element que conté un enllaç o un camp amaga aquesta anotació a la tecnologia d'assistència. Mou el text alternatiu. + Other elements alternate text Text alternatiu d'altres elements + Other elements that require alternate text Altres elements que requereixen text alternatiu + Formulas and similar non-text elements need alternate text. Add alternate text to them. Les fórmules i altres elements que no són text necessiten text alternatiu. Afegeix-hi text alternatiu. + Rows Files + TR must be a child of Table, THead, TBody, or TFoot TR ha de ser fill de Table, THead, TBody o TFoot + Table cells belong in a row. Fix the table's tags. Les cel·les de taula pertanyen a una fila. Corregeix les etiquetes de la taula. + Headers Capçaleres + Tables should have headers Les taules haurien de tenir capçaleres + Header cells (TH) tell listeners what each column or row holds. Mark the header cells. Les cel·les de capçalera (TH) indiquen als oients què conté cada columna o fila. Marca les cel·les de capçalera. + Regularity Regularitat + Tables must contain the same number of columns in each row and rows in each column Les taules han de contenir el mateix nombre de columnes a cada fila i de files a cada columna + Irregular tables confuse cell navigation. Give every row the same number of cells (counting spans). Les taules irregulars confonen la navegació per cel·les. Dona a cada fila el mateix nombre de cel·les (comptant els abastos). + Summary Resum + Tables must have a summary Les taules han de tenir un resum + A summary describes the table's purpose and layout. Add a Summary attribute to each table. Un resum descriu la finalitat i la disposició de la taula. Afegeix un atribut Summary a cada taula. + List items Elements de llista + LI must be a child of L LI ha de ser fill de L + List items belong in a list. Fix the list's tags. Els elements de llista pertanyen a una llista. Corregeix les etiquetes de la llista. + Lbl and LBody Lbl i LBody + Lbl and LBody must be children of LI Lbl i LBody han de ser fills de LI + List labels and bodies belong in a list item. Fix the list's tags. Les etiquetes i els cossos de llista pertanyen a un element de llista. Corregeix les etiquetes de la llista. + Appropriate nesting Imbricació adequada + Heading levels shouldn't skip (an H1 followed by an H3). Retag the headings. Els nivells d'encapçalament no s'haurien de saltar (un H1 seguit d'un H3). Torna a etiquetar els encapçalaments. + TH and TD TH i TD + TH and TD must be children of TR TH i TD han de ser fills de TR + Mark Page Range Marca l'interval de pàgines + Pages from Pàgines des de + Single word or phrase Una sola paraula o frase + Text to find Text que cal cercar + Patterns Patrons + Phone Numbers Números de telèfon + Email Addresses Adreces de correu electrònic + Credit Cards Targetes de crèdit + Social Security Numbers Números de la seguretat social + Dates Dates + Text in images isn't found; recognise text (OCR) first. El text de les imatges no es troba; reconeix el text (OCR) primer. + No matches. Cap coincidència. + Some bookmarks are not shown here: the panel lists a limited number, nested a limited depth. Alguns marcadors no es mostren aquí: el tauler en llista un nombre limitat, imbricats fins a una profunditat limitada. + {n} match(es) marked for redaction. {n} coincidència(es) marcada(es) per censurar. + Multiple words or phrases Diverses paraules o frases + One word or phrase per line Una paraula o frase per línia + Import list… Importa una llista… + {n} word(s) or phrase(s) {n} paraula(es) o frase(s) + {name} is too large for a word list (at most 1 MB). {name} és massa gran per a una llista de paraules (com a màxim 1 MB). + Redaction Tool Properties Propietats de l'eina de censura + Redacted area fill colour: Color d'emplenament de l'àrea censurada: + Use overlay text Utilitza text superposat + Custom text: Text personalitzat: + Redaction code: Codi de censura: + Font: Tipus de lletra: + Font size: Mida del tipus de lletra: + Auto-size text to fit redaction region Ajusta automàticament la mida del text a la regió censurada + Font colour: Color del tipus de lletra: + Repeat overlay text Repeteix el text superposat + Text alignment: Alineació del text: + Center Centrat + Apply redactions Aplica les censures + You are about to apply 1 redaction mark. Text, images and drawings under the marks, and comments and form fields that overlap them, are removed permanently. Estàs a punt d'aplicar 1 marca de censura. El text, les imatges i els dibuixos que hi ha sota les marques, i els comentaris i camps de formulari que se superposen, se suprimeixen de manera permanent. + You are about to apply {n} redaction marks. Text, images and drawings under the marks, and comments and form fields that overlap them, are removed permanently. Estàs a punt d'aplicar {n} marques de censura. El text, les imatges i els dibuixos que hi ha sota les marques, i els comentaris i camps de formulari que se superposen, se suprimeixen de manera permanent. + Save the document afterwards: saving rewrites the whole file so no trace of the removed content stays in it. Desa el document després: en desar, es reescriu tot el fitxer perquè no hi quedi cap rastre del contingut suprimit. + Select the items to remove from this document. Selecciona els elements que s'han d'eliminar d'aquest document. + Metadata Metadades + File attachments Fitxers adjunts + Comments and markups Comentaris i marques + Hidden text Text ocult + Hidden layers Capes ocultes + Links, actions and JavaScripts Enllaços, accions i JavaScripts + Private data of other applications Dades privades d'altres aplicacions + None found No se n'ha trobat cap + Form fields are flattened: their values stay visible. Saving rewrites the whole file. Els camps de formulari s'aplanen: els valors continuen visibles. En desar, es reescriu tot el fitxer. + Remove Elimina + Sanitizing removes hidden information from the document: metadata, file attachments, comments, form fields (flattened), hidden text and layers, bookmarks, links, actions and scripts, and private application data. La neteja elimina la informació oculta del document: metadades, fitxers adjunts, comentaris, camps de formulari (aplanats), text i capes ocults, marcadors, enllaços, accions i scripts, i dades privades d'aplicacions. + Save the document afterwards; saving rewrites the whole file so nothing removed stays in it. Desa el document després; en desar, es reescriu tot el fitxer perquè no hi quedi res del que s'ha eliminat. + Printer: Impressora: + Save as PDF Anomena i desa com a PDF + {name} (default) {name} (per defecte) + Copies: Còpies: + Collate Intercala + Print in grayscale Imprimeix en escala de grisos + Two-sided: A doble cara: + Off Desactivat + Flip on long edge Gira pel costat llarg + Flip on short edge Gira pel costat curt + Paper: Paper: + Pages to Print Pàgines per imprimir + More options: Més opcions: + All pages in range Totes les pàgines de l'interval + Odd pages only Només les pàgines senars + Even pages only Només les pàgines parelles + Reverse pages Inverteix les pàgines + Page Sizing & Handling Mida i gestió de les pàgines + Size Mida + Poster Pòster + Multiple Múltiple + Booklet Quadern + Fit Ajusta + Shrink oversized pages Redueix les pàgines que no hi caben + Custom scale: Escala personalitzada: + Tile scale: Escala de mosaic: + Overlap: Superposició: + Cut marks Marques de tall + Pages per sheet: Pàgines per full: + Page order: Ordre de les pàgines: + Horizontal Horitzontal + Horizontal reversed Horitzontal invertit + Vertical Vertical + Vertical reversed Vertical invertit + Print page border Imprimeix la vora de la pàgina + Auto-rotate pages Gira les pàgines automàticament + Booklet subset: Subconjunt del quadern: + Both sides Les dues cares + Front side only Només la cara anterior + Back side only Només la cara posterior + Binding: Enquadernació: + Left Esquerra + Right Dreta + Orientation: Orientació: + Auto portrait/landscape Vertical/horitzontal automàtic + Portrait Vertical + Landscape Horitzontal + Comments & Forms Comentaris i formularis + Document Document + Document and markups Document i marques + Document and stamps Document i segells + Form fields only Només els camps de formulari + Previous sheet Full anterior + Next sheet Full següent + No sheets Cap full + Sheet {s} of {n} Full {s} de {n} + Removed 1 hidden item. Save to remove them from the file. S'ha eliminat 1 element ocult. Desa per eliminar-lo del fitxer. + Removed {n} hidden items. Save to remove them from the file. S'han eliminat {n} elements ocults. Desa per eliminar-los del fitxer. + Document sanitized. Save to finish: saving rewrites the whole file. Document netejat. Desa per acabar: en desar, es reescriu tot el fitxer. + Applied 1 redaction mark. Save to remove the content from the file. S'ha aplicat 1 marca de censura. Desa per eliminar el contingut del fitxer. + Applied {n} redaction marks. Save to remove the content from the file. S'han aplicat {n} marques de censura. Desa per eliminar el contingut del fitxer. + JavaScript Console Consola de JavaScript + JavaScript is turned off (Preferences ▸ JavaScript). JavaScript està desactivat (Preferències > JavaScript). + Output appears here. La sortida apareix aquí. + Script Name: Nom de l'script: + This document has no document-level scripts. Aquest document no té scripts a nivell de document. + No form fields were detected No s'ha detectat cap camp de formulari + Detected 1 form field S'ha detectat 1 camp de formulari + Detected {n} form fields S'han detectat {n} camps de formulari + {field}: {e} {field}: {e} + Current page Pàgina actual + Selected pages Pàgines seleccionades + Document language Idioma del document + Output Sortida + Searchable Image (Exact) Imatge amb text cercable (exacte) + Adds invisible text over each word; the page image is not changed Afegeix text invisible sobre cada paraula; la imatge de la pàgina no canvia + Downsample to Redueix la resolució a + Also recognize pages that already have text Reconeix també les pàgines que ja tenen text + Pictures on those pages are recognized too; words already in the page's text are not added again També es reconeixen les imatges d'aquestes pàgines; les paraules que ja són al text de la pàgina no es tornen a afegir + Text recognition isn't installed: its model files are missing. Reinstall PdfCraft, or set PDFCRAFT_MODELS to the folder that holds them. El reconeixement de text no està instal·lat: falten els seus fitxers de model. Reinstal·la PdfCraft o defineix PDFCRAFT_MODELS amb la carpeta que els conté. + Settings Configuració + Optional Opcional + Planned · {m} Previst · {m} + Planned for milestone {m} — open to see what it will include Previst per a la fita {m} — obre per veure què inclourà + Coming in milestone {m}. Items marked Ready work today. Arribarà a la fita {m}. Els elements marcats com a Llest funcionen avui. + 1 mark 1 marca + {n} marks {n} marques + Dynamic Dinàmic + Sign Here Signa aquí + Standard Business Empresarial estàndard + Choose a stamp, then click on the page to place it. Tria un segell i fes clic a la pàgina per col·locar-lo. + Note Nota + Polyline Polilínia + Attachment Adjunt + Callout Crida + Typewriter Màquina d'escriure + Checked Marcat + Unchecked Desmarcat + Marked Assenyalat + Locked Bloquejat + Search comments Cerca comentaris + Add a comment Afegeix un comentari + No comments yet. Encara no hi ha comentaris. + Pick a tool in the quick bar, or type above. Tria una eina a la barra ràpida o escriu a dalt. + No comments match. Cap comentari coincideix. + Unknown author Autor desconegut + No colour Sense color + Remove checkmark Elimina la marca de verificació + Mark with checkmark Marca amb una marca de verificació + Reply Respon + Add a reply Afegeix una resposta + Post Publica + Page {label} Pàgina {label} + {kind} — click to show it on the page {kind} — fes clic per mostrar-ho a la pàgina + Set status Defineix l'estat + Copy text Copia el text + Properties… Propietats… + Make Current Properties Default Estableix les propietats actuals com a per defecte + More options Més opcions + Sort by Ordena per + Author Autor + Type Tipus + Colour Color + Show all comments Mostra tots els comentaris + Create PDF comment summary… Crea un resum de comentaris en PDF… + Export all to data file… Exporta-ho tot a un fitxer de dades… + Filter comments Filtra els comentaris + Status Estat + Accepted Acceptat + Rejected Rebutjat + Cancelled Cancel·lat + Completed Completat + Show all Mostra-ho tot + Yellow Groc + Orange Taronja + Red Vermell + Pink Rosa + Purple Porpra + Blue Blau + Light blue Blau clar + Green Verd + Gray Gris + Black Negre + Bookmark options Opcions dels marcadors + Expand all bookmarks Expandeix tots els marcadors + Expand top-level bookmarks Expandeix els marcadors de primer nivell + Collapse all bookmarks Replega tots els marcadors + New bookmark ({key}) Marcador nou ({key}) + This document has no bookmarks. Aquest document no té marcadors. + This document has no layers. Aquest document no té capes. + This document has no attachments. Aquest document no té adjunts. + Hide layer Amaga la capa + Show layer Mostra la capa + Set layer visibility Defineix la visibilitat de la capa + on page {label} a la pàgina {label} + Save attachment… Desa l'adjunt… + Open in a new tab Obre en una pestanya nova + This document has no pages. Aquest document no té pàgines. + Find text Cerca text + No matches Cap coincidència + Searching… {s}/{p} Cercant… {s}/{p} + {c} of {n}{more} {c} de {n}{more} + Previous ({key}) Anterior ({key}) + Next ({key}) Següent ({key}) + Find options Opcions de cerca + Whole words only Només paraules senceres + Case-sensitive Distingeix majúscules i minúscules + Close (Esc) Tanca (Esc) + Align Alinea + Top Superior + Bottom Inferior + Center horizontally Centra horitzontalment + Center vertically Centra verticalment + Distribute Distribueix + Horizontally Horitzontalment + Vertically Verticalment + Set Fields to Same Size Estableix els camps a la mateixa mida + Height Alçada + Width Amplada + Both Ambdues + Duplicate… Duplica… + All pages Totes les pàgines + Odd pages Pàgines senars + Even pages Pàgines parelles + Landscape pages Pàgines horitzontals + Portrait pages Pàgines verticals + Move earlier Mou abans + Move later Mou després + Back to the document Torna al document + Protect Using Password Protegeix amb contrasenya + Requires user to enter a password for: Requereix que l'usuari introdueixi una contrasenya per a: + Viewing Visualització + Editing Edició + Type Password Escriu la contrasenya + Re-type Password Torna a escriure la contrasenya + Strength: {s} Fortalesa: {s} + Strong Forta + Medium Mitjana + Weak Feble + Advanced Options {chevron} Opcions avançades {chevron} + Compatibility Compatibilitat + Acrobat X and later (256-bit AES) Acrobat X i posteriors (AES de 256 bits) + Acrobat 7.0 and later (128-bit AES) Acrobat 7.0 i posteriors (AES de 128 bits) + Acrobat 5.0 and later (128-bit RC4) Acrobat 5.0 i posteriors (RC4 de 128 bits) + Acrobat 3.0 and later (40-bit RC4) Acrobat 3.0 i posteriors (RC4 de 40 bits) + Encrypt Xifra + All document contents Tot el contingut del document + All document contents except metadata Tot el contingut del document excepte les metadades + Printing allowed Impressió permesa + Low Resolution (150 dpi) Baixa resolució (150 dpi) + Changes allowed Canvis permesos + Inserting, deleting, and rotating pages Inserció, supressió i gir de pàgines + Filling in form fields and signing existing signature fields Emplenament de camps de formulari i signatura de camps de signatura existents + Commenting, filling in form fields, and signing existing signature fields Comentaris, emplenament de camps de formulari i signatura de camps de signatura existents + Any except extracting pages Qualsevol excepte l'extracció de pàgines + Enable copying of text, images, and other content Permet copiar text, imatges i altre contingut + Enable text access for screen reader devices for the visually impaired Permet l'accés al text als lectors de pantalla per a persones amb discapacitat visual + Type a password. Escriu una contrasenya. + The passwords don't match. Les contrasenyes no coincideixen. + This compatibility level supports only plain ASCII passwords. Aquest nivell de compatibilitat només admet contrasenyes en ASCII simple. + Anyone opening the document will need this password. It's applied when you save. Qualsevol persona que obri el document necessitarà aquesta contrasenya. S'aplica en desar. + The document opens without a password; this password is needed to change the restrictions. It's applied when you save. El document s'obre sense contrasenya; aquesta contrasenya cal per canviar les restriccions. S'aplica en desar. + Recover unsaved documents? Vols recuperar els documents no desats? + PdfCraft didn't shut down normally. These documents had changes that were autosaved: PdfCraft no s'ha tancat amb normalitat. Aquests documents tenien canvis desats automàticament: + just now ara mateix + {n} min ago fa {n} min + {n} h ago fa {n} h + · password-protected · protegit amb contrasenya + Recover Recupera + Discard Descarta + Version {v} Versió {v} + A clean-room, open-source PDF application written in Rust. MIT OR Apache-2.0. Una aplicació PDF de codi obert i clean-room escrita en Rust. MIT OR Apache-2.0. + Part of Part de + Summarize Options Opcions de resum + Choose a layout: Tria una disposició: + Comments only Només comentaris + Sort comments by: Ordena els comentaris per: + Create PDF Comment Summary Crea un resum de comentaris en PDF + Revert to the previously saved version of “{name}”? Changes since then can't be undone afterwards. Vols revertir a la versió desada anteriorment de “{name}”? Els canvis fets des d'aleshores no es podran desfer després. + Number pages Numera les pàgines + Style Estil + None (prefix only) Cap (només prefix) + Prefix Prefix + Start Inici + Labels: {preview}. Later pages keep their labels. Etiquetes: {preview}. Les pàgines posteriors mantenen les seves etiquetes. + Even and Odd Pages Pàgines parelles i senars + Even Pages Only Només pàgines parelles + Odd Pages Only Només pàgines senars + Landscape and Portrait Pages Pàgines horitzontals i verticals + Landscape Pages Pàgines horitzontals + Portrait Pages Pàgines verticals + Duplicate Field Duplica el camp + Duplicate "{name}" onto: Duplica "{name}" a: + 1 page selected. 1 pàgina seleccionada. + {n} pages selected. {n} pàgines seleccionades. + Delete pages after extracting Suprimeix les pàgines després d'extreure-les + Extract pages as separate files Extreu les pàgines com a fitxers separats + Rotate Pages Gira les pàgines + Direction: Direcció: + Clockwise 90 degrees 90 graus en sentit horari + Counterclockwise 90 degrees 90 graus en sentit antihorari + 180 degrees 180 graus + Pages: Pàgines: + All Totes + Selection Selecció + From Des de + Rotate: Gira: + Repairs Reparacions + Repair log Registre de reparacions + Split document Divideix el document + Number of pages Nombre de pàgines + Pages per file Pàgines per fitxer + File size Mida del fitxer + At most Com a màxim + Top-level bookmarks ({n}) Marcadors de primer nivell ({n}) + Before each selected page (select pages in Organize) Abans de cada pàgina seleccionada (selecciona pàgines a Organitza) + Creates 1 file from {n} pages. Crea 1 fitxer a partir de {n} pàgines. + Creates {f} files from {n} pages. Crea {f} fitxers a partir de {n} pàgines. + Each file holds as many of the {n} pages as fit. Cada fitxer conté tantes de les {n} pàgines com hi càpiguen. + Replace Pages Substitueix pàgines + Original: replace pages Original: substitueix les pàgines + to a + to {n} a {n} + Replacement: pages of {name} Substitució: pàgines de {name} + of {name} de {name} + Only the page content changes: links, comments, form fields and bookmarks on the original pages stay. Només canvia el contingut de la pàgina: els enllaços, comentaris, camps de formulari i marcadors de les pàgines originals es mantenen. + The replacement file doesn't have that many pages. El fitxer de substitució no té tantes pàgines. + Tagged PDF PDF etiquetat + Document Properties Propietats del document + Description Descripció + Initial View Visualització inicial + Security Seguretat + Fonts Tipus de lletra + Advanced Avançat + Title Títol + Subject Assumpte + Keywords Paraules clau + Application Aplicació + PDF producer Productor del PDF + Layout and Magnification Disposició i ampliació + Navigation tab Pestanya de navegació + Page Only Només la pàgina + Bookmarks Panel and Page Tauler de marcadors i pàgina + Pages Panel and Page Tauler de pàgines i pàgina + Attachments Panel and Page Tauler d'adjunts i pàgina + Layers Panel and Page Tauler de capes i pàgina + Page layout Disposició de la pàgina + Default Per defecte + Single Page Pàgina única + Single Page Continuous Pàgina única contínua + Two-Up (Facing) Dues pàgines (enfrontades) + Two-Up Continuous (Facing) Dues pàgines contínues (enfrontades) + Two-Up (Cover Page) Dues pàgines (amb coberta) + Two-Up Continuous (Cover Page) Dues pàgines contínues (amb coberta) + Magnification Ampliació + Actual Size Mida real + Fit Page Ajusta a la pàgina + Fit Width Ajusta a l'amplada + Fit Height Ajusta a l'alçada + Fit Visible Ajusta a la part visible + Open to page Obre a la pàgina + of {pages} de {pages} + Window Options Opcions de finestra + Resize window to initial page Redimensiona la finestra a la pàgina inicial + Center window on screen Centra la finestra a la pantalla + Open in Full Screen mode Obre en mode de pantalla completa + Show: Mostra: + File Name Nom del fitxer + Document Title Títol del document + User Interface Options Opcions de la interfície d'usuari + Hide menu bar Amaga la barra de menús + Hide toolbars Amaga les barres d'eines + Hide window controls Amaga els controls de la finestra + Security method Mètode de seguretat + No security Sense seguretat + Restrictions Restriccions + None — everything is allowed Cap — tot està permès + Password security Seguretat amb contrasenya + Encryption Xifratge + Opened with S'ha obert amb + — (protection is applied when you save) — (la protecció s'aplica en desar) + Owner password (no restrictions apply) Contrasenya del propietari (no s'aplica cap restricció) + User password Contrasenya de l'usuari + Change settings… Canvia la configuració… + Printing Impressió + Not allowed No permès + Allowed Permès + High resolution Alta resolució + Low resolution Baixa resolució + Changing the document Canvi del document + Document assembly Assemblatge del document + Content copying Còpia del contingut + Content copying for accessibility Còpia del contingut per a l'accessibilitat + Commenting Comentaris + Filling of form fields Emplenament de camps de formulari + No fonts are referenced by the pages. Les pàgines no fan referència a cap tipus de lletra. + PDF version Versió del PDF + Location Ubicació + Page size Mida de la pàgina + Yes Sí + No No + Revisions Revisions + View revision {n} Mostra la revisió {n} + Open the file as it was saved then Obre el fitxer tal com es va desar aleshores + Binding Enquadernació + Left Edge Vora esquerra + Right Edge Vora dreta + Language Idioma + Saved {place}: {before} → {after} ({pct}% smaller){detail} S'ha desat {place}: {before} → {after} ({pct} % més petit){detail} + This file is already as small as it can be made ({size}). No copy was saved. Aquest fitxer ja és tan petit com es pot fer ({size}). No s'ha desat cap còpia. + Saved {place}: {before} → {after} (not smaller){detail} S'ha desat {place}: {before} → {after} (no és més petit){detail} + Couldn't save the image: {e} No s'ha pogut desar la imatge: {e} + Adding images arrives on the web with file pickers for images L'addició d'imatges arribarà al web amb selectors de fitxers d'imatge + Replacing images on page {p} arrives on the web with image pickers ({i}) La substitució d'imatges a la pàgina {p} arribarà al web amb selectors d'imatges ({i}) + {name}: choosing images arrives on the web with file pickers for images {name}: la selecció d'imatges arribarà al web amb selectors de fitxers d'imatge + Replacing images arrives on the web with image file pickers La substitució d'imatges arribarà al web amb selectors de fitxers d'imatge + Couldn't create a PDF: {e} No s'ha pogut crear un PDF: {e} + The clipboard has no image or text El porta-retalls no té cap imatge ni text + On the web, open or drop an image to convert it Al web, obre o deixa anar una imatge per convertir-la + Couldn't optimize the file: {e} No s'ha pogut optimitzar el fitxer: {e} + Couldn't write {path}: {e} No s'ha pogut escriure {path}: {e} + The form asks to be submitted to {u}; PdfCraft doesn't send form data. Save the document to keep your entries. El formulari demana que s'enviï a {u}; PdfCraft no envia dades de formularis. Desa el document per conservar les dades introduïdes. + This PDF uses the unsupported {s} action. Aquest PDF utilitza l'acció {s}, que no és compatible. + {name}: the {other} action isn't supported yet {name}: l'acció {other} encara no és compatible + {name} submits the form to {url}; PdfCraft doesn't send form data. Save the document to keep your entries. {name} envia el formulari a {url}; PdfCraft no envia dades de formularis. Desa el document per conservar les dades introduïdes. + Export stopped: {e} Exportació aturada: {e} + Exported 1 image S'ha exportat 1 imatge + Exported {n} images S'han exportat {n} imatges + ({s} not exported: {first}) ({s} no s'han exportat: {first}) + Exported the text of 1 page S'ha exportat el text d'1 pàgina + Exported the text of {n} pages S'ha exportat el text de {n} pàgines + {msg} to {dir} {msg} a {dir} + Exporting… {d} of {t} Exportant… {d} de {t} + Choose a folder for the exported files Tria una carpeta per als fitxers exportats + New {tool} comments will look like this one Els comentaris nous de {tool} tindran aquest aspecte + This document can't be checked: it couldn't be read for editing No es pot comprovar aquest document: no s'ha pogut llegir per editar-lo + The checker found no problems in this document. El verificador no ha trobat cap problema en aquest document. + The checker found 1 problem which may prevent the document from being fully accessible. El verificador ha trobat 1 problema que pot impedir que el document sigui totalment accessible. + The checker found {n} problems which may prevent the document from being fully accessible. El verificador ha trobat {n} problemes que poden impedir que el document sigui totalment accessible. + The text is the same El text és el mateix + 1 difference found S'ha trobat 1 diferència + {n} differences found S'han trobat {n} diferències + Added 1 comment S'ha afegit 1 comentari + Added {n} comments S'han afegit {n} comentaris + Choose a folder for the results Tria una carpeta per als resultats + Files for {name} Fitxers de {name} + An action is already running Ja hi ha una acció en execució + Running action… file {d} of {t} Executant l'acció… fitxer {d} de {t} + No unlinked web addresses were found in the text No s'ha trobat cap adreça web sense enllaç al text + Created 1 link S'ha creat 1 enllaç + Created {n} links S'han creat {n} enllaços + Text recognition is already running El reconeixement de text ja s'està executant + Optimizing… removing user data Optimitzant… eliminant les dades d'usuari + Optimizing… image {d} of {t} Optimitzant… imatge {d} de {t} + Optimizing… cleaning up Optimitzant… netejant + Optimizing… merging identical objects Optimitzant… combinant objectes idèntics + Optimizing… writing the copy Optimitzant… escrivint la còpia + Cancelling… Cancel·lant… + Optimization is already running L'optimització ja s'està executant + Optimization cancelled Optimització cancel·lada + Couldn't optimize the file No s'ha pogut optimitzar el fitxer + Recognizing text… file {d} of {t} Reconeixent text… fitxer {d} de {t} + Recognizing text… page {d} of {t} Reconeixent text… pàgina {d} de {t} + Recognized 1 word S'ha reconegut 1 paraula + Recognized {n} words S'han reconegut {n} paraules + {words} on {pages} {words} a {pages} + ; 1 page already had text ; 1 pàgina ja tenia text + ; {n} pages already had text ; {n} pàgines ja tenien text + Recognized {w} words in 1 file S'han reconegut {w} paraules en 1 fitxer + Recognized {w} words in {n} files S'han reconegut {w} paraules en {n} fitxers + ; failed: {list} ; ha fallat: {list} + 1 file done 1 fitxer fet + {n} files done {n} fitxers fets + The selected area has been copied ({w} × {h} pixels) S'ha copiat l'àrea seleccionada ({w} × {h} píxels) + Couldn't take the snapshot: {e} No s'ha pogut fer la captura: {e} + Couldn't recover {name}: {e} No s'ha pogut recuperar {name}: {e} + The document now conforms to {level}; save it to keep the changes El document ara compleix {level}; desa'l per conservar els canvis + Fixed what could be fixed; 1 problem remains S'ha corregit el que s'ha pogut; queda 1 problema + Fixed what could be fixed; {n} problems remain S'ha corregit el que s'ha pogut; queden {n} problemes + Custom stamps arrive on the web with file pickers for images Els segells personalitzats arriben a la web amb selectors de fitxers per a les imatges + {file} is too large for a stamp (at most {n} MB) {file} és massa gran per a un segell (com a màxim {n} MB) + Sent to {printer} Enviat a {printer} + Sent to {printer}: {msg} Enviat a {printer}: {msg} + Looking for printers… Cercant impressores… + Sending to {printer}… Enviant a {printer}… + Choose a folder for the searchable files Tria una carpeta per als fitxers amb text cercable + Files are combined in this order. Leave Pages empty to take every page. Els fitxers es combinen en aquest ordre. Deixa Pàgines en blanc per agafar totes les pàgines. + Files are combined from top to bottom. Leave Pages empty to take every page. Els fitxers es combinen de dalt a baix. Deixa Pàgines en blanc per agafar totes les pàgines. + Unlock… Desbloqueja… + Select a password-protected file first Selecciona primer un fitxer protegit amb contrasenya + Enter the permissions password to allow combining Introdueix la contrasenya de permisos per permetre la combinació + Enter the password that opens it Introdueix la contrasenya que l'obre + Unlock {name} Desbloqueja {name} + Unlock {n} files Desbloqueja {n} fitxers + The same password is tried on each file. Es prova la mateixa contrasenya a cada fitxer. + Hide password Amaga la contrasenya + Show password Mostra la contrasenya + Wrong password Contrasenya incorrecta + The password is only used to read the file; it isn't saved. La contrasenya només s'utilitza per llegir el fitxer; no es desa. + Unlock Desbloqueja + Opened, but its security settings don't allow combining. Enter the permissions password. S'ha obert, però la seva configuració de seguretat no permet combinar. Introdueix la contrasenya de permisos. + Unlocked: the combined file won't be password-protected Desbloquejat: el fitxer combinat no estarà protegit amb contrasenya + Unlocked {n} of {m} files S'han desbloquejat {n} de {m} fitxers + Drop PDFs, images, text files or folders here, or choose them. Deixa aquí PDF, imatges, fitxers de text o carpetes, o tria'ls. + Add folder… Afegeix una carpeta… + Add folder and subfolders… Afegeix una carpeta i les subcarpetes… + More ways to add files Més maneres d'afegir fitxers + Every PDF, image and text file in the folder Tots els PDF, imatges i fitxers de text de la carpeta + Every PDF, image and text file in the folder and the folders inside it Tots els PDF, imatges i fitxers de text de la carpeta i de les carpetes que conté + Add folder Afegeix una carpeta + Add folder and subfolders Afegeix una carpeta i les subcarpetes + No PDFs, images or text files found in {folder} No s'ha trobat cap PDF, imatge ni fitxer de text a {folder} + Added the first {n} files in {folder} S'han afegit els primers {n} fitxers de {folder} +comment menu Edit Edita + Undo {action} Desfés {action} + Redo {action} Refés {action} +certificate Subject Subjecte +action wizard Start Inicia + Click to sort, drag to move the column. Drag its edge to resize it. Fes clic per ordenar i arrossega per moure la columna. Arrossega'n la vora per canviar-ne la mida. + Reset columns Restableix les columnes + Remove {n} files Elimina {n} fitxers + {n} selected {n} seleccionats + sorted ascending ordenat de manera ascendent + sorted descending ordenat de manera descendent + Protected: the combined file won't keep its security settings Protegit: el fitxer combinat no conservarà la configuració de seguretat + Add open documents Afegeix els documents oberts + All open documents Tots els documents oberts + No documents are open No hi ha cap document obert + Select a file first Selecciona primer un fitxer + 1 file 1 fitxer + {n} files {n} fitxers + 1 file needs attention 1 fitxer requereix atenció + {n} files need attention {n} fitxers requereixen atenció + {name} can't be combined: {why} {name} no es pot combinar: {why} + Check the pages of {name}: {why} Comprova les pàgines de {name}: {why} + Add the files to combine Afegeix els fitxers que vulguis combinar + File name Nom del fitxer + Warnings Avisos + Drag to reorder Arrossega per reordenar + {k} of {n} {k} de {n} + ? of {n} ? de {n} + Added more than once Afegit més d'una vegada + yesterday ahir + {n} days ago fa {n} dies + No pages selected Cap pàgina seleccionada + Password-protected Protegit amb contrasenya + Its security settings don't allow copying pages La seva configuració de seguretat no permet copiar pàgines + Can't be read: {e} No es pot llegir: {e} + Leave out files that can't be read? Vols excloure els fitxers que no es poden llegir? + These files can't be read, so they won't be in the combined PDF: Aquests fitxers no es poden llegir, de manera que no apareixeran al PDF combinat: + Combine the rest Combina la resta + and {n} more i {n} més + Includes unsaved changes Inclou canvis sense desar + Pages of {name} to combine, e.g. 1-3, 6 Pàgines de {name} que cal combinar, p. ex. 1-3, 6 + Remove {name} Elimina {name} + Add files… Afegeix fitxers… + Add at least two files Afegeix almenys dos fitxers + Couldn't add {name}: {e} No s'ha pogut afegir {name}: {e} + Couldn't combine files: {e} No s'han pogut combinar els fitxers: {e} + Export comments Exporta els comentaris + Export form data Exporta les dades del formulari + Comment and form data Dades de comentaris i formularis + Export Exporta + Select data files to merge Selecciona els fitxers de dades que vols combinar + Form data and PDF forms Dades de formulari i formularis PDF + Save the spreadsheet Desa el full de càlcul + Save the accessibility report Desa l'informe d'accessibilitat + Save image Desa la imatge + Export certificate Exporta el certificat + Choose a folder for the extracted pages Tria una carpeta per a les pàgines extretes + Choose a folder for the split files Tria una carpeta per als fitxers dividits + Couldn't use {name}: {e} No s'ha pogut utilitzar {name}: {e} + Couldn't extract pages: {e} No s'han pogut extreure les pàgines: {e} + Couldn't write {name}: {e} No s'ha pogut escriure {name}: {e} + Wrote 1 file to {dir} S'ha escrit 1 fitxer a {dir} + Wrote {n} files to {dir} S'han escrit {n} fitxers a {dir} + No pages match those choices Cap pàgina coincideix amb aquestes opcions + Couldn't split: {e} No s'ha pogut dividir: {e} + Couldn't summarize comments: {e} No s'han pogut resumir els comentaris: {e} + Couldn't open the result: {e} No s'ha pogut obrir el resultat: {e} + Importing data arrives on the web with file pickers for data files La importació de dades arriba a la web amb selectors de fitxers per als fitxers de dades + Exported to {path} Exportat a {path} + Merging data files needs the desktop app Combinar fitxers de dades requereix l'aplicació d'escriptori + Merged 1 file into {path} S'ha combinat 1 fitxer a {path} + Merged {n} files into {path} S'han combinat {n} fitxers a {path} + Combined {n} files S'han combinat {n} fitxers + Extracted 1 page S'ha extret 1 pàgina + Extracted {n} pages S'han extret {n} pàgines + Created a comment summary S'ha creat un resum de comentaris + Couldn't open {name}: {e} No s'ha pogut obrir {name}: {e} + Couldn't read {name}: {e} No s'ha pogut llegir {name}: {e} + Portable mode is off: {folder} can't be written ({error}). Settings are kept in your user folder instead. El mode portàtil està desactivat: no es pot escriure a {folder} ({error}). La configuració es conserva a la carpeta d'usuari. + PdfCraft is drawing without a graphics processor, so it may be slow. Updating the graphics driver may help. PdfCraft dibuixa sense processador gràfic, de manera que pot anar lent. Pot ajudar actualitzar el controlador gràfic. + Couldn't save: {e} No s'ha pogut desar: {e} + Downloading attachments on the web arrives with M3.10 ({n} bytes ready) La baixada d'adjunts a la web arriba amb M3.10 ({n} bytes preparats) + `{command}` {when} `{command}` {when} + ships in milestone {m} arriba a la fita {m} + needs an AI provider (off by default) requereix un proveïdor d'IA (desactivat per defecte) + is available està disponible + is not available yet encara no està disponible + {label} failed: {e} {label} ha fallat: {e} + Undid {label} S'ha desfet {label} + Redid {label} S'ha refet {label} + A document needs at least one page: copy instead Un document necessita almenys una pàgina: copia-la en lloc de retallar-la + Cut {what} S'ha retallat {what} + Copied {what} S'ha copiat {what} + 1 page 1 pàgina + {n} pages {n} pàgines + Copy or cut pages first Copia o retalla primer unes pàgines + Couldn't save {name}: {e} No s'ha pogut desar {name}: {e} + Saved {name} S'ha desat {name} + Saved, but reopening failed: {e} S'ha desat, però no s'ha pogut tornar a obrir: {e} + Downloaded {name} S'ha baixat {name} + Couldn't download {name}: {e} No s'ha pogut baixar {name}: {e} + Reverted to the last saved version S'ha revertit a l'última versió desada + That didn't work: an internal error stopped it ({m}). Your documents are unchanged. Això no ha funcionat: un error intern l'ha aturat ({m}). Els teus documents no s'han modificat. + Nothing to undo No hi ha res per desfer + Nothing to redo No hi ha res per refer + This document has no form fields you can fill in Aquest document no té camps de formulari que es puguin emplenar + This document has no comments to flatten Aquest document no té comentaris per aplanar + This document has no form fields to flatten Aquest document no té camps de formulari per aplanar + There are no redaction marks (mark text, areas or pages first) No hi ha marques de censura (marca primer text, àrees o pàgines) + This document has no {kind} to change Aquest document no té cap {kind} per canviar + header or footer capçalera o peu de pàgina + watermark marca d'aigua + background fons + This document isn't password-protected Aquest document no està protegit amb contrasenya + Enter permissions password… Introdueix la contrasenya de permisos… + Permissions password Contrasenya de permisos + “{name}” has security restrictions. Enter its permissions password to lift them. “{name}” té restriccions de seguretat. Introdueix-ne la contrasenya de permisos per aixecar-les. + Restrictions lifted Restriccions aixecades + Couldn't unlock {name}: {e} No s'ha pogut desbloquejar {name}: {e} + This document has no restrictions to lift Aquest document no té restriccions per aixecar + The document's security settings don't allow this change La configuració de seguretat del document no permet aquest canvi + The document's security settings don't allow copying text and images La configuració de seguretat del document no permet copiar text ni imatges + Open a document first Obre primer un document + Security will be removed when you save La seguretat s'eliminarà en desar + Click text or an image to edit it Fes clic en un text o una imatge per editar-lo + Drag a rectangle to create a link; double-click a link to edit it Arrossega un rectangle per crear un enllaç; fes doble clic en un enllaç per editar-lo + There are no redaction marks to apply No hi ha marques de censura per aplicar + Drag to draw the area where the signature should appear. Arrossega per dibuixar l'àrea on ha d'aparèixer la signatura. + Couldn't fit the visible content: {e} No s'ha pogut ajustar el contingut visible: {e} + Drag a rectangle around the area to copy Arrossega un rectangle al voltant de l'àrea que vols copiar + Click on the page to add a {tool}, or drag to set its size Fes clic a la pàgina per afegir-hi un element {tool}, o arrossega per definir-ne la mida + Drag a rectangle on a page to crop it; double-click a page for Set Page Boxes Arrossega un rectangle sobre una pàgina per escapçar-la; fes doble clic en una pàgina per definir els quadres de pàgina + Keep tool selected: on Mantén l'eina seleccionada: activat + Keep tool selected Mantén l'eina seleccionada + Opacity Opacitat + Line thickness Gruix de línia + What word or phrase would you like to search for? Quina paraula o frase vols cercar? + Searching… {s} of {p} pages Cercant… {s} de {p} pàgines + (searching… {s} of {p} pages) (cercant… {s} de {p} pàgines) + 1 instance 1 coincidència + {n} instances {n} coincidències + Go to this result Ves a aquest resultat + Highlight Ressalta + Draw Dibuixa + Polygon Polígon + Connected lines Línies connectades + Eraser Goma d'esborrar + Sign Signa + Certified by {by} Certificat per {by} + At least one signature is invalid. Almenys una signatura no és vàlida. + Signed and all signatures are valid. Signat i totes les signatures són vàlides. + At least one signature has problems. Almenys una signatura té problemes. + This document is secured. Some changes are restricted by its security settings. Aquest document està protegit. Alguns canvis estan restringits per la seva configuració de seguretat. + This is a dynamic XFA form, which PdfCraft can't display yet. What you see is the file's placeholder page. Aquest és un formulari XFA dinàmic, que PdfCraft encara no pot mostrar. El que veus és la pàgina de substitució del fitxer. + This form also contains XFA data, which PdfCraft doesn't read yet. You can fill its fields, but Acrobat may show the XFA values instead. Aquest formulari també conté dades XFA, que PdfCraft encara no llegeix. Pots emplenar-ne els camps, però Acrobat pot mostrar els valors XFA. + This document contains {n} interactive form fields. Aquest document conté {n} camps de formulari interactius. + This file was damaged and has been repaired. Saving keeps the repaired version. Aquest fitxer estava malmès i s'ha reparat. En desar, es conserva la versió reparada. + Dismiss Descarta + Hide field highlights Amaga el ressaltat dels camps + Highlight fields Ressalta els camps + Security settings Configuració de seguretat + Details Detalls + Select (V) Selecciona (V) + Hand (H) Mà (H) + Delete pages (Delete) Suprimeix pàgines (Supr) + Insert a blank page after the selection Insereix una pàgina en blanc després de la selecció + Insert pages from a file… Insereix pàgines d'un fitxer… + Extract pages to a new document Extreu pàgines a un document nou + Split into files… Divideix en fitxers… + Select pages Selecciona pàgines + Cut Retalla + Copy Copia + Paste after Enganxa després + Rename Canvia el nom + Set to current page ({n}) Defineix com a pàgina actual ({n}) + Move up Mou amunt + Move down Mou avall + Indent Sagna + Outdent Treu el sagnat + This document has no form fields. Aquest document no té camps de formulari. + Tab order: move a field with its arrows. Ordre de tabulació: mou un camp amb les fletxes. + Unplaced Sense col·locar + Has JavaScript actions (run in M6) Té accions de JavaScript (s'executen a M6) + Page Pàgina + None Cap + Delete selected fields Suprimeix els camps seleccionats + Diagnostic details Detalls de diagnòstic + The operation failed. L'operació ha fallat. + no such document no existeix aquest document + nothing to undo no hi ha res per desfer + nothing to redo no hi ha res per refer + this document is signed: rewriting it would invalidate its signatures (save it incrementally instead) aquest document està signat: reescriure'l invalidaria les signatures (desa'l de manera incremental) + the document is protected by a password el document està protegit amb una contrasenya + the password is incorrect la contrasenya és incorrecta + the document has no page tree el document no té arbre de pàgines + a document must keep at least one page un document ha de conservar almenys una pàgina + a bookmark cannot be moved inside itself un marcador no es pot moure dins d'ell mateix + the title must not be empty el títol no pot estar buit + the document has no form fields el document no té camps de formulari + there are no redaction marks to apply no hi ha marques de censura per aplicar + there are no pages to print no hi ha pàgines per imprimir + the document has no tags el document no té etiquetes + {0}: {1} {0}: {1} + the text recognition models are not installed (reinstall PdfCraft, or set PDFCRAFT_MODELS to the folder that holds them) els models de reconeixement de text no estan instal·lats (reinstal·la PdfCraft o defineix PDFCRAFT_MODELS amb la carpeta que els conté) + the image is empty la imatge és buida + this file isn't XFDF, FDF, XML or text form data aquest fitxer no és de dades de formulari XFDF, FDF, XML ni de text + nothing in the file matches this document res del fitxer coincideix amb aquest document + This page couldn't be displayed.\n{e} No s'ha pogut mostrar aquesta pàgina.\n{e} + Go to page {p} Ves a la pàgina {p} + {s} action Acció {s} + Page {p} of {n} Pàgina {p} de {n} + 1 page selected 1 pàgina seleccionada + {n} pages selected {n} pàgines seleccionades + {name} — unsaved changes {name} — canvis sense desar + {kind} field Camp de tipus {kind} + Select a file for the stamp Selecciona un fitxer per al segell + JavaScript, e.g. getField("total").value JavaScript, p. ex. getField("total").value + Font: Helvetica Tipus de lletra: Helvetica + e.g. en-US p. ex. ca-ES + Rendering: hayro (bootstrap) · UI: egui · Icons: Lucide (ISC) · Fonts: Inter, JetBrains Mono, Dancing Script (OFL) Renderització: hayro (bootstrap) · Interfície: egui · Icones: Lucide (ISC) · Tipus de lletra: Inter, JetBrains Mono, Dancing Script (OFL) + CheckBox Casella de selecció + Radio Botó d'opció + PushButton Botó d'acció + Combo Llista combinada + List Llista + Unknown Desconegut + The document has no XMP metadata El document no té metadades XMP + The title in the metadata and the document information differ El títol de les metadades i la informació del document difereixen + The document is encrypted El document està xifrat + Device colour is used, but there is no PDF/A output intent S'utilitza color de dispositiu, però no hi ha cap intenció de sortida PDF/A + DeviceCMYK is used: it needs a CMYK output intent (not added automatically) S'utilitza DeviceCMYK: necessita una intenció de sortida CMYK (no s'afegeix automàticament) + DeviceCMYK is used, but the PDF/A output intent isn't a CMYK profile S'utilitza DeviceCMYK, però la intenció de sortida PDF/A no és un perfil CMYK + DeviceRGB is used, but the PDF/A output intent isn't an RGB profile S'utilitza DeviceRGB, però la intenció de sortida PDF/A no és un perfil RGB + The document has additional actions (/AA) El document té accions addicionals (/AA) + The document has document-level JavaScript El document té JavaScript a nivell de document + The form asks viewers to make appearances (NeedAppearances) El formulari demana als visualitzadors que generin aparences (NeedAppearances) + A form field has additional actions Un camp de formulari té accions addicionals + A stream uses LZW compression Un flux utilitza compressió LZW + A stream refers to an external file Un flux fa referència a un fitxer extern + An image asks to be interpolated Una imatge demana ser interpolada + An image has alternates or OPI information Una imatge té alternatives o informació OPI + PostScript XObjects aren't allowed No es permeten els XObjects PostScript + Embedded files must be PDF/A files themselves (use PDF/A-3 for others) Els fitxers incrustats han de ser fitxers PDF/A (utilitza PDF/A-3 per a la resta) + An embedded file has no AFRelationship Un fitxer incrustat no té AFRelationship + Select Icon Selecciona la icona + Choose images Tria imatges + {dpi} pixels/inch {dpi} píxels/polzada + Type your {what}. Escriu {what}. + Draw your {what} below. Dibuixa {what} a sota. + Your name El teu nom + Images and text (converted to PDF) Imatges i text (convertits a PDF) + Images and text Imatges i text + Check Box Style: Estil de la casella de selecció: + Button Style: Estil del botó: + Check Marca + Circle Cercle + Diamond Rombe + Square Quadrat + Star Estrella + {month} {y} {month} {y} + Change {key} Canvia {key} + Insert pages from {name} Insereix pàgines de {name} + Insert pages from {name} — 1 field renamed Insereix pàgines de {name} — 1 camp s'ha reanomenat + Insert pages from {name} — fields renamed Insereix pàgines de {name} — camps reanomenats + Fill in {name} Emplena {name} + Set the image of {name} Defineix la imatge de {name} + Edit script of {name} Edita l'script de {name} + Import {name} Importa {name} + Add bookmark Afegeix un marcador + Rename bookmark Canvia el nom del marcador + Delete bookmark Suprimeix el marcador + Move bookmark Mou el marcador + Set bookmark destination Defineix la destinació del marcador + Add stamp Afegeix un segell + Delete comment Suprimeix el comentari + Edit comment Edita el comentari + Erase Esborra + Lock comment Bloqueja el comentari + Unlock comment Desbloqueja el comentari + Move comment Mou el comentari + Resize comment Canvia la mida del comentari + Change comment properties Canvia les propietats del comentari + Add field Afegeix un camp + Change field properties Canvia les propietats del camp + Delete field Suprimeix el camp + Duplicate field Duplica el camp + Set tab order Defineix l'ordre de tabulació + Change initial view Canvia la visualització inicial + Set alternate text Defineix el text alternatiu + Mark figure as decorative Marca la figura com a decorativa + Run JavaScript Executa JavaScript + Delete document JavaScript Suprimeix el JavaScript del document + Edit document JavaScript Edita el JavaScript del document + Edit text Edita el text + Load document font Carrega el tipus de lletra del document + Move image Mou la imatge + Rotate image Gira la imatge + Flip image Inverteix la imatge + Delete image Suprimeix la imatge + Add header & footer Afegeix capçalera i peu de pàgina + Update header & footer Actualitza la capçalera i el peu de pàgina + Update watermark Actualitza la marca d'aigua + Add background Afegeix un fons + Update background Actualitza el fons + Add image Afegeix una imatge + Edit content Edita el contingut + Delete content Suprimeix el contingut + Remove redaction marks Elimina les marques de censura + Add link Afegeix un enllaç + Change link properties Canvia les propietats de l'enllaç + Delete link Suprimeix l'enllaç + Create link Crea un enllaç + Flatten Aplana + Flatten Fill & Sign Aplana Emplena i signa + Add sticky note Afegeix una nota adhesiva + Add highlight Afegeix un ressaltat + Add underline Afegeix un subratllat + Add strikethrough Afegeix un ratllat + Add squiggly underline Afegeix un subratllat ondulat + Add rectangle Afegeix un rectangle + Add oval Afegeix un oval + Add arrow Afegeix una fletxa + Add line Afegeix una línia + Add drawing Afegeix un dibuix + Add text box Afegeix un quadre de text + Add checkmark Afegeix una marca de verificació + Add cross Afegeix una creu + Add dot Afegeix un punt + Add signature Afegeix una signatura + Add redaction mark Afegeix una marca de censura + Add cloud Afegeix un núvol + Add polygon Afegeix un polígon + Add connected lines Afegeix línies connectades + Add callout Afegeix una crida + Add inserted text Afegeix un text inserit + Add file attachment Afegeix un fitxer adjunt + Set status Accepted Defineix l'estat Acceptat + Set status Rejected Defineix l'estat Rebutjat + Set status Cancelled Defineix l'estat Cancel·lat + Set status Completed Defineix l'estat Completat + Set status None Defineix l'estat Cap + Set status Unmarked Defineix l'estat Sense marcar + Save as PDF/A-1b Anomena i desa com a PDF/A-1b + Save as PDF/A-2b Anomena i desa com a PDF/A-2b + Save as PDF/A-3b Anomena i desa com a PDF/A-3b + Fill & Sign: change signature Emplena i signa: canvia la signatura + Fill & Sign: change initials Emplena i signa: canvia les inicials + Fill & Sign: remove saved signature Emplena i signa: elimina la signatura desada + Fill & Sign: remove saved initials Emplena i signa: elimina les inicials desades + Change signature Canvia la signatura + Change initials Canvia les inicials + Measure distance Mesura la distància + Measure perimeter Mesura el perímetre + Measure area Mesura l'àrea + Set measurement scale Defineix l'escala de mesura + Measurement information Informació de mesura + Measurement snapping Ajust de mesura + Export measurements as CSV Exporta les mesures com a CSV + Distance Distància + Perimeter Perímetre + Area Àrea + Drawing scale Escala del dibuix + Snapping Ajust + Export measurements Exporta les mesures + Open a PDF to measure it. Obre un PDF per mesurar-lo. + Click vertices. Enter or double-click finishes a perimeter or area. Click the first point to close an area. Fes clic als vèrtexs. Retorn o doble clic finalitza un perímetre o una àrea. Fes clic al primer punt per tancar una àrea. + Shift constrains to 45 degrees. Backspace removes a vertex. Escape cancels. Maj restringeix a 45 graus. Retrocés elimina un vèrtex. Esc cancel·la. + Angle Angle + Click the first point to begin. Fes clic al primer punt per començar. + Snap to drawing Ajusta al dibuix + Endpoints Extrems + Midpoints Punts mitjans + Intersections Interseccions + Paths Traçats + Sensitivity Sensibilitat + Unit Unitat + Decimals Decimals + Calibrate from two points Calibra a partir de dos punts + Entire page Pàgina sencera + Viewport rectangle in page points (x, y, width, height) Rectangle de la zona visible en punts de pàgina (x, y, amplada, alçada) + Viewport Zona visible + Apply scale Aplica l'escala + Saved measurements Mesures desades + Saved measurements. Mesures desades. + Endpoint Extrem + Midpoint Punt mitjà + Intersection Intersecció + Path Traçat + This drawing exceeds the snapping limit; only the first paths are used. Aquest dibuix supera el límit d'ajust; només s'utilitzen els primers traçats. + Some page content couldn't be read; snapping uses the rest. Part del contingut de la pàgina no s'ha pogut llegir; l'ajust utilitza la resta. + Unsupported measurements Mesures no compatibles + Label Etiqueta + {n} measurements use an unsupported format and are left out. {n} mesures utilitzen un format no compatible i s'han deixat fora. + This area has too many overlapping paths; intersection snapping is limited. Aquesta àrea té massa traçats superposats; l'ajust a les interseccions és limitat. + This measurement needs at least {n} points. Aquesta mesura necessita almenys {n} punts. + Change {what} Canvia {what} + Cut and stack Cascada i apilat + Default workspace mode Mode d'espai de treball per defecte + Documents and view Documents i visualització + Open email app Obre l'aplicació de correu + Open link Obre l'enllaç + Open this web page? Vols obrir aquesta pàgina web? + Scripts run in a sandbox without file or network access. A script that asks to open a web page needs your permission first. With JavaScript off, Acrobat's standard format, validate and calculate functions still work. Els scripts s'executen en un entorn aïllat sense accés a fitxers ni a la xarxa. Un script que demana obrir una pàgina web necessita primer el teu permís. Amb JavaScript desactivat, les funcions estàndard de format, validació i càlcul d'Acrobat continuen funcionant. + Sign yourself Signa tu mateix + Used when opening PDFs. An explicit launch or control mode takes precedence for the session. S'utilitza en obrir PDF. Un mode d'inici o de control explícit té prioritat durant la sessió. + Write this email? Vols escriure aquest correu? + {who} in this document wants to open this address in your browser: {who} d'aquest document vol obrir aquesta adreça al navegador: + {who} in this document wants to open your email app with this address: {who} d'aquest document vol obrir l'aplicació de correu amb aquesta adreça: + This web address mixes letters from different alphabets, a common way to imitate another site's name. Aquesta adreça web barreja lletres de diferents alfabets, una manera habitual d'imitar el nom d'un altre lloc. + This web address uses letters from another alphabet, which can look like familiar ones. Aquesta adreça web utilitza lletres d'un altre alfabet, que poden semblar-se a les habituals. + Create PDF from images Crea un PDF a partir d'imatges + Selected image files: {count} Fitxers d'imatge seleccionats: {count} + Use image resolution Utilitza la resolució de la imatge + Use each image's embedded DPI; use 72 DPI when it is absent. Utilitza els DPI incrustats de cada imatge; si no n'hi ha, utilitza 72 DPI. + Use 72 DPI (one point per pixel) Utilitza 72 DPI (un punt per píxel) + Use custom DPI Utilitza uns DPI personalitzats + DPI sets the printed page size without resampling the image. Els DPI defineixen la mida de la pàgina impresa sense remostrejar la imatge. + Create Crea + Dynamic XFA form laid out from its template: {pages}, {fields}. Formulari XFA dinàmic disposat a partir de la seva plantilla: {pages}, {fields}. + This form's scripts are turned off because one ran too long. Reopen the document to run them again. Els scripts d'aquest formulari estan desactivats perquè un s'ha executat massa temps. Torna a obrir el document per executar-los de nou. + XFA form: its fields and its XFA data are kept in step, so other viewers show what you fill in. Formulari XFA: els seus camps i les seves dades XFA es mantenen sincronitzats, de manera que altres visualitzadors mostren el que emplenes. +@plural {n} page|{n} pages {n} pàgina|{n} pàgines +@plural {n} field|{n} fields {n} camp|{n} camps +@plural {n} field name collides with earlier files and will be renamed: {list}|{n} field names collide with earlier files and will be renamed: {list} {n} camp té un nom que col·lideix amb fitxers anteriors i es reanomenarà: {list}|{n} camps tenen un nom que col·lideix amb fitxers anteriors i es reanomenaran: {list} + Switch to two-page view first to show the cover page Canvia primer a la visualització de dues pàgines per mostrar la portada + Page display: {layout} Visualització de pàgina: {layout} + Fit to width scrolling Desplaçament ajustat a l'amplada + Fit one full page Ajusta una pàgina sencera + Default page display Visualització de pàgina per defecte + Default zoom Zoom per defecte + Used when a PDF doesn't ask for a layout or zoom. Continuous scrolling never snaps between pages. S'utilitza quan un PDF no demana cap disposició ni zoom. El desplaçament continu mai no salta entre pàgines. + Show Mostra + Sort Ordena + Reverse the order Inverteix l'ordre + Grab bag Calaix de sastre + Table Taula + Username Nom d'usuari + Display name Nom visible + Real name Nom real + Name (A–Z) Nom (A–Z) + Merged PRs PR combinats + PRs PR + Commits Commits + Lines added Línies afegides + +LOC +LOC + Lines deleted Línies suprimides + −LOC −LOC + Line delta Diferència de línies + ΔLOC ΔLOC + Binary assets added Recursos binaris afegits + +Bin +Bin + Binary assets removed Recursos binaris eliminats + −Bin −Bin + First commit Primera contribució + First Primera + Last commit Última contribució + Last Última + No contributor data was built into this copy. En aquesta còpia no s'han inclòs dades de contribuïdors. + No model credits were built into this copy. En aquesta còpia no s'han inclòs crèdits de models. + {n} contributors · {c} commits {n} contribuïdors · {c} contribucions + Company Empresa + Model Model + % of all commits % de totes les contribucions + Lines +/− Línies +/− + @{login}: {prs} PRs, {commits} commits, +{added} / −{deleted} lines (Δ {delta}), +{bin_added} / −{bin_deleted} binary assets, {first} – {last} @{login}: {prs} PR, {commits} contribucions, +{added} / −{deleted} línies (Δ {delta}), +{bin_added} / −{bin_deleted} recursos binaris, {first} – {last} + Reopen the files that were open when PdfCraft last closed Reobre els fitxers que eren oberts l'última vegada que es va tancar PdfCraft + Add {what} Afegeix {what} + Use {what} Utilitza {what} + Place saved {what} Col·loca {what} desats + Remove saved {what} Elimina {what} desats + A link Un enllaç + A button Un botó + A script Un script + {who} in this document tried to open an address PdfCraft won't open: {e}. {who} d'aquest document ha intentat obrir una adreça que PdfCraft no obre: {e}. + {who} in this document tried to open an address PdfCraft won't open: {e}. Only web (http, https) and email (mailto) links open from documents. {who} d'aquest document ha intentat obrir una adreça que PdfCraft no obre: {e}. Als documents només s'hi poden obrir enllaços web (http, https) i de correu electrònic (mailto). + Another file dialog is still open. Finish with it first. Hi ha un altre diàleg de fitxers obert. Acaba'l primer. + Couldn't show the file picker. Please try again. No s'ha pogut mostrar el selector de fitxers. Torna-ho a provar. + The document changed while you were choosing a file, so nothing was changed. El document ha canviat mentre triaves un fitxer, de manera que no s'ha modificat res. + The document was closed before it could be saved. El document s'ha tancat abans de poder-se desar. + The pages were extracted but not deleted, because the document changed while you were choosing a folder. Les pàgines s'han extret però no s'han suprimit, perquè el document ha canviat mentre triaves una carpeta. + That didn't work: an internal error stopped it ({m}). No ha funcionat: un error intern ho ha aturat ({m}). + The Windows store's digital IDs couldn't be listed: {e} No s'han pogut llistar els identificadors digitals de l'emmagatzematge de Windows: {e} + Align fields Alinea els camps + Distribute fields Distribueix els camps + Match field sizes Iguala la mida dels camps + Mark for redaction Marca per censurar + Mark pages for redaction Marca pàgines per censurar + Change document properties Canvia les propietats del document + Mark differences Marca les diferències + Run form script Executa l'script del formulari + Scripted content must be usable with a keyboard and assistive technology. Check the document's scripts. El contingut amb scripts ha de ser utilitzable amb teclat i amb tecnologies d'assistència. Revisa els scripts del document. + Table rows belong directly in a table or its head, body or foot. Fix the table's tags. Les files d'una taula han d'anar directament dins la taula o dins de la seva capçalera, cos o peu. Corregeix les etiquetes de la taula. + Basic constraints Restriccions bàsiques + SHA-1 digest Resum SHA-1 + SHA-256 digest Resum SHA-256 + Squiggly Ondulat + Home / End Inici / Fi + H / Space (hold) H / Espai (mantén premut) + Reload documents when their files change on disk Torna a carregar els documents quan els seus fitxers canviïn al disc + This file changed on disk. Reload it to see the new version; your unsaved changes will be lost. Aquest fitxer ha canviat al disc. Torna'l a carregar per veure'n la versió nova; es perdran els canvis sense desar. + Reload Torna a carregar + Couldn't reload {name}: {e} No s'ha pogut tornar a carregar {name}: {e} + Created a PDF from {n} files S'ha creat un PDF a partir de {n} fitxers + PDF, images and text PDF, imatges i text + Insert a file before page {label} Insereix un fitxer abans de la pàgina {label} + Insert a file at the end Insereix un fitxer al final + Save pages Desa les pàgines + Save these pages as one PDF Desa aquestes pàgines com un sol PDF + No changes to save No hi ha canvis per desar + Created a PDF from {n} files; left out: {names} S'ha creat un PDF a partir de {n} fitxers; exclosos: {names} + Created a PDF from the first {n} files S'ha creat un PDF a partir dels primers {n} fitxers + None of those files can be made into a PDF; use PDFs, images or .txt files Cap d'aquests fitxers es pot convertir en PDF; utilitza PDF, imatges o fitxers .txt + Choose a PNG or JPEG image (up to 4 MiB). Transparency is preserved. Tria una imatge PNG o JPEG (fins a 4 MiB). Es conserva la transparència. + Couldn't import the signature image: {e} No s'ha pogut importar la imatge de la signatura: {e} + Go to page… Vés a la pàgina… + About Quant a + Contributors Contribuïdors + Models Models + Only continue if you trust this document. An address can carry information from the document, such as what you typed into its form. Continua només si confies en aquest document. Una adreça pot dur informació del document, com ara el que has escrit al formulari. + Print single-sided. Keep the sheets in order, cut at the marks, then stack the piles left to right, top to bottom. Imprimeix a una cara. Mantén els fulls en ordre, talla per les marques i apila els munts d'esquerra a dreta i de dalt a baix. + For page sizes and margins. Per a les mides de pàgina i els marges. + The PDF text fonts can't draw “{c}” ({code}). Choose supported text. Els tipus de lletra de text del PDF no poden dibuixar “{c}” ({code}). Tria un text compatible. + The standard fonts can't draw “{c}” ({code}). Only Western European characters can be added as text for now. Els tipus de lletra estàndard no poden dibuixar “{c}” ({code}). De moment només es poden afegir com a text caràcters d'Europa occidental. + This field's font can't draw “{c}” ({code}), so PdfCraft shows ? in its place. The value is saved, and other PDF viewers redraw the field from it. El tipus de lletra d'aquest camp no pot dibuixar “{c}” ({code}), de manera que PdfCraft hi mostra un ?. El valor es desa i altres visors de PDF tornen a dibuixar el camp a partir d'ell. + The fonts PdfCraft writes with can't draw “{c}” ({code}), so it shows as ? in every PDF viewer. The text is saved. Els tipus de lletra amb què escriu PdfCraft no poden dibuixar “{c}” ({code}), de manera que es mostra com a ? a tots els visors de PDF. El text es desa. + Open arrow Fletxa oberta + Closed arrow Fletxa tancada + Butt Pla + Reverse open arrow Fletxa oberta inversa + Reverse closed arrow Fletxa tancada inversa + Slash Barra inclinada + Larger pages Pàgines més grans + Smaller pages Pàgines més petites + Reset page size Restableix la mida de la pàgina + Date format Format de data + Fill & Sign dates Dates d'Omple i signa + Pattern Patró + Today: {date} Avui: {date} + yyyy or yy year · m or mm month · mmm or mmmm month name · d or dd day · ddd or dddd weekday. H, h, M, s and t are time letters and can't be used on their own: put {escape} before a letter to show it as is. yyyy o yy any · m o mm mes · mmm o mmmm nom del mes · d o dd dia · ddd o dddd dia de la setmana. H, h, M, s i t són lletres d'hora i no es poden usar soles: posa {escape} davant d'una lletra per mostrar-la tal com és. + Same as interface ({language}) Igual que la interfície ({language}) + {chars} can't be written into the PDF yet: Fill & Sign text is Western European only. Pick a numeric format such as dd.mm.yyyy. {chars} encara no es pot escriure al PDF: el text d'Omple i signa només admet l'europeu occidental. Tria un format numèric com dd.mm.yyyy. + Opens the printer driver's preferences. They are saved for every print from this computer; the copies, two-sided, grayscale and paper chosen here still apply. Obre les preferències del controlador de la impressora. Es desen per a totes les impressions d'aquest ordinador; les còpies, la impressió a doble cara, l'escala de grisos i el paper triats aquí continuen aplicant-se. + The printer driver's own settings for this print: paper tray, paper type, finishing and more. La configuració pròpia del controlador de la impressora per a aquesta impressió: safata de paper, tipus de paper, acabats i més. + Couldn't open the printer's preferences: {e} No s'han pogut obrir les preferències de la impressora: {e} + Printer properties Propietats de la impressora + Reset to printer defaults Restableix els valors per defecte de la impressora + This printer offers no settings of its own. Aquesta impressora no ofereix cap configuració pròpia. + Scroll tabs left Desplaça les pestanyes cap a l'esquerra + Scroll tabs right Desplaça les pestanyes cap a la dreta + Shared Field Properties Propietats compartides dels camps + {n} fields selected {n} camps seleccionats + Mixed Barrejat + Custom font Tipus de lletra personalitzat + Only checked properties will change. Mixed means the selected fields have different values. Només canviaran les propietats marcades. Barrejat vol dir que els camps seleccionats tenen valors diferents. + Shift- or Ctrl/Command-click to select several fields. Fes clic amb Maj o Ctrl/Ordre premuts per seleccionar diversos camps. + Font size 0 uses automatic sizing. La mida de lletra 0 utilitza la mida automàtica. + Character limit: Límit de caràcters: + Character limit 0 means no limit. A comb of characters needs a limit. Un límit de caràcters 0 vol dir sense límit. Una pinta de caràcters necessita un límit. + To change locked fields, also set Locked to No. Per canviar camps bloquejats, defineix també Bloquejat com a No. + Comb of characters Pinta de caràcters + The document changed while you were editing field properties. El document ha canviat mentre n'editaves les propietats dels camps. + The document is no longer open. El document ja no és obert. + The field properties dialog is no longer open. El diàleg de propietats dels camps ja no és obert. + The field properties could not be changed. No s'han pogut canviar les propietats dels camps. + The selected fields could not be found. Select them again. No s'han trobat els camps seleccionats. Torna'ls a seleccionar. + The field {name} no longer exists. El camp {name} ja no existeix. + A selected field has no widget on any page, so the fields can't be edited together. Un camp seleccionat no té cap giny a cap pàgina, de manera que els camps no es poden editar junts. + ({n} at {dpi} dpi, the largest size they can be drawn at) ({n} a {dpi} ppp, la mida més gran a la qual es poden dibuixar) + The security settings don't allow screen readers to read the text La configuració de seguretat no permet que els lectors de pantalla llegeixin el text + No page has text: the document appears to be images of pages Cap pàgina no té text: el document sembla ser imatges de pàgines + The document has no tags (structure tree) El document no té etiquetes (arbre d'estructura) + The document isn't marked as tagged (MarkInfo Marked) El document no està marcat com a etiquetat (MarkInfo Marked) + No document language is set No s'ha definit cap idioma del document + The document has no title El document no té títol + The window shows the file name, not the title (Initial View > Show) La finestra mostra el nom del fitxer, no el títol (Visualització inicial > Mostra) + {n} pages and no bookmarks {n} pàgines i cap marcador + The document isn't tagged, so none of its content is El document no està etiquetat, de manera que cap dels seus continguts ho està + Page {p}: {n} untagged content item Pàgina {p}: {n} element de contingut sense etiquetar + Page {p}: {n} untagged content items Pàgina {p}: {n} elements de contingut sense etiquetar + Form field on page {p} isn't tagged El camp de formulari de la pàgina {p} no està etiquetat + {} annotation on page {p} isn't tagged L'anotació {} de la pàgina {p} no està etiquetada + Page {p} doesn't tab in structure order La pàgina {p} no segueix l'ordre d'estructura en tabular + Font {} on page {p} doesn't map its characters to Unicode El tipus de lletra {} de la pàgina {p} no assigna els seus caràcters a Unicode + Font (unnamed) on page {p} doesn't map its characters to Unicode El tipus de lletra (sense nom) de la pàgina {p} no assigna els seus caràcters a Unicode + Field "{}" on page {p} has no description (tooltip) El camp "{}" de la pàgina {p} no té descripció (suggeriment) + {ty} element: {what} Element {ty}: {what} + {ty} element on page {p}: {what} Element {ty} a la pàgina {p}: {what} + no alternate text sense text alternatiu + its alternate text is inside another element's and will never be read el seu text alternatiu és dins del d'un altre element i no es llegirà mai + alternate text on an element with no page content text alternatiu en un element sense contingut de pàgina + alternate text hides an annotation inside it el text alternatiu amaga una anotació que hi ha dins + not in a Table, THead, TBody or TFoot no és dins d'un Table, THead, TBody o TFoot + not in a TR no és dins d'un TR + no header cells (TH) sense cel·les de capçalera (TH) + rows have between {min} and {max} columns les files tenen entre {min} i {max} columnes + no summary sense resum + not in an L (list) no és dins d'un L (llista) + not in an LI (list item) no és dins d'un LI (element de llista) + the first heading is an H{n}; headings should not skip levels el primer encapçalament és un H{n}; els encapçalaments no haurien de saltar nivells + H{n} follows an H{d}; headings should not skip levels H{n} va després d'un H{d}; els encapçalaments no haurien de saltar nivells + … and {n} more … i {n} més + Accessibility Report Informe d'accessibilitat + Filename Nom del fitxer + Report created Informe creat + The checker found problems which may prevent the document from being fully accessible. El verificador ha trobat problemes que poden impedir que el document sigui plenament accessible. + Detailed Report Informe detallat + Rule Name Nom de la regla + The metadata doesn't identify the file as {} Les metadades no identifiquen el fitxer com a {} + Page {} has additional actions La pàgina {} té accions addicionals + A {} action isn't allowed No es permet una acció {} + {} annotations aren't allowed No es permeten les anotacions {} + A {} annotation isn't set to print, or is hidden Una anotació {} no està configurada per imprimir-se, o està amagada + A {} annotation has no appearance stream Una anotació {} no té flux d'aparença + A {} annotation has additional actions Una anotació {} té accions addicionals + The font {} isn't embedded El tipus de lletra {} no està incrustat + A font isn't embedded Un tipus de lletra no està incrustat + The signature has no valid byte range. La signatura no té un interval de bytes vàlid. + The signature's byte range does not match the file. L'interval de bytes de la signatura no coincideix amb el fitxer. + The signature's byte range does not exclude exactly its contents. L'interval de bytes de la signatura no exclou exactament el seu contingut. + The signature contents are not hexadecimal. El contingut de la signatura no és hexadecimal. + The signature could not be read ({}). No s'ha pogut llegir la signatura ({}). + PdfCraft can't check this signature yet: {}. PdfCraft encara no pot comprovar aquesta signatura: {}. + The signature uses the legacy adbe.x509.rsa_sha1 format. La signatura utilitza el format antic adbe.x509.rsa_sha1. + The signature is BER-encoded (indefinite lengths) rather than DER; it was read leniently. La signatura està codificada en BER (longituds indefinides) en lloc de DER; s'ha llegit de manera permissiva. + The signed content is a constructed (segmented) OCTET STRING, as BER allows; it was read anyway. El contingut signat és un OCTET STRING construït (segmentat), com permet el BER; s'ha llegit igualment. + The RSA signature value does not have the length of the key's modulus (leading zero bytes dropped or added); it was read anyway. El valor de la signatura RSA no té la longitud del mòdul de la clau (s'han suprimit o afegit bytes zero inicials); s'ha llegit igualment. + The RSA signature's DigestInfo has no NULL parameter (older signers write it so); it was read anyway. El DigestInfo de la signatura RSA no té el paràmetre NULL (els signants més antics l'escriuen així); s'ha llegit igualment. + The ECDSA signature is not in canonical DER (trailing bytes, padding or a missing sign byte); it was read anyway. La signatura ECDSA no està en DER canònic (bytes finals, farciment o byte de signe que falta); s'ha llegit igualment. + The ECDSA signature is the raw r and s values instead of a DER sequence; it was read anyway. La signatura ECDSA són els valors r i s en brut en lloc d'una seqüència DER; s'ha llegit igualment. + The signature algorithm and the SignerInfo's digest algorithm name different hashes; the signature was made with the SignerInfo's. L'algorisme de signatura i l'algorisme de resum del SignerInfo indiquen resums diferents; la signatura es va fer amb el del SignerInfo. + This signature uses SHA-1, a weak hash algorithm: collisions in it have been demonstrated. It still validates because many documents signed years ago use it, but it should not be relied on. Aquesta signatura utilitza SHA-1, un algorisme de resum feble: se n'han demostrat col·lisions. Encara se'n valida perquè molts documents signats fa anys l'utilitzen, però no s'hi ha de confiar. + This signature uses RIPEMD-160, a legacy 160-bit hash algorithm that is no longer recommended for signatures. It still validates, but it should not be relied on. Aquesta signatura utilitza RIPEMD-160, un algorisme de resum antic de 160 bits que ja no es recomana per a signatures. Encara es valida, però no s'hi ha de confiar. + The document has been altered or corrupted since the signature was applied. El document ha estat alterat o s'ha corromput des que es va aplicar la signatura. + The signer's certificate is not in the signature. El certificat del signant no és a la signatura. + The signature value does not match the signer's certificate: the signature is corrupt. El valor de la signatura no coincideix amb el certificat del signant: la signatura està corrompuda. + The signature could not be checked ({}). No s'ha pogut comprovar la signatura ({}). + The signature could not be verified ({}). No s'ha pogut verificar la signatura ({}). + This document has not been modified since this signature was applied. Aquest document no s'ha modificat des que es va aplicar aquesta signatura. + The document has been modified since this signature was applied, but the changes are permitted ({}). El document s'ha modificat des que es va aplicar aquesta signatura, però els canvis són permesos ({}). + The document has been altered since this signature was applied in ways it does not permit ({}). El document ha estat alterat des que es va aplicar aquesta signatura d'una manera que no permet ({}). + The signer's certificate was not valid at the time of signing. El certificat del signant no era vàlid en el moment de signar. + The signer's certificate does not allow digital signatures (its key usage has neither digital signature nor non-repudiation). El certificat del signant no permet signatures digitals (el seu ús de clau no inclou ni signatura digital ni no repudi). + The signer's certificate is not issued for signing documents (its extended key usage has no document-signing purpose). El certificat del signant no s'ha emès per signar documents (el seu ús estès de clau no inclou el propòsit de signatura de documents). + The signer's certificate has critical extensions PdfCraft does not recognize ({}). El certificat del signant té extensions crítiques que PdfCraft no reconeix ({}). + The certificate of {} is not a CA certificate that may issue certificates, so it is not used to vouch for {}. El certificat de {} no és un certificat de CA que pugui emetre certificats, de manera que no s'utilitza per avalar {}. + The certificate of {} does not allow this many CA certificates below it (path length), so it is not used to vouch for {}. El certificat de {} no permet tants certificats de CA per sota seu (longitud de camí), de manera que no s'utilitza per avalar {}. + The certificate of {} was not valid at the time of signing, so it is not used to vouch for {}. El certificat de {} no era vàlid en el moment de signar, de manera que no s'utilitza per avalar {}. + The signer's identity is unknown because it has not been included in your list of trusted certificates and none of its parent certificates are trusted certificates. La identitat del signant és desconeguda perquè no s'ha inclòs a la llista de certificats de confiança i cap dels seus certificats pare és un certificat de confiança. + The signer's identity is valid. La identitat del signant és vàlida. + The signature includes an embedded timestamp. La signatura inclou una marca de temps incrustada. + Signing time is from the clock on the signer's computer. L'hora de signatura prové del rellotge de l'ordinador del signant. + The signature's timestamp token does not cover the signature value. El testimoni de marca de temps de la signatura no cobreix el valor de la signatura. + The signature's timestamp token could not be verified ({}). No s'ha pogut verificar el testimoni de marca de temps de la signatura ({}). + The embedded timestamp token is valid and its authority is trusted; trusted time is {}. El testimoni de marca de temps incrustat és vàlid i la seva autoritat és de confiança; l'hora de confiança és {}. + The signature carries an unverified timestamp ({}): the timestamp authority is not in your list of trusted certificates, so the signing time claimed by the signer is used instead. La signatura porta una marca de temps no verificada ({}): l'autoritat de marca de temps no és a la llista de certificats de confiança, de manera que s'utilitza l'hora de signatura indicada pel signant. + The signer's certificate has been revoked ({}). El certificat del signant ha estat revocat ({}). + The document's embedded revocation information shows that the signer's certificate has not been revoked. La informació de revocació incrustada al document mostra que el certificat del signant no ha estat revocat. + The timestamp has no valid byte range. La marca de temps no té un interval de bytes vàlid. + The timestamp's byte range does not match the file. L'interval de bytes de la marca de temps no coincideix amb el fitxer. + The timestamp's byte range does not exclude exactly its contents. L'interval de bytes de la marca de temps no exclou exactament el seu contingut. + The timestamp contents are not hexadecimal. El contingut de la marca de temps no és hexadecimal. + The timestamp token could not be read ({}). No s'ha pogut llegir el testimoni de marca de temps ({}). + The document has been altered or corrupted since the timestamp was applied. El document ha estat alterat o s'ha corromput des que es va aplicar la marca de temps. + The timestamp authority's certificate was not valid at the time of timestamping. El certificat de l'autoritat de marca de temps no era vàlid en el moment de marcar el temps. + This document has not been modified since this timestamp was applied. Aquest document no s'ha modificat des que es va aplicar aquesta marca de temps. + The document has been modified since this timestamp was applied, but the changes are permitted ({}). El document s'ha modificat des que es va aplicar aquesta marca de temps, però els canvis són permesos ({}). + The document has been altered since this timestamp was applied in ways it does not permit ({}). El document ha estat alterat des que es va aplicar aquesta marca de temps d'una manera que no permet ({}). + The timestamp token is valid and its authority is trusted. El testimoni de marca de temps és vàlid i la seva autoritat és de confiança. + The timestamp token is valid, but the timestamp authority is not in your list of trusted certificates. El testimoni de marca de temps és vàlid, però l'autoritat de marca de temps no és a la llista de certificats de confiança. + Unsigned signature field Camp de signatura sense signar + Signature is valid La signatura és vàlida + Signature validity is unknown La validesa de la signatura és desconeguda + Signature is invalid La signatura no és vàlida + page content contingut de la pàgina + form fill emplenament de formulari + comments comentaris + document security store magatzem de seguretat del document + metadata metadades + links enllaços + document structure estructura del document + pages added or removed pàgines afegides o eliminades + other changes altres canvis + the signed version could not be read no s'ha pogut llegir la versió signada + page {n} is out of range (1–{count}) la pàgina {n} és fora de l'interval (1–{count}) + {page} is not a page number or label {page} no és un número ni una etiqueta de pàgina + Change Title Canvia el títol + Change Author Canvia l'autor + Change Subject Canvia l'assumpte + Change Keywords Canvia les paraules clau + Save as {level} Anomena i desa com a {level} + Create links Crea enllaços +@plural {n} object selected|{n} objects selected {n} objecte seleccionat|{n} objectes seleccionats + Drag the selection to move it. Esc clears the selection. Arrossega la selecció per moure-la. Esc esborra la selecció. + Shift-click to select several objects. Drag empty space to select an area. Fes clic amb Maj per seleccionar diversos objectes. Arrossega per un espai buit per seleccionar una àrea. + Select at most 1000 objects at a time. Selecciona com a màxim 1000 objectes alhora. + Finish or discard the text being edited before selecting several objects. Acaba o descarta el text que s'està editant abans de seleccionar diversos objectes. + Move object Mou l'objecte + Move objects Mou els objectes + Vertical text cannot be moved with this selection. El text vertical no es pot moure amb aquesta selecció. + Text used as a clipping path cannot be moved with this selection. El text utilitzat com a traçat de retall no es pot moure amb aquesta selecció. + These objects could not be moved. Select them again and try a smaller move. No s'han pogut moure aquests objectes. Torna'ls a seleccionar i prova amb un moviment més petit. + This page contains objects that cannot be selected together. Aquesta pàgina conté objectes que no es poden seleccionar junts. + Fill colour Color de farciment + No fill Sense farciment + Fill colour: none Color de farciment: cap +key Ctrl Ctrl +key Shift Maj +key Delete Supr +key Esc Esc +key Home Inici +key End Fi +key Space Espai + Grid view Visualització en quadrícula + List view Visualització en llista + Files are combined in the order shown. Drag them to change it. Els fitxers es combinen en l'ordre mostrat. Arrossega'ls per canviar-lo. + Preview unavailable: {e} Previsualització no disponible: {e} + Pages: {k} of {n} Pàgines: {k} de {n} + Check the pages Revisa les pàgines + Switch to List view to change the pages it takes. Canvia a la visualització en llista per canviar les pàgines que utilitza. + Expand all Expandeix-ho tot + Collapse all Replega-ho tot + Remove page Elimina la pàgina + Remove {n} pages Elimina {n} pàgines + Reset panel layout Restableix la disposició dels taulers + Float panel Fes flotant el tauler + Move to group Mou al grup + Panels Taulers + Resize panels Canvia la mida dels taulers + Resize panel window Canvia la mida de la finestra del tauler + Tools Eines + Inspector Inspector + Select page {label} Selecciona la pàgina {label} + Rotate page {label} counterclockwise Gira la pàgina {label} en sentit antihorari + Rotate page {label} clockwise Gira la pàgina {label} en sentit horari + Delete page {label} Suprimeix la pàgina {label} + Mouse wheel scroll speed Velocitat de desplaçament de la roda del ratolí +scroll speed Slow Lenta +scroll speed Normal Normal +scroll speed Fast Ràpida + Animation effects Efectes d'animació +animation effects On Activats +animation effects Off Desactivats + Enhance camera image Millora la imatge de la càmera + Drag the corners onto the document's edges, then choose Enhance page. Arrossega les cantonades fins a les vores del document i tria Millora la pàgina. + Enhance page Millora la pàgina + Certificate authority Autoritat de certificació + End entity Entitat final + Clean-up Neteja + Original Original + Greyscale Escala de grisos + Black and white Blanc i negre + This printer's driver doesn't take two-sided settings from other programs, so its own setting applies. Change it in Properties… El controlador d'aquesta impressora no accepta la configuració de doble cara d'altres programes, de manera que s'aplica la seva pròpia configuració. Canvia-la a Propietats… + Browser's print dialog Diàleg d'impressió del navegador + Copies, two-sided printing and colour are chosen in the browser's print dialog. Les còpies, la impressió a doble cara i el color es trien al diàleg d'impressió del navegador. + Preparing {n} sheets for printing… Preparant {n} fulls per imprimir… + Preparing sheet {done} of {total} for printing… Preparant el full {done} de {total} per imprimir… + Opening the browser's print dialog… Obrint el diàleg d'impressió del navegador… + Couldn't print from the browser ({e}); downloaded {name} to print instead No s'ha pogut imprimir des del navegador ({e}); s'ha baixat {name} per imprimir-lo en lloc d'això + Tools panel side Costat del tauler d'eines + Add comment Afegeix un comentari + Change tag properties Canvia les propietats de l'etiqueta + Tags panel Tauler d'etiquetes + Tags Etiquetes + Tag type Tipus d'etiqueta + Actual text Text real + Find a tag Cerca una etiqueta + Collapse tag Replega l'etiqueta + Expand tag Expandeix l'etiqueta + Revert changes Reverteix els canvis + Save tag properties Desa les propietats de l'etiqueta + This document has no editable structure tags. Aquest document no té etiquetes d'estructura editables. + {n} tags {n} etiquetes + Save or revert changes before selecting another tag. Desa o reverteix els canvis abans de seleccionar una altra etiqueta. + Left out: {names} Exclosos: {names} + already a PDF ja és un PDF + no unused output name cap nom de sortida sense utilitzar + no output folder was chosen no s'ha triat cap carpeta de sortida +@plural Downloaded {n} PDF|Downloaded {n} PDFs S'ha baixat {n} PDF|S'han baixat {n} PDF + Scan Escaneja + Sign a sheet of white paper and take a photo of it in bright, even light (use the flash). Choose the photo or drop it here: PdfCraft finds the signature and removes the paper. Signa un full de paper blanc i fes-ne una foto amb llum intensa i uniforme (utilitza el flaix). Tria la foto o deixa-la anar aquí: PdfCraft troba la signatura i elimina el paper. + Choose photo… Tria una foto… + No photo chosen No s'ha triat cap foto + Photo Foto + Ink sensitivity Sensibilitat de la tinta + No signature was found in the frame. Move the frame over the signature or raise the ink sensitivity. No s'ha trobat cap signatura al marc. Mou el marc sobre la signatura o augmenta la sensibilitat de la tinta. + Couldn't use the photo: {e} No s'ha pogut utilitzar la foto: {e} + Close Tab Tanca la pestanya + Reopen Closed Tab Reobre la pestanya tancada + Reveal in Finder Mostra al Finder + Reveal in File Explorer Mostra a l'Explorador de fitxers + Other colour… Un altre color… + Recent colours Colors recents + Reading colours Colors de lectura + Replace document colours Substitueix els colors del document + Page background Fons de la pàgina + Only change the colour of black text or line art Canvia només el color del text negre o dels dibuixos de línies + Change the colour of line art as well as text Canvia el color dels dibuixos de línies i també del text + Colours are remapped while rendering; the document itself never changes. Els colors es reassignen en renderitzar; el document en si mai no canvia. + Black on white Negre sobre blanc + White on black Blanc sobre negre + Yellow on black Groc sobre negre + Green on black Verd sobre negre + Couldn't follow linked PDF: {reason} No s'ha pogut seguir el PDF enllaçat: {reason} + The linked PDF opened, but its named destination was not applied. S'ha obert el PDF enllaçat, però no s'ha aplicat la seva destinació amb nom. + The linked PDF opened, but its page destination was out of range. S'ha obert el PDF enllaçat, però la seva destinació de pàgina era fora de l'interval. + Local cross-PDF links require the desktop app Els enllaços locals entre PDF requereixen l'aplicació d'escriptori + The existing action will be preserved. Es conservarà l'acció existent. + Minimize Minimitza + Maximize Maximitza + Restore Restaura + Use system title bar Utilitza la barra de títol del sistema + Show a basic title bar for the window buttons instead of the tab strip. GNOME doesn't draw title bars for apps, so this one doesn't follow its theme. Mostra una barra de títol bàsica per als botons de la finestra en lloc de la tira de pestanyes. GNOME no dibuixa barres de títol per a les aplicacions, de manera que aquesta no segueix el seu tema. + Allow Permet + Only allow this if you trust the source document. Permet-ho només si confies en el document d'origen. + Open this local PDF? Vols obrir aquest PDF local? + This document is trying to open a local file: Aquest document intenta obrir un fitxer local: + Move tag earlier Mou l'etiqueta cap amunt + Move tag later Mou l'etiqueta cap avall + Margins (in) Marges (polz.) +signature pad Type Escriu +calendar date January Gener +calendar date February Febrer +calendar date March Març +calendar date April Abril +calendar date May Maig +calendar date June Juny +calendar date July Juliol +calendar date August Agost +calendar date September Setembre +calendar date October Octubre +calendar date November Novembre +calendar date December Desembre + Text recognition isn't installed: its models are missing (run `cargo xtask models`, or set PDFCRAFT_MODELS). El reconeixement de text no està instal·lat: falten els seus models (executa `cargo xtask models` o defineix PDFCRAFT_MODELS). + PDF page: {size} Pàgina del PDF: {size} + Match page at 100% Ajusta la pàgina al 100 % + PDF scale: {scale}% Escala del PDF: {scale} % + Printer paper and scaling may differ. Check driver settings. El paper i l'escala de la impressora poden ser diferents. Revisa la configuració del controlador. + Drawing scale changes. Use Actual size for full-scale plans. L'escala del dibuix canvia. Utilitza Mida real per a plànols a escala completa. + Done adding text Acaba d'afegir text + Discard this text (Esc) Descarta aquest text (Esc) + Save (M4) Desa (M4) + Only the document's owner can change its security (open it with the permissions password) Només el propietari del document en pot canviar la seguretat (obre'l amb la contrasenya de permisos) + Creator Creador + Producer Productor + Enter a name. Escriu un nom. + The password must have at least 6 characters. La contrasenya ha de tenir almenys 6 caràcters. + The passwords do not match. Les contrasenyes no coincideixen. + There is no folder to save the digital ID in. No hi ha cap carpeta on desar l'identificador digital. + The password is incorrect. La contrasenya és incorrecta. + Choose a digital ID. Tria un identificador digital. + Unsigned signature field: {name} Camp de signatura sense signar: {name} + Rev. {rev}: Signed by {name} Rev. {rev}: signat per {name} + Rev. {rev}: Signed by an unknown signer Rev. {rev}: signat per un signant desconegut + Rev. {rev}: Certified by {name} Rev. {rev}: certificat per {name} + Rev. {rev}: Certified by an unknown signer Rev. {rev}: certificat per un signant desconegut + {who}, certificate issued by {issuer}. {who}, certificat emès per {issuer}. + {who}, certificate issued by an unknown issuer. {who}, certificat emès per un emissor desconegut. + Digital Signature Signatura digital + Non-Repudiation No repudi + Key Encipherment Xifratge de claus + Data Encipherment Xifratge de dades + Key Agreement Acord de claus + Certificate Signing Signatura de certificats + CRL Signing Signatura de CRL + Encipher Only Només xifratge + Decipher Only Només desxifratge + Enter a page number Introdueix un número de pàgina + Enter a URL Introdueix una URL + Enter the field names Introdueix els noms dels camps + Cut and stack needs Two-sided: Off. Print single-sided sheets. Tallar i apilar requereix Doble cara: desactivat. Imprimeix fulls a una cara. + Panel layout could not be restored: {error} No s'ha pogut restaurar la disposició dels taulers: {error} + Panel move was not applied: {error} No s'ha aplicat el moviment del tauler: {error} + Rendering… Renderitzant… + Still rendering — this page is unusually complex… Encara es renderitza — aquesta pàgina és inusualment complexa… + English Anglès +@plural {n} image optimized|{n} images optimized {n} imatge optimitzada|{n} imatges optimitzades +@plural {n} item discarded|{n} items discarded {n} element descartat|{n} elements descartats +@plural {n} byte|{n} bytes {n} byte|{n} bytes +@plural {n} pixel|{n} pixels {n} píxel|{n} píxels +@plural Delete {n} field|Delete {n} fields Suprimeix {n} camp|Suprimeix {n} camps + on page {label} a la pàgina {label} + Drop PDFs or folders here, or choose them. Deixa anar aquí PDF o carpetes, o tria'ls. + Every PDF in the folder Tots els PDF de la carpeta + Every PDF in the folder and the folders inside it Tots els PDF de la carpeta i de les carpetes que conté + No PDFs found in {folder} No s'ha trobat cap PDF a {folder} + Added the first {n} PDFs in {folder} S'han afegit els primers {n} PDF de {folder} + Add the PDFs to combine Afegeix els PDF per combinar + Document properties (⌘D) Propietats del document (⌘D) + New bookmark (⌘B) Marcador nou (⌘B) + Next (⌘G) Següent (⌘G) + Open a PDF (⌘O) Obre un PDF (⌘O) + Previous (⇧⌘G) Anterior (⇧⌘G) + Print (⌘P) Imprimeix (⌘P) + Rotate view clockwise (⇧⌘+) Gira la visualització en sentit horari (⇧⌘+) + Zoom in (⌘+) Amplia (⌘+) + Zoom in / out (also pinch or ⌘-scroll) Amplia / redueix (també amb pessic o ⌘-desplaçament) + Zoom out (⌘−) Redueix (⌘−) + Paste Enganxa + Select all Selecciona-ho tot + Next Següent + Previous Anterior + Choose… Tria… + Refresh Actualitza + Loading… Carregant… + Save changes? Vols desar els canvis? + Page {n} Pàgina {n} + of de + Comment Comentari + Font Tipus de lletra + Color Color + Theme Tema + System Sistema + Save file Desa el fitxer + Import Importa + Help… Ajuda… + Automatically Automàticament + Never Mai + Always Sempre + On Activat + Enabled Habilitat + Disabled Inhabilitat + Error Error + Warning Avís + Information Informació + Success Èxit + Folder Carpeta + Choose a file… Tria un fitxer… + Choose a folder… Tria una carpeta… + Open folder Obre la carpeta + Create folder Crea una carpeta + Duplicate Duplica + Move Mou + Copy to clipboard Copia al porta-retalls + Copied to clipboard S'ha copiat al porta-retalls + Organize Organitza + Comment and review Comenta i revisa + Search results Resultats de la cerca + No results Cap resultat + Page {n} of {total} Pàgina {n} de {total} +calendar weekday Su dg. +calendar weekday Mo dl. +calendar weekday Tu dt. +calendar weekday We dc. +calendar weekday Th dj. +calendar weekday Fr dv. +calendar weekday Sa ds. +certificate Issued to Emès per a +certificate Issued by Emès per +certificate Valid from Vàlid des de +certificate Valid to Vàlid fins a +certificate Intended usage Ús previst +certificate Version Versió +certificate Serial number Número de sèrie +certificate Issuer Emissor +certificate Validity starts La validesa comença +certificate Validity ends La validesa acaba +certificate Public key Clau pública +certificate Basic constraints Restriccions bàsiques +certificate Key usage Ús de la clau +certificate Self-signed Autosignat +certificate SHA-1 digest Resum SHA-1 +certificate SHA-256 digest Resum SHA-256 +@plural {n} file|{n} files {n} fitxer|{n} fitxers +@plural {n} comment|{n} comments {n} comentari|{n} comentaris +@plural {n} result|{n} results {n} resultat|{n} resultats + 4 x 6 in label (101.6 x 152.4 mm) Etiqueta de 4 x 6 polz. (101,6 x 152,4 mm) + Characters Caràcters + Characters without spaces Caràcters sense espais + Collapse all pages Replega totes les pàgines + Counting words… {n} pages read S'estan comptant les paraules… {n} pàgines llegides + Create Link… Crea un enllaç… + Crop Image Escapça la imatge + Current page only Només la pàgina actual + Cut Image Retalla la imatge + Cuts each page to its printed area, turns it upright and fits it to the sheet without stretching. One label per sheet. Escapça cada pàgina a la seva àrea impresa, la posa dreta i l'ajusta al full sense deformar-la. Una etiqueta per full. + DN: DN: + Date: Data: + Digitally signed by Signat digitalment per + Exclude image/OCR text Exclou el text d'imatges i OCR + Exclude tagged code blocks Exclou els blocs de codi etiquetats + Exclude tagged tables Exclou les taules etiquetades + Exclusions use PDF tags. Untagged tables and code remain included. Image exclusion also removes invisible text. Les exclusions utilitzen les etiquetes del PDF. Les taules i el codi sense etiquetar continuen inclosos. Excloure imatges també elimina el text invisible. + Expand all pages Desplega totes les pàgines + Fill colour: Color d'emplenament: + Find untagged content Cerca contingut sense etiquetar + Font size Mida del tipus de lletra + Found {n} untagged content problems. S'han trobat {n} problemes de contingut sense etiquetar. + Full Screen Pantalla completa + Hide hover previews for highlights without comment text Amaga les previsualitzacions en passar-hi per sobre dels ressaltats sense text de comentari + Location: Ubicació: + Make Properties Default Fes que les propietats siguin les predeterminades + Make properties default Fes que les propietats siguin les predeterminades + Mark as artifact Marca com a artefacte + Mark content as artifact Marca el contingut com a artefacte + Merge image fragments Fusiona els fragments d'imatge + Mobile Mòbil + New file only Només el fitxer nou + New file: {name} Fitxer nou: {name} + No printers were found. Check that the printer is installed and the print spooler is running, then open Print again. No s'ha trobat cap impressora. Comprova que la impressora estigui instal·lada i que el servei d'impressió s'estigui executant, i torna a obrir Imprimeix. + No untagged content was found. No s'ha trobat contingut sense etiquetar. + Not now Ara no + Old file: {name} Fitxer antic: {name} + Opacity: Opacitat: + Open in Full Screen mode? Vols obrir en mode de pantalla completa? + Optimizing… merging image fragments S'està optimitzant… fusionant fragments d'imatge + Outline colour: Color del contorn: + Page properties Propietats de la pàgina + Pages counted Pàgines comptades + Pages selected Pàgines seleccionades + Print as image Imprimeix com a imatge + Reason: Motiu: + Recognize Text… Reconeix el text… + Redact Image Censura la imatge + Redaction mark appearance Aparença de la marca de censura + Remove Crop Elimina l’escapçat + Remove this leaf tag from reading order and mark its direct content as an artifact Elimina aquesta etiqueta final de l'ordre de lectura i marca el seu contingut directe com a artefacte + Resolution: Resolució: + Save anyway Desa igualment + Save over the changed file? Vols desar sobre el fitxer modificat? + Scroll speed (mouse wheel and arrow keys) Velocitat de desplaçament (roda del ratolí i tecles de fletxa) + Sending sheet {s} of {n} to {printer}… S'està enviant el full {s} de {n} a {printer}… + Set page transitions Defineix les transicions de pàgina + Shown while the pointer is over a mark. Es mostra mentre el punter és sobre una marca. + Side by side Un al costat de l'altre + Some content could not be classified safely and was kept in the count. Part del contingut no s'ha pogut classificar amb seguretat i s'ha mantingut al recompte. + Some pages contain no countable text. Scanned images need OCR first. Algunes pàgines no tenen text comptable. Les imatges escanejades necessiten OCR abans. + Standard Estàndard + Tag form fields Etiqueta els camps del formulari + The labels are in English: the signature's font can't draw them in this language. Les etiquetes són en anglès: el tipus de lletra de la signatura no pot dibuixar-les en aquesta llengua. + The password must have at least 8 characters. La contrasenya ha de tenir almenys 8 caràcters. + This document asks to open in Full Screen mode: the page fills the screen and nothing else shows. Press Esc at any time to leave it. Aquest document demana obrir-se en mode de pantalla completa: la pàgina omple la pantalla i no es veu res més. Prem Esc en qualsevol moment per sortir-ne. + This file changed on disk. Reload shows the new version and drops your unsaved changes; Save replaces it with this version. Aquest fitxer ha canviat al disc. Recarrega mostra la versió nova i descarta els canvis sense desar; Desa la substitueix per aquesta versió. + Trim the picture with its handles; Enter or Done applies Escapça la imatge amb els seus tiradors; Retorn o Fet ho aplica + Turn upside down (180°) Gira cap per avall (180°) + Use it when a printer skips text, shading or transparency. The print is no longer searchable text; with Print in grayscale, the pictures are grey. Fes-ho servir quan una impressora ometi text, ombrejats o transparències. La impressió deixa de ser text cercable; amb Imprimeix en escala de grisos, les imatges són grises. + What takes up the space in this file, by kind of content. El que ocupa l'espai d'aquest fitxer, per tipus de contingut. + Word count Recompte de paraules + Word counting stopped unexpectedly. El recompte de paraules s'ha aturat de manera inesperada. + Word count… Recompte de paraules… + Words Paraules + “{name}” changed on disk after it was opened or last saved. Saving now replaces that newer version with this one. «{name}» ha canviat al disc després d'obrir-lo o d'haver-lo desat per última vegada. Si ara el deses, aquesta versió substituirà la més recent. +@id file.word_count Recompte de paraules… +theme Appearance Aspecte diff --git a/crates/ui-egui/src/i18n/mod.rs b/crates/ui-egui/src/i18n/mod.rs index 5bb2889c9..43229e75d 100644 --- a/crates/ui-egui/src/i18n/mod.rs +++ b/crates/ui-egui/src/i18n/mod.rs @@ -147,7 +147,7 @@ fn plural_sl(n: u64) -> usize { } /// The registry. English first: it is the fallback and the source language. -pub static LANGUAGES: [LangInfo; 23] = [ +pub static LANGUAGES: [LangInfo; 24] = [ LangInfo { code: "en", name: "English", source: "", plural: plural_one_other, rtl: false, catalog: OnceLock::new() }, LangInfo { code: "ja", name: "日本語", source: include_str!("ja.tsv"), plural: plural_none, rtl: false, catalog: OnceLock::new() }, // Simplified Chinese; `zh`, `zh-CN`, `zh-SG` and `zh-Hans-*` locales resolve here (see `candidates`). @@ -210,6 +210,8 @@ pub static LANGUAGES: [LangInfo; 23] = [ // Vietnamese; every `vi-*` locale (`vi-VN`, `vi_VN.UTF-8`) resolves here. CLDR `vi` counts have // one form ("other"), so `@plural` entries list a single form. LangInfo { code: "vi", name: "Tiếng Việt", source: include_str!("vi.tsv"), plural: plural_none, rtl: false, catalog: OnceLock::new() }, + // Catalan; every `ca-*` locale (`ca-ES`, `ca_ES.UTF-8`, `ca_ES@valencia`) resolves here. + LangInfo { code: "ca", name: "Català", source: include_str!("ca.tsv"), plural: plural_one_other, rtl: false, catalog: OnceLock::new() }, ]; impl LangInfo { @@ -2539,6 +2541,89 @@ mod tests { assert!(unchanged.is_empty(), "unapproved English Vietnamese catalog entries: {unchanged:#?}"); } + #[test] + fn catalan_is_registered_and_persists() { + let ca = Lang::from_code("ca").expect("ca registered"); + assert_eq!(ca.name(), "Català"); + assert_eq!(normalize_pref("CA"), Some("ca")); + for tag in ["ca", "ca-ES", "ca_ES.UTF-8", "CA-es", "ca_ES@valencia"] { + assert_eq!(lang_from_tag(tag), Some(ca), "{tag}"); + } + assert_eq!(first_supported("ca-ES\r\nen-US"), Some(ca)); + assert_eq!(tr(ca, "File"), "Fitxer"); + assert_eq!(tr(ca, "Save as…"), "Anomena i desa…"); + assert_eq!(tr(ca, "Cancel"), "Cancel·la"); + assert_eq!(tr_ctx(ca, "comment menu", "Edit"), "Edita"); + assert_eq!(tr_ctx(ca, "signature pad", "Type"), "Escriu"); + // one (1), other (0, 2+), as in English + assert_eq!((0..=3).map(|n| (ca.0.plural)(n)).collect::>(), [1, 0, 1, 1]); + assert_eq!(trn(ca, 1, "{n} page", "{n} pages"), "1 pàgina"); + assert_eq!(trn(ca, 3, "{n} page", "{n} pages"), "3 pàgines"); + let mut app = crate::PdfCraftApp::default(); + app.set_option("language", "CA").unwrap(); + assert_eq!(app.language, "ca"); + let mut restored = crate::PdfCraftApp::default(); + restored.restore(&app.persist()); + assert_eq!(restored.language, "ca"); + assert!(restored.set_option("language", "xx").is_err()); + assert_eq!(restored.language, "ca"); + } + + /// Catalan translates every registered command, menu, All tools group, section and item. + #[test] + fn catalan_covers_commands_and_catalogue() { + let ca = Lang::from_code("ca").expect("ca registered"); + for command in pdfcraft_engine::commands::COMMANDS { + assert!(has(ca, command.label), "missing command: {}", command.label); + if let Some(menu) = command.menu { + assert!(has(ca, menu), "missing menu: {menu}"); + } + } + for group in pdfcraft_engine::catalog::TOOL_GROUPS { + assert!(has(ca, group.label), "missing group: {}", group.label); + for section in group.sections { + assert!(has(ca, section.title), "missing section: {}", section.title); + for item in section.items { + assert!(has(ca, item.label), "missing item: {}", item.label); + } + } + } + } + + /// Catalan translates every `tl!("…")` literal in the UI source, so a new string can't ship in + /// English by accident. + #[test] + fn catalan_covers_ui_literals() { + let ca = Lang::from_code("ca").expect("ca registered"); + let literals = ui_literals(); + assert!(literals.len() > 900, "source scan found only {} literals", literals.len()); + let missing: Vec<_> = literals.iter().filter(|label| !has(ca, label)).collect(); + assert!(missing.is_empty(), "untranslated Catalan UI literals: {missing:#?}"); + } + + /// Catalan has every key the other bundled catalogs have (English keys, not their translations). + #[test] + fn catalan_covers_bundled_catalog_keys() { + let ca = Lang::from_code("ca").expect("ca registered"); + let mut missing = std::collections::BTreeSet::new(); + for reference in LANGUAGES.iter().filter(|language| language.code != "ca") { + let (entries, errors) = catalog::parse_entries(reference.source, reference.plural_forms()); + assert!(errors.is_empty(), "{}: invalid reference catalog: {errors:?}", reference.code); + for entry in entries { + let translated = match entry.context.as_str() { + "" => ca.catalog().plain(&entry.source), + "@id" => ca.catalog().id(&entry.source), + "@plural" => entry.source.split_once('|').and_then(|(one, other)| ca.catalog().plural(one, other, 0)), + context => ca.catalog().contextual(context, &entry.source), + }; + if translated.is_none() { + missing.insert((entry.context, entry.source)); + } + } + } + assert!(missing.is_empty(), "Catalan misses bundled catalog keys: {missing:#?}"); + } + #[test] fn slovene_is_registered_and_persists() { let sl = Lang::from_code("sl").expect("sl registered"); diff --git a/crates/ui-egui/tests/fonts.rs b/crates/ui-egui/tests/fonts.rs index 258abe89c..9580f7729 100644 --- a/crates/ui-egui/tests/fonts.rs +++ b/crates/ui-egui/tests/fonts.rs @@ -290,7 +290,7 @@ fn ui_fonts_work_without_craft_fonts() { theme::install_fonts(&ctx); } -/// Latin- and Cyrillic-script catalogs (Czech, Brazilian Portuguese, German, Spanish, French, Russian, Bulgarian, Hungarian, Ukrainian, Italian, Slovene) are drawn entirely by the app's own faces +/// Latin- and Cyrillic-script catalogs (Czech, Brazilian Portuguese, German, Spanish, French, Russian, Bulgarian, Hungarian, Ukrainian, Italian, Slovene, Catalan) are drawn entirely by the app's own faces /// (Inter, JetBrains Mono): no letter falls through to egui's defaults or a CJK fallback. (egui's /// `has_glyphs` can't answer this: with only the primary face it is also the replacement face.) #[test] @@ -314,6 +314,7 @@ fn primary_ui_fonts_cover_latin_and_cyrillic_catalogs() { ("sl", include_str!("../src/i18n/sl.tsv")), ("lt", include_str!("../src/i18n/lt.tsv")), ("vi", include_str!("../src/i18n/vi.tsv")), + ("ca", include_str!("../src/i18n/ca.tsv")), ] { let mut text = String::from("áčďéěíňóřšťúůýžÁČĎÉĚÍŇÓŘŠŤÚŮÝŽãõçâêôàÃÕÇÂÊÔÀñÑüÜäÄöÖőűß„“¿¡«»…ґҐєЄіІїЇәғқңөұүһӘҒҚҢӨҰҮҺ"); for line in catalog.lines().filter(|l| !l.starts_with('#')) { diff --git a/docs/localization-parity.md b/docs/localization-parity.md index 995293af3..95adfae46 100644 --- a/docs/localization-parity.md +++ b/docs/localization-parity.md @@ -70,13 +70,11 @@ none has translated help. Vietnamese's **To `full`** hours are therefore residua | Greek | `el` | 2,341 entries | partial | no | | Turkish | `tr` | 2,313 entries | partial | yes | | Lithuanian | `lt` | 2,585 entries | partial; community native-speaker review ([#1401](https://github.com/storytold/pdfcraft/pull/1401)) | no | +| Catalan | `ca` | 2,592 entries | partial: no translated help, engine error details in English; native-speaker review by the contributor | no | -**14 other languages** ship (22 catalogs plus English = **23** interface languages in Preferences). -The entry counts without percentages were measured on 2026-10-12–13; they are not percentages of the older 2,143-key snapshot above. Their presence does not imply a detailed linguistic or runtime review. +**15 other languages** ship (23 catalogs plus English = **24** interface languages in Preferences). +The entry counts without percentages were measured on 2026-10-12–14; they are not percentages of the older 2,143-key snapshot above. Their presence does not imply a detailed linguistic or runtime review. Acrobat languages PdfCraft lacks: Danish, Dutch, Finnish, Norwegian, Swedish, Hebrew. Vietnamese is shipped here but not by Acrobat. -**14 other languages** ship (21 catalogs plus English, 22 interface languages in Preferences). -The entry counts without percentages were measured on 2026-10-12 (Italian on 2026-10-14); they are not percentages of the older 2,143-key snapshot above. Their presence does not imply a detailed linguistic or runtime review. -Acrobat languages PdfCraft lacks: Danish, Dutch, Finnish, Norwegian, Swedish, Hebrew. ## Revision history @@ -84,5 +82,6 @@ Acrobat languages PdfCraft lacks: Danish, Dutch, Finnish, Norwegian, Swedish, He |---|---|---| | 2026-10-13 | minor | Vietnamese (`vi`) catalog: 2,591 entries (100% of current key union + `theme`/`Appearance`); twelve-language mean ≈ 68%; native-speaker community review; registered with `plural_none` | | 2026-10-14 | minor | Italian: 2,528 entries after adding the 201 keys the other catalogs had and the code looks up | +| 2026-10-14 | minor | Added Catalan (`ca`, 2,592 entries, measured 2026-10-14); retained existing language assessments | | 2026-10-12 | minor | Added current counts for Kazakh, Polish, Slovenian, Greek, Turkish and Lithuanian; retained existing language assessments and the original percentage snapshot | | 2026-10-10 | major | Created. Catalog counts measured from `crates/ui-egui/src/i18n/*.tsv` against the 2,143-key union; Acrobat's localizations from its bundle's `.lproj` and Sequences folder names | diff --git a/docs/localization.md b/docs/localization.md index 657e2eb24..fef4fd99c 100644 --- a/docs/localization.md +++ b/docs/localization.md @@ -1,10 +1,10 @@ # Interface language -Choose **Menu > Edit > Preferences…** (Command-comma on macOS, Ctrl-comma elsewhere) **> Interface language** and select **Auto**, **English**, **日本語**, **简体中文**, **繁體中文**, **Čeština**, **Português (Brasil)**, **Deutsch**, **Español**, **Français**, **Русский**, **Қазақша**, **Български**, **తెలుగు**, **Magyar**, **Українська**, **Italiano**, **العربية**, **Polski**, **Slovenščina**, **Ελληνικά**, **Türkçe**, **Lietuvių** or **Tiếng Việt**. The change applies immediately and persists between launches. Command ids, document contents and file names are unchanged. +Choose **Menu > Edit > Preferences…** (Command-comma on macOS, Ctrl-comma elsewhere) **> Interface language** and select **Auto**, **English**, **日本語**, **简体中文**, **繁體中文**, **Čeština**, **Português (Brasil)**, **Deutsch**, **Español**, **Français**, **Русский**, **Қазақша**, **Български**, **తెలుగు**, **Magyar**, **Українська**, **Italiano**, **العربية**, **Polski**, **Slovenščina**, **Ελληνικά**, **Türkçe**, **Lietuvių**, **Tiếng Việt** or **Català**. The change applies immediately and persists between launches. Command ids, document contents and file names are unchanged. Displayed keyboard shortcuts use the same active interface language. For example, German shows `Strg+K` and `Strg+Umschalt+S` in the toolbar, menus, command palette, tooltips and Keyboard shortcuts dialog; macOS keeps its modifier symbols (`⌘`, `⇧`, `⌃`). Key names have their own `key` catalog context, so the Delete key can read `Entf` while the command remains `Löschen`. A missing key-name entry falls back to the English key name. Actual bindings and machine-facing command ids remain stable. -**Auto** (the default) follows the system language: `LC_ALL`, `LC_MESSAGES` or `LANG`, then the preferred-languages list on macOS. Any Portuguese locale (`pt_BR`, `pt_PT`) uses the Brazilian catalog, any French locale (`fr`, `fr_FR`, `fr_CA`, `fr_BE`) the French one, any German locale (`de`, `de_DE`, `de_AT`, `de_CH`) the German one, and Chinese locales for Taiwan, Hong Kong and Macau (`zh_TW`, `zh_HK`, `zh_MO`, `zh-Hant`) the Traditional Chinese one; other Chinese locales (`zh`, `zh_CN`, `zh_SG`, `zh-Hans`) the Simplified Chinese one. Telugu locales (`te`, `te_IN`) use the Telugu catalog, Bulgarian locales (`bg`, `bg_BG`) the Bulgarian one, and Hungarian locales (`hu`, `hu_HU`) the Hungarian one, and Ukrainian locales (`uk`, `uk_UA`) the Ukrainian one, and Italian locales (`it`, `it_IT`, `it_CH`) the Italian one, and Arabic locales (`ar`, `ar_MA`, `ar_EG`, `ar_SA`, …) the Arabic one, and Turkish locales (`tr`, `tr_TR`) the Turkish one, and Slovenian locales (`sl`, `sl_SI`) the Slovenian one, and Vietnamese locales (`vi`, `vi_VN`) the Vietnamese one. A system language without a catalog shows English. On Windows, **Auto** uses the Windows display languages, in preference order, when no supported locale is selected by those environment variables. Neutral `C`/`POSIX` locale values (including `C.UTF-8`) inherited from a launcher do not override the Windows display language; explicitly named supported locales such as `fr_FR.UTF-8` still do. The query asks Windows directly (`GetUserPreferredUILanguages`, through the `sys-locale` crate) without starting a process, and is cached for the process. If detection fails or the display language has no catalog, PdfCraft shows English. +**Auto** (the default) follows the system language: `LC_ALL`, `LC_MESSAGES` or `LANG`, then the preferred-languages list on macOS. Any Portuguese locale (`pt_BR`, `pt_PT`) uses the Brazilian catalog, any French locale (`fr`, `fr_FR`, `fr_CA`, `fr_BE`) the French one, any German locale (`de`, `de_DE`, `de_AT`, `de_CH`) the German one, and Chinese locales for Taiwan, Hong Kong and Macau (`zh_TW`, `zh_HK`, `zh_MO`, `zh-Hant`) the Traditional Chinese one; other Chinese locales (`zh`, `zh_CN`, `zh_SG`, `zh-Hans`) the Simplified Chinese one. Telugu locales (`te`, `te_IN`) use the Telugu catalog, Bulgarian locales (`bg`, `bg_BG`) the Bulgarian one, and Hungarian locales (`hu`, `hu_HU`) the Hungarian one, and Ukrainian locales (`uk`, `uk_UA`) the Ukrainian one, and Italian locales (`it`, `it_IT`, `it_CH`) the Italian one, and Arabic locales (`ar`, `ar_MA`, `ar_EG`, `ar_SA`, …) the Arabic one, and Turkish locales (`tr`, `tr_TR`) the Turkish one, and Slovenian locales (`sl`, `sl_SI`) the Slovenian one, and Vietnamese locales (`vi`, `vi_VN`) the Vietnamese one, and Catalan locales (`ca`, `ca_ES`, `ca_AD`, `ca_ES@valencia`, …) the Catalan one. A system language without a catalog shows English. On Windows, **Auto** uses the Windows display languages, in preference order, when no supported locale is selected by those environment variables. Neutral `C`/`POSIX` locale values (including `C.UTF-8`) inherited from a launcher do not override the Windows display language; explicitly named supported locales such as `fr_FR.UTF-8` still do. The query asks Windows directly (`GetUserPreferredUILanguages`, through the `sys-locale` crate) without starting a process, and is cached for the process. If detection fails or the display language has no catalog, PdfCraft shows English. The control channel exposes the setting through `ui.set`: @@ -12,7 +12,7 @@ The control channel exposes the setting through `ui.set`: {"method":"ui.set","params":{"key":"language","value":"ja"}} ``` -The value is `auto` or a language code (`en`, `ja`, `zh-hans`, `zh-hant`, `cs`, `pt-br`, `de`, `es`, `fr`, `ru`, `kk`, `bg`, `te`, `hu`, `uk`, `it`, `ar`, `pl`, `sl`, `el`, `tr`, `lt` or `vi`), in any case. `ui.state` reports `language` as written in the preferences (`auto`, `en`, `ja`, `zh-hans`, `zh-hant`, `cs`, `pt-br`, `de`, `es`, `fr`, `ru`, `kk`, `bg`, `te`, `hu`, `uk`, `it`, `ar`, `pl`, `sl`, `el`, `tr`, `lt` or `vi`). Unknown values return an error without changing the current setting. Preferences saved before this setting existed follow the system language. +The value is `auto` or a language code (`en`, `ja`, `zh-hans`, `zh-hant`, `cs`, `pt-br`, `de`, `es`, `fr`, `ru`, `kk`, `bg`, `te`, `hu`, `uk`, `it`, `ar`, `pl`, `sl`, `el`, `tr`, `lt`, `vi` or `ca`), in any case. `ui.state` reports `language` as written in the preferences (`auto`, `en`, `ja`, `zh-hans`, `zh-hant`, `cs`, `pt-br`, `de`, `es`, `fr`, `ru`, `kk`, `bg`, `te`, `hu`, `uk`, `it`, `ar`, `pl`, `sl`, `el`, `tr`, `lt`, `vi` or `ca`). Unknown values return an error without changing the current setting. Preferences saved before this setting existed follow the system language. Dialogs, panels, menus, notices and history labels go through the catalog (`tl!`). Most shipped catalogs (Japanese, Chinese, Russian, Bulgarian, German, Spanish, French, Telugu, Hungarian, Ukrainian, Italian, Brazilian Portuguese, Arabic, Slovenian, Kazakh, Polish, Greek, Turkish, Lithuanian, Vietnamese and others) cover the current localizable surface (about 2,000–2,600 entries each); Czech still covers mainly the menus. Untranslated labels use English. Error details that come from the engine or the operating system are shown as they are, inside a translated frame ("操作「…」に失敗しました: …"). The command palette matches the translated label, the English label and the command id. Vertical Japanese PDF rendering is an existing viewer feature; this change does not add vertical text editing. Document contents, filenames, CLI/MCP/control protocol strings and external help stay outside the catalog. Per-language coverage, script support and what each language still needs are in [localization-parity.md](localization-parity.md). Dialogs, panels, menus, notices and history labels go through the catalog (`tl!`). Japanese, Traditional Chinese, Simplified Chinese, Russian, Bulgarian, German, Spanish, French, Telugu, Hungarian, Ukrainian, Brazilian Portuguese and Arabic translate them (about 2,000–2,140 entries each), and Italian has 2,528 entries; Czech and Turkish cover the menus so far. Untranslated labels use English. Error details that come from the engine or the operating system are shown as they are, inside a translated frame ("操作「…」に失敗しました: …"). The command palette matches the translated label, the English label and the command id. Vertical Japanese PDF rendering is an existing viewer feature; this change does not add vertical text editing. Per-language coverage, script support and what each language still needs are in [localization-parity.md](localization-parity.md). @@ -24,6 +24,8 @@ The Ukrainian catalog has 2,047 entries, written from the meaning of the English The Lithuanian catalog has 2,585 entries and three integer plural forms. Calendar headings use standalone month names; dates use genitive forms. Coverage tests check commands/tools, scanned literal and direct lookups, and source/context keys in the other bundled catalogs. Calendar, inspector and password-dialog UI regressions check dynamic labels and preserve document values. A native Lithuanian-speaking contributor has reviewed the translation. +The Catalan catalog has 2,592 entries, written from the meaning of the English labels in standard Catalan computing vocabulary. Commands use the second-person imperative (`Desa`, `Obre`, `Cancel·la`) and notices use impersonal or informal wording. Catalan has two plural forms like English (1 is singular; 0 and every other count take the plural: `1 pàgina`, `3 pàgines`). Every `ca-*` locale, including Valencian (`ca_ES@valencia`), uses this catalog. The interpunct of `l·l` is U+00B7, which the bundled Latin faces cover (tested in `tests/fonts.rs`). The date picker has Catalan month and weekday names; dates are day-first like French (`dddd d mmmm yyyy`), but after a day the month carries its own preposition, elided before a vowel (`7 de març`, `7 d'abril`, `8 d'octubre`), as Czech and Russian change theirs through `months_with_day`; the year takes `\de` from the pattern (`d mmmm \de yyyy`). A native Catalan speaker (the contributor) has reviewed the translation. + The Vietnamese catalog has 2,591 entries and one plural form (`plural_none`). Preferences theme `Appearance` uses context `theme` → `Giao diện`; object/comment/signature appearance stays plain `Diện mạo`. Form fields use `Trường`; redaction apply wording states permanent removal. Calendar months are numeric (`Tháng 1`…`12` / `tháng 1`…`12`). Coverage tests require every current command, UI literal, bundled key and credit label. A native Vietnamese-speaking contributor has reviewed the translation. Status stays `partial`: no translated help, and engine/OS details stay English inside a translated frame. Edit text reads Hebrew lines in typing order and writes them back in drawing order (`crates/edit/src/bidi.rs`); letters the page's own font lacks are drawn with the craft-fonts `Hebr` face (Noto Sans Hebrew) as Type 3 glyphs, and a build without one says so. Hebrew points (niqqud) can't be written yet in Edit text. Add text (#128) draws Hebrew with the same face through the shaped path Arabic and Thai use: right to left with numbers and Latin in place, points kept on their letter, and typing order for copy and search. The craft-fonts revision pinned for CI and releases has no `Hebr` face yet, so until one is added releases report that error instead of drawing the missing letters, and refuse Hebrew in Add text. diff --git a/docs/roadmap.md b/docs/roadmap.md index 3148823ea..e441e2297 100644 --- a/docs/roadmap.md +++ b/docs/roadmap.md @@ -192,6 +192,7 @@ M2 (renderer), M7 (content editing), M10 (OCR and Office), M11 (Preflight and st | 2026-10-14 | minor | M5: reconciled PR #1457 with upstream main, preserving comment submission shortcuts and upstream roadmap progress. Estimates unchanged. | | 2026-10-13 | minor | M2/M6: images with at most 16 bits of samples a pixel (8-bit Separation/DeviceN, 1-4-bit gray or indexed) convert once per pixel value (hayro-interpret patch 28), so spot-colour form backgrounds draw in milliseconds instead of seconds; widgets without `/P` are placed in one pass; the Fields panel no longer searches the form per row and draws only the rows in view. Estimates unchanged. | | 2026-10-13 | minor | M3: native-open admission preserves modal/picker ownership; regressions cover queued replies and one-shot picker wakes. Estimates unchanged | +| 2026-10-14 | minor | M14: Catalan interface and date language (2,592-entry catalog, coverage tests). Estimates unchanged | | 2026-10-12 | minor | M13: CLI check directory identity, with overlap and symlink regressions; estimates unchanged | | 2026-10-12 | minor | M4: shared Type 3 glyph resources survive extraction, with save/reopen and independent raster regressions; estimates unchanged | | 2026-10-12 | minor | M2: packed TIFF-predictor RGB row boundaries, with decoding and page-render regressions; estimates unchanged | From 7e68ef44d581728bef50f173cb921e419f89fa05 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Cie=C5=9Blik?= <132496025+Hathor875@users.noreply.github.com> Date: Thu, 15 Oct 2026 17:43:46 +0200 Subject: [PATCH 035/498] fix(combine): let the cards zoom to 500% (#2531) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The Combine grid stopped at 200%, too small to read a value off an invoice while reordering the pages of a statement. The main viewer already reached 6400%, so only the card grid was capped. - The range is 60–500%, and the buttons and keys step 60/80/100/125/150/175/200/250/300/400/500%. - MAX_SIDE, the thumbnail texture cap, goes 768 → 1536, so a card near the top re-renders sharper instead of upscaling a 768px texture. It only binds near the top: a card below it asks for less and costs no more than it did. Up there one thumbnail is a few megabytes, so TEXTURE_BUDGET and UPLOAD_BYTES_PER_FRAME keep the cache at a screenful plus one frame's uploads — and a screenful at the top of the range is a card or two, because a card is wider than most windows. - The control channel's range message is derived from the constant rather than repeating "60 and 200", so it cannot drift from the range again. --- crates/ui-egui/src/combine_grid.rs | 45 ++++++++++++++++----- crates/ui-egui/src/lib.rs | 3 +- crates/ui-egui/tests/combine_grid.rs | 60 +++++++++++++++++++++++----- parity/acrobat-features.toml | 4 +- 4 files changed, 89 insertions(+), 23 deletions(-) diff --git a/crates/ui-egui/src/combine_grid.rs b/crates/ui-egui/src/combine_grid.rs index e0336d969..ee3b03f69 100644 --- a/crates/ui-egui/src/combine_grid.rs +++ b/crates/ui-egui/src/combine_grid.rs @@ -34,9 +34,13 @@ const UPLOAD_BYTES_PER_FRAME: usize = 8 << 20; /// view are kept even over budget (at most a screenful of thumbnails of at most [`MAX_SIDE`]). const TEXTURE_BUDGET: usize = 32 << 20; /// The longest side of a thumbnail, in pixels. -/// (Room for a Letter page at 200% on a screen of 1.5 pixels per point; sharper screens upscale a -/// little at the largest sizes.) -const MAX_SIDE: f32 = 768.0; +/// (Room for a Letter page at 500% on a screen of 1.5 pixels per point; sharper screens upscale a +/// little at the largest sizes.) This only binds near the top of the zoom range: a card below it +/// asks for less than this and costs no more than it did. Near the top one thumbnail is a few +/// megabytes, so [`TEXTURE_BUDGET`] and [`UPLOAD_BYTES_PER_FRAME`] keep the cache at a screenful +/// plus one frame's uploads — and at the top of the range a screenful is a card or two, because a +/// card is wider than most windows. +const MAX_SIDE: f32 = 1536.0; /// Thumbnail sizes round up to this many pixels, so a slightly different layout reuses them. const SIZE_STEP: u32 = 16; /// The box a page is fitted in at 100%, and the room the card adds around it (for the hover bar @@ -50,8 +54,8 @@ const ABOVE: f32 = 32.0; const BAR_H: f32 = 34.0; /// The grid's zoom range, and the sizes its buttons and keys step through (the slider, the wheel /// and a pinch go anywhere between). -pub(crate) const ZOOM_RANGE: std::ops::RangeInclusive = 0.6..=2.0; -const ZOOM_STEPS: [f32; 7] = [0.6, 0.8, 1.0, 1.25, 1.5, 1.75, 2.0]; +pub(crate) const ZOOM_RANGE: std::ops::RangeInclusive = 0.6..=5.0; +const ZOOM_STEPS: [f32; 11] = [0.6, 0.8, 1.0, 1.25, 1.5, 1.75, 2.0, 2.5, 3.0, 4.0, 5.0]; /// The next size up (or down) from `zoom`; the end of the range stays put. pub(crate) fn zoom_step(zoom: f32, larger: bool) -> f32 { @@ -1371,10 +1375,10 @@ mod tests { // The box follows the zoom, within its range; nonsense is 100%. assert_eq!(paper_box(1.0), PAPER); assert_eq!(paper_box(2.0), PAPER * 2.0); - assert_eq!(paper_box(99.0), PAPER * 2.0); + assert_eq!(paper_box(99.0), PAPER * 5.0); assert_eq!(paper_box(-1.0), PAPER * 0.6); assert_eq!(paper_box(f32::NAN), PAPER); - for zoom in [0.6, 1.0, 2.0] { + for zoom in [0.6, 1.0, 2.0, 5.0] { let fit = paper_box(zoom); // Letter is a little wider than the box: it fills the width. A tall page fills the height. let letter = paper_size(612.0, 792.0, fit).unwrap(); @@ -1394,12 +1398,12 @@ mod tests { fn zoom_buttons_step_through_round_sizes() { let mut z = 0.6; let mut up = vec![z]; - while z < 2.0 { + while z < 5.0 { z = zoom_step(z, true); up.push(z); } assert_eq!(up, ZOOM_STEPS); - assert_eq!(zoom_step(2.0, true), 2.0, "the largest stays put"); + assert_eq!(zoom_step(5.0, true), 5.0, "the largest stays put"); assert_eq!(zoom_step(0.6, false), 0.6, "the smallest stays put"); // From anywhere the slider left it, to the next round size. assert_eq!(zoom_step(1.1, true), 1.25); @@ -1408,6 +1412,29 @@ mod tests { assert_eq!(zoom_step(1.0000001, true), 1.25, "a hair over a size counts as that size"); } + #[test] + fn the_cards_zoom_far_enough_to_read_a_value() { + // #2531: the grid stopped at 200%, which was not enough to read invoice values while + // reordering the pages of a statement. It has to reach 500%. + assert_eq!(*ZOOM_RANGE.end(), 5.0, "the grid stops at {}%, not 500%", ZOOM_RANGE.end() * 100.0); + assert_eq!(paper_box(5.0), PAPER * 5.0, "500% is kept, not clamped to the old ceiling"); + // Every round size above the old 200% ceiling is a step the toolbar can reach. + let mut z = *ZOOM_RANGE.start(); + let mut up = vec![z]; + while z < *ZOOM_RANGE.end() { + z = zoom_step(z, true); + up.push(z); + } + for want in [2.5, 3.0, 4.0, 5.0] { + assert!(up.contains(&want), "no step reaches {want}%: {up:?}"); + } + // A card stays sharp at the ceiling instead of upscaled from the old 768px cap. A Letter + // page fills the height of the box, so at 500% it needs PAPER.y * 5.0 points of it, which + // on a 1.5 pixels-per-point screen is this many pixels. + let wanted = PAPER.y * 5.0 * 1.5; + assert!(MAX_SIDE >= wanted, "MAX_SIDE {MAX_SIDE} is under the {wanted}px a card needs at 500%"); + } + #[test] fn arrow_keys_step_by_file_and_by_row() { // The list: one at a time, staying put at both ends. diff --git a/crates/ui-egui/src/lib.rs b/crates/ui-egui/src/lib.rs index f800ad6a0..c6e7c6652 100644 --- a/crates/ui-egui/src/lib.rs +++ b/crates/ui-egui/src/lib.rs @@ -2586,7 +2586,8 @@ impl PdfCraftApp { ("combine-zoom", _) => { let percent = value.trim_end_matches('%').parse::().map_err(|e| e.to_string())?; if !percent.is_finite() || !combine_grid::ZOOM_RANGE.contains(&(percent / 100.0)) { - return Err("combine-zoom must be between 60 and 200".into()); + let (lo, hi) = (combine_grid::ZOOM_RANGE.start(), combine_grid::ZOOM_RANGE.end()); + return Err(format!("combine-zoom must be between {} and {}", lo * 100.0, hi * 100.0)); } self.set_combine_zoom(percent / 100.0); } diff --git a/crates/ui-egui/tests/combine_grid.rs b/crates/ui-egui/tests/combine_grid.rs index a447933cc..4ed7b5778 100644 --- a/crates/ui-egui/tests/combine_grid.rs +++ b/crates/ui-egui/tests/combine_grid.rs @@ -403,7 +403,8 @@ fn thumbnails_show_the_first_page_each_file_takes() { assert!(matches!(thumbs[0], CombineThumb::Ready { page: 2, .. }), "\"3, 1\" starts with page 3: {:?}", thumbs[0]); assert!(matches!(thumbs[1], CombineThumb::Ready { page: 0, .. })); let CombineThumb::Ready { width, height, .. } = thumbs[1] else { unreachable!() }; - assert!(width > 0 && height > 0 && width <= 768 && height <= 768, "{width}×{height}"); + // Within MAX_SIDE (combine_grid), which is not visible from here. + assert!(width > 0 && height > 0 && width <= 1536 && height <= 1536, "{width}×{height}"); // A new range is a new thumbnail, never the old page. h.state_mut().combine_draft[0].range = "2".into(); assert!(settle(&mut h, |app| matches!(app.combine_thumbnails()[0], CombineThumb::Ready { page: 1, .. }))); @@ -541,7 +542,8 @@ fn long_thin_pages_get_thumbnails_within_the_size_limits() { assert!(settle(&mut h, |app| app.combine_thumbnails().iter().all(|t| *t != CombineThumb::None && *t != CombineThumb::Pending))); for t in h.state().combine_thumbnails() { match t { - CombineThumb::Ready { width, height, .. } => assert!(width <= 768 && height <= 768, "{width}×{height}"), + // Within MAX_SIDE (combine_grid), which is not visible from here. + CombineThumb::Ready { width, height, .. } => assert!(width <= 1536 && height <= 1536, "{width}×{height}"), other => panic!("each strip gets a thumbnail: {other:?}"), } } @@ -728,15 +730,15 @@ fn the_toolbar_sizes_the_cards_within_limits_and_the_size_is_kept_in_the_setting assert_eq!(h.state().combine_zoom, 1.25); let after = card(&h, "a.pdf"); assert!(after.width() > before.width() && after.height() > before.height(), "{before:?} → {after:?}"); - // Larger until it can't go further: 200%, and the button says so. - for _ in 0..10 { + // Larger until it can't go further: 500% (#2531), and the button says so. + for _ in 0..12 { if disabled(&h, "Larger pages") { break; } h.get_by_label("Larger pages").click(); h.run_steps(2); } - assert_eq!(h.state().combine_zoom, 2.0); + assert_eq!(h.state().combine_zoom, 5.0); assert!(disabled(&h, "Larger pages")); // The percentage resets it. h.get_by_label("Reset page size").click(); @@ -758,17 +760,22 @@ fn the_toolbar_sizes_the_cards_within_limits_and_the_size_is_kept_in_the_setting fresh.restore(&saved); assert_eq!(fresh.combine_zoom, 0.6); fresh.restore(r#"{"combine_zoom": 99}"#); - assert_eq!(fresh.combine_zoom, 2.0); + assert_eq!(fresh.combine_zoom, 5.0); fresh.restore(r#"{"combine_zoom": "big"}"#); - assert_eq!(fresh.combine_zoom, 2.0); + assert_eq!(fresh.combine_zoom, 5.0); // Scriptable in percent, with a clear refusal outside the range. let app = h.state_mut(); app.set_option("combine-zoom", "150%").unwrap(); assert_eq!(app.combine_zoom, 1.5); - for bad in ["59", "201", "big", "NaN", "inf", ""] { + // #2531: 200% was not enough to read a value off a card; 500% has to be reachable. + for pct in ["200", "300", "400", "500"] { + app.set_option("combine-zoom", pct).unwrap(); + assert_eq!(app.combine_zoom, pct.parse::().unwrap() / 100.0); + } + for bad in ["59", "501", "big", "NaN", "inf", ""] { assert!(app.set_option("combine-zoom", bad).is_err(), "{bad:?}"); } - assert_eq!(app.combine_zoom, 1.5); + assert_eq!(app.combine_zoom, 5.0, "a refused value leaves the size alone"); // The list has no card size. h.get_by_label("List view").click(); h.run_steps(2); @@ -780,7 +787,7 @@ fn the_slider_sizes_the_cards_from_smallest_to_largest() { let mut h = grid_of_pages(&[("a.pdf", 1), ("b.pdf", 1)]); let slider = h.get_by_label("Page size").rect(); drag(&mut h, slider.center(), slider.right_center() + vec2(40.0, 0.0)); - assert_eq!(h.state().combine_zoom, 2.0); + assert_eq!(h.state().combine_zoom, 5.0); let slider = h.get_by_label("Page size").rect(); drag(&mut h, slider.center(), slider.left_center() - vec2(40.0, 0.0)); assert_eq!(h.state().combine_zoom, 0.6); @@ -883,7 +890,38 @@ fn zooming_keeps_the_card_under_the_pointer_in_place_and_thumbnails_never_go_bla } #[test] -fn dragging_and_arrow_keys_work_at_the_smallest_and_largest_sizes() { +fn cards_at_the_top_zoom_render_a_sharper_thumbnail_within_the_texture_limit() { + // #2531: raising the ceiling is only worth something if the thumbnail gets sharper with it. + // The texture cap was 768px, which upscaled any card past 200%. + let mut h = grid_of_pages(&[("a.pdf", 1)]); + h.state_mut().set_option("combine-zoom", "100").unwrap(); + assert!(settle(&mut h, |app| ready(&app.combine_thumbnails()[0]))); + let CombineThumb::Ready { width: w0, height: h0, .. } = h.state().combine_thumbnails()[0] else { unreachable!() }; + let at_100 = w0.max(h0); + + h.state_mut().set_option("combine-zoom", "500").unwrap(); + // The old thumbnail stands in until the sharper one arrives, so "ready" is not enough: wait + // for the size to actually change. + let mut redrawn = false; + for _ in 0..400 { + h.run_steps(1); + if matches!(h.state().combine_thumbnails()[0], CombineThumb::Ready { width, height, .. } if width.max(height) != at_100) { + redrawn = true; + break; + } + std::thread::sleep(Duration::from_millis(10)); + } + let CombineThumb::Ready { width, height, .. } = h.state().combine_thumbnails()[0] else { unreachable!() }; + let at_500 = width.max(height); + assert!(redrawn, "500% never re-rendered the thumbnail: {width}×{height}"); + assert!(at_500 <= 1536, "past the texture limit: {width}×{height}"); + assert!(at_500 >= at_100 * 4, "500% is not sharper than 100%: {at_100}px → {at_500}px"); +} + +// 60% against a large size, rather than the largest: at 500% a card is wider than this viewport, +// so only one fits across and "down moves a row" would have nothing to check. +#[test] +fn dragging_and_arrow_keys_work_at_the_smallest_and_a_large_size() { let mut columns = Vec::new(); for zoom in ["60", "200"] { let files: Vec<(String, Vec)> = (0..24).map(|i| (format!("f{i:02}.pdf"), fixture(1))).collect(); diff --git a/parity/acrobat-features.toml b/parity/acrobat-features.toml index 3f56e207a..c3431b5e8 100644 --- a/parity/acrobat-features.toml +++ b/parity/acrobat-features.toml @@ -2992,8 +2992,8 @@ milestone = "M4" status = "shipped" commands = ["page.combine"] tools = ["doc_combine"] -evidence = ["crates/ui-egui/tests/combine_grid.rs::combine_shows_a_grid_by_default_and_the_view_is_kept_in_the_settings", "crates/ui-egui/tests/combine_grid.rs::cards_select_like_the_list_and_the_selection_survives_switching_views", "crates/ui-egui/tests/combine_grid.rs::dragging_a_card_moves_it_and_undo_puts_it_back", "crates/ui-egui/tests/combine_grid.rs::a_dragged_selection_moves_together_to_the_first_and_last_gaps", "crates/ui-egui/tests/combine_grid.rs::thumbnails_show_the_first_page_each_file_takes", "crates/ui-egui/tests/combine_grid.rs::many_files_render_only_what_is_in_view_a_few_at_a_time", "crates/ui-egui/tests/combine_grid.rs::long_thin_pages_get_thumbnails_within_the_size_limits", "crates/ui-egui/tests/combine_grid.rs::combine_follows_the_order_shown_in_the_grid", "crates/ui-egui/src/combine_grid.rs::render_threads_never_exceed_three_while_files_come_and_go", "crates/ui-egui/src/combine_grid.rs::textures_over_budget_go_longest_unseen_first_and_those_in_view_stay", "crates/ui-egui/src/combine_grid.rs::on_the_web_one_thumbnail_waits_at_a_time", "crates/ui-egui/tests/combine_grid.rs::a_file_whose_pages_cant_be_measured_says_there_is_no_preview", "crates/ui-egui/tests/combine_grid.rs::the_toolbar_sizes_the_cards_within_limits_and_the_size_is_kept_in_the_settings", "crates/ui-egui/tests/combine_grid.rs::ctrl_keys_and_ctrl_wheel_size_the_cards_and_leave_the_window_alone", "crates/ui-egui/tests/combine_grid.rs::zooming_keeps_the_card_under_the_pointer_in_place_and_thumbnails_never_go_blank", "crates/ui-egui/tests/combine_grid.rs::zooming_quickly_never_runs_more_than_three_render_threads", "crates/ui-egui/tests/combine_grid.rs::hovering_a_card_shows_its_trash_and_magnifier_and_only_then", "crates/ui-egui/tests/combine_grid.rs::the_card_trash_removes_only_that_file_and_undo_brings_it_back", "crates/ui-egui/tests/combine_grid.rs::the_magnifier_shows_the_file_large_and_flips_through_the_pages_it_adds", "crates/ui-egui/tests/combine_grid.rs::the_preview_closes_when_its_file_leaves_and_keeps_to_three_render_threads", "crates/ui-egui/tests/combine_grid.rs::a_right_click_on_a_card_offers_preview_and_remove", "crates/ui-egui/tests/combine_grid.rs::space_shows_the_selected_file_large_in_the_grid_and_the_list", "crates/ui-egui/tests/combine_grid.rs::expanding_a_file_shows_the_pages_it_adds_in_order_with_their_numbers", "crates/ui-egui/tests/combine_grid.rs::expand_all_and_collapse_all_from_the_toolbar_and_a_right_click", "crates/ui-egui/tests/combine_grid.rs::expanding_is_a_view_kept_across_views_and_zoom_and_never_an_undo_step", "crates/ui-egui/tests/combine_grid.rs::dragging_a_page_moves_that_page_even_between_another_files_pages", "crates/ui-egui/tests/combine_grid.rs::combining_with_files_expanded_gives_the_same_document", "crates/ui-egui/tests/combine_grid.rs::a_page_click_selects_that_page_and_the_arrows_step_rows_of_cards", "crates/ui-egui/tests/combine_grid.rs::a_page_cards_magnifier_opens_the_preview_on_that_page", "crates/ui-egui/tests/combine_grid.rs::a_long_file_expanded_renders_only_its_pages_in_view_within_three_threads", "crates/ui-egui/tests/combine_grid.rs::collapsing_brings_the_files_card_into_view", "crates/ui-egui/tests/combine_grid.rs::a_file_too_long_to_spread_out_offers_no_expand", "crates/ui-egui/src/combine_grid.rs::the_next_page_of_a_file_reuses_its_open_document_until_it_closes", "crates/ui-egui/tests/combine_grid.rs::removing_pages_from_the_hover_bar_the_toolbar_and_delete_never_touches_the_file", "crates/ui-egui/tests/combine_grid.rs::a_split_file_counts_once_and_combines_with_one_bookmark", "crates/ui-egui/src/combine_ui.rs::a_page_moved_between_another_files_pages_splits_its_file_and_parts_rejoin", "crates/ui-egui/src/combine_ui.rs::removing_pages_drops_emptied_parts_and_joins_what_meets", "crates/ui-egui/src/combine_ui.rs::page_lists_become_the_shortest_range", "crates/ui-egui/tests/combine_grid.rs::pages_picked_out_of_sight_or_before_an_undo_are_let_go_of", "crates/ui-egui/tests/combine_grid.rs::a_files_parts_join_when_what_was_between_them_goes_and_one_file_cannot_be_combined", "crates/organize/src/tests.rs::a_page_shown_twice_gets_its_own_annotations", "crates/engine/src/tests.rs::a_page_with_a_form_field_shown_twice_keeps_one_field", "crates/ui-egui/tests/combine_grid.rs::files_picked_by_automation_let_go_of_the_pages_picked"] -notes = "Combine files shows a card per file (the default; Grid/List toggle kept in the settings, --combine-view grid|list): the first page the file contributes (its page range's first page), stacked when it contributes more, and its name shortened in the middle. Cards are sized from 60% to 200% (toolbar slider, buttons and percentage reset, Ctrl/⌘ +/−/0, Ctrl/⌘ with the wheel or a pinch over the grid; kept in the settings, --combine-zoom 60..200), keeping the card under the pointer in place. Hovering a card shows its own actions along the top of its page: remove that file only (whatever else is selected; undoable) and a magnifier that shows the file large, flipping through the pages it adds (buttons, Left/Right; Esc, close or a click outside closes it), also on the card's right-click menu, and Space shows the selected file large (the way there by keyboard). Cards select (click, Ctrl, Shift, arrows by card and by row), drag to reorder (one undo step; the grid scrolls at its edges) and share the list's toolbar. Thumbnails render off the UI thread, only for cards in view, sized to both sides of the page and at most 768 px; at most three render threads at once, counted as threads until they exit (no watchdog replacements; a page stuck for good in one step that can't be interrupted keeps its thread, and so its place, for the rest of the run); textures out of view are dropped over a 32 MB budget (those in view are kept). Locked, unreadable and bad-range files show why instead of a page, and a file whose page size can't be read (e.g. opened with an RC4 owner password) says No preview; page ranges are edited in the list. On the web a thumbnail, and the page shown large, render on the UI thread (one per frame, and only one waits at a time), so a very slow or very large page stalls that frame. A file that adds more than one page (up to 2000) expands into its pages (hover bar, right-click, or Expand all / Collapse all in the toolbar): one card per page it adds, in its range's order, each saying Page N and the file's name, on a tinted band; a click on a page selects that page, Up/Down step rows of cards, dragging a file's card moves the whole file (a drop among a file's pages goes to its nearer end), and its magnifier opens the preview on that page; expanding is a view, not an undo step, and changes nothing in the combined file; a page's render reuses its file's open document for a moment rather than reading the file again. With a file expanded, single pages are selected (click, Ctrl, Shift), dragged anywhere (a page moved between another file's pages splits its file into parts, shown as rows in the list with their own page ranges; parts side by side join again) and removed (a page card's trash, the toolbar, Delete), each one undo step, never changing the files themselves; a split file still counts and combines as one file." +evidence = ["crates/ui-egui/tests/combine_grid.rs::combine_shows_a_grid_by_default_and_the_view_is_kept_in_the_settings", "crates/ui-egui/tests/combine_grid.rs::cards_select_like_the_list_and_the_selection_survives_switching_views", "crates/ui-egui/tests/combine_grid.rs::dragging_a_card_moves_it_and_undo_puts_it_back", "crates/ui-egui/tests/combine_grid.rs::a_dragged_selection_moves_together_to_the_first_and_last_gaps", "crates/ui-egui/tests/combine_grid.rs::thumbnails_show_the_first_page_each_file_takes", "crates/ui-egui/tests/combine_grid.rs::many_files_render_only_what_is_in_view_a_few_at_a_time", "crates/ui-egui/tests/combine_grid.rs::long_thin_pages_get_thumbnails_within_the_size_limits", "crates/ui-egui/tests/combine_grid.rs::combine_follows_the_order_shown_in_the_grid", "crates/ui-egui/src/combine_grid.rs::render_threads_never_exceed_three_while_files_come_and_go", "crates/ui-egui/src/combine_grid.rs::textures_over_budget_go_longest_unseen_first_and_those_in_view_stay", "crates/ui-egui/src/combine_grid.rs::on_the_web_one_thumbnail_waits_at_a_time", "crates/ui-egui/tests/combine_grid.rs::a_file_whose_pages_cant_be_measured_says_there_is_no_preview", "crates/ui-egui/tests/combine_grid.rs::the_toolbar_sizes_the_cards_within_limits_and_the_size_is_kept_in_the_settings", "crates/ui-egui/src/combine_grid.rs::the_cards_zoom_far_enough_to_read_a_value", "crates/ui-egui/tests/combine_grid.rs::ctrl_keys_and_ctrl_wheel_size_the_cards_and_leave_the_window_alone", "crates/ui-egui/tests/combine_grid.rs::zooming_keeps_the_card_under_the_pointer_in_place_and_thumbnails_never_go_blank", "crates/ui-egui/tests/combine_grid.rs::zooming_quickly_never_runs_more_than_three_render_threads", "crates/ui-egui/tests/combine_grid.rs::hovering_a_card_shows_its_trash_and_magnifier_and_only_then", "crates/ui-egui/tests/combine_grid.rs::the_card_trash_removes_only_that_file_and_undo_brings_it_back", "crates/ui-egui/tests/combine_grid.rs::the_magnifier_shows_the_file_large_and_flips_through_the_pages_it_adds", "crates/ui-egui/tests/combine_grid.rs::the_preview_closes_when_its_file_leaves_and_keeps_to_three_render_threads", "crates/ui-egui/tests/combine_grid.rs::a_right_click_on_a_card_offers_preview_and_remove", "crates/ui-egui/tests/combine_grid.rs::space_shows_the_selected_file_large_in_the_grid_and_the_list", "crates/ui-egui/tests/combine_grid.rs::expanding_a_file_shows_the_pages_it_adds_in_order_with_their_numbers", "crates/ui-egui/tests/combine_grid.rs::expand_all_and_collapse_all_from_the_toolbar_and_a_right_click", "crates/ui-egui/tests/combine_grid.rs::expanding_is_a_view_kept_across_views_and_zoom_and_never_an_undo_step", "crates/ui-egui/tests/combine_grid.rs::dragging_a_page_moves_that_page_even_between_another_files_pages", "crates/ui-egui/tests/combine_grid.rs::combining_with_files_expanded_gives_the_same_document", "crates/ui-egui/tests/combine_grid.rs::a_page_click_selects_that_page_and_the_arrows_step_rows_of_cards", "crates/ui-egui/tests/combine_grid.rs::a_page_cards_magnifier_opens_the_preview_on_that_page", "crates/ui-egui/tests/combine_grid.rs::a_long_file_expanded_renders_only_its_pages_in_view_within_three_threads", "crates/ui-egui/tests/combine_grid.rs::collapsing_brings_the_files_card_into_view", "crates/ui-egui/tests/combine_grid.rs::a_file_too_long_to_spread_out_offers_no_expand", "crates/ui-egui/src/combine_grid.rs::the_next_page_of_a_file_reuses_its_open_document_until_it_closes", "crates/ui-egui/tests/combine_grid.rs::removing_pages_from_the_hover_bar_the_toolbar_and_delete_never_touches_the_file", "crates/ui-egui/tests/combine_grid.rs::a_split_file_counts_once_and_combines_with_one_bookmark", "crates/ui-egui/src/combine_ui.rs::a_page_moved_between_another_files_pages_splits_its_file_and_parts_rejoin", "crates/ui-egui/src/combine_ui.rs::removing_pages_drops_emptied_parts_and_joins_what_meets", "crates/ui-egui/src/combine_ui.rs::page_lists_become_the_shortest_range", "crates/ui-egui/tests/combine_grid.rs::pages_picked_out_of_sight_or_before_an_undo_are_let_go_of", "crates/ui-egui/tests/combine_grid.rs::a_files_parts_join_when_what_was_between_them_goes_and_one_file_cannot_be_combined", "crates/organize/src/tests.rs::a_page_shown_twice_gets_its_own_annotations", "crates/engine/src/tests.rs::a_page_with_a_form_field_shown_twice_keeps_one_field", "crates/ui-egui/tests/combine_grid.rs::files_picked_by_automation_let_go_of_the_pages_picked"] +notes = "Combine files shows a card per file (the default; Grid/List toggle kept in the settings, --combine-view grid|list): the first page the file contributes (its page range's first page), stacked when it contributes more, and its name shortened in the middle. Cards are sized from 60% to 500% (toolbar slider, buttons and percentage reset, Ctrl/⌘ +/−/0, Ctrl/⌘ with the wheel or a pinch over the grid; the buttons step 60/80/100/125/150/175/200/250/300/400/500%, kept in the settings, --combine-zoom 60..500), keeping the card under the pointer in place. 200% used to be the ceiling, which was too small to read values off an invoice while reordering the pages of a statement (#2531). Hovering a card shows its own actions along the top of its page: remove that file only (whatever else is selected; undoable) and a magnifier that shows the file large, flipping through the pages it adds (buttons, Left/Right; Esc, close or a click outside closes it), also on the card's right-click menu, and Space shows the selected file large (the way there by keyboard). Cards select (click, Ctrl, Shift, arrows by card and by row), drag to reorder (one undo step; the grid scrolls at its edges) and share the list's toolbar. Thumbnails render off the UI thread, only for cards in view, sized to both sides of the page and at most 1536 px (room for a Letter page at 500% on a 1.5 pixels-per-point screen); at most three render threads at once, counted as threads until they exit (no watchdog replacements; a page stuck for good in one step that can't be interrupted keeps its thread, and so its place, for the rest of the run); textures out of view are dropped over a 32 MB budget (those in view are kept). Locked, unreadable and bad-range files show why instead of a page, and a file whose page size can't be read (e.g. opened with an RC4 owner password) says No preview; page ranges are edited in the list. On the web a thumbnail, and the page shown large, render on the UI thread (one per frame, and only one waits at a time), so a very slow or very large page stalls that frame. A file that adds more than one page (up to 2000) expands into its pages (hover bar, right-click, or Expand all / Collapse all in the toolbar): one card per page it adds, in its range's order, each saying Page N and the file's name, on a tinted band; a click on a page selects that page, Up/Down step rows of cards, dragging a file's card moves the whole file (a drop among a file's pages goes to its nearer end), and its magnifier opens the preview on that page; expanding is a view, not an undo step, and changes nothing in the combined file; a page's render reuses its file's open document for a moment rather than reading the file again. With a file expanded, single pages are selected (click, Ctrl, Shift), dragged anywhere (a page moved between another file's pages splits its file into parts, shown as rows in the list with their own page ranges; parts side by side join again) and removed (a page card's trash, the toolbar, Delete), each one undo step, never changing the files themselves; a split file still counts and combines as one file." [[feature]] id = "organize.combine-options" From 963609d7d611be382584f88b0191b943a912d2a5 Mon Sep 17 00:00:00 2001 From: fanyzp Date: Fri, 16 Oct 2026 00:31:49 +0800 Subject: [PATCH 036/498] fix(edit): draw the Cyrillic the Japanese faces lack with the bundled Inter face (#2593) --- crates/automation/src/tools.rs | 2 +- crates/automation/tests/automation.rs | 53 ++++++++++++++++ crates/edit/src/tests.rs | 54 +++++++++++++--- crates/edit/src/text.rs | 90 ++++++++++++++++++++++----- crates/fonts/src/craft.rs | 32 ++++++++++ crates/fonts/src/lib.rs | 4 +- docs/editing-existing-text.md | 6 +- parity/acrobat-features.toml | 4 +- 8 files changed, 216 insertions(+), 29 deletions(-) diff --git a/crates/automation/src/tools.rs b/crates/automation/src/tools.rs index 5e89aef78..e91c31427 100644 --- a/crates/automation/src/tools.rs +++ b/crates/automation/src/tools.rs @@ -1276,7 +1276,7 @@ pub fn tools() -> Vec { .ro() .cmd("edit.edit_text") .with(schema(json!({ "doc": doc(), "page": { "type": "integer", "minimum": 1 }, "paragraph": { "type": "integer", "minimum": 1 }, "text": { "type": "string" }, "size": { "type": "number" }, "width": { "type": "number" }, "font_resource":{"type":"string"}, "ranges":{"type":"array","maxItems":1024,"items":{"type":"object"}} }), &["doc", "page", "paragraph"])), - t("text_edit", "Edit text", "Replace the text of one paragraph (paragraph, from text_paragraphs: rewrapped to the paragraph's width with its line spacing) or one line (line, from text_lines) in place, keeping position, size and colour. For a mixed-style region, editor_text supplies visual row breaks; surviving text keeps its source-run styles and inserted text inherits the surrounding run. For a paragraph, also change its formatting: font (helvetica, times, courier) with bold/italic, size (points), color (#rrggbb), align (left, center, right, justify), underline, line_spacing (× size), char_spacing (points) and scale (horizontal, percent), or move it (dx, dy in points; up is +dy) and rewrap it to a new width (points); text may then be omitted. Its own font is reused when it can show every character and no font/weight change is requested; otherwise it uses a standard font matching the source style or, for Japanese and other text no standard font can show (Cyrillic, Greek), real Mincho/Gothic fallback outlines matching the requested/source family and available weight, from a face that has every character (the result shows the font used). Missing Japanese weights use Regular, not synthetic bold; the small web build has only Gothic Regular. Paragraph bold may be set without font to keep the source family. Text that no available font can show is refused. Undoable.") + t("text_edit", "Edit text", "Replace the text of one paragraph (paragraph, from text_paragraphs: rewrapped to the paragraph's width with its line spacing) or one line (line, from text_lines) in place, keeping position, size and colour. For a mixed-style region, editor_text supplies visual row breaks; surviving text keeps its source-run styles and inserted text inherits the surrounding run. For a paragraph, also change its formatting: font (helvetica, times, courier) with bold/italic, size (points), color (#rrggbb), align (left, center, right, justify), underline, line_spacing (× size), char_spacing (points) and scale (horizontal, percent), or move it (dx, dy in points; up is +dy) and rewrap it to a new width (points); text may then be omitted. Its own font is reused when it can show every character and no font/weight change is requested; otherwise it uses a standard font matching the source style or, for text no standard font can show, real fallback outlines from PdfCraft's own faces, from the one that has every character: the craft-fonts Japanese faces (Mincho/Gothic matching the requested/source family and available weight) or, behind them, the bundled Inter face, which carries the Latin, Greek and Cyrillic letters they lack (Uzbek қ, Kazakh ә). The result shows the font used. Missing Japanese weights use Regular, not synthetic bold; the small web build has only Gothic Regular. Paragraph bold may be set without font to keep the source family. Text that no available font can show is refused. Undoable.") .cmd("edit.edit_text") .with(schema( json!({ "doc": doc(), "page": { "type": "integer", "minimum": 1 }, "line": { "type": "integer", "minimum": 1 }, diff --git a/crates/automation/tests/automation.rs b/crates/automation/tests/automation.rs index 1e662d8f3..e6640985e 100644 --- a/crates/automation/tests/automation.rs +++ b/crates/automation/tests/automation.rs @@ -2474,6 +2474,59 @@ fn editing_existing_text_through_tools() { assert_eq!(p["lines"].as_array().map(Vec::len), Some(2), "{p}"); } +/// #2593: a paragraph whose own font cannot show a character is written from PdfCraft's fallback +/// faces. The Cyrillic the craft-fonts faces lack (Uzbek қ ғ ҳ, Kazakh ә ө ү ұ һ) comes from the +/// bundled Inter face, so the edit is not refused even without `CRAFT_FONTS_DIR`, and the words +/// survive a save and a reopen. (`crates/edit/src/tests.rs::uzbek_and_kazakh_cyrillic_use_the_bundled_latin_face` +/// pins which face drew them.) +#[test] +fn editing_uzbek_and_kazakh_cyrillic_through_tools() { + let dir = workdir("cyrillic-fallback"); + let body = "BT /F1 12 Tf 14.4 TL 1 0 0 1 72 700 Tm (The quick brown fox jumps over the lazy dog) Tj T* (and keeps running through the long field.) Tj ET"; + std::fs::write(dir.join("cy.pdf"), win_ansi_paragraph_pdf(body)).unwrap(); + let mut a = auto(&dir); + let doc = ok(&mut a, "doc_open", json!({ "path": "cy.pdf" }))["doc"].as_u64().unwrap(); + for word in ["қизил", "әже"] { + let text = format!("The quick brown fox jumps over the lazy dog {word}\nand keeps running through the long field."); + let edited = ok(&mut a, "text_edit", json!({ "doc": doc, "page": 1, "paragraph": 1, "text": text })); + let paragraph = edited["paragraph"]["text"].as_str().unwrap(); + assert!(paragraph.starts_with("The quick brown fox") && paragraph.ends_with("long field."), "{word}: {edited}"); + assert!(paragraph.contains(word), "{word}: {edited}"); + assert!(page_text(&mut a, doc)[0].contains(word), "{word}: the edited page reads it back"); + assert_eq!(ok(&mut a, "edit_undo", json!({ "doc": doc }))["undone"], "Edit text"); + } + // Keep the Kazakh edit, save it, and read it back from the file on disk. + let text = "The quick brown fox jumps over the lazy dog әже\nand keeps running through the long field."; + ok(&mut a, "text_edit", json!({ "doc": doc, "page": 1, "paragraph": 1, "text": text })); + ok(&mut a, "doc_save", json!({ "doc": doc, "path": "cy-out.pdf" })); + let saved = ok(&mut a, "doc_open", json!({ "path": "cy-out.pdf" }))["doc"].as_u64().unwrap(); + assert!(page_text(&mut a, saved)[0].contains("әже"), "the saved file reads it back"); +} + +/// One Letter page whose Helvetica is not embedded (WinAnsi), with `body` as its content stream. +fn win_ansi_paragraph_pdf(body: &str) -> Vec { + let objs: Vec = vec![ + "<< /Type /Catalog /Pages 2 0 R >>".into(), + "<< /Type /Pages /Kids [3 0 R] /Count 1 /MediaBox [0 0 612 792] >>".into(), + "<< /Type /Page /Parent 2 0 R /Contents 4 0 R /Resources << /Font << /F1 5 0 R >> >> >>".into(), + format!("<< /Length {} >>\nstream\n{body}\nendstream", body.len()), + "<< /Type /Font /Subtype /Type1 /BaseFont /Helvetica /Encoding /WinAnsiEncoding >>".into(), + ]; + let mut bytes = b"%PDF-1.7\n".to_vec(); + let mut offsets = Vec::new(); + for (i, o) in objs.iter().enumerate() { + offsets.push(bytes.len()); + bytes.extend_from_slice(format!("{} 0 obj\n{o}\nendobj\n", i + 1).as_bytes()); + } + let xref = bytes.len(); + bytes.extend_from_slice(format!("xref\n0 {}\n0000000000 65535 f \n", objs.len() + 1).as_bytes()); + for o in offsets { + bytes.extend_from_slice(format!("{o:010} 00000 n \n").as_bytes()); + } + bytes.extend_from_slice(format!("trailer\n<< /Size {} /Root 1 0 R >>\nstartxref\n{xref}\n%%EOF\n", objs.len() + 1).as_bytes()); + bytes +} + /// One page whose content is one stream in three pieces (#155): a `TJ` array ends the middle /// piece and its operator starts the last one. fn split_streams_pdf() -> Vec { diff --git a/crates/edit/src/tests.rs b/crates/edit/src/tests.rs index b542142df..5c4b1dfda 100644 --- a/crates/edit/src/tests.rs +++ b/crates/edit/src/tests.rs @@ -1085,6 +1085,44 @@ fn cyrillic_in_a_serif_line_falls_back_to_a_face_that_has_it() { } } +/// #2593: the craft-fonts faces are Japanese, and part of the Cyrillic (Uzbek қ ғ ҳ, Kazakh ә ө ү +/// ұ һ) is in none of them. The bundled Inter face has it, so the replacement is written instead of +/// being refused, and a build without craft-fonts can do it too. +#[test] +fn uzbek_and_kazakh_cyrillic_use_the_bundled_latin_face() { + for replacement in ["The quick brown fox jumps over the lazy dog қизил", "әже", "ўзбекча ғўза"] { + for paragraph in [false, true] { + let mut doc = text_page("BT /F2 12 Tf 72 700 Td (ab) Tj ET"); + let edit = + if paragraph { text::replace_block(&mut doc, 0, 0, replacement) } else { text::replace_line(&mut doc, 0, 0, replacement) }.unwrap(); + assert_eq!(edit.substituted.as_deref(), Some("Inter Type3"), "{replacement}: {edit:?}"); + let content = String::from_utf8_lossy(&page_content_bytes(&doc, 0)).into_owned(); + assert!(content.contains("/PCLat"), "{replacement}: {content}"); + let lines = text::text_lines(&reopen(&doc), 0).unwrap(); + assert_eq!(lines[0].text, replacement); + assert_eq!(lines[0].base_font, "Inter-Regular", "the generated font reports the face it drew"); + } + } +} + +/// The Japanese faces keep first refusal for the Cyrillic they do carry, so Russian text keeps the +/// face it was drawn with before the bundled Latin face was added. +#[test] +fn cyrillic_the_japanese_faces_carry_keeps_them() { + if without_craft_fonts("cyrillic_the_japanese_faces_carry_keeps_them") { + return; + } + let face = pdfcraft_fonts::document_japanese_font_for_style(false, false).unwrap(); + if pdfcraft_fonts::japanese_glyph_from(face, 'ф').is_err() { + eprintln!("skipping: the Japanese fallback face has no Cyrillic"); + return; + } + let mut doc = text_page("BT /F2 12 Tf 72 700 Td (ab) Tj ET"); + let edit = text::replace_line(&mut doc, 0, 0, "Привет, world").unwrap(); + let expected = format!("{} Type3", face.family); + assert_eq!(edit.substituted.as_deref(), Some(expected.as_str())); +} + #[test] fn japanese_paragraph_uses_unicode_type3_fallback() { if without_craft_fonts("japanese_paragraph_uses_unicode_type3_fallback") { @@ -4186,16 +4224,18 @@ fn a_new_character_comes_from_the_source_fonts_own_embedded_program() { #[test] fn a_subset_program_is_not_trusted_for_new_characters_and_the_error_names_the_character() { + let mut doc = embedded_program_page("BT /F1 12 Tf 72 700 Td (Stable text) Tj ET", "ABCDEF+Inter-Regular"); + // The subset's own program is not trusted for a character: the bundled Inter face draws it + // through a generated font instead (the subset may map a code whose outline was dropped). + let edit = text::rewrite_block(&mut doc, 0, 0, Some("Stable tőxt"), &text::BlockStyle::default()).unwrap(); + assert_eq!(edit.substituted.as_deref(), Some("Inter Type3")); + assert_eq!(text::text_blocks(&reopen(&doc), 0).unwrap()[0].editor_text, "Stable tőxt"); + // A character no fallback face has is refused, named, and left as it was. let mut doc = embedded_program_page("BT /F1 12 Tf 72 700 Td (Stable text) Tj ET", "ABCDEF+Inter-Regular"); let before = page_content_bytes(&doc, 0); - let result = text::rewrite_block(&mut doc, 0, 0, Some("Stable tőxt"), &text::BlockStyle::default()); - if pdfcraft_fonts::document_japanese_font().is_some() { - eprintln!("built with craft-fonts: the fallback font draws the new character"); - assert!(result.is_ok(), "{result:?}"); - return; - } + let result = text::rewrite_block(&mut doc, 0, 0, Some("Stable กtext"), &text::BlockStyle::default()); let Err(EditError::Invalid(msg)) = result else { panic!("expected a clear error, got {result:?}") }; - assert!(msg.contains("ő (U+0151)") && msg.contains("Load font") && !msg.contains("Japanese"), "{msg}"); + assert!(msg.contains("ก (U+0E01)") && msg.contains("Load font") && !msg.contains("Japanese"), "{msg}"); assert_eq!(page_content_bytes(&doc, 0), before); } diff --git a/crates/edit/src/text.rs b/crates/edit/src/text.rs index 9c83cf9a3..7f1a6d2ac 100644 --- a/crates/edit/src/text.rs +++ b/crates/edit/src/text.rs @@ -1303,12 +1303,28 @@ fn needs_type3(text: &str) -> bool { const JAPANESE_FONT_NAME: &str = "PCJapanese"; /// The `/Name` of the Type 3 fonts generated for Hebrew text. const HEBREW_FONT_NAME: &str = "PCHebrew"; +/// The `/Name` of the Type 3 fonts generated from the bundled Latin (Inter) face. +const LATIN_FONT_NAME: &str = "PCLatin"; -/// Whether `font` is one of those generated fonts (Japanese or Hebrew): a replacement longer than -/// one of them is split across several, which read back as one line (see [`same_font`]). +/// Whether `font` is one of those generated fonts (Latin, Japanese or Hebrew): a replacement longer +/// than one of them is split across several, which read back as one line (see [`same_font`]). fn is_type3_fallback(font: &Dict) -> bool { font.name(b"Subtype") == Some(b"Type3") - && font.name(b"Name").is_some_and(|n| n == JAPANESE_FONT_NAME.as_bytes() || n == HEBREW_FONT_NAME.as_bytes()) + && font + .name(b"Name") + .is_some_and(|n| n == JAPANESE_FONT_NAME.as_bytes() || n == HEBREW_FONT_NAME.as_bytes() || n == LATIN_FONT_NAME.as_bytes()) +} + +/// The generated font's `/Name` and its resource prefix: the bundled Latin face, Hebrew, or the +/// Japanese ones. +fn fallback_names(face: &CraftFont, hebrew: bool) -> (&'static str, &'static str) { + if hebrew { + (HEBREW_FONT_NAME, "PCHe") + } else if face.family == "Inter" { + (LATIN_FONT_NAME, "PCLat") + } else { + (JAPANESE_FONT_NAME, "PCJp") + } } /// Whether a run shown in `font` (a resource name, and the Japanese or Hebrew fallback face it subsets, if @@ -1340,7 +1356,8 @@ const MAX_TYPE3_GLYPHS: usize = 240; struct Type3Fallback { /// The family its glyphs come from ("Shippori Mincho"). family: &'static str, - /// The fonts' resource names in order; the first is `PCJp` (`PCHe` for Hebrew text). + /// The fonts' resource names in order; the first is `PCJp` (`PCLat` for the bundled Latin + /// face, `PCHe` for Hebrew text). names: Vec, /// Every unique character with its advance (em), in order of first appearance. widths: Vec<(char, f64)>, @@ -1414,11 +1431,19 @@ fn unicode_hex(ch: char) -> String { encoded.iter().map(|u| format!("{u:04X}")).collect() } -/// No font this build has can draw `text`. Only Japanese text is about the Japanese face: other +/// The same outline for a face that may simply lack the glyph: `None` then, so the caller can try +/// the next face (and report the character once none of them has it). +fn type3_glyph(face: &CraftFont, ch: char) -> Result, f64)>, EditError> { + match japanese_glyph_from(face, ch) { + Err(GlyphError::Missing) => Ok(None), + _ => type3_path(face, ch).map(Some), + } +} + +/// No face this build has can draw `text`. Only Japanese text is about the Japanese face: other /// characters are missing from the paragraph's font, and choosing a font that has them works too. fn no_fallback_font(text: &str) -> EditError { - let japanese = |c: char| matches!(u32::from(c), 0x3000..=0x30FF | 0x3400..=0x4DBF | 0x4E00..=0x9FFF | 0xF900..=0xFAFF | 0xFF00..=0xFFEF); - if text.chars().any(japanese) { + if text.chars().any(needs_japanese) { return no_japanese_font(); } let Some(ch) = text.chars().find(|c| !c.is_whitespace() && !is_win_ansi_char(*c)) else { return no_japanese_font() }; @@ -1430,6 +1455,28 @@ fn no_fallback_font(text: &str) -> EditError { )) } +/// The character the craft-fonts Japanese faces are for: kana, CJK ideographs and their compatibility +/// and full-width forms. +fn needs_japanese(ch: char) -> bool { + matches!(u32::from(ch), 0x3000..=0x30FF | 0x3400..=0x4DBF | 0x4E00..=0x9FFF | 0xF900..=0xFAFF | 0xFF00..=0xFFEF) +} + +/// The chosen face has no outline for `ch`, and neither has any other: say which character it is and +/// what the writer can do about it. A CJK character without a Japanese face in the build is about +/// that build input, which is the one answer that changes it. +fn no_glyph_for(face: &CraftFont, ch: char) -> EditError { + if needs_japanese(ch) && pdfcraft_fonts::document_japanese_font().is_none() { + return no_japanese_font(); + } + EditError::Invalid(format!( + "the {} fallback font has no glyph for {ch} (U+{:04X}), and no fallback face covers the text; \ + choose a font that has it (Load font… or Installed fonts…), or use an official release, which includes \ + PdfCraft's fallback fonts (to build them in, set CRAFT_FONTS_DIR to a craft-fonts checkout)", + face.family, + u32::from(ch) + )) +} + /// This build has no Japanese face to draw replacement text with. fn no_japanese_font() -> EditError { EditError::Invalid( @@ -1454,12 +1501,15 @@ fn no_hebrew_font() -> EditError { } /// The faces a Type 3 replacement may draw `text` with, best first. Text with Hebrew takes the -/// Hebrew face first (its Latin and digits too, so a line keeps one look), then the Japanese -/// faces for anything it lacks; other text takes the Japanese faces, as before. +/// Hebrew face first (its Latin and digits too, so a line keeps one look), then the Japanese faces +/// and the bundled Latin one for anything it lacks; other text takes the Japanese faces, and the +/// bundled Latin face behind them, which covers the Latin, Greek and Cyrillic letters they lack +/// (#2593: the Japanese faces have no қ, ғ, ҳ, ә, ө, ү, ұ or һ). fn type3_faces(text: &str, family: crate::added::Family, bold: bool) -> Result<(Vec<&'static CraftFont>, bool), EditError> { let japanese = pdfcraft_fonts::document_japanese_fonts_for_style(family == crate::added::Family::Times, bold); + let latin = pdfcraft_fonts::document_latin_fonts(bold); if !text.chars().any(crate::bidi::is_hebrew) { - return Ok((japanese, false)); + return Ok((japanese.into_iter().chain(latin).collect(), false)); } // Points are drawn on their letter with the font's positioning, which a one-glyph-per- // character Type 3 font can't do; refuse rather than print them beside the letter. @@ -1467,7 +1517,7 @@ fn type3_faces(text: &str, family: crate::added::Family, bold: bool) -> Result<( return Err(EditError::Invalid("Hebrew points (niqqud) can't be written into a PDF yet; type the text without them".into())); } let hebrew = pdfcraft_fonts::document_hebrew_font(bold).ok_or_else(no_hebrew_font)?; - Ok((std::iter::once(hebrew).chain(japanese).collect(), true)) + Ok((std::iter::once(hebrew).chain(japanese).chain(latin).collect(), true)) } fn type3_font( @@ -1501,8 +1551,16 @@ fn type3_font( let per_font = max_glyphs.clamp(1, MAX_TYPE3_GLYPHS); let mut glyphs = Vec::with_capacity(chars.len()); for (i, ch) in chars.into_iter().enumerate() { - // Hebrew text: the first face with the glyph, else the Hebrew face's error. - let (path, width) = others.iter().fold(type3_path(face, ch), |found, f| found.or_else(|e| type3_path(f, ch).map_err(|_| e)))?; + // The chosen face first, then the faces after it (Hebrew text takes a character the Hebrew + // face lacks from the next face that has it); a character no face draws is reported once. + let mut drawn = type3_glyph(face, ch)?; + for f in others.iter().copied() { + if drawn.is_some() { + break; + } + drawn = type3_glyph(f, ch)?; + } + let Some((path, width)) = drawn else { return Err(no_glyph_for(face, ch)) }; let code = u8::try_from((i % per_font).saturating_add(1)) .map_err(|_| EditError::Invalid("replacement text has too many unique characters".into()))?; glyphs.push(Type3Glyph { code, ch, path, width }); @@ -1526,7 +1584,7 @@ fn type3_font( } /// Adds one generated font whose codes 1 to `glyphs.len()` show `glyphs`, and returns its resource -/// name (`PCJp`, then `PCJp1`, ...; `PCHe`, ... for Hebrew text). Nothing here can fail: the +/// name (`PCLat`, `PCJp`, then `PCJp1`, ...; `PCHe`, ... for Hebrew text). Nothing here can fail: the /// outlines were read already. fn add_type3_font(doc: &mut Document, fonts_res: &mut Dict, face: &CraftFont, hebrew: bool, glyphs: Vec) -> String { let last_char = glyphs.len(); @@ -1557,7 +1615,8 @@ fn add_type3_font(doc: &mut Document, fonts_res: &mut Dict, face: &CraftFont, he let mut font = Dict::new(); font.set(b"Type".to_vec(), Object::name("Font")); font.set(b"Subtype".to_vec(), Object::name("Type3")); - font.set(b"Name".to_vec(), Object::name(if hebrew { HEBREW_FONT_NAME } else { JAPANESE_FONT_NAME })); + let (font_name, prefix) = fallback_names(face, hebrew); + font.set(b"Name".to_vec(), Object::name(font_name)); let mut descriptor = Dict::new(); descriptor.set(b"Type".to_vec(), Object::name("FontDescriptor")); descriptor.set(b"FontName".to_vec(), Object::name(&format!("{}-{}", face.family, face.style).replace(' ', ""))); @@ -1577,7 +1636,6 @@ fn add_type3_font(doc: &mut Document, fonts_res: &mut Dict, face: &CraftFont, he font.set(b"Encoding".to_vec(), Object::Dict(encoding)); font.set(b"CharProcs".to_vec(), Object::Dict(charprocs)); font.set(b"ToUnicode".to_vec(), Object::Ref(cmap_ref)); - let prefix = if hebrew { "PCHe" } else { "PCJp" }; let mut name = String::from(prefix); let mut suffix = 0usize; while fonts_res.contains(name.as_bytes()) { diff --git a/crates/fonts/src/craft.rs b/crates/fonts/src/craft.rs index 099179cf2..50e05adf4 100644 --- a/crates/fonts/src/craft.rs +++ b/crates/fonts/src/craft.rs @@ -138,6 +138,24 @@ pub fn document_japanese_fonts_for_style(serif: bool, bold: bool) -> Vec<&'stati document_faces(CRAFT_FONTS, serif, bold) } +/// The scripts the bundled Inter faces are for. +static LATIN_SCRIPTS: &[&str] = &["Latn", "Cyrl", "Grek"]; + +/// The bundled Latin document faces (`assets/fonts`, OFL): every build has them, unlike +/// craft-fonts. The Japanese faces carry only part of the Cyrillic (`привет` yes, Uzbek `қизил` +/// and Kazakh `әже` no), so letters like қ, ғ, ҳ, ә, ө, ү, ұ and һ have no face at all without +/// these. +static INTER_REGULAR_FACE: CraftFont = + CraftFont { family: "Inter", style: "Regular", scripts: LATIN_SCRIPTS, bytes: include_bytes!("../../../assets/fonts/Inter-Regular.ttf") }; +static INTER_SEMIBOLD_FACE: CraftFont = + CraftFont { family: "Inter", style: "SemiBold", scripts: LATIN_SCRIPTS, bytes: include_bytes!("../../../assets/fonts/Inter-SemiBold.ttf") }; + +/// The face for Latin, Greek and Cyrillic text written into PDFs: the bundled Inter Regular, or +/// SemiBold for bold text. Present in every build, crafted ones included. +pub fn document_latin_fonts(bold: bool) -> Vec<&'static CraftFont> { + vec![if bold { &INTER_SEMIBOLD_FACE } else { &INTER_REGULAR_FACE }] +} + fn document_face(faces: &[CraftFont], serif: bool, bold: bool) -> Option<&CraftFont> { document_faces(faces, serif, bold).into_iter().next() } @@ -296,6 +314,20 @@ mod tests { assert_eq!(document_hebrew_font(false).is_some(), CRAFT_FONTS.iter().any(|f| f.covers("Hebr"))); } + /// The bundled Inter faces carry the Latin, Greek and Cyrillic letters the craft-fonts faces + /// lack: Uzbek қ ғ ҳ, Kazakh ә ө ү ұ һ, Ukrainian ї є ґ, Greek. This one runs with or without + /// CRAFT_FONTS_DIR (#2593). + #[test] + fn latin_faces_carry_the_letters_the_japanese_faces_lack() { + for face in document_latin_fonts(false).into_iter().chain(document_latin_fonts(true)) { + for ch in ['қ', 'ғ', 'ҳ', 'ә', 'ө', 'ү', 'ұ', 'һ', 'ї', 'є', 'ґ', 'ё', 'α', 'β', 'γ', '≥', '≈'] { + assert!(crate::japanese_glyph_from(face, ch).is_ok(), "{} has no {ch}", face.name()); + } + } + assert_eq!(document_latin_fonts(false)[0].style, "Regular"); + assert_eq!(document_latin_fonts(true)[0].style, "SemiBold"); + } + #[test] fn craft_fonts_are_optional_and_consistent() { // Holds with or without CRAFT_FONTS_DIR. diff --git a/crates/fonts/src/lib.rs b/crates/fonts/src/lib.rs index 73b4fbb08..41ed77324 100644 --- a/crates/fonts/src/lib.rs +++ b/crates/fonts/src/lib.rs @@ -19,8 +19,8 @@ mod std14; mod std14_metrics; pub use craft::{ CRAFT_FONTS, CraftFont, SHIPPORI_MINCHO, document_arabic_font, document_hebrew_font, document_japanese_font, document_japanese_font_for_style, - document_japanese_fonts_for_style, document_thai_font, ui_arabic_fonts, ui_chinese_fonts, ui_cjk_fonts, ui_hebrew_fonts, ui_japanese_fonts, - ui_telugu_fonts, ui_thai_fonts, + document_japanese_fonts_for_style, document_latin_fonts, document_thai_font, ui_arabic_fonts, ui_chinese_fonts, ui_cjk_fonts, ui_hebrew_fonts, + ui_japanese_fonts, ui_telugu_fonts, ui_thai_fonts, }; pub use script::{ GlyphError, GlyphOutline, INTER_REGULAR, MAX_SIGNATURE_CHARS, ScriptOutline, japanese_glyph, japanese_glyph_from, script_missing, script_outline, diff --git a/docs/editing-existing-text.md b/docs/editing-existing-text.md index e8bb03b9a..be9a34edd 100644 --- a/docs/editing-existing-text.md +++ b/docs/editing-existing-text.md @@ -24,7 +24,11 @@ page. Select **Keep source fonts** to preserve each run's original face. A match completes its subsets automatically, including new Chinese characters. When the PDF itself embeds the complete program of a paragraph's font (not a subset) and its licence allows editable embedding, a character the font's encoding can't show is drawn with that same program. A -character no available face has is refused with an error that names it. Choosing another face +character no available face has is refused with an error that names it, and a CJK character +without a craft-fonts build says so. Replacement text takes the craft-fonts Japanese faces when +they can draw all of it, and the bundled Inter face (`assets/fonts`) for the Latin, Greek and +Cyrillic letters they lack (Uzbek `қизил`, Kazakh `әже`): that face needs no build input, so +these work in every build, the web one included. Choosing another face is explicit. Fonts with restricted embedding, unsupported collections, excluded families or no open-licence declaration are refused. Interface fallback fonts are never exported. diff --git a/parity/acrobat-features.toml b/parity/acrobat-features.toml index 533013b54..b75078e66 100644 --- a/parity/acrobat-features.toml +++ b/parity/acrobat-features.toml @@ -1866,8 +1866,8 @@ milestone = "M7" status = "partial" commands = ["edit.edit_text"] tools = ["text_lines", "text_paragraphs", "text_edit", "text_edit_layout", "text_font_files", "text_font_import", "text_fonts"] -evidence = ["crates/edit/src/tests.rs::paragraphs_are_found_and_rewrapped", "crates/edit/src/tests.rs::text_lines_are_found_and_replaced_in_place", "crates/ui-egui/tests/editing.rs::editing_existing_text_in_place", "crates/automation/tests/automation.rs::editing_existing_text_through_tools", "crates/edit/src/tests.rs::a_line_whose_operator_starts_the_next_stream_can_be_edited", "crates/automation/tests/automation.rs::a_line_split_across_content_streams_is_listed_and_edited", "crates/ui-egui/tests/editing.rs::selected_text_formatting_keeps_the_rest_of_the_paragraph_and_reopens", "crates/edit/src/tests.rs::marked_paragraph_boundaries_and_cross_stream_transforms_survive_rewrite", "crates/automation/tests/automation.rs::explicit_font_and_disjoint_ranges_save_reopen_through_tools", "crates/edit/src/tests.rs::disjoint_style_ranges_preserve_unselected_runs_and_validate_utf8_atomically", "crates/engine/tests/document_fonts.rs::opentype_cff_document_font_preserves_program_codes_and_rendering_after_reopen", "crates/ui-egui/tests/editing.rs::cropped_images_do_not_intercept_text_and_stay_inside_each_page", "crates/automation/tests/automation.rs::clipped_image_bounds_and_text_edit_save_reopen_through_tools", "crates/edit/src/tests.rs::mixed_styles_and_matrix_sizes_form_visual_regions_without_merging_columns", "crates/edit/src/tests.rs::rich_region_edits_preserve_styles_positions_and_delete_all_runs_after_reopen", "crates/ui-egui/tests/editing.rs::one_editor_contains_mixed_styles_and_visual_rows", "crates/ui-egui/tests/editing.rs::inline_editor_preserves_source_font_and_previews_live_bounds", "crates/fonts/src/pdf.rs::mac_subset_cmap_uses_pdf_unicode_without_changing_source_program", "crates/automation/tests/automation.rs::mixed_visual_region_edit_preview_save_reopen_and_undo_through_tools", "crates/ui-egui/tests/ui.rs::the_edit_tab_turns_on_edit_text_and_images"] -notes = "The Edit tab turns Edit text & images on at once, as in Acrobat (leaving the tab puts the tool down and applies an edit in progress); click a paragraph box and retype it in place (font reused or Helvetica substituted, colour and spacing kept, rewrapped); a page's /Contents pieces are parsed joined, so a line whose operands and operator sit in different pieces is listed and edited (lines and paragraphs still don't join across pieces; Edit image still parses each piece alone); drag a box to move it or its right-edge handle to rewrap it (edit.text-move-resize); per-character formatting changes are next Since #1116: mixed-style visual regions retain source rows, subset encodings, colour and baseline anchors in one textless-background editor. Explicit paragraph/heading scopes constrain grouping; compatible graphics planes permit cross-stream regions. Full matching document fonts complete absent subset glyphs; installed/file selection, TrueType/OpenType-CFF embedding and disjoint UTF-8 range styles have save/reopen coverage. Single-face OpenType shaping/bidi retains logical text through ToUnicode/ActualText. Legacy non-SFNT preview, mixed-font/style contextual runs, full structure-tree preservation and author intent in untagged PDFs remain limited; see docs/editing-existing-text.md" +evidence = ["crates/edit/src/tests.rs::paragraphs_are_found_and_rewrapped", "crates/edit/src/tests.rs::text_lines_are_found_and_replaced_in_place", "crates/ui-egui/tests/editing.rs::editing_existing_text_in_place", "crates/automation/tests/automation.rs::editing_existing_text_through_tools", "crates/edit/src/tests.rs::a_line_whose_operator_starts_the_next_stream_can_be_edited", "crates/automation/tests/automation.rs::a_line_split_across_content_streams_is_listed_and_edited", "crates/ui-egui/tests/editing.rs::selected_text_formatting_keeps_the_rest_of_the_paragraph_and_reopens", "crates/edit/src/tests.rs::marked_paragraph_boundaries_and_cross_stream_transforms_survive_rewrite", "crates/automation/tests/automation.rs::explicit_font_and_disjoint_ranges_save_reopen_through_tools", "crates/edit/src/tests.rs::disjoint_style_ranges_preserve_unselected_runs_and_validate_utf8_atomically", "crates/engine/tests/document_fonts.rs::opentype_cff_document_font_preserves_program_codes_and_rendering_after_reopen", "crates/ui-egui/tests/editing.rs::cropped_images_do_not_intercept_text_and_stay_inside_each_page", "crates/automation/tests/automation.rs::clipped_image_bounds_and_text_edit_save_reopen_through_tools", "crates/edit/src/tests.rs::mixed_styles_and_matrix_sizes_form_visual_regions_without_merging_columns", "crates/edit/src/tests.rs::rich_region_edits_preserve_styles_positions_and_delete_all_runs_after_reopen", "crates/ui-egui/tests/editing.rs::one_editor_contains_mixed_styles_and_visual_rows", "crates/ui-egui/tests/editing.rs::inline_editor_preserves_source_font_and_previews_live_bounds", "crates/fonts/src/pdf.rs::mac_subset_cmap_uses_pdf_unicode_without_changing_source_program", "crates/automation/tests/automation.rs::mixed_visual_region_edit_preview_save_reopen_and_undo_through_tools", "crates/ui-egui/tests/ui.rs::the_edit_tab_turns_on_edit_text_and_images", "crates/edit/src/tests.rs::uzbek_and_kazakh_cyrillic_use_the_bundled_latin_face", "crates/automation/tests/automation.rs::editing_uzbek_and_kazakh_cyrillic_through_tools"] +notes = "The Edit tab turns Edit text & images on at once, as in Acrobat (leaving the tab puts the tool down and applies an edit in progress); click a paragraph box and retype it in place (font reused or Helvetica substituted, colour and spacing kept, rewrapped); a page's /Contents pieces are parsed joined, so a line whose operands and operator sit in different pieces is listed and edited (lines and paragraphs still don't join across pieces; Edit image still parses each piece alone); drag a box to move it or its right-edge handle to rewrap it (edit.text-move-resize); per-character formatting changes are next Since #1116: mixed-style visual regions retain source rows, subset encodings, colour and baseline anchors in one textless-background editor. Explicit paragraph/heading scopes constrain grouping; compatible graphics planes permit cross-stream regions. Full matching document fonts complete absent subset glyphs; installed/file selection, TrueType/OpenType-CFF embedding and disjoint UTF-8 range styles have save/reopen coverage. Single-face OpenType shaping/bidi retains logical text through ToUnicode/ActualText. Replacement text the paragraph's font can't show takes the craft-fonts Japanese faces when they draw all of it (Uzbek қ, Kazakh ә are in none of them), else the bundled Inter face, so those letters write in every build (#2593). Legacy non-SFNT preview, mixed-font/style contextual runs, full structure-tree preservation and author intent in untagged PDFs remain limited; see docs/editing-existing-text.md" [[feature]] id = "edit.text-reflow" From a146648648b1c9e15b0bca596d9752babc401fce Mon Sep 17 00:00:00 2001 From: PerchAnton <101743951+PerchAnton@users.noreply.github.com> Date: Thu, 15 Oct 2026 19:52:42 +0300 Subject: [PATCH 037/498] M12: enforce XFA rich-text maxLength (#2570) --- ROADMAP.md | 5 ++++- crates/automation/tests/automation.rs | 32 +++++++++++++++++++++++++++ crates/xfa/README.md | 1 + crates/xfa/src/parse.rs | 10 +++++++-- crates/xfa/src/tests.rs | 26 ++++++++++++++++++++++ docs/roadmap.md | 5 +++-- parity/acrobat-features.toml | 4 ++-- 7 files changed, 76 insertions(+), 7 deletions(-) diff --git a/ROADMAP.md b/ROADMAP.md index fe9723fdf..c97889952 100644 --- a/ROADMAP.md +++ b/ROADMAP.md @@ -2,7 +2,7 @@ **Stage: alpha** · next: beta, ~25% (ready for real work 50% → 75%) and ~400–700 h away -> **Last reviewed:** 2026-10-13 · **Last updated:** 2026-10-14 · **Change:** minor (M14: the Italian catalog has every entry the other catalogs had and the code looks up; estimates unchanged) · **Target:** Adobe Acrobat Pro (Acrobat DC, continuous track 26.002.21931, macOS) +> **Last reviewed:** 2026-10-15 · **Last updated:** 2026-10-15 · **Change:** minor (M12 #2570: dynamic XFA rich-text character limits; estimates unchanged) · **Target:** Adobe Acrobat Pro (Acrobat DC, continuous track 26.002.21931, macOS) > **Last reviewed:** 2026-10-14 · **Last updated:** 2026-10-14 · **Change:** minor (M3 #2080 candidate: explicit search jumps join per-tab history; rail and control-channel Back/Forward; estimates unchanged) > **Last reviewed:** 2026-10-13 · **Last updated:** 2026-10-13 · **Change:** minor (M4 #1910: Organize Pages opens on the current page; estimates unchanged) · **Target:** Adobe Acrobat Pro (Acrobat DC, continuous track 26.002.21931, macOS) > **Last reviewed:** 2026-10-14 · **Last updated:** 2026-10-14 · **Change:** minor (M3 candidate: coordinate control clicks keep press/release together on slow frames and preserve text multi-click selection; estimates unchanged) · **Target:** Adobe Acrobat Pro (Acrobat DC, continuous track 26.002.21931, macOS) @@ -156,6 +156,8 @@ Ranked; detail and the full milestone table in [docs/roadmap.md](docs/roadmap.md | 8 | 1.0 polish: performance, right-to-left, missing languages, keyboard-only (M14) | 55–95 | ## Progress log + +- **2026-10-15 (M12, #2570):** Dynamic XFA text fields carry `exData/maxLength` into the generated AcroForm, so `form_fields` reports the limit and `form_fill` rejects longer text. Synthetic parser/layout and automation regressions cover limits, Unicode character counting and save/reopen. XFA remains partial; estimates unchanged. - **2026-10-13 (community, M3, #1569 review):** Pixel-only Wayland wheel, wheel-tilt and continuous input use standalone moved events, so Ctrl zoom does not remain latched after the modifier is released (#991); vendored winit patch (13), with a policy test. Estimates unchanged. - **2026-10-12 (M6):** XFDF field import and data-file extraction join all text nodes in a value, preserving text after XML comments and processing instructions. Synthetic regressions cover Unicode, CDATA, empty values and PDF save/reopen. Estimates unchanged. - **2026-10-12 (M7, picture right-click menu):** The Edit text & images menu of a picture gains Cut Image, Redact Image (a redaction mark over the picture, applied from Redact a PDF), Create Link… and Recognize Text… (for that page), in all 21 catalogs. The menu was drawn only while the pointer was over the picture, so its items outside the picture (most of a logo's menu, and Delete below a page) could not be clicked; an open menu now stays drawn. Still missing from Acrobat's menu: Arrange (bring to front, send backward), Remove crop, Draw freehand and Edit image using… (opening an external editor). @@ -490,6 +492,7 @@ Newest first: the date, what moved, and the new overall estimate. | Date | Change | Summary | |---|---|---| +| 2026-10-15 | minor | M12/#2570: dynamic XFA exData/maxLength reaches AcroForm field limits; parser/layout and headless fill/save/reopen regressions. Estimates unchanged. | | 2026-10-12 | minor | M6: valid AcroForm XML element names with original PDF field names preserved; saved-PDF collision and Unicode regressions. Estimates unchanged. | | 2026-10-12 | minor | M6: preserve carriage returns in exported CSV field names and values; saved-PDF round-trip coverage. Estimates unchanged. | | 2026-10-13 | minor | M4: Insert-from-file preserves source bookmarks; integration tests retained with current main. Estimates unchanged. | diff --git a/crates/automation/tests/automation.rs b/crates/automation/tests/automation.rs index 1e662d8f3..93b1d417a 100644 --- a/crates/automation/tests/automation.rs +++ b/crates/automation/tests/automation.rs @@ -5210,6 +5210,38 @@ fn xfa_data_files_export_and_import_through_tools() { assert!(std::fs::read_to_string(dir.join("static.xml")).unwrap().contains("Ada"), "a static XFA form exports its data too"); } +#[test] +fn xfa_rich_text_max_length_is_reported_and_enforced_through_tools() { + let dir = workdir("xfa-rich-limit"); + let template = pdfcraft_xfa::fixtures::template_with_data(0, "
Old") + .replace(r#""#, r#""#) + .replace("", ""); + std::fs::write(dir.join("rich.pdf"), pdfcraft_xfa::fixtures::shell(&template)).unwrap(); + let mut a = auto(&dir); + let doc = ok(&mut a, "doc_open", json!({ "path": "rich.pdf" }))["doc"].as_u64().unwrap(); + let fields = ok(&mut a, "form_fields", json!({ "doc": doc })); + let family = fields["fields"].as_array().unwrap().iter().find(|f| f["name"] == "familyName").unwrap(); + assert_eq!(family["max_length"], 5); + + // The boundary counts Unicode characters, not UTF-8 bytes. + ok(&mut a, "form_fill", json!({ "doc": doc, "values": { "familyName": "éàöüñ" } })); + ok(&mut a, "doc_export_data", json!({ "doc": doc, "path": "before.xml", "what": "fields" })); + let before = std::fs::read(dir.join("before.xml")).unwrap(); + assert!(std::str::from_utf8(&before).unwrap().contains("éàöüñ")); + let error = a.call("form_fill", &json!({ "doc": doc, "values": { "familyName": "éàöüñX" } })).unwrap_err(); + assert!(error.to_string().contains("at most 5 characters"), "{error}"); + ok(&mut a, "doc_export_data", json!({ "doc": doc, "path": "after.xml", "what": "fields" })); + assert_eq!(std::fs::read(dir.join("after.xml")).unwrap(), before, "refused edits leave the XFA data unchanged"); + + ok(&mut a, "doc_save", json!({ "doc": doc, "path": "out.pdf" })); + ok(&mut a, "doc_close", json!({ "doc": doc })); + let doc = ok(&mut a, "doc_open", json!({ "path": "out.pdf" }))["doc"].as_u64().unwrap(); + let fields = ok(&mut a, "form_fields", json!({ "doc": doc })); + let family = fields["fields"].as_array().unwrap().iter().find(|f| f["name"] == "familyName").unwrap(); + assert_eq!(family["max_length"], 5); + assert_eq!(family["value"], "éàöüñ"); +} + #[test] fn dynamic_xfa_forms_open_render_fill_and_save_through_tools() { let dir = workdir("xfa"); diff --git a/crates/xfa/README.md b/crates/xfa/README.md index 5d494d7b4..db5c4cb28 100644 --- a/crates/xfa/README.md +++ b/crates/xfa/README.md @@ -17,6 +17,7 @@ the automation tools) works on it unchanged. The engine does this when it opens page areas, content areas and media; measurements in mm, cm, in, pt and px; fonts, paragraphs, margins, borders (edge order rules), captions with reserves, check-button items, pictures, rich text (`exData` XHTML: paragraphs, `br`, bold/italic/underline/size spans, embedded fields), + text-field limits (`text/maxChars` and `exData/maxLength`, carried into AcroForm `/MaxLen`), inline JPEG, PNG and GIF images, lines, rectangles, occurrences, `breakBefore`/`breakAfter`, overflow leaders, `columnWidths` and `colSpan`. - **Layout** (`layout`): positioned, `tb`, `lr-tb`/`rl-tb`, `table` and `row` layouts; a diff --git a/crates/xfa/src/parse.rs b/crates/xfa/src/parse.rs index f6c69789b..7a894ab49 100644 --- a/crates/xfa/src/parse.rs +++ b/crates/xfa/src/parse.rs @@ -424,8 +424,14 @@ fn parse_field(n: XmlNode, warnings: &mut Vec) -> Field { Some(_) => Ui::Unknown, }; let value_el = child(n, "value"); - let max_chars = - value_el.and_then(|v| child(v, "text")).and_then(|t| t.attribute("maxChars")).and_then(|m| m.trim().parse::().ok()).filter(|m| *m > 0); + let max_chars = value_el + .and_then(|v| child(v, "text")) + .and_then(|t| t.attribute("maxChars")) + .and_then(|m| m.trim().parse::().ok()) + // XFA 3.3, exData/maxLength: a character limit excluding markup; -1 is unlimited. + .or_else(|| value_el.and_then(|v| child(v, "exData")).and_then(|e| e.attribute("maxLength")).and_then(|m| m.trim().parse::().ok())) + // Preserve the existing zero/unbounded convention of generated form fields. + .filter(|m| *m > 0); let scripts = parse_events(n); let numeric = matches!(kind, Ui::NumericEdit) || value_el.is_some_and(|v| v.children().any(|c| c.is_element() && matches!(c.tag_name().name(), "decimal" | "integer" | "float"))); diff --git a/crates/xfa/src/tests.rs b/crates/xfa/src/tests.rs index 1e8730586..72c58abb1 100644 --- a/crates/xfa/src/tests.rs +++ b/crates/xfa/src/tests.rs @@ -74,6 +74,32 @@ fn the_template_parses_with_fonts_captions_and_rich_text() { assert!(last.break_before_page); } +#[test] +fn rich_text_max_length_reaches_the_field_and_layout() { + for (attribute, expected) in [ + (r#"maxLength="5250""#, Some(5250)), + (r#"maxLength=" 10500 ""#, Some(10500)), + (r#"maxLength="0""#, None), + (r#"maxLength="-1""#, None), + (r#"maxLength="invalid""#, None), + (r#"maxLength="999999999999999999999999999999999999""#, None), + ("", None), + ] { + let xml = template(0).replace( + r#""#, + &format!(r#"

Hello

"#), + ); + let (tpl, _) = parse(&xml).unwrap(); + let Node::Subform(head) = &tpl.root.children[0] else { panic!() }; + let Node::Field(field) = &head.children[2] else { panic!() }; + assert_eq!(field.max_chars, expected, "{attribute}"); + assert_eq!(field.value.plain().as_deref(), Some("Hello")); + let form = layout_xml(&xml).unwrap(); + let field = form.pages.iter().flat_map(widgets).find(|w| w.name == "familyName").unwrap(); + assert_eq!(field.max_chars, expected, "{attribute}"); + } +} + #[test] fn the_xdp_template_wins_over_the_config_packets_template_element() { // The config packet has a