Bir PDF içerik-akışı örneğinden kopyalanmış bir dip çizgisi 72 72 m 540 72 l S okur: (72, 72)'ye git, (540, 72)'ye bir çizgi çiz, konturla. Ham PDF'te o çizgi bir US Letter sayfasının alt kenarının bir inç üstündedir. Aynı dört sayıyı sol üst köşeden ölçen bir çizim API'sine verin ve çizgi, üstün bir inç altına, antetin tam içinden düşer. Çizginin kendisi sağlamdır. Yalnızca başvuru çerçevesi değişmiştir ve 792 puntoluk bir sayfada iki çerçeve arasında geçiş tek bir çıkarma işlemidir: 792 eksi Y
Bir HotPDF sayfasında Y = 0 nerededir?
HotPDF sayfa çizim çağrıları kökeni sayfanın sol üst köşesine koyar; X sağa, Y aşağıya büyür; VCL TCanvas'ın kullandığı çerçeve budur. ISO 32000-1 §8.3.2.3'te tanımlı PDF kullanıcı uzayı, Y yukarıya büyüyerek sol alttan başlar ve HotPDF, içerik akışını yazarken geçirdiğiniz her Y'yi çevirir. Böylece THotPDF.CurrentPage üzerinde Y := 72, sayfa boyutu ne olursa olsun üst kenarın bir inç altı demektir
Sayfa boyutu öbür uç için önemlidir. 612'ye 792 puntoluk bir US Letter sayfasında Y := 720, alttan bir inç üsttedir. Yeni bir HotPDF sayfası, söylemedikçe A4'tür ve A4 842 punto boyundadır; aynı Y := 720 altında 122 punto, kabaca 1,7 inç bırakır. 792'den çıkararak konumlanan dipnotlar, tam bu nedenle A4'te yukarı sürüklenir. Yüksekliği elle kodlamak yerine CurrentPage.Height'tan okuyun ya da BeginDoc'tan hemen sonra CurrentPage.Size'ı açıkça kurun
Birim punto, 1/72 inçtir; çünkü THotPDF.Resolution varsayılan olarak 72'dir. Resolution'u yükseltmek koordinat ve boyutların 1/Resolution inç cinsinden sayılmasını sağlar. Vektör işi için 72'de bırakın: çizgi kalınlıkları, kesik uzunlukları ve koordinatlar o zaman hepsi PDF dosyasının sakladığı birimle okunur ve içerik akışında gördüğünüz bir değer, kaynağınızdaki bir değerle eşleşir
Metin aynı modeli izler. Varsayılan olarak TextOut'a verdiğiniz Y, metnin üst kenarıdır; böylece bir etiket ile onu çevreleyen kutu tek bir kılavuza göre planlanır. Az sayıda çağrı, çizim yüzeyi yerine PDF dosyası üzerinde çalışır ve aşağıdan yukarı PDF koordinatları kullanır: SetCropBox(Left, Bottom, Right, Top) gibi sayfa-kutusu ayarlayıcıları ve zaten yüklenmiş bir belgeye damga vuran StampLoadedPageText / StampLoadedPageImage ailesi. Bunları yol çağrılarıyla harmanlamak, çevrilmiş düzenlerin çoğunun kaynağıdır; o yüzden ayrı yordamlarda tutun
Bir yol kurmak ve boyamak
Yol önce kurulur, sonra boyanır. MoveTo hiçbir şey işaretlemeden bir başlangıç noktası kurar; her LineTo bir doğru parçası ekler ve Stroke gibi bir boyama çağrısı, geçerli kontur rengiyle çizgi kalınlığını kullanana dek hiçbir şey sayfaya ulaşmaz. PDF terimleriyle Stroke, S işlecini yazar ve her boyama işleci geçerli yolu bitirir; böylece sonraki MoveTo temiz başlar
var
Pdf: THotPDF;
begin
Pdf := THotPDF.Create(nil);
try
Pdf.FileName := 'DrawPaths.pdf';
Pdf.BeginDoc;
Pdf.CurrentPage.Size := Letter; // 612 x 792 pt; varsayılan A4'tür
// Genişlik ve renk sayfa durumudur: bir kez kurulur, sonraki her Stroke kullanır
Pdf.CurrentPage.SetLineWidth(1.5);
Pdf.CurrentPage.SetRGBStrokeColor(clBlack);
// Üstten bir inç aşağıda bir çizgi, iki yanda 72 punto kenar boşluğu
Pdf.CurrentPage.MoveTo(72, 72);
Pdf.CurrentPage.LineTo(540, 72);
Pdf.CurrentPage.Stroke;
// Girişteki dip çizgisi: alttan bir inç yukarıda
Pdf.CurrentPage.MoveTo(72, Pdf.CurrentPage.Height - 72);
Pdf.CurrentPage.LineTo(540, Pdf.CurrentPage.Height - 72);
Pdf.CurrentPage.Stroke;
// Tek yolda üç bağlı parça, daha kalın ve mavi
Pdf.CurrentPage.SetLineWidth(3);
Pdf.CurrentPage.SetRGBStrokeColor(RGB(30, 90, 200));
Pdf.CurrentPage.MoveTo(72, 152);
Pdf.CurrentPage.LineTo(172, 102);
Pdf.CurrentPage.LineTo(272, 172);
Pdf.CurrentPage.LineTo(372, 112);
Pdf.CurrentPage.Stroke;
Pdf.EndDoc;
finally
Pdf.Free;
end;
end;
Çizgi kalınlığı bir değişken değil, durumdur. SetLineWidth bir w işleci yazar ve sayfadaki sonraki her kontur, siz değiştirene dek o kalınlığı kullanır; çoklu çizginin 3 punto çıkmasının, iki çizginin 1,5'te kalmasının nedeni budur. Hiç kurmadıysanız PDF varsayılanı olan 1,0 geçerlidir (ISO 32000-1 §8.4.3.2). Kaybolan şekillerin daha donuk bir nedeni vardır: sonrasında boyama çağrısı olmayan geometri hiç işlenmez
Koordinatlar ve kalınlıklar Single'dır; böylece 72.25 ile 0,5 puntoluk bir ince çizgi ikisi de dosyaya sağ çıkarır. Sıfır özel durumdur. Spesifikasyon 0 kalınlığını, çıktı aygıtının çizebileceği en ince çizgi olarak tanımlar: her yakınlaştırmada ekranda bir piksel, 600 dpi'li yazıcıda 1/600 inç; aynı çizgi bir görüntüleyicide kalın, kâğıtta neredeyse yok görünür. İnce çizgiler için 0,25 ya da 0,5 gibi gerçek bir kalınlık seçin; çizgi ağırlığını her aygıtta korur
Kapalı bir üçgenin bir köşesinde neden çentik var?
Başlangıç noktasına dönen üç LineTo çağrısıyla çizilen bir üçgen kapalı görünür ama PDF'te hâlâ açık bir alt yoldur. ISO 32000-1 §8.5.3.2, çizgi birleşimini yalnızca parçaların bir alt yolun içinde buluştuğu yerlere uygular; iki serbest uç bunun yerine çizgi ucu alır. Varsayılan butt uçla ve 6 punto kalemle başlangıç köşesi, öbür iki köşe pürüzsüz miter taşırken kare bir ısırık gösterir. ClosePath (h işleci) son parçayı ekler ve işleyiciye onu ilkinle birleştirmesini söyler
Pdf.CurrentPage.SetLineWidth(6);
Pdf.CurrentPage.SetRGBStrokeColor(clBlack);
// Kapalı görünür, değildir: butt uçlar (72, 500)'de buluşur ve bir çentik bırakır
Pdf.CurrentPage.MoveTo(72, 500);
Pdf.CurrentPage.LineTo(132, 420);
Pdf.CurrentPage.LineTo(192, 500);
Pdf.CurrentPage.LineTo(72, 500);
Pdf.CurrentPage.Stroke;
// Kapalı alt yol: üç köşe de aynı miter birleşimini alır
Pdf.CurrentPage.MoveTo(232, 500);
Pdf.CurrentPage.LineTo(292, 420);
Pdf.CurrentPage.LineTo(352, 500);
Pdf.CurrentPage.ClosePath;
Pdf.CurrentPage.Stroke; // ya da tek çağrıda ClosePathStroke
// Dolgunun ClosePath'e ihtiyacı yoktur: dolgu her alt yolu örtük kapatır
Pdf.CurrentPage.SetRGBFillColor(RGB(220, 60, 60));
Pdf.CurrentPage.MoveTo(392, 500);
Pdf.CurrentPage.LineTo(452, 420);
Pdf.CurrentPage.LineTo(512, 500);
Pdf.CurrentPage.Fill;
Konturlamayı düşündüğünüz her çokgeni ClosePath ya da ClosePathStroke ile kapatın; son nokta zaten ilkine eşit olsa bile. 1 puntoda çentik ekranda görünmez; 6 puntoda normal yakınlaştırmada belirir ve basılı bir grafik göstergesinde bir işleme hatası gibi okunur. Dolgulu şekillerde soru hiç doğmaz ve bir yol kendisiyle kesiştiğinde sıfır-olmayan sarma yerine tek-çift kuralını istiyorsanız EoFill oradadır
Dikdörtgenler, daireler ve TCanvas alışkanlığı
Kapalı ilkeller MoveTo defter tutmayı ortadan kaldırır. Rectangle(X, Y, Width, Height) sol üst köşeyi ve bir boy alır; Circle(X, Y, Radius) bir merkez ve yarıçap alır; ikisi de Fill, Stroke ya da FillAndStroke ile boyanır. Dolgu rengi ile kontur rengi bağımsızdır: SetRGBFillColor ile SetRGBStrokeColor her biri bir TColor alır; böylece Delphi sabitleri ve RGB(...) doğrudan çalışır ve SetRGBColor ikisini birden kurar
Rectangle'daki argüman biçimi tuzağın ta kendisidir. TCanvas.Rectangle, (Left, Top, Right, Bottom) alır ve yılların VCL boya kodu parmaklarınıza ikinci bir köşe geçirtir. HotPDF'e Rectangle(72, 202, 232, 292) verirseniz 160'a 90 yerine 232 punto genişliğinde, 292 yükseklikte bir kutu alırsınız. Elinizdeki sayılar gerçekten iki köşe ise köşe koordinatları alıp boyutu sizin için hesaplayan MFRectangle(X, Y, X1, Y1)'i çağırın; Rectangle'ı boyutlarla düşünen koda saklayın
Bir PDF dosyasının daire işleci yoktur. Circle, her zamanki 0,5523 kontrol noktası çarpanıyla dört kübik Bezier parçası yazar; sayfa içerik akışını sıkıştırıp açarsanız bunu görürsünüz: bir m arkasından dört c işleci. Ellipse(X, Y, Width, Height), sol üst köşesi (X, Y) olan bir sınır kutusunun içinde aynı şeyi yapar
HotPDF ayrıca geçerli sayfa için standart bir TCanvas olan THotPDF.Canvas'ı da açar ve Graphic örneklerindeki CanvasDraw programı, sıradan Canvas.Rectangle, Ellipse ve RoundRect çağrılarıyla bir Ledger sayfasını doldurur. O yol, var olan VCL boya kodunu taşırken mantıklıdır. Yeni çizim kodu CurrentPage üzerinde daha iyi durur; çünkü her çağrı, punto cinsinden tek bir PDF işlecine eşlenir ve çıktı sayıya kadar öngörülebilir olur
Dört işlemle bir açıklama kutusu
Bir açıklama kutusu yukarıdakilerin hepsini birden kullanır: dolgulu ve çerçeveli bir panel, bir işaretçi çizgisi, bir sabitleme noktası ve aynı sol üst koordinatlarla panelin içine yerleştirilmiş iki satır metin. FillAndStroke (B işleci) tek bir yolun içini ve çerçevesini tek çağrıda boyar; böylece dikdörtgen iki kez yerine bir kez kurulur
procedure DrawCallout(Page: THPDFPage);
begin
// 1. Panel: soluk dolgu ve daha koyu çerçeve, tek yol, tek işleme
Page.SetRGBFillColor(RGB(255, 244, 214));
Page.SetRGBStrokeColor(RGB(180, 130, 40));
Page.SetLineWidth(1);
Page.Rectangle(90, 122, 240, 70); // sol üst (90, 122), 240 x 70
Page.FillAndStroke;
// 2. İşaretçi, panelin sol kenarından hedefe iner
Page.SetLineWidth(1.5);
Page.MoveTo(90, 177);
Page.LineTo(66, 246);
Page.Stroke;
// 3. İşaretçinin ucundaki sabitleme noktası, çerçeve renginde
Page.SetRGBFillColor(RGB(180, 130, 40));
Page.Circle(64, 250, 3);
Page.Fill;
// 4. Etiketler: her Y metnin üstüdür, aynı kılavuzda ölçülür
Page.SetFont('Arial', [fsBold], 10);
Page.TextOut(102, 134, 0, 'Check this total');
Page.SetFont('Arial', [], 9);
Page.TextOut(102, 152, 0, 'Rounded to two decimals per line,');
Page.TextOut(102, 164, 0, 'then summed');
end;
// BeginDoc ile EndDoc arasında çağrılır:
// DrawCallout(Pdf.CurrentPage);
Her blok, gereksinim duyan şeklin hemen önünde kendi dolgu rengini, kontur rengini ve kalınlığını kurar; önceki blok aynı değeri bırakmış olsa bile. Bu, dosyada birkaç gereksiz işlece mal olur. Karşılığında herhangi bir blok, önünde koşandan başıboş bir kırmızı dolgu miras almadan taşınabilir, silinebilir ya da kendi yordamına dönüşebilir ve raporlar değiştikçe değişen çizim kodu için o takas her seferinde alınmaya değer
Renkler aynı disiplini hak eder. Dolguları Random($FFFFFF) ile tohumlamak bir demo sayfasını canlı, aynı veriden üretilen iki yapıyı baytça kıyaslanamaz kılar; veriden ya da sabit bir palet dizisinden renk sürükleyin — CanvasDraw demosunun sekiz girdili CanvasColors tablosu yaptığı gibi — aynı girdi aynı dosyayı verir
Kesikler, eğriler ve saydamlık
SetDash, çizgi kalınlığı gibi sayfa durumudur. SetDash([3, 3], 0) sonraki her konturu üç punto açık üç punto kapalı yapar; ikinci argüman örüntünün nereden başlayacağını kaydırır ve NoDash katı kaleme döndürür. Kesik dizisi array of Byte'tır; böylece uzunluklar 1-255 arası tam puntolardır ve içerik akışına verildiği gibi yazılır. Bir grup kılavuz çizgisi için kurulan kesik, sonrasındaki her çizgide açık kalır; o yüzden kesikli bölümü GStateSave ile GStateRestore arasına alın: bunlar q ile Q yazarlar ve saklanan durumu geri yüklemek önceki kesiği, kalınlığı ve renkleri tek adımda geri getirir
Eğriler aynı yolu uzatır. CurveToC(X1, Y1, X2, Y2, X3, Y3), geçerli noktadan iki kontrol noktasıyla (X3, Y3)'e bir kübik Bezier ekler; CurveToV ile CurveToY birinci ya da ikinci kontrol noktasının bir uç noktayla çakıştığı durumları kapsar. Tek bir yol, bir Stroke ya da Fill'ten önce LineTo ile CurveToC parçalarını harmanlayabilir; yuvarlatılmış köşeler ve yumuşatılmış grafik çizgileri böyle çizilir
Saydamlık adlandırılmış bir grafik durumunda yaşar; çünkü PDF alfa'yı renkte değil, bir ExtGState sözlüğünde saklar. THotPDF.RegisterExtGState(FillAlpha, StrokeAlpha) 0-1 arası değerler alır ve bir ad döndürür; CurrentPage.SetGraphicsState(Name) onu sonradan boyanan her şeye uygular. Her saydamlığı belge başına bir kez kaydedin ve adı yeniden kullanın; böylece dosya kaç şekil kullanırsa kullansın saydamlık başına tek sözlük taşır. Alfa PDF 1.4 ister ve HotPDF gerektiğinde çıktı sürümünü 1.4'e yükseltir; StrictVersionLock kuruluysa sürüme dokunmaz ve boş bir ad döndürür. PDFACompliance bir PDF/A-1 profili seçtiğinde 1'in altındaki alfa istisna oluşturur; çünkü ISO 19005-1 §6.4 orada saydamlığı yasaklar. PDF/A-2 ile PDF/A-3 profilleri kabul eder
var
Half: AnsiString;
begin
// Belge başına bir kez kaydedin, döndürülen adı her sayfada yeniden kullanın
Half := Pdf.RegisterExtGState(0.5, 1.0); // %50 dolgu, opak kontur
Pdf.CurrentPage.GStateSave; // q
Pdf.CurrentPage.SetDash([3, 3], 0);
Pdf.CurrentPage.SetLineWidth(0.5);
Pdf.CurrentPage.SetRGBStrokeColor(clGray);
Pdf.CurrentPage.MoveTo(72, 400);
Pdf.CurrentPage.LineTo(540, 400);
Pdf.CurrentPage.Stroke;
Pdf.CurrentPage.SetGraphicsState(Half);
Pdf.CurrentPage.SetRGBFillColor(clYellow);
Pdf.CurrentPage.Rectangle(72, 380, 200, 16); // metin satırının üzerine vurgu
Pdf.CurrentPage.Fill;
Pdf.CurrentPage.GStateRestore; // Q: katı kalem, tam saydamlık geri geldi
end;
Vektör çağrıları, programınızın hesapladığı geometriye uyar: tablo çizgileri, grafik eksenleri ve çubukları, açıklama kutuları, bir düzine yoldan kurulu bir logo. Bir fotoğraf ya da ekran görüntüsü AddImage ile ShowImage'e aittir; pikselleri yollarla izlemek yalnızca dosyayı büyütür. Çıktıyı denetlerken kalın konturların köşelerine ve kesikli her çizgiye 1600%'de yaklaşın; kapatılmamış yolların çentikleri ile bölümünün ötesine sızan kesikler o büyütmede barizdir ve 100%'de gözden kaçar
Bu yazıdaki her çağrı, Delphi ve C++Builder VCL projelerinde koşan ve sonucu düz PDF yol işleçleri olarak yazan HotPDF Delphi Component'in sayfa nesnesi üzerinde yaşar