-
-
Notifications
You must be signed in to change notification settings - Fork 718
/
Copy pathPDFFont.ts
154 lines (139 loc) · 4.95 KB
/
PDFFont.ts
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
143
144
145
146
147
148
149
150
151
152
153
154
import Embeddable from 'src/api//Embeddable';
import PDFDocument from 'src/api/PDFDocument';
import {
CustomFontEmbedder,
PDFHexString,
PDFRef,
StandardFontEmbedder,
} from 'src/core';
import { assertIs, assertOrUndefined } from 'src/utils';
export type FontEmbedder = CustomFontEmbedder | StandardFontEmbedder;
/**
* Represents a font that has been embedded in a [[PDFDocument]].
*/
export default class PDFFont implements Embeddable {
/**
* > **NOTE:** You probably don't want to call this method directly. Instead,
* > consider using the [[PDFDocument.embedFont]] and
* > [[PDFDocument.embedStandardFont]] methods, which will create instances
* > of [[PDFFont]] for you.
*
* Create an instance of [[PDFFont]] from an existing ref and embedder
*
* @param ref The unique reference for this font.
* @param doc The document to which the font will belong.
* @param embedder The embedder that will be used to embed the font.
*/
static of = (ref: PDFRef, doc: PDFDocument, embedder: FontEmbedder) =>
new PDFFont(ref, doc, embedder);
/** The unique reference assigned to this font within the document. */
readonly ref: PDFRef;
/** The document to which this font belongs. */
readonly doc: PDFDocument;
/** The name of this font. */
readonly name: string;
private modified = true;
private readonly embedder: FontEmbedder;
private constructor(ref: PDFRef, doc: PDFDocument, embedder: FontEmbedder) {
assertIs(ref, 'ref', [[PDFRef, 'PDFRef']]);
assertIs(doc, 'doc', [[PDFDocument, 'PDFDocument']]);
assertIs(embedder, 'embedder', [
[CustomFontEmbedder, 'CustomFontEmbedder'],
[StandardFontEmbedder, 'StandardFontEmbedder'],
]);
this.ref = ref;
this.doc = doc;
this.name = embedder.fontName;
this.embedder = embedder;
}
/**
* > **NOTE:** You probably don't need to call this method directly. The
* > [[PDFPage.drawText]] method will automatically encode the text it is
* > given.
*
* Encodes a string of text in this font.
*
* @param text The text to be encoded.
* @returns The encoded text as a hex string.
*/
encodeText(text: string): PDFHexString {
assertIs(text, 'text', ['string']);
this.modified = true;
return this.embedder.encodeText(text);
}
/**
* Measure the width of a string of text drawn in this font at a given size.
* For example:
* ```js
* const width = font.widthOfTextAtSize('Foo Bar Qux Baz', 36)
* ```
* @param text The string of text to be measured.
* @param size The font size to be used for this measurement.
* @returns The width of the string of text when drawn in this font at the
* given size.
*/
widthOfTextAtSize(text: string, size: number): number {
assertIs(text, 'text', ['string']);
assertIs(size, 'size', ['number']);
return this.embedder.widthOfTextAtSize(text, size);
}
/**
* Measure the height of this font at a given size. For example:
* ```js
* const height = font.heightAtSize(24)
* ```
*
* The `options.descender` value controls whether or not the font's
* descender is included in the height calculation.
*
* @param size The font size to be used for this measurement.
* @param options The options to be used when computing this measurement.
* @returns The height of this font at the given size.
*/
heightAtSize(size: number, options?: { descender?: boolean }): number {
assertIs(size, 'size', ['number']);
assertOrUndefined(options?.descender, 'options.descender', ['boolean']);
return this.embedder.heightOfFontAtSize(size, {
descender: options?.descender ?? true,
});
}
/**
* Compute the font size at which this font is a given height. For example:
* ```js
* const fontSize = font.sizeAtHeight(12)
* ```
* @param height The height to be used for this calculation.
* @returns The font size at which this font is the given height.
*/
sizeAtHeight(height: number): number {
assertIs(height, 'height', ['number']);
return this.embedder.sizeOfFontAtHeight(height);
}
/**
* Get the set of unicode code points that can be represented by this font.
* @returns The set of unicode code points supported by this font.
*/
getCharacterSet(): number[] {
if (this.embedder instanceof StandardFontEmbedder) {
return this.embedder.encoding.supportedCodePoints;
} else {
return this.embedder.font.characterSet;
}
}
/**
* > **NOTE:** You probably don't need to call this method directly. The
* > [[PDFDocument.save]] and [[PDFDocument.saveAsBase64]] methods will
* > automatically ensure all fonts get embedded.
*
* Embed this font in its document.
*
* @returns Resolves when the embedding is complete.
*/
async embed(): Promise<void> {
// TODO: Cleanup orphan embedded objects if a font is embedded multiple times...
if (this.modified) {
await this.embedder.embedIntoContext(this.doc.context, this.ref);
this.modified = false;
}
}
}