العربية
شركات

كتابة PDF من الصفر (01): مرحبا بالعالم - بناء PDF قابل للاستخدام

فريق Doclingo30 يناير 2026

كتابة PDF من الصفر (01): مرحبا بالعالم - بناء PDF قابل للاستخدام

هدف السلسلة: فهم PDF كنوع من تنسيق الملفات القابل للقراءة - بدءًا من "مثال صغير يعمل"، ثم التوسع تدريجيًا إلى الرسوميات، والصفحات المتعددة، والضغط وإعادة استخدام الموارد.

فهرس السلسلة

  • المقالة 01 (هذه المقالة): كتابة PDF صغير يدويًا (صفحة واحدة + سطر واحد من النص)، واستخدام الأدوات لإكماله ليصبح PDF قياسي يمكن فتحه
  • المقالة 02: رسم خطوط/مستطيلات في تدفق المحتوى (فهم المسارات، الحدود، التعبئة)
  • المقالة 03: PDF متعدد الصفحات (كيف تتشكل شجرة الصفحات)
  • المقالة 04: الاقتراب من العالم الحقيقي (تدفق مضغوط، إعادة استخدام الموارد، الهياكل الاختيارية، إلخ)

لماذا يجب أن نفهم الهيكل الأساسي لـ PDF؟

PDF (تنسيق المستندات القابل للنقل) هو واحد من أكثر لغات وصف الصفحات شيوعًا اليوم. على عكس HTML/CSS الذي يفصل بين "المحتوى والعرض، وقابل لإعادة التدفق"، يركز PDF أكثر على ثبات التخطيط، وما تراه هو ما تحصل عليه - بغض النظر عن الجهاز الذي يتم فتحه عليه، يظل التنسيق ثابتًا.

هناك عدة فوائد عملية لفهم الهيكل الأساسي لـ PDF:

  • تصحيح مشاكل إنشاء PDF: عندما يحدث خطأ أثناء إنشاء PDF باستخدام مكتبة كود، فإن فهم الهيكل الأساسي يمكن أن يساعدك في تحديد المشكلة بسرعة
  • المعالجة الآلية: لاستخراج النصوص بكميات كبيرة، دمج الوثائق، إضافة علامات مائية، إلخ، بعد فهم الهيكل يمكنك إجراء العمليات بدقة
  • التدقيق الأمني: فهم ما يمكن تضمينه في PDF (JavaScript، المرفقات، النماذج، إلخ) يساعد في التحليل الأمني
  • تعلم تصميم تنسيقات الملفات: تصميم PDF "رسم الكائنات + الوصول العشوائي" هو مثال كلاسيكي يستحق التعلم

التحضيرات

ستكتب هذه المقالة ملف hello-broken.pdf "غير مكتمل الهيكل ولكن منطقي"، ثم تستخدم pdftk لإكمال الهيكل الأساسي تلقائيًا وإخراج hello.pdf.

  • الأدوات المطلوبة: pdftk (أداة سطر أوامر مجانية، تدعم Windows/macOS/Linux)
  • ملفات الإخراج: hello-broken.pdf (مكتوب يدويًا)، hello.pdf (بعد الإصلاح يمكن فتحه)

المفاهيم الأساسية: الهيكل الثلاثي لـ PDF

أهم شيء لفهم PDF هو بناء نموذج ذهني ثلاثي:

نموذج PDF الثلاثي

1. طبقة الكائنات (محتوى المستند)

يتكون مستند PDF من العديد من الكائنات، وترتبط الكائنات ببعضها البعض باستخدام الإشارات غير المباشرة (مثل 2 0 R) لتشكيل صورة. أنواع الكائنات الشائعة:

النوعالمثالالوصف
اسم/Pageاسم يبدأ بـ /
عدد صحيح/عدد عشري50، 36.0قيمة عددية
سلسلة(Hello, World!)محاطة بأقواس
مصفوفة[0 0 612 792]مجموعة مرتبة
قاموس<< /Type /Page >>مجموعة من أزواج المفاتيح والقيم
إشارة غير مباشرة2 0 Rإشارة إلى الكائن 2 (رقم الجيل 0)
تدفقstream...endstreamبيانات ثنائية (مثل تعليمات الرسم، الصور)

2. طبقة المحتوى (محتوى الصفحة)

سلسلة التعليمات التي "ترسم النص/الرسوم على الصفحة"، عادة ما تكون مكتوبة في stream ... endstream. التنسيق هو: المعاملات تأتي أولاً، ثم المشغل.

/F0 36 Tf          ← المعامل: /F0، 36  المشغل: Tf (تعيين الخط)
(Hello, World!) Tj ← المعامل: سلسلة   المشغل: Tj (رسم النص)

3. طبقة هيكل الملف (هيكل الملف)

تمكن القارئ من الوصول العشوائي السريع إلى أي كائن، دون الحاجة لقراءة الملف من البداية إلى النهاية:

العنصرالوظيفة
%PDF-1.xرأس الملف، يحدد إصدار PDF
xrefجدول الإشارات المتقاطعة: رقم الكائن → إزاحة البايت
trailerقاموس النهاية: يشير إلى الكائن الجذري /Root
startxrefيشير إلى موقع بداية جدول الإشارات المتقاطعة
%%EOFعلامة نهاية الملف

ما هي الكائنات المطلوبة لـ PDF صغير؟

PDF "صغير ولكنه يمكنه عرض النص" له علاقات الإشارة بين الكائنات كما يلي:

رسم علاقة الكائنات الصغيرة لـ PDF

قائمة الكائنات الصغيرة:

الكائنالوظيفةالحقول الرئيسية
الفهرسالكائن الجذري، مدخل الوثيقة/Type /Catalog, /Pages
الصفحاتشجرة الصفحات/Type /Pages, /Kids, /Count
الصفحةصفحة واحدة/Type /Page, /MediaBox, /Resources, /Contents, /Parent
المواردحاوية الموارد/Font (قاموس الخطوط)
الخطتعريف الخط/Type /Font, /BaseFont, /Subtype
المحتوياتتدفق المحتوىتدفق تعليمات الرسم

التطبيق العملي: كتابة hello-broken.pdf

قم بإنشاء ملف hello-broken.pdf، والصق المحتوى التالي بالكامل فيه:

%PDF-1.0
1 0 obj
<< /Type /Pages
   /Count 1
   /Kids [2 0 R]
>>
endobj

2 0 obj
<< /Type /Page
   /MediaBox [0 0 612 792]
   /Resources 3 0 R
   /Parent 1 0 R
   /Contents [4 0 R]
>>
endobj

3 0 obj
<< /Font
     << /F0
          << /Type /Font
             /BaseFont /Times-Italic
             /Subtype /Type1 >>
     >>
>>
endobj

4 0 obj
<< >>
stream
1. 0. 0. 1. 50. 700. cm
BT
 /F0 36. Tf
 (Hello, World!) Tj
ET
endstream
endobj

5 0 obj
<< /Type /Catalog
   /Pages 1 0 R
>>
endobj

xref
0 6
trailer
<< /Size 6
   /Root 5 0 R
>>
startxref
0
%%EOF

لماذا يعتبر هذا الملف "معطلاً"؟

لقد تعمدنا حذف أو ملء المحتوى بشكل خاطئ في العناصر التالية:

العنصر المفقود/الخطأالوصف
إزاحة xrefلم يتم ملء الإزاحة الحقيقية لكل كائن
startxrefتم ملؤه بـ 0، وليس الموقع الحقيقي لـ xref
/Lengthلم يتم إعلان طول تدفق المحتوى
علامة ثنائيةتفتقر إلى سطر التعريف الثنائي في الرأس

هذه كلها معلومات رئيسية يحتاجها القارئ، وغيابها قد يؤدي إلى عدم القدرة على الفتح أو الفتح مع الأخطاء.


شرح التعليمات الرئيسية لتدفق المحتوى

تدفق المحتوى بين 4 0 obj في stream ... endstream، يتم شرحه سطرًا بسطر:

1. 0. 0. 1. 50. 700. cm   ← تعيين مصفوفة التحويل (لاحظ أن 1. تمثل العدد العشري 1.0)
BT                         ← بدء كائن النص
 /F0 36. Tf                ← اختيار الخط F0، حجم الخط 36pt
 (Hello, World!) Tj        ← رسم السلسلة
ET                         ← إنهاء كائن النص

مشغل مصفوفة التحويل cm

1 0 0 1 50 700 cm هو مصفوفة تحويل مكونة من 6 عناصر [a b c d e f]، تتوافق مع:

| a  b  0 |     | 1  0  0 |
| c  d  0 |  =  | 0  1  0 |
| e  f  1 |     | 50 700 1 |

عندما يكون a=1, b=0, c=0, d=1، تكون هذه مصفوفة نقل نقية، حيث يتم نقل نقطة الأصل في نظام الإحداثيات (أي النقطة (0,0) التي سيتم رسمها لاحقًا) إلى (50, 700). إذا لم يتم النقل، فإن نقطة الأصل تكون في الزاوية السفلى اليسرى من الصفحة.

مشغلات النص

المشغلالمعنىالمثال
BTبدء النص، بدء كائن النصBT
ETإنهاء النص، إنهاء كائن النصET
Tfتعيين الخط وحجم الخط/F0 36 Tf
Tjرسم السلسلة(Hello!) Tj

استخدام pdftk لإصلاح PDF ليصبح قابلًا للفتح

في الدليل الذي يحتوي على hello-broken.pdf، نفذ:

pdftk hello-broken.pdf output hello.pdf

استخدم أي قارئ PDF لفتح hello.pdf، يجب أن ترى النص "Hello, World!" (خط Times-Italic، 36pt، في الزاوية العليا اليسرى من الصفحة).

ماذا أكمل لك pdftk؟

العناصر المكتملةالوصف
سطر العلامة الثنائيةأضاف سطرًا غير قابل للطباعة بعد %PDF-1.0، لضمان التعرف عليه كملف ثنائي
/Lengthحساب وإضافة طول البايت لتدفق المحتوى
جدول xrefحساب إزاحة البايت لكل كائن وإدخالها
startxrefإدخال الموقع الحقيقي لبداية جدول xref

لماذا نحتاج إلى xref / trailer / startxref؟

الهدف الأساسي: الوصول العشوائي

تخيل PDF مكون من 500 صفحة، إذا لم يكن هناك xref، يجب على القارئ قراءة من البداية حتى الصفحة 449 لعرض الصفحة 450 - وهذا بطيء جدًا.

مع وجود xref، يمكن للقارئ:

  1. قراءة startxref → العثور على موقع xref
  2. قراءة trailer → العثور على الكائن الجذري /Root
  3. من الكائن الجذري، تتبع الكائنات → القفز مباشرة إلى كائن الصفحة 450
  4. من خلال xref، تحقق من إزاحة البايت لذلك الكائن → انتقل مباشرة لقراءته

تتغير تعقيد الوقت من O(n) إلى O(1).


تمارين هذا المقال

ننصحك حقًا بتعديل hello-broken.pdf، ثم إعادة إصلاحه باستخدام pdftk، وملاحظة النتائج:

التمرينالمحتوى المعدلنقاط الملاحظة
Aتغيير (Hello, World!) إلى جملة إنجليزية أخرىتغيير النص
Bتغيير 36 إلى 12 أو 72تغيير حجم الخط
Cتغيير 50 700 إلى 50 100نقل الموقع لأسفل (نقطة الأصل في نظام إحداثيات PDF في الزاوية السفلى اليسرى)
Dتغيير /Times-Italic إلى /Helvetica أو /Courierتغيير الخط
Eتغيير /MediaBox [0 0 612 792] إلى [0 0 595 842]تغيير الورق من US Letter إلى A4

تلميح: نقطة الأصل في نظام إحداثيات PDF في الصفحة الزاوية السفلى اليسرى، والمحور Y يتجه لأعلى. (50, 700) تعني 50pt من اليسار، و700pt من الأسفل.


الأسئلة الشائعة

س: لماذا نستخدم خطوط Type1 المدمجة بدلاً من TrueType؟

ج: خطوط Type1 الأربعة عشر القياسية (Times، Helvetica، Courier، إلخ) هي خطوط يجب أن تكون مدمجة في قارئ PDF، ولا تحتاج إلى تضمين ملفات الخط، وهذا هو الأسهل. في السيناريوهات الحقيقية، عادة ما تحتاج إلى تضمين الخطوط لضمان التوافق عبر الأنظمة.

س: ما هي هذه الأرقام في /MediaBox [0 0 612 792]؟

ج: الوحدة هي النقطة (1 نقطة = 1/72 بوصة). 612 × 792 نقطة = 8.5 × 11 بوصة = ورق US Letter. A4 هو 595 × 842 نقطة.

س: ما هو رقم الجيل (مثل 0 في 2 0 R)?

ج: يستخدم للتحديث التدريجي. عندما يتم تعديل كائن، يزداد رقم الجيل بمقدار 1. عادةً ما تكون جميع أرقام الجيل في PDF الجديد 0.


المعاينة للمقالة التالية

في المقالة 02، سنواصل استخدام "كتابة تدفق المحتوى" لإضافة عمليات مسار الرسوم الأساسية:

  • m (moveto)، l (lineto): تعريف المسار
  • S (stroke): رسم الحدود
  • re (rectangle)، f (fill): رسم مستطيل وتعبئته

سيمكنك من رسم: نص العنوان + خط فاصل أفقي + إطار مستطيل على نفس الصفحة، من "القدرة على الكتابة" إلى "القدرة على رسم الأشكال".

Copyright © 2026 Doclingo. All Rights Reserved.
المنتجات
ترجمة المستندات
المزيد من الأدوات
API
شركات
الموارد
الأسعار
تطبيق
حول
المساعدة
شروط الخدمة
سياسة الخصوصية
تحديثات الإصدار
المدونة
معلومات الاتصال
البريد الإلكتروني: support@doclingo.ai
العربية
Copyright © 2026 Doclingo. All Rights Reserved.