PDFium Component, AddCidType2Text ile bir PDF sayfasına glif düzeyinde metin yazar ve sizin sağladığınız TrueType verisini bir CID Type 2 yazı tipi olarak gömer. Her glif örneğine sıralı bir CID atar, açık CID-ile-GID eşlemini ve ToUnicode CMap'ini üretir ve aynı taban çizgisindeki glifleri tek bir yerel metin nesnesinde birleştirir. İsteğe bağlı alt kümeleme dosyayı küçük tutar; alt kümeleme başarısız olduğunda ne olacağına dair açık bir politikayla birlikte
Glif düzeyinde yazma, metin zaten şekillendirilmişse ihtiyacınız olan şeydir. Arapça, Devanagari ve bağlamsal biçimlere sahip her yazı sistemi, artık karakterlere birebir eşlenmeyen bir glif tanımlayıcıları dizisi üretir, bu yüzden bir dize ve bir yazı tipi adı alan bir API sonucu ifade edemez. Glifleri ve konumları doğrudan teslim etmek, doğru şekillendirilmiş karmaşık yazı sistemi metnini bir PDF'e koymanın tek yoludur
Her Glif Örneği Neden Kendi CID'sini Alır
Cazip optimizasyon, yinelenenleri kaldırmaktır: farklı bir glif tanımlayıcısı başına bir CID, o glif nerede görünürse görünsün yeniden kullanılır. Bu, daha küçük bir yazı tipi üretir ve metin çıkarmayı bozar, çünkü aynı glif, farklı yerlerde meşru olarak farklı Unicode içeriğine karşılık gelebilir
Bir ligatür glifi bariz bir örnektir. Aynı "ffi" glifi, bir kelimedeki üç karakteri temsil edebilirken başka bir yerdeki farklı bir şekillendirme kararından sonra başka bir şeyi temsil edebilir. ToUnicode eşlemi CID'ye göre anahtarlanır, bu yüzden paylaşılan bir CID yalnızca bir eşleme taşıyabilir ve bu yarışmayı kaybeden metin çıkarılamaz hale gelir
Bu yüzden her glif örneği kendi CID'sini alır ve her eşleme birkaç UTF-16 kod birimi olmakta serbesttir. Anlamlı metni olmayan bir glif — dekoratif bir öğe, yalnızca konumlandırma amaçlı bir glif — açıkça sıfır genişlikli bir boşluk olan U+200B'ye eşlenir, bu yüzden her CID bir boşluk yerine gözlemlenebilir bir çıkarma sonucuna sahiptir
uses
PDFium;
var
Pdf: TPdf;
Glyphs: TPdfCidGlyphs;
Options: TPdfCidFontOptions;
Report: TPdfCidFontReport;
begin
Pdf := TPdf.Create(nil);
try
Pdf.FileName := 'label.pdf';
Pdf.LoadDocument;
Pdf.PageNumber := 1;
// Şekillendirilmiş her glif için bir girdi: glif kimliği, temsil ettiği metin,
// ve metin uzayındaki ilerlemesi ve ofsetleri
SetLength(Glyphs, 3);
Glyphs[0].GlyphID := 402; Glyphs[0].UnicodeText := 'ffi';
Glyphs[0].Advance := 18.4;
Glyphs[1].GlyphID := 71; Glyphs[1].UnicodeText := 'c';
Glyphs[1].Advance := 9.8;
Glyphs[2].GlyphID := 74; Glyphs[2].UnicodeText := 'e';
Glyphs[2].Advance := 9.2;
Options := TPdfCidFontOptions.Default; // alt küme tercih edilir
Options.VerifyExtraction := True;
if Pdf.AddCidType2Text(LoadFileBytes('NotoSans.ttf'), Glyphs,
11, 72, 700, Options, Report) then
Writeln(Format('%d glyphs, %d unique, font %d -> %d bytes, match=%s',
[Report.GlyphCount, Report.UniqueGlyphCount,
Report.OriginalFontBytes, Report.EmbeddedFontBytes,
BoolToStr(Report.ExtractionMatches, True)]));
finally
Pdf.Free;
end;
end;
Alt Kümeleme ve Bir Dönüş Kodunun Size Vermediği Kontroller
Bir yazı tipini gerçekte kullanılan gliflere alt kümelemek, 300 KB gömmek ile 12 KB gömmek arasındaki farktır ve birkaç yazı tipine sahip bir belgede bu, dosyanın e-postayla gönderilebilir olup olmadığını belirler. Platform alt kümeleme yolu doğrudan bir glif listesi kabul eder; bu, çağıran zaten kullanımdaki her glif tanımlayıcısını bildiği için bu API'ye mükemmel şekilde uyar
Size vermediği şey güvendir. Bir alt kümeleme çağrısı başarı bildirebilir ve kullanılamaz bir çıktı döndürebilir, bu yüzden bileşen sonucu kabul etmeden önce üç özelliği doğrular: çıktı özgününden küçük olmalıdır, okunabilir bir maxp tablosuna sahip geçerli bir sfnt olarak yeniden ayrıştırılmalıdır ve istenen en yüksek özgün tanımlayıcıya kadar glifleri korumalıdır. Herhangi bir başarısızlık, alt kümenin reddedildiği anlamına gelir
Bundan sonra ne olacağı çağıranın politikasıdır. Varsayılan olan pcfemSubsetPreferred altında, reddedilen bir alt küme tam yazı tipini gömmeye geri döner, bu yüzden sayfa doğrudur ve yalnızca daha büyüktür. pcfemSubsetRequired altında ise, sayfa değiştirilmeden önce işlem başarısız olur; bu, boyut kısıtlı bir boru hattının istediği şeydir. pcfemFull, alt kümelemeyi tamamen atlar. Rapor, SubsetAttempted, SubsetApplied, UsedFullFontFallback ve SubsetErrorCode aracılığıyla hangi yolun izlendiğini söyler
Yanlış Pozitif Üretemeyen Doğrulama
VerifyExtraction etkinleştirildiğinde bileşen, yazdığı şeyin geri okunabildiğini doğrular. Bunu yapmanın naif yolu tüm sayfayı çıkarmak ve beklenen dizeyi aramaktır ve bu yanlıştır: zaten o metni içeren bir sayfa, yeni metin yanlış yazılmış olsa bile kontrolü geçer
Bunun yerine metin sayfası yeniden oluşturulur ve bu çağrı tarafından eklenen nesne tanıtıcıları tek tek, ekleme sırasına göre okunur ve birleştirilir. Sonuç, beklenen metinle karşılaştırılır ve rapor, boolean ile birlikte her iki dizeyi de gösterir, bu yüzden bir uyumsuzluk yalnızca tespit edilmekle kalmaz teşhis de edilebilir
Geliştirme sırasında ve çıkarılabilirliğin bir gereksinim olduğu her boru hattında etkinleştirin — aranabilir arşivler, erişilebilirlik uyumluluğu, sonraki metin madenciliği. Maliyeti, çağrı başına bir metin sayfası yeniden oluşturmadır; sıkı döngülerde varsayılan olarak açık olmamasının nedeni budur
Bütçeler ve Atomik Başarısızlık
Yazı tipi baytları, glif örnekleri ve Unicode kod birimlerinin her biri ayırmadan önce üst sınırlandırılır ve yazı tipi biçimi, TTC indeksi, glif tanımlayıcı aralığı ve geometri değerleri bir şey yazılmadan önce doğrulanır. Geometri sonlu olmalıdır; bu, bir şekillendirme motoru size bozuk bir yazı tipinden bir NaN ilerlemesi verene kadar bariz görünür
Başarısızlık sayfa düzeyinde atomiktir. Yazı tipi yükleme, nesne yazma, içerik üretme veya çıkarma doğrulaması başarısız olursa, o çağrının eklediği her nesne ters sırada kaldırılır ve sayfa içeriği yeniden üretilir. Başarısız bir çağrı sayfayı üzerinde yarım bir metin dizisiyle değil, olduğu gibi bırakır
Bunun Bir Metin Boru Hattında Nereye Oturduğu
İş bölümünü açıkça belirtmeye değer. Şekillendirme — karakterleri konumlandırılmış gliflere dönüştürmek — bu API'nin işi değildir; bir şekillendirme motoruna aittir ve bileşenin kendi çift yönlü ve karmaşık yazı sistemi desteği, emoji, CJK ve vekil çift işleme başlığında ele alınmıştır. Bu API, şekillendiricinin ürettiği glif dizisiyle sonrasında çağırdığınız şeydir
Bağlamsal şekillendirme gerektirmeyen sıradan Latin metin için daha basit dize tabanlı metin API'leri doğru araçtır ve daha küçük kod üretir. Şekillendirilmiş çıktınız olduğunda, glif tanımlayıcıları üzerinde tam denetime ihtiyaç duyduğunuzda veya yazı tipi ada göre çözümlenmek yerine elinizdeki baytlardan gömülmesi gerektiğinde CID Type 2 yazımına başvurun — yazı tipi çözümleme alternatifi, PDF yazı tipi ikamesini denetleme başlığında anlatılan sağlayıcı mekanizmasıdır
Bir dağıtım notu: bir yazı tipini gömmek, teknik olduğu kadar bir lisanslama sorusudur da. Yazı tipleri, gömmeye hiç izin verilip verilmediği, yalnızca görüntüleme için izin verildiği veya düzenleme için izin verildiği bakımından farklılık gösterir. Kitaplık, kendisine verdiğiniz her ne baytsa gömer ve lisansı kontrol etmek dosya biçiminin değil sizin sorumluluğunuzdadır
Glif düzeyinde metin yazma, yazı tipi sağlama ve metin çıkarma, Delphi, C++Builder ve Lazarus'ta aynı sayfa modelini paylaşır; tam API, Delphi için PDFium Component sayfasında açıklanmıştır