مقال تقني

تدرجات COLRv1 المتكررة والمنعكسة كتظليل PDF داخل Delphi

يرسم HotPDF Component تدرجات COLRv1 المتكررة والمنعكسة تظليل PDF متجهياً بدل تنقيط المحرف. تمدد الهندسة لتغطي عدداً صحيحاً من دورات خط الألوان، وتحصل كل دورة على تظليل محوري أو قطري خاص بها مع إطفاء Extend، وتُستوفى الألوان في ضوء خطي بفضاء CalRGB، وتُعبَّر أنماط التركيب in/out من Porter-Duff بأقنعة ناعمة لومينوزية (luminosity soft masks)

عندما غطينا كيفية رسم HotPDF لخطوط COLR v1 ورموز تعبيرية ملونة SVG داخل Delphi، كانت نمطا الامتداد repeat و reflect ضمن قائمة ما لم يبثه المسار الأصلي، وتذهب تلك المحارف إلى البديل التنقيطي. ترسم إصدارات HotPDF الأحدث كليهما متجهياً. وتطلب الوصول إلى ذلك عدة بدايات خاطئة، أسببت معظمها افتراضاً يبدو معقولاً عن PDF تبيّن أنه خاطئ في عارضة واحدة واسعة الاستخدام على الأقل. تسلك هذه التدوينة تلك الافتراضات، لأن كل من يربط تدرجات CSS أو SVG أو OpenType بـ PDF سيصطدم بها نفسها

لماذا لا تستطيع عارضة PDF تكرار التدرج عنك؟

تظليل PDF لا يملك نمط تكرار ولا انعكاس، فعلى المنتِج أن يرتب كل دورة بنفسه. يعرف ISO 32000-1 §8.7.4.5.3 و §8.7.4.5.4 خاصية /Extend للتظليل المحوري والقطري، وكل ما تفعله هو مواصلة اللون عند t0 أو t1 بعد نهاية المحور. ذلك هو EXTEND_PAD في COLRv1 ولا شيء غيره. ويعرف OpenType COLR v1 أيضاً EXTEND_REPEAT حيث يعيد خط الألوان البدء كلما عبر المعامل عدداً صحيحاً، و EXTEND_REFLECT حيث تجري كل دورة ثانية بالعكس

ربط تدرجات COLRv1 في HotPDF بتظليل PDF داخل Delphi: يطابق EXTEND_PAD علم المواصلة /Extend للتظليل المحوري والقطري، بينما لا مكافئ لـ EXTEND_REPEAT و EXTEND_REFLECT في PDF ولا بد من بنائهما من هندسة تظليل لكل دورة
تظليلات PDF لا تدعم الألوان سوى المداومة عند t0 و t1، فيجب ترتيب تدرج COLRv1 المتكرر أو المنعكس دورة بدورة من المنتِج لا تشغيله من العارضة

حاولت أول محاولة في HotPDF أن تجعل الدالة تقوم بالعمل الدوري. سجلت دالة معاينة Type 0 واحدة (§7.10.2) بنطاق واسع، نحو [-12.73, 12.73] لامتداد من 25 دورة، وملأتها بعينات مطوية، وشغلت Extend. داخل الدورة الأولى عرض ملف اختبار مصغر بشكل صحيح؛ وخارجه رسمت MuPDF لوناً واحداً متوسطاً ولم تكن Poppler أفضل. كلتا العارضتين تحسبان الدالة على طول معامل التظليل وتبثان ما بعد المحور بالمداومة، ولا واحدة منهما تعود للاستعلام عن دالة دورية في المنطقة الممددة. وكان النطاق الواسع أيضاً سوء قراءة للمواصفة: معامل التظليل t يمرر إلى الدالة مباشرة، ووفق §7.10.1 يُقص مدخل خارج نطاق الدالة، فالدالة التي لا يطابق نطاقها /Domain للتظليل‏ (الافتراضي [0 1]) لا تُقرأ عيناتها إلا جزئياً

التصميم الذي يعمل له ثلاثة أجزاء، تحققت جميعها مقابل مخرجات MuPDF و Poppler. تغطي هندسة التظليل مادياً عدداً صحيحاً N من الدورات، فلا بكسل يعتمد على Extend. وتحتفظ الدالة المعاينة بالنطاق الافتراضي [0 1] مطابقة لما تمرره العارضة فعلاً. وتُطوى سلسلة العينات نفسها لكل دورة، بـ 256 فاصلاً لكل دورة، فتحمل الدالة بيانات لون التكرار أو الانعكاس بدل الاعتماد على أي ميزة عارضة

طي خط ألوان في عينات Type 0

الطي يعني معاينة خط الألوان مرة لكل دورة ومرآة السلسلة في الدورات الفردية لنمط الانعكاس. المساعد أدناه ديلفي صافٍ لا هو API من HotPDF، ويصنع شيئين تخطئ فيهما النسخة الساذجة. يستوفي في الضوء الخطي بدل بايتات sRGB المخزنة، ويحل المحطات الصلبة (محطتان عند الإزاحة نفسها) إلى لون الجهة البعيدة، وهي دلالة OpenType و CSS

uses
  System.SysUtils, System.Math;

type
  TColorStop = record
    Offset: Single;  // ‏0..1 داخل دورة واحدة، مرتبة تصاعدياً
    R, G, B: Byte;   // بايتات sRGB بنمط CPAL
  end;

function SRGBToLinear(V: Byte): Double;
var
  C: Double;
begin
  C := V / 255;
  if C <= 0.04045 then
    Result := C / 12.92
  else
    Result := Power((C + 0.055) / 1.055, 2.4);
end;

function LinearToSRGB(L: Double): Byte;
var
  C: Double;
begin
  L := EnsureRange(L, 0, 1);
  if L <= 0.0031308 then
    C := L * 12.92
  else
    C := 1.055 * Power(L, 1 / 2.4) - 0.055;
  Result := Round(C * 255);
end;

// دورة واحدة من خط ألوان بثلاثيات RGB ذات 8 بت. عند Reverse = True
// تنعكس الدورة، وهو ما يفعله نمط الانعكاس في الدورات الفردية
function SampleCycle(const Stops: array of TColorStop; Count: Integer;
  Reverse: Boolean): TBytes;
var
  I, S: Integer;
  T, F, Span: Double;
begin
  SetLength(Result, Count * 3);
  for I := 0 to Count - 1 do
  begin
    T := I / (Count - 1);
    if Reverse then
      T := 1 - T;
    S := 0;
    // ‏>= تختار الجهة اللاحقة لمحطة صلبة
    while (S < High(Stops) - 1) and (T >= Stops[S + 1].Offset) do
      Inc(S);
    Span := Stops[S + 1].Offset - Stops[S].Offset;
    if Span > 0 then
      F := EnsureRange((T - Stops[S].Offset) / Span, 0, 1)
    else
      F := 1;
    Result[I * 3] := LinearToSRGB(SRGBToLinear(Stops[S].R) +
      (SRGBToLinear(Stops[S + 1].R) - SRGBToLinear(Stops[S].R)) * F);
    Result[I * 3 + 1] := LinearToSRGB(SRGBToLinear(Stops[S].G) +
      (SRGBToLinear(Stops[S + 1].G) - SRGBToLinear(Stops[S].G)) * F);
    Result[I * 3 + 2] := LinearToSRGB(SRGBToLinear(Stops[S].B) +
      (SRGBToLinear(Stops[S + 1].B) - SRGBToLinear(Stops[S].B)) * F);
  end;
end;

يذهب عارض COLRv1 داخل HotPDF أبعد من هذا المخطط. يكتب عينات خطية ذات 16 بت بترتيب big-endian في دالة CalRGB ويخزن ألفا عينة رمادية منفصلة ذات 16 بت، بينما تأخذ المساعدات العامة المعروضة لاحقاً ثلاثيات DeviceRGB ذات 8 بت، ولهذا يعيد المخطط التحويل إلى بايتات sRGB. ولنظرية ما يفعله القارئ بتلك العينات تغطي مقالة دوال Type 0 المعاينة بوصفها LUT ألوان ثلاثية الأبعاد نموذج الاستيفاء بالتفصيل

لماذا تحتاج كل دورة إلى تظليل خاص بها؟

تحتاج كل دورة تظليلاً خاصاً بها لأن القارئات لا تحسب دالة معاينة بدقة؛ بل تحسب سلفاً جدول ألوان، ويتوسط الجدول عبر الالتفاف من آخر لون في دورة إلى أول لون في الدورة التالية. تخزن MuPDF الدالة أحادية البعد للتظليل بوصفها جدول ألوان من 256 مدخلاً. احشو 11 دورة في دالة واحدة من 2816 عينة ويمكن لكل عينة محفوظة أن تكون دقيقة بينما تظل MuPDF تظهر من 12 إلى 14 مستوى من خطأ القناة، لأن مدخلات الجدول الـ 256 موزعة على الامتداد كله وتنعمل درز التكرار الصلبة إلى منحدر. وكانت Poppler والاستيفاء التحليلي للملف نفسه صحيحين كليهما، فهذا حد دقة قارئ لا خطأ ملف، ومزيد العينات لا ينفع

مخطط درز تدرج التكرار في COLRv1 لـ HotPDF داخل Delphi: دالة معاينة واحدة تمتد على 11 دورة تجعل جدول ألوان MuPDF ذا 256 مدخلاً يعمل كل درز تكرار منحدراً، بينما يحبس تظليل محوري لكل دورة كل جدول داخل دورة واحدة ويحفظ القفزة اللونية الحادة
تحسب القارئات جدول ألوان ثابتاً لكل تظليل سلفاً، فالإصلاح هندسي: تظليل واحد لكل دورة مع Extend مطفأة ينقل درز التكرار إلى حد لا يتوسطه أي جدول قط

الإصلاح هو حبس كل جدول قارئ داخل دورة واحدة. تبث HotPDF التدرجات الخطية الدورية تظليلاً محورياً مستقلاً واحداً لكل دورة أصلية، وكلا علمي Extend خاطئ، فتهبط قفزة اللون من النهاية إلى البداية على الحد بين تظليلين بدل داخل جدول واحد. وفي الانعكاس يستخدم اختبار الفردية رقم الدورة الموقع الأصلي، بما فيه الدورات السالبة قبل بداية خط الألوان، ويُبدل اتجاه التظليل بدل إعادة حساب العينات. وترسم كل الدورات في سطح معزول واحد بضوء خطي ويطبق ألفا الرسم مرة واحدة في النهاية، فلا يضاعف تدرج شبه شفاف عتامته عبر الدروز

تكشف الطريقتان العامتان THotPDF.RegisterSampledAxialGradient و THotPDF.RegisterSampledRadialGradient لبنة بناء التظليل المعاين لرسمك الخاص. وتأخذان (..., DomainT0, DomainT1: Single; const Samples: TBytes; SampleCount, Cycles: Integer) بعد الهندسة، وتشترطان PDF 1.3، وترفعان استثناء إلا إذا حملت Samples بالضبط SampleCount * 3 بايتاً، وتعيدان اسم نمط لـ THPDFPage.SetFillPattern. تضبطان Extend في الطرفين وتسجلان Cycles مفتاح نمط مخصصاً /Cycles تتجاهله العارضات. ولاتباع قاعدة دورة لكل تظليل معهما، سجل نمطاً واحداً لكل دورة ودع مستطيل شريط يقصه

// تدرج متكرر أو منعكس أفقي مكوّن من تظليل واحد لكل دورة.
// إحداثيات النمط في فضاء PDF الافتراضي؛ والمحور الأفقي يجعل
// هذا المثال مستقلاً عن اصطلاح Y من الأعلى للأسفل في الصفحة
procedure PaintPeriodicBands(Pdf: THotPDF; const Stops: array of TColorStop;
  X, Y, Width, Height, CycleLength: Single; Reflect: Boolean);
const
  SamplesPerCycle = 257;  // 256 فاصلاً لكل دورة
var
  Cycle, CycleCount: Integer;
  X0, X1: Single;
  Samples: TBytes;
  PatternName: AnsiString;
begin
  CycleCount := Ceil(Width / CycleLength);
  for Cycle := 0 to CycleCount - 1 do
  begin
    X0 := X + Cycle * CycleLength;
    X1 := X0 + CycleLength;
    Samples := SampleCycle(Stops, SamplesPerCycle, Reflect and Odd(Cycle));
    // النطاق [0, 1]: يصل معامل التظليل إلى الدالة دون تغيير
    PatternName := Pdf.RegisterSampledAxialGradient(X0, 0, X1, 0, 0, 1,
      Samples, SamplesPerCycle, 1);
    if PatternName = '' then
      Exit;  // إصدار المستند مقفل أدنى من PDF 1.3
    Pdf.CurrentPage.SetFillPattern(PatternName);
    // يقص الشريط التظليل إلى دورة واحدة تماماً، فلا يظهر Extend قط
    Pdf.CurrentPage.Rectangle(X0, Y, Math.Min(X1, X + Width) - X0, Height);
    Pdf.CurrentPage.Fill;
  end;
end;

الامتدادات الطويلة جداً تحتاج خدعة مختلفة، لأن تظليلاً واحداً لكل دورة يعني مورداً واحداً لكل دورة. في التدرجات الخطية الدورية لـ COLRv1 تتحول HotPDF إلى مخطط مضاعفة: نموذج ورقي يحمل بدائية تكرار بدورة واحدة أو انعكاس بدورتين، وكل مستوى Form XObject يرسم المستوى السابق مرتين، مزاحاً بعرضه. ينمو عدد النماذج لوغاريتمياً مع الامتداد، بينما تظل العارضة ترسم كل دورة مرئية، فيسقف التغطية بعد محاذاة الطور عند 65536 وحدة دورة. وأسقطت نسخة سابقة كانت تضع البدائية في نمط تبليط Type 1، لأن القارئات تضبط تباعد البلاطات على شبكة الجهاز وانحرفت Poppler عن الطور في دورة لم تكن عدداً صحيحاً من البكسلات

حل مدى المعامل لعائلات الدوائر القطرية

لا يغطي التدرج القطري المحرف إلا إذا حُسب مدى الدورات للعائلة الصحيحة من الدوائر، وتقع الرسوم القطرية في COLRv1 في ثلاث عائلات برياضيات مختلفة. عند D = c1 - c0 و dr = r1 - r0، يكون للعائلة المتداخلة بدقة |dr| > |D|، وللمخروط غير المتداخل |D|² > dr²، وللعائلة المماسة |D| = |dr|. تقيس HotPDF المعامل من نقطة نصف القطر الصفري للعائلة الأصلية وتحافظ على ارتباط مركز ونصف قطر كل دائرة تبثها بالمعامل الأصلي نفسه، فلا يُقلَّم نصف قطر سالب معاد الربط باستقلال قط

شجرة قرار التدرج القطري COLRv1 في HotPDF لـ Delphi: تفصل مقارنة dr مع D عائلات الدوائر المتداخلة التي تحل بالتنصيف، والمخاريط التي تحل بتظليلات قطرية قصيرة لكل دورة، والعائلات المماسة التي تخفض إلى الجذر الخطي q = |W|^2 / (2(W*V))
تفصل المتراجحة بين |dr| و |D| رياضيات الدورات: تنصف العائلات المتداخلة لأول دائرة ملامسة، وتحصل المخاريط على تظليل قصير لكل دورة، وتبقي الخطوط المماسة شريطاً شاذّاً شفافاً
  • تقطع العائلات المتداخلة صندوق التعبئة رتيباً، فيأتي مدى المعامل من الزوايا الأربع مع تنصيف لأول دائرة تلمس الصندوق. تعين حتى 64 دورة في تظليل واحد بمعدل 256 عينة لكل دورة، بسقف 4096 عينة؛ والامتدادات الأعمق تتحول إلى شرائح لكل دورة
  • تستخدم المخاريط والأشرطة متساوية نصف القطر تظليلات قطرية قصيرة منفصلة عند حدود الدورات الأصلية، كل منها بـ 257 عينة و Extend مطفأة، تُركّب بترتيب المعامل الأصلي داخل مجموعة معزولة غير قاطعة (non-knockout) فيغلب أكبر معامل صالح حيث تتقاطع الدوائر
  • تخفض العائلات المماسة معادلة الدائرة إلى معادلة خطية. بالنسبة إلى نقطة التماس المشتركة، يكون الجذر q = |W|² / (2·(W·V))، والمنطقة المغطاة نصف المستوى المفتوح أمام تلك النقطة

لحالة التماس شذوذ حقيقي. عندما يقطع خط التماس صندوق التعبئة، يصبح عدد الدورات اللازم للوصول إلى بكسلات قرب ذلك الخط غير محدود، فلا عدد محدود من التظليلات يغطيه. تنفق HotPDF ميزانية 64 دورة من نقطة التماس وتبقي الشريط الرقيق المتبقي شفافاً. وعندما تجلس الزوايا الأربع للصندوق خلف نقطة التماس يكون الرسم شفافاً ككل وما زالت بقية المحرف ترسم. ويقبل مسار المخروط المحدود حتى 4096 دورة مطلوبة، بتغطية مقيدة عند 1024 شريحة ويترك ما فوق السقف بلا رسم؛ ومحرف من 1024 شريحة يبلغ نحو 1.8 MB

لون الضوء الخطي وفخ المنزلتين العشريتين

تستوفي COLRv1 وتركب في الضوء الخطي، فتفك HotPDF ترميز كل بايت CPAL بدالة النقل العكسية لـ sRGB وترسم السطوح الصلبة والتظليلات والمجموعات الداخلية في فضاء CalRGB واحد بأبيض D65 وأوليات sRGB و /Gamma [1 1 1]‏ (§8.6.5.3). لا يتحول إلا السطح الجذري المنتهي إلى فضاء المزج لدى المستدعي. والاستيفاء على بايتات sRGB المخزنة بدلاً من ذلك ينتج نقاطاً وسطى أغمق بوضوح، وهو خطأ gamma الكلاسيكي الذي يقع فيه كل محرك تدرجات مرة واحدة

كشفت الخطوة إلى الضوء الخطي خطأ منسّق قديما. قيمة قناة CPAL داكنة عند 12 تصير نحو 0.0036765 في الضوء الخطي، وكان منسّق الأعداد المشترك خلف scn يحفظ منزلتين عشريتين فقط، فتلك المكونة كُتبت صفراً قبل أن تمس أي عارضة الملف. وكان العرَض يبدو تماماً كتكميم قارئ، وأول نزوة كانت لوم مخازن المجموعات ذات 8 بت في MuPDF. تجري مكونات التعبئة والتحديد الآن عبر منسّق عشري خالٍ من الأسّ يبقي القيم الصغيرة ويتجاهل محلية العملية. ويتعمم الدرس: عندما يختفي لون داكن، أفرغ تدفق المحتوى وافحص المعامل المكتوب قبل التحقيق في العارضة

تبقى العارضة مهمة بعد ذلك الإصلاح. تفقد MuPDF 1.28.2 القنوات الخطية قريبة الصفر عندما تركب مجموعة شفافية معزولة تحمل فضاء ألوان مزج صريحاً، وتتجاهل Splash في Poppler 26.07.0 فضاءات مزج المجموعات كلياً. تبث خاصية THotPDF.COLRv1DeviceSpaceGroupBlend الاختيارية‏ (الافتراضي False) مجموعات COLRv1 دون فضاء ألوان المزج، فتركب في فضاء الجهاز الموروث بينما تبقى ألوان المحتوى والتظليلات والدوال بضوء خطي في CalRGB. والمقايضة أن طبقات شبه شفافة متداخلة تمتزج عندئذ في فضاء الجهاز في العارضات التي تحترم فضاءات ألوان المجموعات

أي أنماط تركيب COLRv1 يعبر عنها PDF بدقة؟

يعرض HotPDF أنماط تركيب COLRv1 من 5 إلى 8‏ (SRC_IN و DEST_IN و SRC_OUT و DEST_OUT) أصلياً، وتذهب الأنماط من 9 إلى 12‏ (SRC_ATOP و DEST_ATOP و XOR و PLUS) إلى OnColorGlyphRasterize. أنماط in و out جداءات سطح في ألفا الآخر، وهذا بالضبط ما يحسبه القناع الناعم (§11.6.5). يلتقط المعامل الباقي بوصفه نموذجاً عادياً؛ ويلتقط المعامل المقنع في ممر ألفا بوصفه محتوى مسطحاً داخل مجموعة DeviceGray معزولة واحدة ويستخدم قناعاً /Luminosity مع /BC [0]. وتكتب أنماط out‏ 1 − α لكل ألفا وتضع غطاء أبيض معتماً تحت محتوى القناع، فيبقى الناجي مرئياً حيث لم يرسم المعامل الآخر قط

الأربعة الأخرى تحتاج جمعاً مسبق الضرب لسطحين. في نموذج source-over لـ PDF يخفف حد الخلفية دوماً بـ (1 − α) للمصدر، ولا توجد بدائية تجمع سطحين أو تقيس الخلفية بتغطية المصدر وحدها، فلا يمكن كتابة atop و xor و plus متجهياً. وقيّد آخر جاء من ملفات PDF اختبار عارية: تحسب كلتا العارضتين خطأً مجموعات الأقنعة الناعمة التي يتداخل محتواها نموذجاً Do، فيجب أن يكون المعامل المقنع مسطحاً. تصلح الألوان الصلبة وتدرجات pad وغلاف PaintGlyph حولها؛ أما الطبقات والتحويلات والتدرجات الدورية، التي تنتج كلها نماذج داخلية، فترسل المحرف إلى البديل

var
  Pdf: THotPDF;
  Fallback: TEmojiFallback;  // صنف معالج بالتوقيع الحدثي أدناه
begin
  Pdf := THotPDF.Create(nil);
  Fallback := TEmojiFallback.Create;
  try
    Pdf.AutoLaunch := False;
    Pdf.FileName := 'periodic-icons.pdf';
    // اختياري: تركيب المجموعات في فضاء الجهاز لـ MuPDF و Poppler
    Pdf.COLRv1DeviceSpaceGroupBlend := True;
    // يستقبل محارف atop/xor/plus وكل شيء آخر خارج المجموعة المدعومة:
    // (Sender; Format; const FontBytes, AssetData: TBytes; GlyphID: Word;
    //  PaletteIndex, PixelSize: Integer; out Width, Height: Integer;
    //  out RGBA: TBytes; out Handled: Boolean)
    Pdf.OnColorGlyphRasterize := Fallback.Rasterize;
    Pdf.BeginDoc;
    Pdf.RegisterUnicodeTTF('Fonts\GradientIcons.ttf');
    if not Pdf.DrawRegisteredColorGlyph(Pdf.CurrentPage, $E001,
      72, 144, 'Gradient Icons', 48) then
      Writeln('U+E001 was neither drawn natively nor rasterized');
    Pdf.EndDoc;
  finally
    Fallback.Free;
    Pdf.Free;
  end;
end;

أين ما يزال المسار المتجهي أقصر من اللازم

المخرجات المتجهية ليست بكسلات مطابقة في كل عارضة، وتقول سجلات قبول HotPDF ذلك بوضوح. تنعمل العينات على بعد خطوة أو خطوتين من حد دورة باستيفاء القارئ، لذا تعين فحوصات البكسل بعيداً عن الدروز ويُتحقق من تدفقات الدوال بفك ترميزها بدلاً من ذلك. والاستيفاء على عينات RGB مستقيمة وألفا مخزنة منفصلة تقريب قرب النهايات منخفضة الألفا والمحطات الصلبة؛ والخطأ المقاس من الدرجة الثانية عند 256 عينة لكل دورة، لكنه ليس تاماً. وتعين Splash في Poppler عند الحافة اليسرى للبكسل لا مركزه، وهو ما يظهر فروقاً صغيرة على أشد المنحدرات

الميزانيات حدود حقيقية أيضاً. ترفض العائلات القطرية المتداخلة امتدادات فوق 4096 دورة، والمخاريط والعائلات المماسة فوق 4096 دورة مطلوبة، ويبقى شريط التماس قرب الخط الشاذ فارغاً. وتحتاج ألفا المحطات المتغيرة شفافية PDF 1.4، فلا تُمكَّن تحت PDF/A-1 أو PDF/X-1a أو PDF/X-3. وإذا وقع محرف خارج أي من هذه الحدود، يرفض DrawRegisteredColorGlyph الرسم البياني كله قبل كتابة أي معامل، وهو السلوك الكلي أو لا شيء نفسه السابق

FAQ

هل ينقّط HotPDF تدرجات COLRv1 المتكررة والمنعكسة؟

لا. تبث إصدارات HotPDF الأحدث تظليلات محورية وقطريّة متجهية تغطي دورات كاملة. لا تذهب الرسوم خارج المجموعة المدعومة، كتركيبات atop و xor و plus، إلى OnColorGlyphRasterize

لماذا لا تستخدم دالة معاينة واحدة لكل الدورات؟

تحسب القارئات جدول ألوان من الدالة سلفاً، وجدول MuPDF من 256 مدخلاً. وموزعاً على دورات كثيرة يتوسط عبر كل درز تكرار. تظليل واحد لكل دورة يحبس كل جدول داخل دورة واحدة

متى أشغّل COLRv1DeviceSpaceGroupBlend؟

شغّله عندما تسقط القنوات شبه السوداء في محارف COLRv1 إلى الصفر في MuPDF. واتركه مطفأً عندما يجب أن تمتزج طبقات شبه شفافة متداخلة في الضوء الخطي في عارضات تحترم فضاءات ألوان المجموعات

تدرجات COLRv1 الأصلية والرموز التعبيرية الملونة والتظليلات المعاينة ومجموعات الشفافية كلها من HotPDF Component لـ Delphi و C++Builder، التي تولّد مستندات PDF مباشرة من كود Delphi و C++Builder