מאמר טכני

Delphi HotPDF Hello World: תוכנית ה-PDF הראשונה שלך

כל ספריית PDF מגיעה עם "hello world" (שלום עולם), ובזה של HotPDF שווה להתעכב, מכיוון שהתוכנית הקטנה ביותר שעושה משהו כבר כופה שתי החלטות שתחזור עליהן בכל מסמך לאחר מכן: איזה גופן להגדיר, והיכן בעמוד נוחת הטקסט. קבל את שניהם נכון ושאר ה-API הוא וריאציות על נושא. הנה כל העניין, תוכנית מסוף (console program) שכותבת עמוד יחיד המברך את הקורא בכמעט תריסר שפות:

program HelloWorld;

{$APPTYPE CONSOLE}

uses
  Winapi.Windows,   // for DEFAULT_CHARSET; on pre-XE2 Delphi use plain Windows
  HPDFDoc;          // HotPDF main unit

procedure CreateHelloWorld(const FileName: string);
var
  Pdf: THotPDF;
begin
  Pdf := THotPDF.Create(nil);
  try
    Pdf.FileName := FileName;
    Pdf.Compression := cmFlateDecode;   // shrink the content streams
    Pdf.FontEmbedding := True;          // embed the face so it renders anywhere
    Pdf.BeginDoc;

    // One face covering many scripts. The 4th argument is the Windows charset;
    // DEFAULT_CHARSET lets the system pick glyphs per string.
    Pdf.CurrentPage.SetFont('Arial Unicode MS', [], 14, DEFAULT_CHARSET);

    // TextOut measures from the BOTTOM-LEFT corner, in points, Y growing upward.
    Pdf.CurrentPage.TextOut(72, 760, 0, 'Hello, Delphi PDF world!');     // English
    Pdf.CurrentPage.TextOut(72, 730, 0, 'Hola, mundo Delphi PDF!');      // Spanish
    Pdf.CurrentPage.TextOut(72, 700, 0, 'Hallo, Delphi PDF Welt!');      // German
    Pdf.CurrentPage.TextOut(72, 670, 0, 'Bonjour, monde PDF Delphi!');   // French
    Pdf.CurrentPage.TextOut(72, 640, 0, 'Ciao, mondo Delphi PDF!');      // Italian
    Pdf.CurrentPage.TextOut(72, 610, 0, 'Olá, mundo Delphi PDF!');       // Portuguese
    Pdf.CurrentPage.TextOut(72, 580, 0, 'Здравствуйте, Delphi PDF мир!'); // Russian
    Pdf.CurrentPage.TextOut(72, 550, 0, 'こんにちは、Delphi PDFの世界!');    // Japanese
    Pdf.CurrentPage.TextOut(72, 520, 0, 'Merhaba, Delphi PDF dünyası!');  // Turkish
    Pdf.CurrentPage.TextOut(72, 490, 0, '你好,Delphi PDF世界');           // Chinese
    Pdf.CurrentPage.TextOut(72, 460, 0, '여보세요, Delphi PDF 세계!');      // Korean

    Pdf.EndDoc;
  finally
    Pdf.Free;
  end;
end;

begin
  CreateHelloWorld('HelloWorld.pdf');
  Writeln('Wrote HelloWorld.pdf');
end.

מסמך PDF Hello World רב לשוני המופק על ידי רכיב HotPDF ב-Delphi

זוהי כל הדוגמה. ה-THotPDF.Create(nil) המזווג עם try/finally ... Free היא תבנית הבעלות הרגילה של Delphi, ו-PDF אינו משנה אותה. מה שראוי לתשומת לב הוא עמוד השדרה בן ארבעת השלבים שבפנים: הגדרת מאפיינים, BeginDoc, ציור, EndDoc. הסדר אינו ניתן להחלפה

הגדר מאפייני מסמך לפני BeginDoc

BeginDoc הוא הרגע שבו HotPDF מקבע את מבנה המסמך, ולכן כל מה שמשפיע על הקובץ כולו חייב להיקבע לפניו. Compression := cmFlateDecode מפעיל את FlateDecode עבור זרמי התוכן, שזה ההבדל בין קובץ קומפקטי לקובץ נפוח שלא לצורך. FontEmbedding := True אורז את הגופן שאתה מצייר איתו לתוך הקובץ, כך שהוא נראה זהה במחשב שמעולם לא הותקן בו Arial Unicode MS כפי שהוא נראה בשלך. הקצה כל אחד מהם לאחר BeginDoc והוא לא יעשה בשקט שום דבר למסמך שכבר מתהווה, ללא שום שגיאה שתזהיר אותך

קבע SetFont, לאחר מכן TextOut, וצפה במקור (origin)

שני דברים לגבי קריאות הציור תופסים כל אחד בעמוד הראשון שלו. הראשון הוא סדר: SetFont חייב לרוץ לפני כל TextOut שתלוי בו, ויש לחזור עליו לאחר כל AddPage, מכיוון שהגופן הנוכחי אינו שורד מעבר עמוד (page break). השני הוא מערכת הקואורדינטות. TextOut מודד מהפינה השמאלית-תחתונה של העמוד, לא מהשמאלית-עליונה, כשציר Y גדל ככל שאתה נע מעלה, בנקודות (1/72 אינץ'). זו הסיבה שהשורות כאן צועדות כלפי מטה מ-760, כל אחת 30 נקודות מתחת לקודמתה. כל מי שמגיע מגרפיקת מסך מניח את ההפך וכותב את השורה הראשונה היישר מחוץ לקצה התחתון

גופן אחד, כתבים רבים

הסיבה ש-SetFont יחיד יכול לשאת לטינית, קירילית, יפנית וסינית על אותו עמוד היא הגופן (face) עצמו: Arial Unicode MS מאגד גליפים לכמעט כל כתב לקובץ אחד. הארגומנט הרביעי ל-SetFont הוא ערכת התווים (character set) של Windows, והעברת DEFAULT_CHARSET מאפשרת למערכת לבחור גליפים לכל מחרוזת במקום להצמיד הכל לדף קוד מורשת (legacy code page) אחד. שתי אזהרות מתלוות לנוחות הזו. הגופן חייב להיות נוכח במחשב שבונה את ה-PDF, מכיוון ש-HotPDF מטמיע כל מה שמערכת ההפעלה מפענחת אליו את השם; אם Arial Unicode MS חסר, Windows מחליף בשקט בתחליף וטקסט ה-CJK שלך עלול לצאת כתיבות ריקות. והוא אינו מכסה כל כתב במידה שווה: עבור כתיבה מימין לשמאל כמו ערבית ועברית, או כל דבר הדורש עיצוב מורכב, אתה שולח יד לגופן ייעודי הנטען עם RegisterUnicodeTTF וקריאות טקסט מימין לשמאל, שזהו נושא בפני עצמו

הרץ את זה ותקבל את HelloWorld.pdf בספריית העבודה (working directory): עמוד אחד, מספר שורות של טקסט רב-לשוני, דחוס, עם הגופן מוטמע. הצעדים הבאים המובנים מאליהם הם מתן גודל, סגנון וסיבוב (rotation) לטקסט זה, והצבת יותר מבלוק אחד שלו במכוון, שאת שניהם דוגמת TextOut מעבדת. כאשר ברצונך לצייר כללים (rules), תיבות ותמונות ולא רק טקסט, אותו אובייקט עמוד מחזיק גם בקריאות אלו

קריאות המסמך, SetFont, ו-TextOut המוצגות כאן הן חלק מרכיב HotPDF עבור Delphi ו-C++Builder