HotPDF, bir SVG dosyasını yüklenmiş veya oluşturulmuş bir PDF'e, oluşturulan formun kaynak adını döndüren ImportSVGFormXObject aracılığıyla yeniden kullanılabilir bir Form XObject olarak aktarır. Bu formu yerleştirmek ayrı bir çağrı olan DrawSVGFormXObject ile yapılır; böylece tek bir içe aktarma, görselin tek bir baytını bile çoğaltmadan farklı boyutlarda birçok sayfaya basılabilir
Bu ayrım göründüğünden daha önemlidir. 300 DPI'de rasterize edilmiş ve 400 sayfaya yerleştirilmiş bir logo, bir bit eşlemin 400 kopyasıdır. Aynı logo Form XObject olarak kullanıldığında ise 400 kez referans verilen tek bir nesnedir; her yakınlaştırma seviyesinde keskin kalır ve derleme zamanında yeterli görünen DPI yerine cihaz çözünürlüğünde yazdırılır
Her Seferinde SVG Çizmek Yerine Neden Form XObject?
Form XObject, PDF'nin yeniden kullanılabilir içerik için kendi mekanizmasıdır: kendi sınırlayıcı kutusuna ve kaynak sözlüğüne sahip, ada göre çağrılan, kendi kendine yeterli bir içerik akışı. SVG'yi bir Form XObject'e aktarmak, doğrudan çizimin sağlamadığı üç özellik kazandırır. Görsel, dosyada yalnızca bir kez bulunur. Her yerleştirme küçük bir matris ve bir çağrıdan ibarettir. Şekiller de vektör olarak kalır, böylece yüzde 800 yakınlaştırmadaki bir görüntüleyici piksel değil eğri çizer
İnceliği kaynaklarda yatar. Bir formun yazı tipleri ve grafik durumları, içe aktarma sırasında hangi sayfa geçerliyse onun kaynaklarında değil, formun kendi /Resources sözlüğünde bulunmalıdır. HotPDF, bir formun ihtiyaç duyduğu Base 14 yazı tiplerini ve ExtGState girdilerini doğrudan formun içine yazar; çünkü ilk barındırıcı sayfasından bir ad ödünç alan bir form, orada doğru şekilde işlenir ama daha sonra yerleştirildiği diğer her sayfada çözümlenemeyen bir kaynak adı üretir
İki Ters Çevirme: Biri Geometri, Biri Glif İçin
SVG'nin koordinat sistemi sol üst köşeden aşağıya doğru büyür; bir PDF Form XObject ise sol alttan yukarıya doğru büyüyen PDF kullanıcı alanını kullanır. Kök viewBox dönüşümü, geometrinin doğru şekilde yerleşmesi için tek bir Y ekseni ters çevirmesi uygular. Metin ise ikinci, yerel bir ters çevirmeye ihtiyaç duyar; çünkü zaten ters çevrilmiş bir çerçevede çizilen bir glif baş aşağı görünürdü
Bu, bir PDF sayfası SVG olarak dışa aktarıldığında tersine görünen aynı düzeltmedir; konu PDF sayfalarını SVG'ye aktarma başlığında ele alınmıştır. Bu hatayı yanlış yapmak, metin içeren görsellerde fark edilmesi kolayken metin içermeyen görsellerde neredeyse görünmezdir; bu yüzden sloganlı bir logo, tek başına bir logodan daha iyi bir duman testidir
uses
HPDFDoc;
var
Pdf: THotPDF;
SvgBytes: TBytes;
FormName: AnsiString;
Stats: THPDFSVGImportStatistics;
I: Integer;
begin
Pdf := THotPDF.Create(nil);
try
Pdf.FileName := 'catalogue.pdf';
Pdf.BeginDoc;
SvgBytes := LoadFileBytes('brand-logo.svg');
FormName := Pdf.ImportSVGFormXObject(SvgBytes, Stats);
if FormName = '' then
raise Exception.Create('SVG rejected - see the import statistics');
// Tek içe aktarma, çok yerleştirme: görsel baytları yalnızca bir kez var
for I := 1 to 40 do
begin
if I > 1 then
Pdf.AddPage;
Pdf.CurrentPage.DrawSVGFormXObject(FormName, 40, 780, 120, 40);
end;
Pdf.EndDoc;
finally
Pdf.Free;
end;
end;
Köprüler Bu Yolculuğu Nasıl Atlatır?
Formun içinde hayatta kalamazlar, çünkü bir Form XObject içeriktir, PDF bağlantı hedefleri ise bir sayfaya ait olan ek açıklamalardır (annotation). Bu nedenle kaynak SVG'deki bir <a> öğesi, formun içerik akışına doğrudan kopyalanamaz
HotPDF bunu, ayrıştırma sırasında bağlantı dikdörtgenlerini form alanı meta verisi olarak tutup her yerleştirmede bunları sayfa düzeyinde bağlantı ek açıklamalarına dönüştürerek çözer. DrawSVGFormXObject, bu dikdörtgenleri sizin geçirdiğiniz hedef dikdörtgen üzerinden eşler; böylece farklı boyutlarda iki kez yerleştirilen bir form, doğru boyutlandırılmış iki tıklama alanı kümesi elde eder. Bağlantı dikdörtgenleri yalnızca kök boyut üzerinden eşlenir ve hiçbir zaman içerik akışına girmez, bu da çizilen görselin taşıdığı bağlantı sayısından bağımsız olarak aynı kalmasını sağlar. Örneğin yalnızca yazdırma amaçlı bir sayfada olduğu gibi, etkileşim olmadan görseli istediğinizde AddLinks = False geçirin
İçe Aktarıcının Reddettikleri ve Bunun Neden Önemli Olduğu
SVG, betik çalıştırma, dış referanslar ve varlık (entity) genişletmesi içeren bir XML lehçesidir; bu da rastgele bir SVG dosyasını, rastgele bir HTML dosyası kadar düşmanca bir girdi haline getirir. İçe aktarma profili, belgenin dışına uzanan her şeye karşı hataya kapalı (fail-closed) çalışır: dış kaynak referansları, betikler, olay işleyici öznitelikleri, DTD'ler ve yerel bir parça referansı olmayan her url()
Hataya kapalı olmak, sorunlu yapıyı sessizce atmak yerine içe aktarmanın başarısız olması demektir. Bu ayrım toplu işlem hatları için önemlidir, çünkü sessiz bir atlama, kimsenin bilmediği bir eksiği olan bir belge üretirken, bir reddetme karantinaya alıp inceleyebileceğiniz bir dosya üretir. Kullanıcılardan SVG yüklemesi kabul ediyorsanız istediğiniz davranış budur ve bu, güvenilmeyen görüntüler için codec süreç izolasyonu başlığında anlatılan süreç düzeyindeki izolasyonla birlikte çalışır
Renkli yazı tipleri de işliyorsanız bilmeye değer bir iç sınır vardır. OpenType SVG renkli glifleri için kullanılan katı SVG alt kümesi, ayrı bir giriş noktasından geçer ve kendi özgün, daha dar başarısızlık davranışını korur. Genel görsel içe aktarma ayrı bir yoldur, bu yüzden içe aktarılan görsellere yay, saydamlık ve CSS desteği eklemek, bir yazı tipi glifinin içerebileceği şeyleri genişletmedi
Gradyanlar, Maskeler ve Rasterleştirme Yok Kuralı
Gradyanlar, rasterleştirilmiş bir görüntü olarak değil, özgün geometrinin kırpma yoluyla sınırlandırılmış, sınırlı vektör renk bantları olarak içe aktarılır. Maskeler de aynı yaklaşımı kullanır: maske dış hattı bir vektör kırpma yoluna dönüşür. Sonuç olarak gradyan ağırlıklı bir illüstrasyon çözünürlükten bağımsız ve küçük kalırken, rasterleştiren bir içe aktarıcı, kalitesi içe aktarma anında sabitlenen büyük bir görüntü nesnesi üretirdi
Buradaki ödünleşim, aşırı durumlarda sadakattir. Pürüzsüz bir gradyanın bantlı bir yaklaşıklığı, SVG gradyanıyla matematiksel olarak özdeş değildir ve onlarca üst üste binen yumuşak maskeye sahip bir görsel, bunun yerine yüksek çözünürlüklü bir görüntüye render edilirse özgününe daha yakın görünür. PDF'nin doğrudan desteklediği gölgelendirme modelleri ve bunlara ne zaman doğrudan başvurulacağı için bkz. eksenel ve radyal gölgelendirmelerin render edilmesi
// İçe aktarma istatistiklerini okumak gerçekte neyin geldiğini gösterir
Writeln(Format('nodes=%d css rules=%d gradients=%d masks=%d',
[Stats.NodeCount, Stats.CSSRuleCount, Stats.GradientCount,
Stats.MaskCount]));
Writeln(Format('text runs=%d links=%d form bytes=%d',
[Stats.TextRunCount, Stats.LinkCount, Stats.OutputBytes]));
// Aynı formu iki farklı boyutta yerleştirmek iki doğru bağlantı kümesi üretir
Pdf.CurrentPage.DrawSVGFormXObject(FormName, 40, 700, 240, 80);
Pdf.CurrentPage.DrawSVGFormXObject(FormName, 320, 700, 120, 40);
// Yalnızca yazdırma için yerleştirme: tıklama alanları olmadan görsel
Pdf.CurrentPage.DrawSVGFormXObject(FormName, 40, 60, 120, 40, False);
SVG İçe Aktarma Diğer Vektör Yollarının Yanında Nereye Oturur
Üç vektör içe aktarma yolu vardır ve bunlar birbirinin yerine geçmez. SVG içe aktarma, tasarım araçlarıyla üretilen görseller ve bir web hattından gelen her şey için uygundur. EMF ve WMF vektör içe aktarma başlığında ele alınan metafile içe aktarma, Windows uygulamaları ve bir aygıt bağlamına çizim yapan grafik bileşenleri tarafından üretilen içerik için uygundur. Sayfa API'si üzerinden doğrudan çizim ise, ara bir formatın hiç bulunmadığı, kendi kodunuzun hesapladığı görseller için uygundur
Yeniden kullanılabilirlik argümanı, özellikle tekrarlanan öğeler için SVG içe aktarmayı öne çıkarır. Antetli kağıtlar, logolar, filigranlar, sertifikasyon işaretleri ve dekoratif çizgiler, birçok sayfada aynı şekilde çizilir; her biri tek bir form nesnesi artı sayfa başına tek bir çağrıdır. Önemli olmadığına karar vermeden önce gerçek bir belgede dosya boyutu farkını ölçün: sayfa başına bir vektör logosu içeren 500 sayfalık bir katalogda, tek bir form ile 500 satır içi kopya arasındaki fark genellikle birkaç megabayttır
SVG içe aktarma, metafile içe aktarma ve doğrudan vektör çizimi, Delphi ve C++Builder için aynı içerik akışı yazıcısını paylaşır; eksiksiz özellik listesi HotPDF Delphi PDF bileşeni sayfasında bulunur