A HotPDF úgy rajzol vektorgrafikát, hogy utat épít az aktuális oldalon, majd megkéri, hogy fesse ki. Nincs közben bitképes lépés. Az a vonal, amelyet a MoveTo és a LineTo hívással rajzol, PDF útvonal-operátorokként kerül a tartalomfolyamba, tehát valódi vektor marad: éles 50%-os nagyításnál, éles 1600%-nál, és töredéke annak a méretnek, amennyibe a raszteres változat kerülne. Ábrákhoz, táblázatvonalakhoz, diagramtengelyekhez és űrlapdíszekhez pontosan erre van szüksége, a mögötte álló API pedig elég kicsi ahhoz, hogy egy ülésben megtanulja
A teljes rajzolási felület a THotPDF.CurrentPage tulajdonságon él. A BeginDoc és az EndDoc között ezen az oldalobjektumon állítja be a színt és a vonalvastagságot, rakja le a geometriát, majd egy festőoperátor hívásával rögzíti. Az a négy alapelem, amelyet a leggyakrabban használ: a MoveTo és a LineTo tetszőleges utakhoz, a Rectangle dobozokhoz, a Circle korongokhoz, valamint a két festőoperátor, a Stroke és a Fill
A koordináta-rendszer bal alsó sarokból indul
Ez az az egy dolog, amely mindenkit elgáncsol, aki a VCL felől érkezik. Az a TCanvas, amelyre a vezérlőket festi, a bal felső sarokba teszi az origót, és az Y lefelé nő. A PDF fordítva csinálja. A HotPDF az oldal bal alsó sarkától mér pontban (1/72 hüvelyk), és az Y felfelé haladva nő. Az Y := 720 pont a US Letter oldal teteje közelében ül, amely 792 pont magas, az Y := 50 pedig az alja közelében. Ha az első rajza függőlegesen tükrözve jön ki, ez az ok: a képernyőgrafikából átvett kód rossz irányt feltételez, és lefut az alsó élen
Ugyanez a szokás irányítja a TextOut hívást is, tehát a szöveg és az alakzatok egyetlen gondolati modellen osztoznak, amint ezt beépíti magába. Az elrendezést úgy tervezze meg, hogy eldönti, hol ül az egyes elemek alja, nem a teteje, és a többi ebből következik
Utak: MoveTo, LineTo, Stroke
A körvonalazott út olyan toll, amelyet felemelnek, letesznek és húznak. A MoveTo felemeli a tollat és beállítja a kezdőpontot anélkül, hogy bármit jelölne. Minden LineTo új pontig terjeszti ki az aktuális utat. Semmi nem jelenik meg az oldalon, amíg meg nem hívja a Stroke operátort, amely az aktuális körvonalszínnel és vonalvastagsággal kirajzolja a felgyülemlett utat, majd kiüríti az utat, hogy a következő MoveTo tiszta lappal induljon
var
Pdf: THotPDF;
begin
Pdf := THotPDF.Create(nil);
try
Pdf.FileName := 'DrawPaths.pdf';
Pdf.BeginDoc;
// A vonalvastagság pontban értendő, és a megváltoztatásáig érvényes.
Pdf.CurrentPage.SetLineWidth(1.5);
Pdf.CurrentPage.SetRGBStrokeColor(clBlack);
// Vízszintes vonal az oldal teteje közelében (az Y alulról mérve).
Pdf.CurrentPage.MoveTo(72, 720);
Pdf.CurrentPage.LineTo(523, 720);
Pdf.CurrentPage.Stroke; // rögzíti az utat; eddig semmi nem rajzolódott
// Vastagabb, összefüggő töröttvonal: három szakasz egyetlen útban.
Pdf.CurrentPage.SetLineWidth(3);
Pdf.CurrentPage.SetRGBStrokeColor(RGB(30, 90, 200));
Pdf.CurrentPage.MoveTo(72, 640);
Pdf.CurrentPage.LineTo(172, 690);
Pdf.CurrentPage.LineTo(272, 620);
Pdf.CurrentPage.LineTo(372, 680);
Pdf.CurrentPage.Stroke;
Pdf.EndDoc;
finally
Pdf.Free;
end;
end;
Két részlet valódi hibakeresési időt spórol. A vonalvastagság állapot, nem argumentum: a SetLineWidth egyszer állítja be, és minden későbbi Stroke ezt az értéket használja, amíg újra meg nem változtatja — ezért vastagabb a fenti töröttvonal, mint a vonal. Az út pedig minden Stroke után nullázódik, tehát egy elfelejtett Stroke azt jelenti, hogy a gondosan lerakott geometria egyáltalán nem jelenik meg. Ha egy alakzat hiányzik a kimenetből, először a festőhívást keresse
A koordináták pontban vannak, a pontok pedig törtek lehetnek. A MoveTo és a LineTo Single értékeket fogad, tehát a 0.5 pontos hajszálvonal vagy a 72.25 pozíció szabályos és értelmes, nem kerekítődik a legközelebbi egész egységre. Ez a pontosság két ellentétes irányban számít. A körülbelül 0.5 alatti vonalvastagság eszközfüggő, lehető legvékonyabb vonalként jelenhet meg, amely a képernyőn eltűnik, nyomtatásban viszont visszatér, tehát a láthatóan szánt vonal olyan vastagságot kíván, amelyet szándékosan állít be, nem az alapértelmezést. A másik végén a táblázatvonalak és rácsvonalak egész pontos koordinátákra igazítása megakadályozza, hogy a sűrű rács enyhén egyenetlennek látsszon ott, ahol a szomszédos vonalak másképp kerekednek. Döntse el előre a rácsosztást pontban, és az elrendezés többi része örökli
Kitöltött alakzatok és szín
A zárt alapelemek körvonalazás helyett kitölthetők. A Rectangle pozíciót és méretet vár, a Circle középpontot és sugarat, és bármelyiket a Fill rögzíti, amely az aktuális kitöltőszínnel festi a belsejét, vagy a Stroke, ha csak körvonalat szeretne. A kitöltőszín és a körvonalszín különálló állapotdarab, amelyeket a SetRGBFillColor és a SetRGBStrokeColor állít be, és mindkettő egyetlen TColor értéket vár. Ez azt jelenti, hogy közvetlenül újrahasználhatja a Delphi színállandóit és az RGB segédfüggvényt
// Rectangle(X, Y, Width, Height): az X és az Y a bal alsó sarok.
Pdf.CurrentPage.SetRGBFillColor(RGB(220, 60, 60));
Pdf.CurrentPage.Rectangle(72, 500, 160, 90);
Pdf.CurrentPage.Fill;
// Circle(X, Y, Radius): az X és az Y a középpont.
Pdf.CurrentPage.SetRGBFillColor(clNavy);
Pdf.CurrentPage.Circle(420, 545, 45);
Pdf.CurrentPage.Fill;
// Csak körvonal: állítson be körvonalszínt és vastagságot, majd Stroke.
Pdf.CurrentPage.SetLineWidth(2);
Pdf.CurrentPage.SetRGBStrokeColor(clBlack);
Pdf.CurrentPage.Rectangle(72, 400, 160, 60);
Pdf.CurrentPage.Stroke;
Figyelje az argumentumok alakját a Rectangle hívásnál. Ez pozíció plusz méret, X, Y, Width, Height, nem két szemközti sarok. Az a TCanvas.Rectangle, amelyet a Delphi fejlesztők ismernek, (Left, Top, Right, Bottom) értéket vár, tehát az izommemória második sarkot ad át a HotPDF-nek ott, ahol az szélességet és magasságot vár, és a doboz rossz méretben jön ki. Az (X, Y) pár a bal alsó sarok, összhangban az oldal origójával. Kör esetén az (X, Y) a középpont, a harmadik argumentum pedig a sugár pontban
Egy színválasztás, amelyet az eredeti minta elrontott
Ennek a példának egy régebbi változata minden alakzathoz Random($FFFFFF) hívással vetette a színt. Élénknek látszik, és rossz ösztön generált dokumentumokhoz. Azt a PDF-et, amelyet kódból épít, általában tesztelni is szeretné, a véletlenszerű kitöltőszínek pedig lehetetlenné teszik a kimenet futásról futásra való összehasonlítását: egy ismerten jó fájllal szembeni bájtszintű eltéréskeresés minden alkalommal elbukik, minden valódi ok nélkül. Válasszon kifejezett színeket. Ha alakzatsorozaton belül változatosságot szeretne, vezérelje az adataiból vagy egy rögzített palettatömbből, hogy ugyanaz a bemenet mindig ugyanazt a fájlt adja. A meghatározottság többet ér az újdonságnál, amikor az eredmény kiadási munkafolyamaton megy át
Az alapelemek összerakása: kiemelődoboz
Minden alapelem önmagában egyszerű; a haszon akkor mutatkozik meg, amikor néhányuk olyanná áll össze, amire egy jelentésnek valóban szüksége van. Egy kiemelődoboz — az a jegyzetelt doboz, amely egy ábrára mutat és megmagyarázza — mindent használ, amit eddig tárgyaltunk: szegélyes, kitöltött téglalapot, körvonalazott mutatóvonalat, a mutatót lehorgonyzó pontot, valamint a dobozon belül elhelyezett szöveget, ugyanazokkal a bal alsó koordinátákkal, amelyeket az alakzatok is használnak. A FillAndStroke itt szolgálja meg a helyét, mert egyetlen rögzítéssel festi ki egy út belsejét és körvonalát ahelyett, hogy kétszer építené fel a téglalapot
var
Pdf: THotPDF;
begin
Pdf := THotPDF.Create(nil);
try
Pdf.FileName := 'Callout.pdf';
Pdf.BeginDoc;
// 1. A doboz: halvány kitöltés plusz látható szegély, egy út, egy rögzítés.
// A Rectangle bal alsó sarok plusz méret, az Y alulról mérve
Pdf.CurrentPage.SetRGBFillColor(RGB(255, 244, 214)); // halvány borostyán panel
Pdf.CurrentPage.SetRGBStrokeColor(RGB(180, 130, 40)); // sötétebb perem
Pdf.CurrentPage.SetLineWidth(1);
Pdf.CurrentPage.Rectangle(90, 600, 240, 70);
Pdf.CurrentPage.FillAndStroke;
// 2. A mutató: egyetlen körvonalazott szakasz a doboz szélétől lefelé
// a megjegyzéssel ellátott dolog irányába
Pdf.CurrentPage.SetLineWidth(1.5);
Pdf.CurrentPage.MoveTo(90, 615); // a doboz bal széle
Pdf.CurrentPage.LineTo(66, 546);
Pdf.CurrentPage.Stroke;
// 3. Kitöltött pont horgonyozza le a mutatót a célpontján
Pdf.CurrentPage.SetRGBFillColor(RGB(180, 130, 40));
Pdf.CurrentPage.Circle(64, 542, 3);
Pdf.CurrentPage.Fill;
// 4. A címke, a doboz bal alsó sarkához képest elhelyezve.
// A szöveg és az alakzatok egy koordináta-rendszeren osztoznak, tehát
// az eltolások egyszerű számtan a (90, 600) ponthoz képest
Pdf.CurrentPage.SetFont('Arial', [fsBold], 10);
Pdf.CurrentPage.TextOut(102, 645, 0, 'Check this total');
Pdf.CurrentPage.SetFont('Arial', [], 9);
Pdf.CurrentPage.TextOut(102, 628, 0, 'The rounding rule changed in the');
Pdf.CurrentPage.TextOut(102, 616, 0, 'June release; verify against v2.1');
Pdf.EndDoc;
finally
Pdf.Free;
end;
end;
Figyelje meg, milyen kevés állapotkezelést kíván az összetett rajz. A kitöltőszín, a körvonalszín és a vonalvastagság mind közvetlenül az őket használó alakzat előtt kerül beállításra, tehát a rajz minden blokkja önálló egységként olvasható, és átrendezhető vagy segédfüggvénybe emelhető anélkül, hogy rejtett állapotot vonszolna magával. Csomagolja ezt eljárásba, amely a horgonypontot és a szövegeket veszi át, és negyven sor áráért újrahasználható ábramegjegyzést kap
Hol térül meg a vektoros rajzolás, és hol nem
Akkor nyúljon ezekhez az út- és alakzathívásokhoz, amikor a geometria generált: diagramrácsvonalak és oszlopok, egy számlatáblázat vonalai, kiemelődobozok egy ábrán, néhány útvonalként kifejezett emblémajel. Mindez elmosódás nélkül skálázódik, és szinte semmit nem tesz hozzá a fájlmérethez, mert egy téglalap néhány szám, nem több ezer képpont. A másik oldal is őszinte. Ha valójában fénykép vagy képernyőkép van a kezében, rajzolja képként az AddImage és a ShowImage hívással; egy bitkép vektorhívásokkal való körberajzolása semmit sem hoz. A fenti egyenes szakaszok, téglalapok és körök viszik a valódi jelentéskészítési munka túlnyomó részét, az a három finomítás pedig, amelyről a fejlesztők legközelebb kérdeznek — görbék, szaggatásminták és átlátszóság —, ugyanazon az oldalobjektumon ül
Görbék, szaggatás és átlátszóság dióhéjban
A szabad formájú görbék ugyanazt az útgépezetet terjesztik ki, amely már megvan. A CurveToC(X1, Y1, X2, Y2, X3, Y3) köbös Bézier-szakaszt fűz az aktuális ponttól az (X3, Y3) pontig, a két vezérlőpont felé hajolva, a rövidített változatok, a CurveToV és a CurveToY pedig azokat az eseteket fedik le, amikor az egyik vezérlőpont egybeesik egy végponttal. Egy út szabadon keverheti a LineTo és a CurveToC szakaszokat, mielőtt egyetlen Stroke vagy Fill rögzítené, és így épülnek a lekerekített sarkok és a sima diagramgörbék
A szaggatott körvonalak állapotok, éppúgy, mint a vonalvastagság. A SetDash([3, 3], 0) minden későbbi körvonalat három pont be, három pont ki mintára vált, ahol a tömb pontban adja meg a be- és kikapcsolt szakaszok hosszát, a második argumentum pedig azt fázisolja, hol kezdődik a ciklus; a NoDash visszaadja a tollnak a folytonos vonalat. Állítsa be, húzza meg azokat a rácsvonalakat, amelyek ezt kívánják, majd állítsa vissza a következő folytonos vonal előtt, különben a szaggatás csendben megfertőzi mindazt, ami utána jön
Az átlátszóság nem színargumentumon, hanem nevesített grafikai állapoton át működik, mert a PDF-ben az alfa a grafikai állapot szótárának tulajdonsága. Regisztráljon egyet a dokumentumon a RegisterExtGState hívással, 0 és 1 közötti kitöltési és körvonalalfát átadva, majd alkalmazza a visszakapott nevet a CurrentPage.SetGraphicsState hívással; a kitöltések és körvonalak ettől kezdve a regisztrált átlátszatlansággal festenek. Nehézkesebb szertartás, mint a színbeállítók, de megéri, amint először kell egy kiemelősávnak szöveg fölé kerülnie anélkül, hogy elrejtené
A megtartandó szokások közül az utolsó az ellenőrzés. A generált geometria átmehet az Ön gépén, és elbukhat egy ügyfélén, jellemzően a belekevert szöveg betűkészlet-helyettesítése vagy egy nem tartható oldalméret-feltevés miatt. Nyissa meg a kész fájlt néhány nagyítási szinten, hogy az élek tiszták maradnak-e, és ellenőrizze, hogy minden alakzat a szándékolt margódobozon belülre esik. Meghatározott színsémával ez az ellenőrzés egy referencia-PDF-fel szemben automatizálható ahelyett, hogy szemre kellene nézni
Az itt bemutatott MoveTo, LineTo, Stroke, Fill és színhívások a HotPDF Delphi Component részei, Delphihez és C++Builderhez