تحويل فضاء الإحداثيات: تدوير وتحجيم وإمالة وانعكاس
لمحة سريعة
قسم بعنوان «لمحة سريعة»حوِّل فضاء إحداثيات الرسم حول محور ارتكاز تختاره. تغطي هذه الوصفة التدوير والتحجيم والإمالة والانعكاس. يظل كل تحويل معزولًا داخل كتلة حالة رسومية محفوظة، لذلك لا يؤثر في المحتوى اللاحق. وتتبع الوصفة examples/21-transforms.php.
التثبيت
قسم بعنوان «التثبيت»composer require nextpdf/core:^3لا تحتاج إلى حزمة Pro أو Enterprise. تأتي واجهة برمجة التطبيقات (API) الخاصة بالتحويل مع Core، وتعمل على PHP من الإصدار 8.1 حتى 8.4.
نظرة مفاهيمية عامة
قسم بعنوان «نظرة مفاهيمية عامة»يُرسم محتوى تنسيق المستندات المحمول (PDF) في فضاء المستخدم. يقع أصل فضاء المستخدم افتراضيًا في الزاوية السفلية اليسرى من الصفحة، وتساوي الوحدة الواحدة 1/72 بوصة (ISO 32000-2 §8.3.2). يضرب التحويل مصفوفة التحويل الحالية (CTM) في مصفوفة جديدة عبر المُعامِل cm (§8.3.4). وتتركب التحويلات عبر تسلسل المصفوفات، لذلك يهم الترتيب.
يتيح لك NextPDF العمل في نظام إحداثيات المؤلف الذي يبدأ من الزاوية العلوية اليسرى. وداخليًا، يحوّل ذلك النظام إلى فضاء المستخدم الأصلي الذي يبدأ من الزاوية السفلية اليسرى عبر إسقاط toY() في توابع التحويل. تستخدم المواضع وحدات فضاء المستخدم: نقاط PDF، حيث تساوي النقطة الواحدة 1/72 بوصة. لإبقاء التحويل محليًا، غلِّفه بين startTransform() وstopTransform(). تصدر هذه التوابع مُعاملَي حالة الرسوميات q (الحفظ) وQ (الاستعادة) (§8.4.2). ويرث كل ما يُرسم بينهما هذا التحويل. أما كل ما يأتي بعد stopTransform() فيعود إلى مصفوفة التحويل الحالية (CTM) السابقة. يأخذ كل استدعاء من rotate()/scale()/skewX()/mirrorH() محور ارتكاز صريحًا، فيرتكز التحويل حيث تتوقعه بدلًا من أصل الصفحة.
سطح واجهة برمجة التطبيقات (API)
قسم بعنوان «سطح واجهة برمجة التطبيقات (API)»يُولَّد سطح واجهة برمجة التطبيقات (API) من PHPDoc. وتأتي نقاط الدخول الرئيسية من السمة (trait) \NextPDF\Core\Concerns\HasTransforms:
Document::startTransform(): static— يصدرqويفتح كتلة حالةDocument::stopTransform(): static— يصدرQويغلق الكتلةDocument::rotate(float $angle, float $x = 0, float $y = 0): staticDocument::scale(float $sx, float $sy, float $x = 0, float $y = 0): staticDocument::skewX(float $angle, float $x = 0, float $y = 0): static/skewY(...)Document::mirrorH(float $x = 0): static/mirrorV(float $y = 0): staticDocument::translateCtm(float $dx, float $dy): static
مثال برمجي — بداية سريعة
قسم بعنوان «مثال برمجي — بداية سريعة»<?php
declare(strict_types=1);
require_once __DIR__ . '/vendor/autoload.php';
use NextPDF\Core\Document;
$doc = Document::createStandalone();$doc->setTitle('Coordinate Transforms');$doc->addPage();
$cx = 60.0;$cy = 60.0;
// Rotate 30° around (cx, cy). The transform is scoped to this block.$doc->startTransform();$doc->rotate(30, $cx, $cy);$doc->setFont('helvetica', '', 14);$doc->text($cx, $cy, 'Rotated 30 degrees');$doc->stopTransform();
// Back to the untransformed CTM — this text is upright.$doc->setFont('helvetica', '', 10);$doc->text($cx, $cy + 20, 'Not rotated');
$doc->save(__DIR__ . '/transforms.pdf');
echo "Created: transforms.pdf\n";مثال برمجي — للإنتاج
قسم بعنوان «مثال برمجي — للإنتاج»يعمل هذا البرنامج المكتفي ذاتيًا ضمن منظومة اختبار دليل الوصفات. ويحاكي قسم التحجيم من examples/21-transforms.php. يبقى كل تحويل داخل كتلة حالة رسومية محفوظة مع محور ارتكاز صريح. وتُعاد حالة اللون والخط إلى الوضع الأصلي في النهاية، فلا يتسرب شيء إلى صفحة لاحقة.
<?php
declare(strict_types=1);
require_once __DIR__ . '/vendor/autoload.php';
use NextPDF\Core\Document;
$doc = Document::createStandalone();$doc->setTitle('Coordinate Transforms');$doc->addPage();
$doc->setFont('helvetica', 'B', 13);$doc->cell(0, 8, 'Scaling a reference square at 0.5x, 1.0x, 1.5x, 2.0x', newLine: true);$doc->ln(6);
$scaleBaseY = $doc->getY();$scaleFactors = [0.5, 1.0, 1.5, 2.0];
$doc->setDrawColor(30, 58, 138);$doc->setLineWidth(0.4);
foreach ($scaleFactors as $idx => $factor) { $cx = 25.0 + $idx * 45; $cy = $scaleBaseY + 5;
$doc->startTransform(); $doc->scale($factor, $factor, $cx, $cy); // scale about (cx, cy)
$doc->setFillColor(220, 230, 241); $doc->rect($cx, $cy, 15, 15, 'DF'); $doc->line($cx, $cy, $cx + 15, $cy + 15);
$doc->stopTransform(); // CTM restored here
// Drawn AFTER the block — at the original scale, untransformed. $doc->setFont('helvetica', '', 8); $doc->setTextColor(0); $doc->text($cx, $scaleBaseY + 38, sprintf('%.1fx', $factor));}
// Explicit state reset so nothing carries into the next section.$doc->setTextColor(0);$doc->setFillColor(255);$doc->setDrawColor(0);
// The harness sets NEXTPDF_COOKBOOK_OUTPUT and runs this script twice under// the structural profile (the transform stream itself is deterministic).$out = getenv('NEXTPDF_COOKBOOK_OUTPUT');$doc->save($out !== false && $out !== '' ? $out : __DIR__ . '/transforms.pdf');
echo "Wrote transforms.pdf\n";الإخراج القياسي (STDOUT) المتوقع:
Wrote transforms.pdfيغطي المثال الكامل عائلات التحويل الأربع كلها: التدوير والتحجيم والإمالة والانعكاس. شغِّله عبر php examples/21-transforms.php؛ فيكتب examples/output/21-transforms.pdf.
الحالات الحدية والمزالق
قسم بعنوان «الحالات الحدية والمزالق»- اقرن الكتلة دائمًا. يجب أن يكون لكل
startTransform()ما يطابقه منstopTransform(). يؤدي اختلال توازن عددq/Qإلى إفساد حالة الرسوميات في بقية الصفحة (ISO 32000-2 §8.4.2). يتتبع NextPDF العمق، لكن العقد على مستوى الوصفة يبقى واحدًا لواحد. - الترتيب غير تبادلي. تتركب التحويلات عبر تسلسل المصفوفات، لذلك فإن
rotate()ثمscale()ليس مثلscale()ثمrotate(). طبِّقها داخل كتلة واحدة بالترتيب الذي تقصده. - محور الارتكاز يكون افتراضيًا عند الأصل. إذا أغفلت محور الارتكاز، فإن التحويل يرتكز حول أصل الصفحة، لا حول الشكل. وهذا عادةً ليس ما تريده، لذلك مرِّر محور الارتكاز صراحةً.
- محور Y في فضاء المؤلف. قيمة
yلمحور الارتكاز هي المسافة من الزاوية العلوية اليسرى في فضاء المؤلف، ويسقطها NextPDF إلى فضاء المستخدم الأصلي. يؤدي خلط إحداثيات PDF الخام مع واجهة برمجة تطبيقات المؤلف إلى نتيجة معكوسة. - تسرب الحالة. يستمر اللون والخط وعرض الخط المحددة داخل كتلة التحويل بعد
stopTransform()، لأنQفي سطح واجهة برمجة التطبيقات هذا يستعيد مصفوفة التحويل الحالية (CTM) فقط. أعد ضبط هذه القيم صراحةً إذا كان ينبغي ألا يرثها قسم لاحق، كما يفعل مثال الإنتاج.
الأداء
قسم بعنوان «الأداء»يصدر التحويل مُعامِل cm واحدًا إضافةً إلى زوج q/Q. يبلغ حجم كل جزء بضعة بايتات فقط، ولا يضيف أي تكلفة قابلة للقياس في زمن التشغيل، لذلك تبقى الوصفة ضمن ميزانية 1500 ms / 96 MB. ملف إمكانية التكرار هو بنيوي. يحتوي الإخراج على مصفوفة /ID في الذيل وبيانات وصفية للإنشاء لا تثبت عبر عمليات التشغيل، لذلك يجب تطبيعها قبل المقارنة. أما دفق التحويل نفسه فهو حتمي.
ملاحظات أمنية
قسم بعنوان «ملاحظات أمنية»- إقامة البيانات وإجراءات التخفيف الخاصة بالمعلومات الشخصية التعريفية (PII). لا ينطبق. ترسم هذه الوصفة عناصر هندسية أولية وتسميات قصيرة، ولا تعالج أي بيانات خارجية أو شخصية.
- القياس عن بُعد الآمن وتنقية السجلات. تكتب الوصفة سطر تقدُّم ثابتًا واحدًا، ولا تسجل أي محتوى للمستند.
- نموذج التهديد. لا ينطبق. لا يوجد تحليل للمدخلات، ولا تشفير، ولا حدود ثقة. فالتحويل مجرد إصدار خالص لدفق المحتوى.
- السلوك في وضع المعايير الفيدرالية لمعالجة المعلومات (FIPS). لا ينطبق. لا توجد أي عملية تشفير.
المطابقة
قسم بعنوان «المطابقة»| العبارة | المواصفة | البند | reference_id |
|---|---|---|---|
يسلسل التحويل مصفوفةً مع مصفوفة التحويل الحالية (CTM) عبر مُعامِل cm. | ISO 32000-2 | §8.3.4 | |
| تتركب التحويلات عبر تسلسل المصفوفات، والترتيب مهم. | ISO 32000-2 | §8.3.4 | |
يحفظ q حالة الرسوميات ويستعيدها Q، وهو ما يحصر نطاق التحويل. | ISO 32000-2 | §8.4.2 | |
| أصل فضاء المستخدم الافتراضي هو الزاوية السفلية اليسرى؛ والوحدة الواحدة تساوي 1/72 بوصة. | ISO 32000-2 | §8.3.2 |
تتبع هذه الوصفة بنود حالة الرسوميات والتحويل المُستشهَد بها من ISO 32000-2. ولا تدّعي مطابقةً شاملةً لـISO 32000-2؛ فالبنود المُستشهَد بها هي وحدها التي تستعملها هذه الوصفة.