مقاله فنی

برنامه Delphi HotPDF Hello World: اولین برنامه PDF شما

هر کتابخانه PDF یک برنامه "hello world" ارائه می‌دهد، و در مورد HotPDF ارزش دارد که کمی مکث کنیم، زیرا کوچکترین برنامه‌ای که کاری انجام می‌دهد، دو تصمیمی را به شما تحمیل می‌کند که در هر سند بعدی تکرار خواهید کرد: کدام فونت را تنظیم کنید، و متن در کجای صفحه قرار می‌گیرد. این دو مورد را به درستی انجام دهید و بقیه API تغییراتی در یک موضوع هستند. در اینجا کل ماجرا، یک برنامه کنسول است که یک صفحه واحد را می‌نویسد و به خواننده به نزدیک به یک دوجین زبان سلام می‌کند:

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.

Multilingual Hello World PDF produced by the HotPDF component in Delphi

این کل مثال است. جفت شدن THotPDF.Create(nil) با try/finally ... Free الگوی معمول مالکیت (ownership) در Delphi است، و PDF آن را تغییر نمی‌دهد. آنچه شایسته توجه است ستون فقرات چهار مرحله‌ای درون آن است: تنظیم ویژگی‌ها (properties)، BeginDoc، رسم کردن، EndDoc. این ترتیب قابل تعویض نیست

ویژگی‌های سند را قبل از BeginDoc تنظیم کنید

BeginDoc لحظه‌ای است که HotPDF ساختار سند را متعهد (commits) می‌کند، بنابراین هر چیزی که بر کل فایل تأثیر می‌گذارد باید قبل از آن تنظیم شود. Compression := cmFlateDecode فشرده‌سازی FlateDecode را برای جریان‌های محتوا روشن می‌کند، که تفاوت بین یک فایل فشرده (compact) و یک فایل بیهوده متورم (bloated) است. FontEmbedding := True فونتی را که با آن رسم می‌کنید در فایل بسته‌بندی می‌کند، بنابراین در دستگاهی که هرگز Arial Unicode MS روی آن نصب نشده است، همان‌طور به نظر می‌رسد که در دستگاه شما به نظر می‌رسد. هر یک از این‌ها را بعد از BeginDoc اختصاص دهید و به طور بی‌صدا هیچ کاری با سندی که در حال انجام است انجام نمی‌دهد، بدون هیچ خطایی که به شما هشدار دهد

SetFont، سپس TextOut، و مبدأ را تماشا کنید

دو چیز در مورد فراخوانی‌های رسم (drawing calls)، همه را در صفحه اولشان غافلگیر می‌کند. اولی ترتیب است: SetFont باید قبل از هر TextOut که به آن وابسته است اجرا شود، و باید بعد از هر AddPage تکرار شود، زیرا فونت فعلی پس از شکست صفحه (page break) باقی نمی‌ماند. دومی سیستم مختصات است. TextOut از گوشه سمت چپ پایین صفحه اندازه‌گیری می‌کند، نه از سمت چپ بالا، و Y با حرکت شما به سمت بالا بر حسب نقطه (1/72 اینچ) افزایش می‌یابد. به همین دلیل است که خطوط در اینجا به سمت پایین از 760 حرکت می‌کنند، و هر کدام 30 نقطه پایین‌تر از خط قبلی است. هرکسی که از گرافیک صفحه نمایش (screen graphics) می‌آید، برعکس این موضوع را فرض می‌کند و خط اول را مستقیماً از لبه پایین می‌نویسد

یک فونت، چندین اسکریپت

دلیلی که یک SetFont واحد می‌تواند لاتین، سیریلیک، ژاپنی، و چینی را در یک صفحه حمل کند، خود قلم (face) است: Arial Unicode MS گلیف‌های تقریباً هر اسکریپت را در یک فایل دسته‌بندی می‌کند. آرگومان چهارم برای SetFont مجموعه کاراکترهای ویندوز است، و ارسال DEFAULT_CHARSET به سیستم اجازه می‌دهد به جای پین کردن همه چیز به یک صفحه کد قدیمی (legacy code page)، گلیف‌ها را به ازای هر رشته انتخاب کند. دو هشدار به همراه این راحتی وجود دارد. فونت باید در دستگاهی که PDF را می‌سازد وجود داشته باشد، زیرا HotPDF هر آنچه را که سیستم عامل به نام آن تفکیک (resolves) می‌کند، جاسازی می‌کند؛ اگر Arial Unicode MS وجود نداشته باشد، ویندوز بی سر و صدا یک جایگزین قرار می‌دهد و متن CJK شما می‌تواند به صورت کادرهای خالی بیرون بیاید. و هر اسکریپت را به طور مساوی پوشش نمی‌دهد: برای نوشتن از راست به چپ مانند عربی و عبری، یا هر چیزی که به شکل‌دهی پیچیده نیاز دارد، به سراغ یک فونت اختصاصی که با RegisterUnicodeTTF بارگذاری شده و فراخوانی‌های متنی راست به چپ می‌روید، که موضوع خاص خود است

آن را اجرا کنید و HelloWorld.pdf را در دایرکتوری کاری (working directory) دریافت می‌کنید: یک صفحه، چند خط متن چندزبانه، فشرده شده، با فونت جاسازی شده. گام‌های بعدی بدیهی، دادن اندازه، سبک، و چرخش به آن متن، و قرار دادن عمدی بیش از یک بلوک از آن است، که هر دوی این‌ها را در نمونه TextOut کار شده است. وقتی می‌خواهید به جای فقط متن، خطوط (rules)، کادرها و تصاویر را رسم کنید، همان شیء صفحه (page object) این فراخوانی‌ها را نیز نگه می‌دارد

فراخوانی‌های TextOut، SetFont، و سند که در اینجا نشان داده شده‌اند بخشی از کامپوننت HotPDF برای Delphi و C++Builder هستند