تخطَّ إلى المحتوى

الرسوميات: بدائيات المسارات والتظليل والتحويل

تحوّل وحدة الرسوميات قصد الرسم إلى عوامل تشغيل رسوميات في تنسيق المستندات المحمولة (⁨PDF⁩). وتشمل المسارات وأنماط الخطوط وفضاءات الألوان والتحويلات والتظليلات والأنماط وأنصاف الدرجات وتحميل الصور.

Terminal window
composer require nextpdf/core:^3

الرسوميات هي طبقة الرسم المتجهي والنقطي. تنتج هذه الطبقة تسلسلات عوامل تشغيل تسلسلها وحدتا ⁨ContentStream⁩ و⁨Writer⁩ في ملف ⁨PDF.⁩ يرمّز دفق المحتوى محتوى الصفحة بوصفه تسلسلاً مرتّباً من عوامل تشغيل الرسوميات وفق المنظمة الدولية للتوحيد القياسي (⁨ISO⁩) 32000-2 §8. تُصدر الوحدة هذه العوامل، لكنها لا تكتب الملف.

DrawingEngine هو واجهة برمجة التطبيقات (⁨API⁩) الأساسية. وهو منشئ انسيابي ذو حالة. يُعيد كل ضابط self، ويسجّل تغييراً في حالة الرسوميات أو عامل تشغيل لطلاء مسار، ثم يلحقه ببُفر داخلي تقرؤه عبر getStream(). يُنمذج المحرك حالة رسوميات ⁨PDF⁩ مباشرةً: عرض الخط، ونمط الخط، ولون الحدّ والتعبئة، وألفا ووضع المزج، وحدّ التشذيب، والقناع الناعم، والقصّ، والطباعة الفائقة، والاستواء، والنعومة، ونية العرض، وتوليد الأسود، وإزالة اللون السفلي؛ ويناظر كلٌ منها عامل تشغيل موثّقاً. تقبل ضوابط الألوان كائن قيمة Color أو فضاء ColorSpace صريحاً، وبذلك تستخدم الفضاءات الخاصة بالجهاز والفضاءات القائمة على اللجنة الدولية للإضاءة (⁨CIE⁩) صيغة الاستدعاء نفسها.

تعمل إلى جانب المحرك ثلاث عائلات. تأتي معالجة الصور أولاً. يفكّ ImageLoader ترميز ملف أو كتلة بيانات في الذاكرة إلى ImageLoadResult. ويزيل ImageRegistry التكرار ويتعقّب الصور المفكوكة الترميز عبر MemoryReport، لتبقى المستندات الكبيرة ضمن ميزانية الذاكرة. ولاستيراد المتجهات، يترجم SvgParser وEpsParser مُدخلات الرسوميات المتجهية القابلة للتحجيم (⁨SVG⁩) وبوست سكريبت المغلّفة (⁨EPS⁩) إلى دفق العوامل نفسه، مع إتاحة getBoundingBox() للتخطيط. أما العائلة الثالثة فهي دقّة لون الجهاز: التظليلات (ShadingManager، وعائلتا Type2/Type3 والعائلات الشبكية)، والأنماط (PatternFill)، وأنصاف الدرجات (Type1/Type5/Type6/Type10/Type16)، ودوال النقل، وفضاءات الألوان القائمة على الاتحاد الدولي للألوان (⁨ICC⁩).

TransformEngine رفيق مخصص لتحويلات الإحداثيات. فهو يغلّف التحويل عبر startTransform() وstopTransform()، اللذين يُصدران زوج الحفظ/الاستعادة q وQ ⁨save/restore.⁩ ويوفّر مساعدات أفينية مُسمّاة: scale، وtranslate، وrotate، وskew، وmirrorH، وmirrorV. يقبل كل مساعد محوراً اختيارياً. وتُسقط مصفوفة التحويل فضاء إحداثيات داخلياً على فضاء الإحداثيات الهدف. وهذا هو النموذج نفسه الذي يُطبّقه ⁨ISO 32000-2⁩ على نطاقات التظليل — §8.7.4.

تتبع إدارة الألوان سجلّ القرار المعماري (⁨ADR⁩)-012: تُصدر الفضاءات اللونية ⁨ICCBased⁩ والقائمة على ⁨CIE⁩ عوامل تشغيل دفق محتوى cs/CS صريحة بدلاً من الاعتماد على احتياطي لون الجهاز. وتُغلّف ملفّات تعريف ⁨ICC⁩ في دفق ⁨ICCBased⁩ بعدد المكوّنات الصحيح وفق ⁨ISO 32000-2⁩ §8.6.5.5.

الصنفالطرائق الرئيسيةالدور
DrawingEnginegetStream(), reset(), setLineWidth(), setLineStyle(), setDrawColor(), setFillColor(), setAlpha(), setSoftMask(), clip(), setOverprint(), setRenderingIntent(), line(), rect(), circle(), ellipse(), polygon(), linearGradient()منشئ عوامل تشغيل ذو حالة للمسارات وحالة الرسوميات
TransformEnginestartTransform(), stopTransform(), scale(), translate(), rotate(), skew(), mirrorH(), mirrorV(), getStream()تحويلات إحداثيات أفينية
ImageLoaderload(string $filePath), loadFromString(string $data, string $mimeType)يفكّ ترميز الصور إلى ImageLoadResult
ImageRegistryload(), loadFromString(), getMetadata(), memoryUsage(), reset()ذاكرة تخزين مؤقت للصور تزيل التكرار مع تقرير الذاكرة
SvgParserparse(), parseFile()يترجم ⁨SVG⁩ إلى دفق العوامل
EpsParserparse(), parseFile(), getBoundingBox()يترجم ⁨EPS⁩ إلى دفق العوامل
ShadingManagerتسجيل التظليلات + إصدار القاموستظليلات محورية وشعاعية وشبكية
Halftone (مجرد)halftoneType(), toDict(), hasStream(), getStream()شاشات أنصاف الدرجات من النوع 1/5/6/10/16

شغّل composer docs:generate-api-php -- --module=Graphics لتوليد جدول ⁨PHPDoc⁩ الكامل.

المصدر: examples/06-colors-and-drawing.php.

<?php
declare(strict_types=1);
require_once __DIR__ . '/../vendor/autoload.php';
use NextPDF\Graphics\Color;
use NextPDF\Graphics\DrawingEngine;
use NextPDF\Graphics\LineStyle;
$engine = new DrawingEngine();
$engine
->setLineWidth(1.5)
->setDrawColor(Color::rgb(0, 51, 102))
->setFillColor(Color::rgb(230, 240, 250))
->rect(20.0, 20.0, 160.0, 80.0)
->line(20.0, 110.0, 180.0, 110.0, new LineStyle(dash: [3.0, 2.0]));
$contentStreamBytes = $engine->getStream();

يربط هذا المثال سجلّ صور بتقرير ذاكرة وقوس تحويل. وهو يحاكي البنية المستخدمة في examples/07-images.php وexamples/21-transforms.php.

<?php
declare(strict_types=1);
require_once __DIR__ . '/../vendor/autoload.php';
use NextPDF\Graphics\DrawingEngine;
use NextPDF\Graphics\ImageRegistry;
use NextPDF\Graphics\TransformEngine;
$registry = new ImageRegistry();
$image = $registry->load('/srv/assets/logo.png');
$report = $registry->memoryUsage();
if ($report->bytes > 32 * 1024 * 1024) {
// Decoded image cache exceeded the budget — reset before the next page.
$registry->reset();
}
$transform = new TransformEngine();
$transform
->startTransform()
->translate(40.0, 700.0)
->scale(0.5, 0.5)
->stopTransform();
$engine = new DrawingEngine();
$engine->reset();
$page = $transform->getStream() . $engine->getStream();
  • DrawingEngine ذو حالة. استدعِ reset() بين الصفحات المستقلة حتى لا تتسرّب حالة الرسوميات السابقة إلى الدفق التالي.
  • يتطلّب TransformEngine زوجاً متطابقاً من startTransform()/stopTransform(). يترك القوس غير المتوازن عامل q معلّقاً ويُفسد كومة الحفظ/الاستعادة ⁨save/restore⁩ لاحقاً في ⁨Writer.⁩
  • تكتب setSoftMask()، وsetOverprint()، وsetBlackGeneration()، وsetUnderColorRemoval() علامات حالة رسوميات ممتدة. وعند استخدام ملفّ تعريف يرفض الميزة، تكون عديمة الأثر. تحقّق من حارس ملفّ التعريف قبل أن تعتمد على النتيجة المرئية.
  • يزيل ImageRegistry التكرار بحسب المحتوى. فمساران ببايتات متطابقة يتشاركان كائناً واحداً. لا تفترض صورة ⁨PDF⁩ واحدة لكل استدعاء load().
  • يُعيد EpsParser::getBoundingBox() المربع المحيط المُحلّل، لا مربع الصفحة. طبّق القصّ الخاص بك إذا تجاوز ⁨EPS⁩ المستطيل الهدف.
  • تعويض النقطة السوداء استرشادي وقائم على العلامات، ولا يحوّل البكسلات بذاته.

هناك تغييران كاسران من جانب المُنتِج. كلاهما يحوّل الفساد الذي كان صامتاً سابقاً إلى فشل صريح في موضع الاستدعاء.

التحقّق من المدخلات يطرح استثناءً الآن (ملاحظة ترحيل). يُتحقّق من مُدخلات الرسم قبل أن تصل إلى دفق العوامل، وتُرفض القيم المُشوّهة بـInvalidArgumentException. كان المستدعون الذين مرّروا NaN أو Infinity أو قيماً خارج النطاق ينتجون سابقاً عوامل فاسدة بصمت؛ أما المُدخل نفسه فيُثير الآن استثناءً. القيود المُتحقّق منها هي:

  • يجب أن تكون ألفا اللون منتهية وضمن [0, 1].
  • يجب أن تكون مُعاملات مصفوفة التحويل الحالية (⁨CTM⁩) وأبعاد القالب وإحداثيات رؤوس التدرج وإحداثيات رقع الشبكة منتهية — بلا NaN أو Infinity.
  • يجب أن تكون راية حافة رقعة التدرج واحدة من {0, 1, 2, 3}.
  • تُفحص حدود مُعاملات دوال النوع 2/3/4 ومُعاملات أنصاف الدرجات.
  • تُهرَّب أسماء المُلوِّنات.
  • يجب أن يكون اسم طبقة مجموعة المحتوى الاختياري (⁨OCG⁩) غير فارغ.

دقّق مواضع الاستدعاء التي تحسب الإحداثيات أو ألفا من بيانات المصدر قبل أن تُرقّي: فأي قيمة كانت تمرّ سابقاً قد أصبحت الآن خطأً صارماً.

⁨ICCBased⁩ /N مغلق-عند-الفشل افتراضياً. يرفض مُخرَج ⁨PDF⁩ العادي أي فضاء لوني ⁨ICCBased⁩ يقع عدد مكوّنات /N الخاص به خارج {1, 3, 4}، ويوفّق بين /N المُعلَن وبين ملفّ التعريف المُضمَّن وفضاء /Alternate. يتبع هذا قاعدة ⁨ISO 32000-2⁩ §8.6.5.5 الخاصة بدفق ⁨ICCBased⁩، الذي يحمل /N إلى جانب فضاء /Alternate. ولا يُحتفظ بملفّ تعريف ⁨ICC⁩ متعدّد القنوات، مثل ملفّ تعريف سداسي اللون بقيمة N = 6، إلا عندما يكون ملفّ تعريف ⁨PDF/A⁩ أو ⁨PDF/X⁩ نشطاً، مع الاشتراك عبر IccConformancePolicy::ProfileGated. هذه بوابة بنيوية على عدد المكوّنات، وليست ادّعاءً بشهادة ⁨PDF/A⁩ أو ⁨PDF/X.⁩

إصدار العوامل خطّي في عدد استدعاءات الرسم: إلحاقات ⁨O⁩(⁨n⁩) ببُفر، من دون إعادة تدفّق. تأتي كلفة فكّ ترميز الصور من المُرمِّز وعدد البكسلات، لا من السجلّ. وإزالة التكرار بتجزئة المحتوى في السجلّ هي الرافعة الرئيسية للمستندات الكبيرة: فالأصول المُعاد استخدامها لا تكلّف إلا فكّ ترميز واحداً وكائن ⁨PDF⁩ واحداً. تبلغ performance_budget لحمل العمل المرجعي لهذه الوحدة 1500 ⁨ms⁩ زمن جدار و64 ⁨MB⁩ ذروة. استخدم ImageRegistry::memoryUsage() لمراقبة بصمة الصور المفكوكة الترميز، وreset() لتحريرها بين مجموعات الصفحات.

يستهلك SvgParser وEpsParser مُدخلات متجهية غير موثوقة. عامل كليهما بوصفهما محلّلين لبيانات معادية. افرض حدوداً على حجم المدخل قبل استدعاء parse(). شغّل الاستخراج في عامل مُقيَّد عندما يكون المصدر مُقدَّماً من المستخدم. ⁨EPS⁩ هي لهجة بوست سكريبت. يترجم المحلّل مجموعة فرعية مُقيَّدة ولا يُنفّذ مُفسِّراً عاماً، لكن ينبغي لك مع ذلك تحديد حجم المدخل وزمن التحليل. تفكّ مُحمِّلات الصور ترميز مُرمِّزات طرف ثالث. أبقِ امتدادات الصور في وقت التشغيل حديثة، وقيّد الأبعاد المفكوكة الترميز. راجع نموذج تهديد المحرك في /modules/core/security/ للاطّلاع على حدّ الثقة وإرشادات عزل العامل.

تُصدر الوحدة بنى عوامل تشغيل رسوميات ⁨PDF⁩ متّسقة مع ⁨ISO 32000-2⁩ §8، وقواميس الفضاء اللوني ⁨ICCBased⁩ وفق §8.6.5.5، وقواميس التظليل التي تتبع نطاقها ودالّتها ومصفوفتها ومربعها المحيط §8.7.4. هذه حقائق تنفيذية: ينتج src/Graphics/ أشكال العوامل والقواميس، وتمارسها tests/Unit/Graphics/ مع مرجعَي tests/Golden/PdfWriter/PdfWriterShadingGoldenBaselineSmokeTest وPdfWriterExtGStateGoldenSmokeTest. وهي ليست بياناً بمطابقة ⁨PDF 2.0⁩ أو ⁨PDF/X⁩ من طرف إلى طرف. تُتحقَّق مطابقة المستند الكامل على نحوٍ منفصل عبر مجموعتي الوحي والذهبية الموصوفتين في /modules/core/conformance/. ويُحدَّد سلوك ملفّ التعريف الخاص بنوايا إخراج ⁨ICC⁩ بموجب ⁨ADR-011⁩ و⁨ADR-012⁩، لا بهذه الوحدة وحدها.