|
声明 PDF 1.3+ Coons patch mesh shading(ISO 32000-1 8.7.4.5.6,/ShadingType 6),并包装为页面 Resources/Pattern 字典中的内联 Pattern Type 2 条目。每个 patch 由四条三次 Bezier 曲线围成,每个角携带一个颜色;渲染器在四条边之间拟合 Coons 曲面,得到任意弯曲的带颜色四边形。直边三角网格(RegisterFreeFormGouraudShading、RegisterLatticeFormGouraudShading)需要大量三角形才能逼近弯曲边界时使用——弯曲路径上的烫印与金属渐变、SVG 派生的渐变网格,以及任何弯边四边形。
Delphi 语法:
function RegisterCoonsPatchMesh(XMin, YMin, XMax, YMax: Single; NumComponents: Integer; const Patches: array of Extended): AnsiString;
C++ 语法:
AnsiString RegisterCoonsPatchMesh(float XMin, float YMin, float XMax, float YMax, int NumComponents, const Extended* Patches, int PatchesElementCount);
说明
shading 作为带 /ShadingType 6、/BitsPerCoordinate 16、/BitsPerComponent 8 与 /BitsPerFlag 8 的间接流输出。每个 patch 打包为 1 个 flag 字节(独立 patch 恒为 0),后接 12 个控制点(每个 4 字节:2 字节大端 X + 2 字节大端 Y)和 4 个角颜色(每个 NumComponents 字节),每 patch 共 1 + 48 + 4 * NumComponents 字节。/Decode 数组把 16 位坐标映射回给定的 [XMin, XMax] x [YMin, YMax] 把每个颜色分量映射回 [0, 1]。
12 个控制点从角 1 开始沿 patch 边界按顺时针编号为 c1..c12。四个角是 c1 / c4 / c7 / c10,其余八个(c1 与 c4 之间的 c2、c3;c4 与 c7 之间的 c5、c6;c7 与 c10 之间的 c8、c9;c10 与 c1 之间的 c11、c12)是每条三次边的内部 Bezier 手柄。当内部手柄位于相邻角连线的 1/3 与 2/3 处时,Coons 曲面退化为双线性插值——视觉上等同于 4 顶点的 Type 4 网格。
XMin, YMin, XMax, YMax - 限定编码坐标的用户空间矩形。这四个值成为 /Decode 的前四个条目。矩形外的控制点在编码时被钳制。请放在将要绘制的同一用户空间坐标中——对 HotPDF 中位于 (X, Y, W, H) 的屏幕坐标 Rectangle,对应的 PDF 用户空间矩形是 (X, PageHeight - Y - H) 到 (X + W, PageHeight - Y)。
NumComponents - 每个角的颜色分量数量。DeviceGray 传 1,DeviceRGB 传 3,DeviceCMYK 传 4。其他值抛出异常。
Patches - Extended 值平面数组。每个 patch 贡献 24 + 4 * NumComponents 个值:12 个控制点的 24 个浮点数(X, Y, X, Y, ...,按 c1..c12 顺时针顺序的 12 对),后接角颜色的 4 * NumComponents 个浮点数(角 1 / 2 / 3 / 4 = 循环顺序的 c1 / c4 / c7 / c10)。数组长度必须是该 stride 的正倍数。所有输出的 patch 都带 flag = 0(独立 patch);本便捷重载不暴露连续 flag 1 / 2 / 3(与前一个 patch 共享边)。
返回值: 自动生成的 pattern 名称(Sh1、Sh2 等),注册在当前页面的 Resources/Pattern 字典。StrictVersionLock 开启且当前 Version 低于 PDF 1.3 时返回空字符串(否则文档版本自动提升到 1.3)。
代码示例
// Single straight-edge Coons patch covering a 200x200 quad. Inner
// control points placed at 1/3 / 2/3 along each edge => bilinear
// surface. Four corner colours = red / green / yellow / blue
var
Doc: THotPDF;
PatName: AnsiString;
Patches: array[0..35] of Extended; // 12 ctrl pts * 2 + 4 corners * 3 = 36
H, XMin, YMin, XMax, YMax, W: 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;
W := 200;
// c1..c12 clockwise. Inner handles at 1/3 / 2/3 => straight edges
Patches[ 0] := XMin; Patches[ 1] := YMax; // c1 TL
Patches[ 2] := XMin + W / 3; Patches[ 3] := YMax; // c2
Patches[ 4] := XMin + 2*W / 3; Patches[ 5] := YMax; // c3
Patches[ 6] := XMax; Patches[ 7] := YMax; // c4 TR
Patches[ 8] := XMax; Patches[ 9] := YMax - W / 3; // c5
Patches[10] := XMax; Patches[11] := YMax - 2*W / 3; // c6
Patches[12] := XMax; Patches[13] := YMin; // c7 BR
Patches[14] := XMax - W / 3; Patches[15] := YMin; // c8
Patches[16] := XMax - 2*W / 3; Patches[17] := YMin; // c9
Patches[18] := XMin; Patches[19] := YMin; // c10 BL
Patches[20] := XMin; Patches[21] := YMin + W / 3; // c11
Patches[22] := XMin; Patches[23] := YMin + 2*W / 3; // c12
// 4 corner colours (c1 / c4 / c7 / c10)
Patches[24] := 1.0; Patches[25] := 0.0; Patches[26] := 0.0; // red
Patches[27] := 0.0; Patches[28] := 1.0; Patches[29] := 0.0; // green
Patches[30] := 1.0; Patches[31] := 1.0; Patches[32] := 0.0; // yellow
Patches[33] := 0.0; Patches[34] := 0.0; Patches[35] := 1.0; // blue
PatName := Doc.RegisterCoonsPatchMesh(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;
另请参阅
RegisterFreeFormGouraudShading, RegisterLatticeFormGouraudShading, RegisterDeviceN, Version, PDF 过滤器支持
|