• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

adnsistemas / pdf-lib / #18

24 Mar 2026 08:15PM UTC coverage: 74.286% (+0.3%) from 74.001%
#18

push

David N. Abdala
Documentation change

2569 of 3981 branches covered (64.53%)

Branch coverage included in aggregate %.

7372 of 9401 relevant lines covered (78.42%)

297170.51 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

86.99
/src/api/operators.ts
1
/** =============== There is a circular dependency ===============
2
 * To avoid inclusion "undefined" elementos, enums are declared before
3
 * imports.
4
 */
5
export enum LineCapStyle {
54✔
6
  Butt = 0,
54✔
7
  Round = 1,
54✔
8
  Projecting = 2,
54✔
9
}
10

11
export enum LineJoinStyle {
54✔
12
  Miter = 0,
54✔
13
  Round = 1,
54✔
14
  Bevel = 2,
54✔
15
}
16

17
export enum FillRule {
54✔
18
  NonZero = 'f',
54✔
19
  EvenOdd = 'f*',
54✔
20
}
21

22
export enum TextRenderingMode {
54✔
23
  Fill = 0,
54✔
24
  Outline = 1,
54✔
25
  FillAndOutline = 2,
54✔
26
  Invisible = 3,
54✔
27
  FillAndClip = 4,
54✔
28
  OutlineAndClip = 5,
54✔
29
  FillAndOutlineAndClip = 6,
54✔
30
  Clip = 7,
54✔
31
}
32

33
import { asNumber, asPDFName, asPDFNumber } from './objects';
54✔
34
import { degreesToRadians } from './rotations';
54✔
35
import {
54✔
36
  PDFHexString,
37
  PDFName,
38
  PDFNumber,
39
  PDFOperator,
40
  PDFOperatorNames as Ops,
41
} from '../core';
42

43
/* ==================== Clipping Path Operators ==================== */
44

45
export const clip = () => PDFOperator.of(Ops.ClipNonZero);
54✔
46
export const clipEvenOdd = () => PDFOperator.of(Ops.ClipEvenOdd);
54✔
47

48
/* ==================== Graphics State Operators ==================== */
49

50
const { cos, sin, tan } = Math;
54✔
51

52
export const concatTransformationMatrix = (
54✔
53
  a: number | PDFNumber,
54
  b: number | PDFNumber,
55
  c: number | PDFNumber,
56
  d: number | PDFNumber,
57
  e: number | PDFNumber,
58
  f: number | PDFNumber,
59
) =>
60
  PDFOperator.of(Ops.ConcatTransformationMatrix, [
712✔
61
    asPDFNumber(a),
62
    asPDFNumber(b),
63
    asPDFNumber(c),
64
    asPDFNumber(d),
65
    asPDFNumber(e),
66
    asPDFNumber(f),
67
  ]);
68

69
export const translate = (xPos: number | PDFNumber, yPos: number | PDFNumber) =>
54✔
70
  concatTransformationMatrix(1, 0, 0, 1, xPos, yPos);
217✔
71

72
export const scale = (xPos: number | PDFNumber, yPos: number | PDFNumber) =>
54✔
73
  concatTransformationMatrix(xPos, 0, 0, yPos, 0, 0);
148✔
74

75
export const rotateRadians = (angle: number | PDFNumber) =>
54✔
76
  concatTransformationMatrix(
199✔
77
    cos(asNumber(angle)),
78
    sin(asNumber(angle)),
79
    -sin(asNumber(angle)),
80
    cos(asNumber(angle)),
81
    0,
82
    0,
83
  );
84

85
export const rotateDegrees = (angle: number | PDFNumber) =>
54✔
86
  rotateRadians(degreesToRadians(asNumber(angle)));
51✔
87

88
export const skewRadians = (
54✔
89
  xSkewAngle: number | PDFNumber,
90
  ySkewAngle: number | PDFNumber,
91
) =>
92
  concatTransformationMatrix(
9✔
93
    1,
94
    tan(asNumber(xSkewAngle)),
95
    tan(asNumber(ySkewAngle)),
96
    1,
97
    0,
98
    0,
99
  );
100

101
export const skewDegrees = (
54✔
102
  xSkewAngle: number | PDFNumber,
103
  ySkewAngle: number | PDFNumber,
104
) =>
105
  skewRadians(
×
106
    degreesToRadians(asNumber(xSkewAngle)),
107
    degreesToRadians(asNumber(ySkewAngle)),
108
  );
109

110
export const setDashPattern = (
54✔
111
  dashArray: (number | PDFNumber)[],
112
  dashPhase: number | PDFNumber,
113
) =>
114
  PDFOperator.of(Ops.SetLineDashPattern, [
139✔
115
    `[${dashArray.map(asPDFNumber).join(' ')}]`,
116
    asPDFNumber(dashPhase),
117
  ]);
118

119
export const restoreDashPattern = () => setDashPattern([], 0);
54✔
120

121
export const setLineCap = (style: LineCapStyle) =>
54✔
122
  PDFOperator.of(Ops.SetLineCapStyle, [asPDFNumber(style)]);
×
123

124
export const setLineJoin = (style: LineJoinStyle) =>
54✔
125
  PDFOperator.of(Ops.SetLineJoinStyle, [asPDFNumber(style)]);
×
126

127
export const setGraphicsState = (state: string | PDFName) =>
54✔
128
  PDFOperator.of(Ops.SetGraphicsStateParams, [asPDFName(state)]);
×
129

130
export const pushGraphicsState = () => PDFOperator.of(Ops.PushGraphicsState);
326✔
131

132
export const popGraphicsState = () => PDFOperator.of(Ops.PopGraphicsState);
326✔
133

134
export const setLineWidth = (width: number | PDFNumber) =>
54✔
135
  PDFOperator.of(Ops.SetLineWidth, [asPDFNumber(width)]);
112✔
136

137
/* ==================== Path Construction Operators ==================== */
138

139
export const appendBezierCurve = (
54✔
140
  x1: number | PDFNumber,
141
  y1: number | PDFNumber,
142
  x2: number | PDFNumber,
143
  y2: number | PDFNumber,
144
  x3: number | PDFNumber,
145
  y3: number | PDFNumber,
146
) =>
147
  PDFOperator.of(Ops.AppendBezierCurve, [
254✔
148
    asPDFNumber(x1),
149
    asPDFNumber(y1),
150
    asPDFNumber(x2),
151
    asPDFNumber(y2),
152
    asPDFNumber(x3),
153
    asPDFNumber(y3),
154
  ]);
155

156
export const appendQuadraticCurve = (
54✔
157
  x1: number | PDFNumber,
158
  y1: number | PDFNumber,
159
  x2: number | PDFNumber,
160
  y2: number | PDFNumber,
161
) =>
162
  PDFOperator.of(Ops.CurveToReplicateInitialPoint, [
13✔
163
    asPDFNumber(x1),
164
    asPDFNumber(y1),
165
    asPDFNumber(x2),
166
    asPDFNumber(y2),
167
  ]);
168

169
export const closePath = () => PDFOperator.of(Ops.ClosePath);
171✔
170

171
export const moveTo = (xPos: number | PDFNumber, yPos: number | PDFNumber) =>
54✔
172
  PDFOperator.of(Ops.MoveTo, [asPDFNumber(xPos), asPDFNumber(yPos)]);
208✔
173

174
export const lineTo = (xPos: number | PDFNumber, yPos: number | PDFNumber) =>
54✔
175
  PDFOperator.of(Ops.LineTo, [asPDFNumber(xPos), asPDFNumber(yPos)]);
372✔
176

177
/**
178
 * @param xPos x coordinate for the lower left corner of the rectangle
179
 * @param yPos y coordinate for the lower left corner of the rectangle
180
 * @param width width of the rectangle
181
 * @param height height of the rectangle
182
 */
183
export const rectangle = (
54✔
184
  xPos: number | PDFNumber,
185
  yPos: number | PDFNumber,
186
  width: number | PDFNumber,
187
  height: number | PDFNumber,
188
) =>
189
  PDFOperator.of(Ops.AppendRectangle, [
×
190
    asPDFNumber(xPos),
191
    asPDFNumber(yPos),
192
    asPDFNumber(width),
193
    asPDFNumber(height),
194
  ]);
195

196
/**
197
 * @param xPos x coordinate for the lower left corner of the square
198
 * @param yPos y coordinate for the lower left corner of the square
199
 * @param size width and height of the square
200
 */
201
export const square = (xPos: number, yPos: number, size: number) =>
54✔
202
  rectangle(xPos, yPos, size, size);
×
203

204
/* ==================== Path Painting Operators ==================== */
205

206
export const stroke = () => PDFOperator.of(Ops.StrokePath);
54✔
207

208
export const fill = () => PDFOperator.of(Ops.FillNonZero);
54✔
209

210
export const fillEvenOdd = () => PDFOperator.of(Ops.FillEvenOdd);
54✔
211

212
export const fillAndStroke = () => PDFOperator.of(Ops.FillNonZeroAndStroke);
93✔
213

214
export const endPath = () => PDFOperator.of(Ops.EndPath);
54✔
215

216
/* ==================== Text Positioning Operators ==================== */
217

218
export const nextLine = () => PDFOperator.of(Ops.NextLine);
57✔
219

220
export const moveText = (x: number | PDFNumber, y: number | PDFNumber) =>
54✔
221
  PDFOperator.of(Ops.MoveText, [asPDFNumber(x), asPDFNumber(y)]);
1✔
222

223
/* ==================== Text Showing Operators ==================== */
224

225
export const showText = (text: PDFHexString) =>
54✔
226
  PDFOperator.of(Ops.ShowText, [text]);
107✔
227

228
/* ==================== Text State Operators ==================== */
229

230
export const beginText = () => PDFOperator.of(Ops.BeginText);
95✔
231
export const endText = () => PDFOperator.of(Ops.EndText);
95✔
232

233
export const setFontAndSize = (
54✔
234
  name: string | PDFName,
235
  size: number | PDFNumber,
236
) => PDFOperator.of(Ops.SetFontAndSize, [asPDFName(name), asPDFNumber(size)]);
146✔
237

238
export const setCharacterSpacing = (spacing: number | PDFNumber) =>
54✔
239
  PDFOperator.of(Ops.SetCharacterSpacing, [asPDFNumber(spacing)]);
×
240

241
export const setWordSpacing = (spacing: number | PDFNumber) =>
54✔
242
  PDFOperator.of(Ops.SetWordSpacing, [asPDFNumber(spacing)]);
×
243

244
/** @param squeeze horizontal character spacing */
245
export const setCharacterSqueeze = (squeeze: number | PDFNumber) =>
54✔
246
  PDFOperator.of(Ops.SetTextHorizontalScaling, [asPDFNumber(squeeze)]);
×
247

248
export const setLineHeight = (lineHeight: number | PDFNumber) =>
54✔
249
  PDFOperator.of(Ops.SetTextLineHeight, [asPDFNumber(lineHeight)]);
57✔
250

251
export const setTextRise = (rise: number | PDFNumber) =>
54✔
252
  PDFOperator.of(Ops.SetTextRise, [asPDFNumber(rise)]);
×
253

254
export const setTextRenderingMode = (mode: TextRenderingMode) =>
54✔
255
  PDFOperator.of(Ops.SetTextRenderingMode, [asPDFNumber(mode)]);
×
256

257
export const setTextMatrix = (
54✔
258
  a: number | PDFNumber,
259
  b: number | PDFNumber,
260
  c: number | PDFNumber,
261
  d: number | PDFNumber,
262
  e: number | PDFNumber,
263
  f: number | PDFNumber,
264
) =>
265
  PDFOperator.of(Ops.SetTextMatrix, [
107✔
266
    asPDFNumber(a),
267
    asPDFNumber(b),
268
    asPDFNumber(c),
269
    asPDFNumber(d),
270
    asPDFNumber(e),
271
    asPDFNumber(f),
272
  ]);
273

274
export const rotateAndSkewTextRadiansAndTranslate = (
54✔
275
  rotationAngle: number | PDFNumber,
276
  xSkewAngle: number | PDFNumber,
277
  ySkewAngle: number | PDFNumber,
278
  x: number | PDFNumber,
279
  y: number | PDFNumber,
280
) =>
281
  setTextMatrix(
107✔
282
    cos(asNumber(rotationAngle)),
283
    sin(asNumber(rotationAngle)) + tan(asNumber(xSkewAngle)),
284
    -sin(asNumber(rotationAngle)) + tan(asNumber(ySkewAngle)),
285
    cos(asNumber(rotationAngle)),
286
    x,
287
    y,
288
  );
289

290
export const rotateAndSkewTextDegreesAndTranslate = (
54✔
291
  rotationAngle: number | PDFNumber,
292
  xSkewAngle: number | PDFNumber,
293
  ySkewAngle: number | PDFNumber,
294
  x: number | PDFNumber,
295
  y: number | PDFNumber,
296
) =>
297
  rotateAndSkewTextRadiansAndTranslate(
×
298
    degreesToRadians(asNumber(rotationAngle)),
299
    degreesToRadians(asNumber(xSkewAngle)),
300
    degreesToRadians(asNumber(ySkewAngle)),
301
    x,
302
    y,
303
  );
304

305
/* ==================== XObject Operator ==================== */
306

307
export const drawObject = (name: string | PDFName) =>
54✔
308
  PDFOperator.of(Ops.DrawObject, [asPDFName(name)]);
9✔
309

310
/* ==================== Color Operators ==================== */
311

312
export const setFillingGrayscaleColor = (gray: number | PDFNumber) =>
54✔
313
  PDFOperator.of(Ops.NonStrokingColorGray, [asPDFNumber(gray)]);
×
314

315
export const setStrokingGrayscaleColor = (gray: number | PDFNumber) =>
54✔
316
  PDFOperator.of(Ops.StrokingColorGray, [asPDFNumber(gray)]);
×
317

318
export const setFillingRgbColor = (
54✔
319
  red: number | PDFNumber,
320
  green: number | PDFNumber,
321
  blue: number | PDFNumber,
322
) =>
323
  PDFOperator.of(Ops.NonStrokingColorRgb, [
310✔
324
    asPDFNumber(red),
325
    asPDFNumber(green),
326
    asPDFNumber(blue),
327
  ]);
328

329
export const setStrokingRgbColor = (
54✔
330
  red: number | PDFNumber,
331
  green: number | PDFNumber,
332
  blue: number | PDFNumber,
333
) =>
334
  PDFOperator.of(Ops.StrokingColorRgb, [
124✔
335
    asPDFNumber(red),
336
    asPDFNumber(green),
337
    asPDFNumber(blue),
338
  ]);
339

340
export const setFillingCmykColor = (
54✔
341
  cyan: number | PDFNumber,
342
  magenta: number | PDFNumber,
343
  yellow: number | PDFNumber,
344
  key: number | PDFNumber,
345
) =>
346
  PDFOperator.of(Ops.NonStrokingColorCmyk, [
×
347
    asPDFNumber(cyan),
348
    asPDFNumber(magenta),
349
    asPDFNumber(yellow),
350
    asPDFNumber(key),
351
  ]);
352

353
export const setStrokingCmykColor = (
54✔
354
  cyan: number | PDFNumber,
355
  magenta: number | PDFNumber,
356
  yellow: number | PDFNumber,
357
  key: number | PDFNumber,
358
) =>
359
  PDFOperator.of(Ops.StrokingColorCmyk, [
×
360
    asPDFNumber(cyan),
361
    asPDFNumber(magenta),
362
    asPDFNumber(yellow),
363
    asPDFNumber(key),
364
  ]);
365

366
/* ==================== Marked Content Operators ==================== */
367

368
export const beginMarkedContent = (tag: string | PDFName) =>
54✔
369
  PDFOperator.of(Ops.BeginMarkedContent, [asPDFName(tag)]);
26✔
370

371
export const endMarkedContent = () => PDFOperator.of(Ops.EndMarkedContent);
54✔
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc