|
یک مشِ وصلهای tensor product در PDF 1.3+ تعریف میکند (ISO 32000-1 8.7.4.5.7، /ShadingType 7) و آن را در یک ورودی inline از نوع Pattern Type 2 در دیکشنری Resources/Pattern صفحه میپیچد. هر patch یک شبکهٔ کامل 4 × 4 از control pointهای Bezier مکعبی p[i][j] است (12 مرزی + 4 داخلی) بهعلاوهٔ یک رنگ برای هر گوشه. وقتی RegisterCoonsPatchMesh (نوع 6) نتواند شکل درونی را بیان کند از این روش استفاده کنید - برای round-tripهای SVG mesh-gradient و هر artworkی که به چهار control point اضافی برای خمکردن interior patch نیاز دارد
سینتکس دلفی:
function RegisterTensorProductPatchMesh(XMin, YMin, XMax, YMax: Single; NumComponents: Integer; const Patches: array of Extended): AnsiString;
سینتکس C++:
AnsiString RegisterTensorProductPatchMesh(float XMin, float YMin, float XMax, float YMax, int NumComponents, const Extended* Patches, int PatchesElementCount);
توضیح
این shading بهصورت یک جریان غیرمستقیم با /ShadingType 7، /BitsPerCoordinate 16، /BitsPerComponent 8 و /BitsPerFlag 8 صادر میشود. هر patch بهصورت 1 بایت flag (همیشه 0 برای patchهای مستقل) و سپس 16 control point (هرکدام 4 بایت: 2 X big-endian + 2 Y big-endian، در ترتیب streamی spec که پایین توضیح داده شده) و 4 رنگ گوشهای (هرکدام NumComponents بایت) بستهبندی میشود، یعنی در مجموع 1 + 64 + 4 * NumComponents بایت برای هر patch
16 control point یک شبکهٔ 4 × 4 از p[i][j] میسازند که در آن i شاخص ردیف است (0 = بالای بصری / YMax، 3 = پایین بصری / YMin) و j شاخص ستون است (0 = چپ / XMin، 3 = راست / XMax). ترتیب stream در spec (Table 88) ابتدا 12 نقطهٔ مرزی را بهصورت ساعتگرد طی میکند (ردیف بالا از چپ به راست، ستون راست از بالا به پایین، ردیف پایین از راست به چپ، ستون چپ از پایین به بالا) و سپس 4 نقطهٔ داخلی را به ترتیب ساعتگرد از نقطهٔ داخلی بالا-چپ فهرست میکند: p[1][1], p[1][2], p[2][2], p[2][1]. آرایهٔ Patches که کاربر میدهد دقیقاً همین ترتیب را دنبال میکند
وقتی هر 16 control point روی یک lattice منظم 1/3 / 2/3 قرار بگیرند (نقاط مرزی در 1/3 / 2/3 روی هر edge و نقاط داخلی در تقاطعهای شبکهٔ درونیِ (1/3, 1/3) / (2/3, 1/3) / (2/3, 2/3) / (1/3, 2/3))، سطح Bezier مکعبی به یک صفحهٔ تخت فرو میریزد و interpolation رنگ به bilinear فرو میریزد - از نظر بصری معادل RegisterCoonsPatchMesh با edgeهای مستقیم یا RegisterFreeFormGouraudShading با چهار vertex گوشهای است
XMin, YMin, XMax, YMax - مستطیل فضای کاربری که مختصات کدگذاریشده را محدود میکند. این چهار مقدار چهار ورودی اول /Decode میشوند. آنها را در همان مختصات فضای کاربری قرار دهید که میخواهید روی آنها رسم کنید - برای Rectangle با مختصات صفحهای HotPDF در (X, Y, W, H)، مستطیل متناظر PDF user space برابر (X, PageHeight - Y - H) تا (X + W, PageHeight - Y) است
NumComponents - شمار مؤلفههای رنگ برای هر گوشه. برای DeviceGray مقدار 1، برای DeviceRGB مقدار 3 و برای DeviceCMYK مقدار 4 را پاس کنید. هر مقدار دیگری exception ایجاد میکند
Patches - آرایهٔ تختی از مقادیر Extended است. هر patch 32 + 4 * NumComponents مقدار میدهد: 32 float برای 16 control point (X, Y, X, Y, ...، 16 جفت در ترتیب streamِ spec) و سپس 4 * NumComponents float برای رنگهای گوشه (در p[0][0] / p[0][3] / p[3][3] / p[3][0]، مطابق ترتیب چرخهای Coons). طول آرایه باید مضرب مثبتی از این stride باشد. همهٔ patchهای صادرشده flag = 0 دارند (patch مستقل)؛ flagهای ادامهدار 1 / 2 / 3 (اشتراک لبه با patch قبلی) در این overload ساده در دسترس نیستند
مقدار بازگشتی: نام patternی که بهطور خودکار تولید میشود (Sh1، Sh2، ...) و در دیکشنری Resources/Pattern صفحهٔ جاری ثبت میشود. وقتی StrictVersionLock روشن باشد و Version فعال پایینتر از PDF 1.3 باشد، یک رشتهٔ خالی برمیگرداند (در غیر این صورت نسخهٔ سند بهطور خودکار به 1.3 میرود)
نمونه کد
// Single bilinear-equivalent tensor-product patch covering a 200x200
// quad. All 16 control points sit on the 1/3 / 2/3 lattice =>
// bicubic surface degenerates to bilinear; four corner colours
// red / green / yellow / blue
var
Doc: THotPDF;
PatName: AnsiString;
Patches: array[0..43] of Extended; // 16 ctrl pts * 2 + 4 corners * 3 = 44
H, XMin, YMin, XMax, YMax: Single;
XThird, X2Third, YThird, Y2Third: Single;
begin
Doc := THotPDF.Create(nil);
try
Doc.Version := pdf14;
Doc.BeginDoc;
H := Doc.CurrentPage.Height;
XMin := 0; YMin := H - 200; XMax := 200; YMax := H;
XThird := XMin + 200 / 3; X2Third := XMin + 2 * 200 / 3;
YThird := YMin + 200 / 3; Y2Third := YMin + 2 * 200 / 3;
// Spec stream order: top row LtoR, right column TtoB, bottom row RtoL,
// left column BtoT, then interior 4 clockwise starting at p[1][1]
Patches[ 0] := XMin; Patches[ 1] := YMax; // p[0][0] TL
Patches[ 2] := XThird; Patches[ 3] := YMax; // p[0][1]
Patches[ 4] := X2Third; Patches[ 5] := YMax; // p[0][2]
Patches[ 6] := XMax; Patches[ 7] := YMax; // p[0][3] TR
Patches[ 8] := XMax; Patches[ 9] := Y2Third; // p[1][3]
Patches[10] := XMax; Patches[11] := YThird; // p[2][3]
Patches[12] := XMax; Patches[13] := YMin; // p[3][3] BR
Patches[14] := X2Third; Patches[15] := YMin; // p[3][2]
Patches[16] := XThird; Patches[17] := YMin; // p[3][1]
Patches[18] := XMin; Patches[19] := YMin; // p[3][0] BL
Patches[20] := XMin; Patches[21] := YThird; // p[2][0]
Patches[22] := XMin; Patches[23] := Y2Third; // p[1][0]
Patches[24] := XThird; Patches[25] := Y2Third; // p[1][1]
Patches[26] := X2Third; Patches[27] := Y2Third; // p[1][2]
Patches[28] := X2Third; Patches[29] := YThird; // p[2][2]
Patches[30] := XThird; Patches[31] := YThird; // p[2][1]
// 4 corner colours at p[0][0] / p[0][3] / p[3][3] / p[3][0]
Patches[32] := 1.0; Patches[33] := 0.0; Patches[34] := 0.0; // red
Patches[35] := 0.0; Patches[36] := 1.0; Patches[37] := 0.0; // green
Patches[38] := 1.0; Patches[39] := 1.0; Patches[40] := 0.0; // yellow
Patches[41] := 0.0; Patches[42] := 0.0; Patches[43] := 1.0; // blue
PatName := Doc.RegisterTensorProductPatchMesh(
XMin, YMin, XMax, YMax, 3, Patches);
Doc.CurrentPage.SetFillPattern(PatName);
Doc.CurrentPage.Rectangle(0, 0, 200, 200);
Doc.CurrentPage.Fill;
Doc.EndDoc;
finally
Doc.Free;
end;
end;
همچنین ببینید
RegisterCoonsPatchMesh, RegisterFreeFormGouraudShading, RegisterLatticeFormGouraudShading, Version, PDF Filter Support
|