مقال تقني

النص الياباني والصيني العمودي في PDF مع Delphi

يرسم PDF Library for Delphi النص الياباني والصيني نازلاً في الصفحة. يفعّل SetVerticalWritingMode الكتابة العمودية، فتجري استدعاءات DrawText العادية نحو الأسفل، ويُبلِّغ GetVerticalWritingMode عن الحالة الراهنة. قبل وجود هذا، كان وضع النص عموديًا يعني وضع كل حرف يدويًا ورجاء أن يبدو التباعد صحيحًا

الكتابة العمودية ليست نصًا أفقيًا مُدارًا تسعين درجة. تبقى الحروف قائمة، يجري التقدّم نحو الأسفل بدلًا من الأفق، وتغيّر مجموعة من الحروف شكلها كليًا — وهذا هو الجزء الذي يفصل مستندًا يُقرَأ طبيعيًا عن آخر يتعرّف عليه القارئ الياباني فورًا على أنه آلي

مخطط من PDF Library for Delphi يقارن سطر نص أفقي مدوّرًا بوضع كتابة عمودي حقيقي تبقى فيه المحارف منتصبة ويسير التقدم نزولًا في الصفحة
يضع الكتابة الرأسية المحارف معتدلة بمقاييس رأسية خاصة بكل وجه بدل تدوير سطر أفقي، ويُقرأ العمود المنسوخ حرفاً بحرف كما هو

ما الذي يتغير داخل PDF

النص المرسوم بهذه الطريقة يمر عبر خط Type0 في نمط كتابة عمودي يحمل مقاييس الخط الرأسية الخاصة. هذا يهم في اتجاهين. يتقدّم القارئ كل حرف بالمسافة التي قصدها مصمّمه بدلًا من خطوة موحّدة، فيحمل العمود إيقاع الخط الذي رُسم له. ونسخ النص يُعيد الحروف الأصلية، لأن الجريان العمودي لا يزال نصًا حقيقيًا بتعيين سليم بدلًا من سلسلة رموز موضوعة

الخط الذي لا يحمل مقاييس رأسية خاصة يتقدّم بمقدار em واحد لكل حرف، وهذا ما يفعله القارئ بالافتراضي. هذه التحوطية تستحق المعرفة لأنها الفرق الذي تراه حين يُعرض مستند بشكل صحيح بخط CJK سليم ويبدو مفصولًا آليًا بخط لاتيني يحدث أنه يحمل بعض الكانا

var
  Lib: TPDFlib;
  H: Double;
begin
  Lib := TPDFlib.Create;
  try
    Lib.SetOrigin(1);
    Lib.AddTrueTypeFont('MS Mincho', 1);      // 1 = ضمّن وجه الخط
    Lib.SetTextSize(12);
    Lib.SetVerticalWritingMode(1);            // DrawText العادية الآن تجري نزولًا
    H := Lib.GetVerticalTextHeight('MS Mincho', 12, '第三章 保守点検');
    Lib.DrawText(480, 72, '第三章 保守点検');
    Lib.SetVerticalWritingMode(0);            // عودة إلى الأفقي
    Lib.DrawText(72, 72 + H, 'Chapter 3');
    Lib.SaveToFile('manual-ja.pdf');
  finally
    Lib.Free;
  end;
end;

لماذا تبدو الأقواس خاطئة في النص العمودي؟

لأن القوس له شكلان واحدٌ منهما فقط ينتمي إلى عمود. تُرسَم الأقواس وعلامة المد الطويلة والكانا الصغيرة بشكل مختلف حين يجري النص نحو الأسفل — قوس يدور ليجلس على طول العمود بدلًا من الاستلقاء عبره، وعلامة المد الطويلة تصبح ضربة رأسية. ارسم الأشكال الأفقية في عمود رأسي وكل واحد منها يستلقي على جنبه

يأخذ PDF Library for Delphi الأشكال من ميزة الخط الرأسية الخاصة، فيزوّد كل خط ما رسمه مصمّمه بدلًا من استبدال مُخمَّن من الحرف. هذا التمييز مهم للصحة: جدول استبدال مُخمَّن صحيح للحالات الشائعة وخاطئ للخطوط التي تعامل حرفًا بشكل مختلف، والخط الذي لا يسمّي أشكالًا رأسية يُرسَم تمامًا كما كان بدلًا من أن يُدفَع عبر جدول لم يطلبه قط

يقيس GetVerticalTextHeight الأشكال التي ستُرسَم فعلًا، فيظل العمود الذي تتغير حروفه في الشكل مقيسًا صحيحًا. قياس الأشكال الأفقية ورسم العمودية هو المصدر الكلاسيكي للأعمدة تتجاوز صندوقها ببضعة حروف

مخطط من PDF Library for Delphi يوضح كيف توفر ميزة الخط العمودية أشكال الأقواس وعلامة مد الصوت المستلقية على طول عمود رأسي بينما تقف المحارف العادية دون تغيير، وكلها تُقاس بـ GetVerticalTextHeight
يقرر ميزة الوجه الرأسية أيُّ المحارف تغيّر شكلها في العمود، ويقيس GetVerticalTextHeight الأشكال التي ستُرسم فعلاً

رسم جريان واحد دون تغيير النمط

يرسم DrawVerticalText جريانًا واحدًا عموديًا، آخذًا الموضع واسم الخط والحجم والنص، تاركًا نمط الكتابة كما هو. استخدمه للاستثناء العمودي داخل مستند أفقي — عنوان كعب، ختم، عمود واحد من الأسماء — حيث تشغيل نمط شامل وإيقافه حول كل استدعاء حالةٌ أكثر مما يستحقها العمل

يُحتفَظ بالشكلين الأفقي والعمودي لخط واحد منفصلين داخليًا، فتحمل الصفحة كليهما دون أن يزعج أحدهما الآخر. هذا ما يجعل الصفحة المختلطة عملية: صفحة كتاب ياباني بنص متن عمودي وترويسات جارية أفقية، أو شهادة صينية بعنوان عمودي فوق سطور تفصيل أفقية

// جريان عمودي واحد داخل صفحة أفقية في بقيتها
Lib.DrawVerticalText(520, 96, 'MS Mincho', 14, '保守点検記録');
// النص الأفقي المحيط به غير متأثر
Lib.DrawText(72, 96, 'Maintenance inspection record');

ضبط الخط الصحيح قبل أي شيء آخر

الكتابة العمودية تتوقف كليًا على الخط. خط CJK بمقاييس رأسية سليمة وميزة رأسية يُنتج إخراجًا صحيحًا بلا عمل إضافي؛ خط بلاها يُنتج حروفًا قائمة تتقدم em واحدًا في المرة بلا تغيير في الشكل إطلاقًا. إن بدا النص العمودي خاطئًا بشكل خفي، افحص الخط قبل فحص الكود

يتبع التضمين القواعد والتكاليف المعتادة. خط CJK كامل كبير، فالتحديد الفرعي ليس خيارًا للمستندات التي تذهب إلى أي مكان — تغطي ملاحظات تحسين حجم ملف PDF وتحديد الخطوط الفرعي ما يجب توقعه، ويغطي شرح تضمين الخطوط المفقودة في PDF موجود حالة الإصلاح حين يصل مستند عمودي بلا خطوطه

أين لا يزال النص العمودي يحتاج قرار تخطيط منك

ترتيب الأعمدة. النص الياباني العمودي يجري من اليمين إلى اليسار بالأعمدة، فتبدأ صفحة بعمودين من الحافة اليمنى، ولا نمط كتابة يستطيع استنتاج ذلك من النص. ينطبق الأمر نفسه على ترتيب الصفحات في مستند يُقرَأ من اليمين إلى اليسار ككل، وعلى أين تجلس الفوريغانا والحاشيات وتعليقات الأشكال

مخطط من PDF Library for Delphi لـ DrawVerticalText يضع مقطعًا عموديًا منتصبًا بجوار أسطر DrawText الأفقية العادية على صفحة مشتركة دون لمس وضع الكتابة العام
يحمل DrawVerticalText خطه ومقاسه وموضعه الخاصين، فيتعايش عمود رأسي واحد مع الاستدعاءات الأفقية من حوله

ما تضمنه المكتبة هو أن كل جريان مضبوط بشكل صحيح: أشكال صحيحة، تقدّم صحيح، نص قابل للاستخراج. أين تذهب الجريانات على الصفحة مشكلة تخطيط، وللمستندات المُجمَّعة من البيانات فإن شرح البحث عن النص وعدّ عناصر الصفحة مفيد للتحقق لاحقًا أن ما هبط على الصفحة هو ما قصدته

PDF Library for Delphi مكتبة Pascal أصلية لـ PDF من أجل Delphi وC++Builder وLazarus، والكتابة العمودية لـ CJK جزء من واجهة الرسم لا إضافة — انظر صفحة منتج PDF Library for Delphi لقائمة ميزات النص والخط