123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301 |
- /**
- * @licstart The following is the entire license notice for the
- * JavaScript code in this page
- *
- * Copyright 2022 Mozilla Foundation
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * @licend The above is the entire license notice for the
- * JavaScript code in this page
- */
- "use strict";
- Object.defineProperty(exports, "__esModule", {
- value: true
- });
- exports.FakeUnicodeFont = void 0;
- exports.createDefaultAppearance = createDefaultAppearance;
- exports.getPdfColor = getPdfColor;
- exports.parseDefaultAppearance = parseDefaultAppearance;
- var _primitives = require("./primitives.js");
- var _core_utils = require("./core_utils.js");
- var _util = require("../shared/util.js");
- var _colorspace = require("./colorspace.js");
- var _evaluator = require("./evaluator.js");
- var _stream = require("./stream.js");
- class DefaultAppearanceEvaluator extends _evaluator.EvaluatorPreprocessor {
- constructor(str) {
- super(new _stream.StringStream(str));
- }
- parse() {
- const operation = {
- fn: 0,
- args: []
- };
- const result = {
- fontSize: 0,
- fontName: "",
- fontColor: new Uint8ClampedArray(3)
- };
- try {
- while (true) {
- operation.args.length = 0;
- if (!this.read(operation)) {
- break;
- }
- if (this.savedStatesDepth !== 0) {
- continue;
- }
- const {
- fn,
- args
- } = operation;
- switch (fn | 0) {
- case _util.OPS.setFont:
- const [fontName, fontSize] = args;
- if (fontName instanceof _primitives.Name) {
- result.fontName = fontName.name;
- }
- if (typeof fontSize === "number" && fontSize > 0) {
- result.fontSize = fontSize;
- }
- break;
- case _util.OPS.setFillRGBColor:
- _colorspace.ColorSpace.singletons.rgb.getRgbItem(args, 0, result.fontColor, 0);
- break;
- case _util.OPS.setFillGray:
- _colorspace.ColorSpace.singletons.gray.getRgbItem(args, 0, result.fontColor, 0);
- break;
- case _util.OPS.setFillColorSpace:
- _colorspace.ColorSpace.singletons.cmyk.getRgbItem(args, 0, result.fontColor, 0);
- break;
- }
- }
- } catch (reason) {
- (0, _util.warn)(`parseDefaultAppearance - ignoring errors: "${reason}".`);
- }
- return result;
- }
- }
- function parseDefaultAppearance(str) {
- return new DefaultAppearanceEvaluator(str).parse();
- }
- function getPdfColor(color, isFill) {
- if (color[0] === color[1] && color[1] === color[2]) {
- const gray = color[0] / 255;
- return `${(0, _core_utils.numberToString)(gray)} ${isFill ? "g" : "G"}`;
- }
- return Array.from(color, c => (0, _core_utils.numberToString)(c / 255)).join(" ") + ` ${isFill ? "rg" : "RG"}`;
- }
- function createDefaultAppearance({
- fontSize,
- fontName,
- fontColor
- }) {
- return `/${(0, _core_utils.escapePDFName)(fontName)} ${fontSize} Tf ${getPdfColor(fontColor, true)}`;
- }
- class FakeUnicodeFont {
- constructor(xref, fontFamily) {
- this.xref = xref;
- this.widths = null;
- this.firstChar = Infinity;
- this.lastChar = -Infinity;
- this.fontFamily = fontFamily;
- const canvas = new OffscreenCanvas(1, 1);
- this.ctxMeasure = canvas.getContext("2d");
- if (!FakeUnicodeFont._fontNameId) {
- FakeUnicodeFont._fontNameId = 1;
- }
- this.fontName = _primitives.Name.get(`InvalidPDFjsFont_${fontFamily}_${FakeUnicodeFont._fontNameId++}`);
- }
- get toUnicodeRef() {
- if (!FakeUnicodeFont._toUnicodeRef) {
- const toUnicode = `/CIDInit /ProcSet findresource begin
- 12 dict begin
- begincmap
- /CIDSystemInfo
- << /Registry (Adobe)
- /Ordering (UCS) /Supplement 0 >> def
- /CMapName /Adobe-Identity-UCS def
- /CMapType 2 def
- 1 begincodespacerange
- <0000> <FFFF>
- endcodespacerange
- 1 beginbfrange
- <0000> <FFFF> <0000>
- endbfrange
- endcmap CMapName currentdict /CMap defineresource pop end end`;
- const toUnicodeStream = FakeUnicodeFont.toUnicodeStream = new _stream.StringStream(toUnicode);
- const toUnicodeDict = new _primitives.Dict(this.xref);
- toUnicodeStream.dict = toUnicodeDict;
- toUnicodeDict.set("Length", toUnicode.length);
- FakeUnicodeFont._toUnicodeRef = this.xref.getNewPersistentRef(toUnicodeStream);
- }
- return FakeUnicodeFont._toUnicodeRef;
- }
- get fontDescriptorRef() {
- if (!FakeUnicodeFont._fontDescriptorRef) {
- const fontDescriptor = new _primitives.Dict(this.xref);
- fontDescriptor.set("Type", _primitives.Name.get("FontDescriptor"));
- fontDescriptor.set("FontName", this.fontName);
- fontDescriptor.set("FontFamily", "MyriadPro Regular");
- fontDescriptor.set("FontBBox", [0, 0, 0, 0]);
- fontDescriptor.set("FontStretch", _primitives.Name.get("Normal"));
- fontDescriptor.set("FontWeight", 400);
- fontDescriptor.set("ItalicAngle", 0);
- FakeUnicodeFont._fontDescriptorRef = this.xref.getNewPersistentRef(fontDescriptor);
- }
- return FakeUnicodeFont._fontDescriptorRef;
- }
- get descendantFontRef() {
- const descendantFont = new _primitives.Dict(this.xref);
- descendantFont.set("BaseFont", this.fontName);
- descendantFont.set("Type", _primitives.Name.get("Font"));
- descendantFont.set("Subtype", _primitives.Name.get("CIDFontType0"));
- descendantFont.set("CIDToGIDMap", _primitives.Name.get("Identity"));
- descendantFont.set("FirstChar", this.firstChar);
- descendantFont.set("LastChar", this.lastChar);
- descendantFont.set("FontDescriptor", this.fontDescriptorRef);
- descendantFont.set("DW", 1000);
- const widths = [];
- const chars = [...this.widths.entries()].sort();
- let currentChar = null;
- let currentWidths = null;
- for (const [char, width] of chars) {
- if (!currentChar) {
- currentChar = char;
- currentWidths = [width];
- continue;
- }
- if (char === currentChar + currentWidths.length) {
- currentWidths.push(width);
- } else {
- widths.push(currentChar, currentWidths);
- currentChar = char;
- currentWidths = [width];
- }
- }
- if (currentChar) {
- widths.push(currentChar, currentWidths);
- }
- descendantFont.set("W", widths);
- const cidSystemInfo = new _primitives.Dict(this.xref);
- cidSystemInfo.set("Ordering", "Identity");
- cidSystemInfo.set("Registry", "Adobe");
- cidSystemInfo.set("Supplement", 0);
- descendantFont.set("CIDSystemInfo", cidSystemInfo);
- return this.xref.getNewPersistentRef(descendantFont);
- }
- get baseFontRef() {
- const baseFont = new _primitives.Dict(this.xref);
- baseFont.set("BaseFont", this.fontName);
- baseFont.set("Type", _primitives.Name.get("Font"));
- baseFont.set("Subtype", _primitives.Name.get("Type0"));
- baseFont.set("Encoding", _primitives.Name.get("Identity-H"));
- baseFont.set("DescendantFonts", [this.descendantFontRef]);
- baseFont.set("ToUnicode", this.toUnicodeRef);
- return this.xref.getNewPersistentRef(baseFont);
- }
- get resources() {
- const resources = new _primitives.Dict(this.xref);
- const font = new _primitives.Dict(this.xref);
- font.set(this.fontName.name, this.baseFontRef);
- resources.set("Font", font);
- return resources;
- }
- _createContext() {
- this.widths = new Map();
- this.ctxMeasure.font = `1000px ${this.fontFamily}`;
- return this.ctxMeasure;
- }
- createFontResources(text) {
- const ctx = this._createContext();
- for (const line of text.split(/\r\n?|\n/)) {
- for (const char of line.split("")) {
- const code = char.charCodeAt(0);
- if (this.widths.has(code)) {
- continue;
- }
- const metrics = ctx.measureText(char);
- const width = Math.ceil(metrics.width);
- this.widths.set(code, width);
- this.firstChar = Math.min(code, this.firstChar);
- this.lastChar = Math.max(code, this.lastChar);
- }
- }
- return this.resources;
- }
- createAppearance(text, rect, rotation, fontSize, bgColor) {
- const ctx = this._createContext();
- const lines = [];
- let maxWidth = -Infinity;
- for (const line of text.split(/\r\n?|\n/)) {
- lines.push(line);
- const lineWidth = ctx.measureText(line).width;
- maxWidth = Math.max(maxWidth, lineWidth);
- for (const char of line.split("")) {
- const code = char.charCodeAt(0);
- let width = this.widths.get(code);
- if (width === undefined) {
- const metrics = ctx.measureText(char);
- width = Math.ceil(metrics.width);
- this.widths.set(code, width);
- this.firstChar = Math.min(code, this.firstChar);
- this.lastChar = Math.max(code, this.lastChar);
- }
- }
- }
- maxWidth *= fontSize / 1000;
- const [x1, y1, x2, y2] = rect;
- let w = x2 - x1;
- let h = y2 - y1;
- if (rotation % 180 !== 0) {
- [w, h] = [h, w];
- }
- let hscale = 1;
- if (maxWidth > w) {
- hscale = w / maxWidth;
- }
- let vscale = 1;
- const lineHeight = _util.LINE_FACTOR * fontSize;
- const lineDescent = _util.LINE_DESCENT_FACTOR * fontSize;
- const maxHeight = lineHeight * lines.length;
- if (maxHeight > h) {
- vscale = h / maxHeight;
- }
- const fscale = Math.min(hscale, vscale);
- const newFontSize = fontSize * fscale;
- const buffer = ["q", `0 0 ${(0, _core_utils.numberToString)(w)} ${(0, _core_utils.numberToString)(h)} re W n`, `BT`, `1 0 0 1 0 ${(0, _core_utils.numberToString)(h + lineDescent)} Tm 0 Tc ${getPdfColor(bgColor, true)}`, `/${this.fontName.name} ${(0, _core_utils.numberToString)(newFontSize)} Tf`];
- const vShift = (0, _core_utils.numberToString)(lineHeight);
- for (const line of lines) {
- buffer.push(`0 -${vShift} Td <${(0, _core_utils.stringToUTF16HexString)(line)}> Tj`);
- }
- buffer.push("ET", "Q");
- const appearance = buffer.join("\n");
- const appearanceStreamDict = new _primitives.Dict(this.xref);
- appearanceStreamDict.set("Subtype", _primitives.Name.get("Form"));
- appearanceStreamDict.set("Type", _primitives.Name.get("XObject"));
- appearanceStreamDict.set("BBox", [0, 0, w, h]);
- appearanceStreamDict.set("Length", appearance.length);
- appearanceStreamDict.set("Resources", this.resources);
- if (rotation) {
- const matrix = (0, _core_utils.getRotationMatrix)(rotation, w, h);
- appearanceStreamDict.set("Matrix", matrix);
- }
- const ap = new _stream.StringStream(appearance);
- ap.dict = appearanceStreamDict;
- return ap;
- }
- }
- exports.FakeUnicodeFont = FakeUnicodeFont;
|