forked from foliojs/pdfkit
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathutils.js
More file actions
142 lines (128 loc) · 3.63 KB
/
utils.js
File metadata and controls
142 lines (128 loc) · 3.63 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
const fArray = new Float32Array(1);
const uArray = new Uint32Array(fArray.buffer);
export function PDFNumber(n) {
// PDF numbers are strictly 32bit
// so convert this number to a 32bit number
// @see ISO 32000-1 Annex C.2 (real numbers)
const rounded = Math.fround(n);
if (rounded <= n) return rounded;
// Will have to perform 32bit float truncation
fArray[0] = n;
// Get the 32-bit representation as integer and shift bits
if (n <= 0) {
uArray[0] += 1;
} else {
uArray[0] -= 1;
}
// Return the float value
return fArray[0];
}
/**
* Measurement of size
*
* @typedef {number | `${number}` | `${number}${'em' | 'in' | 'px' | 'cm' | 'mm' | 'pc' | 'ex' | 'ch' | 'rem' | 'vw' | 'vmin' | 'vmax' | '%' | 'pt'}`} Size
*/
/**
* @typedef {Array<PDFTilingPattern | PDFColor> | string | Array<number>} PDFColor
*/
/** @typedef {string | Buffer | Uint8Array | ArrayBuffer} PDFFontSource */
/**
* Side definitions
* - To define all sides, use a single value
* - To define up-down left-right, use a `[Y, X]` array
* - To define each side, use `[top, right, bottom, left]` array
* - Or `{vertical: SideValue, horizontal: SideValue}`
* - Or `{top: SideValue, right: SideValue, bottom: SideValue, left: SideValue}`
*
* @template T
* @typedef {T | [T, T] | [T, T, T, T] | { vertical: T; horizontal: T } | ExpandedSideDefinition<T>} SideDefinition<T>
**/
/**
* @template T
* @typedef {{ top: T; right: T; bottom: T; left: T }} ExpandedSideDefinition<T>
*/
/**
* Convert any side definition into a static structure
*
* @template S
* @template D
* @template O
* @template {S | D} T
* @param {SideDefinition<S>} sides - The sides to convert
* @param {SideDefinition<D>} defaultDefinition - The value to use when no definition is provided
* @param {function(T): O} transformer - The transformation to apply to the sides once normalized
* @returns {ExpandedSideDefinition<O>}
*/
export function normalizeSides(
sides,
defaultDefinition = undefined,
transformer = (v) => v,
) {
if (
sides == null ||
(typeof sides === 'object' && Object.keys(sides).length === 0)
) {
sides = defaultDefinition;
}
if (sides == null || typeof sides !== 'object') {
sides = { top: sides, right: sides, bottom: sides, left: sides };
} else if (Array.isArray(sides)) {
if (sides.length === 2) {
sides = { vertical: sides[0], horizontal: sides[1] };
} else {
sides = {
top: sides[0],
right: sides[1],
bottom: sides[2],
left: sides[3],
};
}
}
if ('vertical' in sides || 'horizontal' in sides) {
sides = {
top: sides.vertical,
right: sides.horizontal,
bottom: sides.vertical,
left: sides.horizontal,
};
}
return {
top: transformer(sides.top),
right: transformer(sides.right),
bottom: transformer(sides.bottom),
left: transformer(sides.left),
};
}
export const MM_TO_CM = 1 / 10; // 1MM = 1CM
export const CM_TO_IN = 1 / 2.54; // 1CM = 1/2.54 IN
export const PX_TO_IN = 1 / 96; // 1 PX = 1/96 IN
export const IN_TO_PT = 72; // 1 IN = 72 PT
export const PC_TO_PT = 12; // 1 PC = 12 PT
/**
* Get cosine in degrees of a
*
* Rounding errors are handled
* @param a
* @returns {number}
*/
export function cosine(a) {
if (a === 0) return 1;
if (a === 90) return 0;
if (a === 180) return -1;
if (a === 270) return 0;
return Math.cos((a * Math.PI) / 180);
}
/**
* Get sine in degrees of a
*
* Rounding errors are handled
* @param a
* @returns {number}
*/
export function sine(a) {
if (a === 0) return 0;
if (a === 90) return 1;
if (a === 180) return 0;
if (a === 270) return -1;
return Math.sin((a * Math.PI) / 180);
}