Technical Article

مثال Hello World مع HotPDF في Delphi: أول برنامج 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 هو نمط الملكية المعتاد في Delphi، وملفات PDF لا تغيّره. ما يستحق الانتباه هو العمود الفقري ذي الخطوات الأربع داخل المثال: اضبط الخصائص، ثم BeginDoc، ثم ارسم، ثم EndDoc. ترتيب هذه الخطوات ليس قابلًا للتبديل

اضبط خصائص المستند قبل BeginDoc

لحظة BeginDoc هي اللحظة التي يثبّت فيها HotPDF بنية المستند، لذلك يجب ضبط أي شيء يؤثر في الملف كله قبلها. Compression := cmFlateDecode يفعّل FlateDecode في تدفقات المحتوى، وهذا هو الفرق بين ملف صغير وملف متضخم بلا داع. FontEmbedding := True يضمّن الخط الذي ترسم به داخل الملف، فيظهر كما هو على جهاز لم يسبق أن ثُبّت عليه Arial Unicode MS تمامًا كما يظهر على جهازك. إذا أسندت أيًا منهما بعد BeginDoc فلن يحدث شيء للمستند الجاري إنشاؤه، من دون رسالة خطأ تنبهك

اضبط SetFont ثم TextOut وانتبه إلى نقطة الأصل

هناك أمران في استدعاءات الرسم يربكان الجميع في الصفحة الأولى. الأول هو الترتيب: يجب تشغيل SetFont قبل أي TextOut يعتمد عليه، ويجب تكراره بعد كل AddPage لأن الخط الحالي لا يبقى بعد فاصل الصفحة. الثاني هو نظام الإحداثيات. يقيس TextOut من الزاوية السفلية اليسرى للصفحة، لا من العلوية اليسرى، مع ازدياد Y كلما تحركت إلى أعلى، بالنقاط (1/72 بوصة). ولهذا تتحرك الأسطر هنا إلى الأسفل بدءًا من 760، بحيث يكون كل سطر أدنى من السابق بـ 30 نقطة. من يأتي من رسومات الشاشة يفترض العكس ويكتب السطر الأول خارج الحافة السفلية مباشرة

خط واحد، وأنظمة كتابة متعددة

السبب في أن SetFont واحدًا قادر على حمل اللاتينية والسيريلية واليابانية والصينية في الصفحة نفسها هو الخط نفسه: Arial Unicode MS يضم glyphs لمعظم أنظمة الكتابة في ملف واحد. الوسيط الرابع في SetFont هو مجموعة أحرف Windows، وتمرير DEFAULT_CHARSET يسمح للنظام باختيار glyphs لكل سلسلة بدل تثبيت كل شيء على صفحة ترميز قديمة واحدة. وهناك ملاحظتان ترافقان هذه المرونة. يجب أن يكون الخط موجودًا على الجهاز الذي يبني ملف PDF، لأن HotPDF يضمّن ما يحلّه النظام إلى الاسم؛ فإذا كان Arial Unicode MS مفقودًا، يستبدل Windows خطًا آخر بصمت وقد يظهر نص CJK على شكل مربعات فارغة. وهو أيضًا لا يغطي كل الأنظمة على قدم المساواة: للكتابة من اليمين إلى اليسار مثل العربية والعبرية، أو لأي شيء يحتاج إلى تشكيل معقّد، تحتاج إلى خط مخصص محمّل عبر RegisterUnicodeTTF واستدعاءات النص من اليمين إلى اليسار، وهو موضوع مستقل

شغّله وستحصل على HelloWorld.pdf في مجلد العمل: صفحة واحدة، وعدة أسطر من نص متعدد اللغات، مع الضغط وتضمين الخط. الخطوات التالية الواضحة هي إعطاء هذا النص حجمًا ونمطًا ودورانًا، ووضع أكثر من كتلة منه عمدًا، وكل ذلك يشرحه مثال TextOut. وعندما تريد رسم الخطوط والمربعات والصور بدل النص وحده، فإن كائن الصفحة نفسه يحمل تلك الاستدعاءات أيضًا

استدعاءات TextOut وSetFont واستدعاءات المستند الأخرى المعروضة هنا جزء من مكوّن HotPDF الخاص بـ Delphi وC++Builder