@@ -25,9 +25,8 @@ page.drawOperators([
2525```
2626
2727<Callout type="warn">
28- The low-level API requires understanding of PDF content stream structure.
29- Invalid operator sequences may produce corrupted PDFs. Use the high-level
30- methods when they're sufficient.
28+ The low-level API requires understanding of PDF content stream structure. Invalid operator
29+ sequences may produce corrupted PDFs. Use the high-level methods when they're sufficient.
3130</Callout>
3231
3332---
@@ -36,15 +35,15 @@ page.drawOperators([
3635
3736The high-level methods (`drawRectangle`, `drawText`, etc.) cover most needs. Reach for the low-level API when you need:
3837
39- | Feature | Low-Level Approach |
40- | --- | --- |
41- | Matrix transforms | `ops.concatMatrix()` for arbitrary rotation/scale/skew |
42- | Gradients | `createAxialShading()` or `createRadialShading()` |
43- | Repeating patterns | `createTilingPattern()` or `createImagePattern()` |
44- | Blend modes | `createExtGState({ blendMode: "Multiply" })` |
45- | Clipping regions | `ops.clip()` with `ops.endPath()` |
46- | Reusable graphics | `createFormXObject()` for stamps/watermarks |
47- | Fine-grained control | Direct operator sequences |
38+ | Feature | Low-Level Approach |
39+ | -------------------- | --------------------------------------------------- --- |
40+ | Matrix transforms | `ops.concatMatrix()` for arbitrary rotation/scale/skew |
41+ | Gradients | `createAxialShading()` or `createRadialShading()` |
42+ | Repeating patterns | `createTilingPattern()` or `createImagePattern()` |
43+ | Blend modes | `createExtGState({ blendMode: "Multiply" })` |
44+ | Clipping regions | `ops.clip()` with `ops.endPath()` |
45+ | Reusable graphics | `createFormXObject()` for stamps/watermarks |
46+ | Fine-grained control | Direct operator sequences |
4847
4948---
5049
@@ -59,80 +58,80 @@ import { ops } from "@libpdf/core";
5958### Graphics State
6059
6160```typescript
62- ops.pushGraphicsState() // Save current state (q)
63- ops.popGraphicsState() // Restore saved state (Q)
64- ops.setGraphicsState(name) // Apply ExtGState resource (gs)
65- ops.concatMatrix(a, b, c, d, e, f) // Transform CTM (cm)
61+ ops.pushGraphicsState(); // Save current state (q)
62+ ops.popGraphicsState(); // Restore saved state (Q)
63+ ops.setGraphicsState(name); // Apply ExtGState resource (gs)
64+ ops.concatMatrix(a, b, c, d, e, f); // Transform CTM (cm)
6665```
6766
6867### Path Construction
6968
7069```typescript
71- ops.moveTo(x, y) // Begin subpath (m)
72- ops.lineTo(x, y) // Line to point (l)
73- ops.curveTo(x1, y1, x2, y2, x3, y3) // Cubic bezier (c)
74- ops.rectangle(x, y, w, h) // Rectangle shorthand (re)
75- ops.closePath() // Close subpath (h)
70+ ops.moveTo(x, y); // Begin subpath (m)
71+ ops.lineTo(x, y); // Line to point (l)
72+ ops.curveTo(x1, y1, x2, y2, x3, y3); // Cubic bezier (c)
73+ ops.rectangle(x, y, w, h); // Rectangle shorthand (re)
74+ ops.closePath(); // Close subpath (h)
7675```
7776
7877### Path Painting
7978
8079```typescript
81- ops.stroke() // Stroke path (S)
82- ops.fill() // Fill path, non-zero winding (f)
83- ops.fillEvenOdd() // Fill path, even-odd rule (f*)
84- ops.fillAndStroke() // Fill then stroke (B)
85- ops.endPath() // Discard path without painting (n)
80+ ops.stroke(); // Stroke path (S)
81+ ops.fill(); // Fill path, non-zero winding (f)
82+ ops.fillEvenOdd(); // Fill path, even-odd rule (f*)
83+ ops.fillAndStroke(); // Fill then stroke (B)
84+ ops.endPath(); // Discard path without painting (n)
8685```
8786
8887### Clipping
8988
9089```typescript
91- ops.clip() // Set clip region, non-zero (W)
92- ops.clipEvenOdd() // Set clip region, even-odd (W*)
90+ ops.clip(); // Set clip region, non-zero (W)
91+ ops.clipEvenOdd(); // Set clip region, even-odd (W*)
9392```
9493
9594### Color
9695
9796```typescript
98- ops.setStrokingGray(g) // Stroke grayscale (G)
99- ops.setNonStrokingGray(g) // Fill grayscale (g)
100- ops.setStrokingRGB(r, g, b) // Stroke RGB (RG)
101- ops.setNonStrokingRGB(r, g, b) // Fill RGB (rg)
102- ops.setStrokingCMYK(c, m, y, k) // Stroke CMYK (K)
103- ops.setNonStrokingCMYK(c, m, y, k) // Fill CMYK (k)
104- ops.setStrokingColorSpace(cs) // Set stroke color space (CS)
105- ops.setNonStrokingColorSpace(cs) // Set fill color space (cs)
106- ops.setStrokingColorN(name) // Set stroke pattern (SCN)
107- ops.setNonStrokingColorN(name) // Set fill pattern (scn)
97+ ops.setStrokingGray(g); // Stroke grayscale (G)
98+ ops.setNonStrokingGray(g); // Fill grayscale (g)
99+ ops.setStrokingRGB(r, g, b); // Stroke RGB (RG)
100+ ops.setNonStrokingRGB(r, g, b); // Fill RGB (rg)
101+ ops.setStrokingCMYK(c, m, y, k); // Stroke CMYK (K)
102+ ops.setNonStrokingCMYK(c, m, y, k); // Fill CMYK (k)
103+ ops.setStrokingColorSpace(cs); // Set stroke color space (CS)
104+ ops.setNonStrokingColorSpace(cs); // Set fill color space (cs)
105+ ops.setStrokingColorN(name); // Set stroke pattern (SCN)
106+ ops.setNonStrokingColorN(name); // Set fill pattern (scn)
108107```
109108
110109### Line Style
111110
112111```typescript
113- ops.setLineWidth(w) // Line width (w)
114- ops.setLineCap(cap) // 0=butt, 1=round, 2=square (J)
115- ops.setLineJoin(join) // 0=miter, 1=round, 2=bevel (j)
116- ops.setMiterLimit(limit) // Miter limit ratio (M)
117- ops.setDashPattern(array, phase) // Dash pattern (d)
112+ ops.setLineWidth(w); // Line width (w)
113+ ops.setLineCap(cap); // 0=butt, 1=round, 2=square (J)
114+ ops.setLineJoin(join); // 0=miter, 1=round, 2=bevel (j)
115+ ops.setMiterLimit(limit); // Miter limit ratio (M)
116+ ops.setDashPattern(array, phase); // Dash pattern (d)
118117```
119118
120119### Text
121120
122121```typescript
123- ops.beginText() // Begin text object (BT)
124- ops.endText() // End text object (ET)
125- ops.setFont(name, size) // Set font (Tf)
126- ops.moveText(tx, ty) // Position text (Td)
127- ops.setTextMatrix(a, b, c, d, e, f) // Text matrix (Tm)
128- ops.showText(string) // Show text (Tj)
122+ ops.beginText(); // Begin text object (BT)
123+ ops.endText(); // End text object (ET)
124+ ops.setFont(name, size); // Set font (Tf)
125+ ops.moveText(tx, ty); // Position text (Td)
126+ ops.setTextMatrix(a, b, c, d, e, f); // Text matrix (Tm)
127+ ops.showText(string); // Show text (Tj)
129128```
130129
131130### XObjects and Shading
132131
133132```typescript
134- ops.paintXObject(name) // Draw XObject (Do)
135- ops.paintShading(name) // Paint shading (sh)
133+ ops.paintXObject(name); // Draw XObject (Do)
134+ ops.paintShading(name); // Paint shading (sh)
136135```
137136
138137---
@@ -146,7 +145,7 @@ import { Matrix, ops } from "@libpdf/core";
146145
147146const matrix = Matrix.identity()
148147 .translate(200, 300)
149- .rotate(45) // degrees
148+ .rotate(45) // degrees
150149 .scale(2, 1.5);
151150
152151page.drawOperators([
@@ -162,14 +161,14 @@ Or use raw matrix components:
162161
163162```typescript
164163// Translation: move 100 points right, 200 points up
165- ops.concatMatrix(1, 0, 0, 1, 100, 200)
164+ ops.concatMatrix(1, 0, 0, 1, 100, 200);
166165
167166// Scale: 2x horizontal, 0.5x vertical
168- ops.concatMatrix(2, 0, 0, 0.5, 0, 0)
167+ ops.concatMatrix(2, 0, 0, 0.5, 0, 0);
169168
170169// Rotation: 45 degrees around origin
171- const angle = 45 * Math.PI / 180;
172- ops.concatMatrix(Math.cos(angle), Math.sin(angle), -Math.sin(angle), Math.cos(angle), 0, 0)
170+ const angle = ( 45 * Math.PI) / 180;
171+ ops.concatMatrix(Math.cos(angle), Math.sin(angle), -Math.sin(angle), Math.cos(angle), 0, 0);
173172```
174173
175174---
@@ -183,7 +182,7 @@ Create linear or radial gradients with color stops:
183182```typescript
184183// CSS-style: angle + length
185184const gradient = pdf.createLinearGradient({
186- angle: 90, // 0=up, 90=right, 180=down, 270=left
185+ angle: 90, // 0=up, 90=right, 180=down, 270=left
187186 length: 200,
188187 stops: [
189188 { offset: 0, color: rgb(1, 0, 0) },
@@ -194,7 +193,7 @@ const gradient = pdf.createLinearGradient({
194193
195194// Or explicit coordinates
196195const axial = pdf.createAxialShading({
197- coords: [0, 0, 200, 0], // x0, y0, x1, y1
196+ coords: [0, 0, 200, 0], // x0, y0, x1, y1
198197 stops: [
199198 { offset: 0, color: rgb(0, 0, 1) },
200199 { offset: 1, color: rgb(1, 0, 1) },
@@ -206,7 +205,7 @@ const axial = pdf.createAxialShading({
206205
207206```typescript
208207const radial = pdf.createRadialShading({
209- coords: [100, 100, 0, 100, 100, 80], // x0, y0, r0, x1, y1, r1
208+ coords: [100, 100, 0, 100, 100, 80], // x0, y0, r0, x1, y1, r1
210209 stops: [
211210 { offset: 0, color: rgb(1, 1, 1) },
212211 { offset: 1, color: rgb(0, 0, 0) },
@@ -234,9 +233,7 @@ page.drawOperators([
234233// Or wrap in a pattern for PathBuilder
235234const pattern = pdf.createShadingPattern({ shading: gradient });
236235
237- page.drawPath()
238- .rectangle(50, 200, 200, 100)
239- .fill({ pattern });
236+ page.drawPath().rectangle(50, 200, 200, 100).fill({ pattern });
240237```
241238
242239---
@@ -282,9 +279,7 @@ const pattern = pdf.createImagePattern({
282279 height: 50,
283280});
284281
285- page.drawPath()
286- .circle(200, 400, 80)
287- .fill({ pattern });
282+ page.drawPath().circle(200, 400, 80).fill({ pattern });
288283```
289284
290285### Gradient Pattern
@@ -387,23 +382,23 @@ Restrict drawing to a region:
387382```typescript
388383page.drawOperators([
389384 ops.pushGraphicsState(),
390-
385+
391386 // Define clip region (circle)
392387 ops.moveTo(200, 300),
393388 // ... circle path using bezier curves
394389 ops.clip(),
395- ops.endPath(), // Required after clip
396-
390+ ops.endPath(), // Required after clip
391+
397392 // Everything here is clipped to the circle
398393 ops.paintShading(gradientName),
399-
400- ops.popGraphicsState(), // Clipping is restored
394+
395+ ops.popGraphicsState(), // Clipping is restored
401396]);
402397```
403398
404399<Callout type="info">
405- Always follow `ops.clip()` with a path-painting operator. Use `ops.endPath()`
406- to discard the path, or `ops.fill()` to both clip and fill.
400+ Always follow `ops.clip()` with a path-painting operator. Use `ops.endPath()` to discard the path,
401+ or `ops.fill()` to both clip and fill.
407402</Callout>
408403
409404---
@@ -444,7 +439,7 @@ const page = pdf.addPage();
444439
445440// Create button gradient
446441const gradient = pdf.createLinearGradient({
447- angle: 180, // top to bottom
442+ angle: 180, // top to bottom
448443 length: 40,
449444 stops: [
450445 { offset: 0, color: rgb(0.4, 0.6, 1) },
@@ -475,7 +470,8 @@ page.drawOperators([
475470]);
476471
477472// Rounded rectangle path
478- page.drawPath()
473+ page
474+ .drawPath()
479475 .moveTo(110, 700)
480476 .lineTo(250, 700)
481477 .curveTo(255, 700, 260, 705, 260, 710)
0 commit comments