@mlightcad/cad-pdf-plugin 1.8.0-preview.2 → 1.8.0-preview.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -21
- package/README.md +280 -186
- package/dist/cad-pdf-plugin-register.js +29 -11
- package/dist/cad-pdf-plugin-register.umd.cjs +1 -1
- package/dist/cad-pdf-plugin.js +17568 -8428
- package/dist/cad-pdf-plugin.umd.cjs +847 -13
- package/lib/AcApConvertToPdfCmd.d.ts.map +1 -1
- package/lib/AcApConvertToPdfCmd.js +14 -3
- package/lib/AcApConvertToPdfCmd.js.map +1 -1
- package/lib/AcApImportPdfCmd.d.ts +5 -3
- package/lib/AcApImportPdfCmd.d.ts.map +1 -1
- package/lib/AcApImportPdfCmd.js +5 -3
- package/lib/AcApImportPdfCmd.js.map +1 -1
- package/lib/AcApImportPdfPromptCmd.d.ts +16 -0
- package/lib/AcApImportPdfPromptCmd.d.ts.map +1 -0
- package/lib/AcApImportPdfPromptCmd.js +89 -0
- package/lib/AcApImportPdfPromptCmd.js.map +1 -0
- package/lib/AcApPdfBlockCmd.d.ts +15 -0
- package/lib/AcApPdfBlockCmd.d.ts.map +1 -0
- package/lib/AcApPdfBlockCmd.js +75 -0
- package/lib/AcApPdfBlockCmd.js.map +1 -0
- package/lib/AcApPdfDimCmd.d.ts +20 -0
- package/lib/AcApPdfDimCmd.d.ts.map +1 -0
- package/lib/AcApPdfDimCmd.js +413 -0
- package/lib/AcApPdfDimCmd.js.map +1 -0
- package/lib/AcApPdfDimSession.d.ts +82 -0
- package/lib/AcApPdfDimSession.d.ts.map +1 -0
- package/lib/AcApPdfDimSession.js +252 -0
- package/lib/AcApPdfDimSession.js.map +1 -0
- package/lib/AcApPdfFontResolver.d.ts.map +1 -1
- package/lib/AcApPdfFontResolver.js +2 -5
- package/lib/AcApPdfFontResolver.js.map +1 -1
- package/lib/AcApPdfHatchCmd.d.ts +33 -0
- package/lib/AcApPdfHatchCmd.d.ts.map +1 -0
- package/lib/AcApPdfHatchCmd.js +411 -0
- package/lib/AcApPdfHatchCmd.js.map +1 -0
- package/lib/AcApPdfHatchSession.d.ts +122 -0
- package/lib/AcApPdfHatchSession.d.ts.map +1 -0
- package/lib/AcApPdfHatchSession.js +357 -0
- package/lib/AcApPdfHatchSession.js.map +1 -0
- package/lib/AcApPdfImportConvertor.d.ts +47 -5
- package/lib/AcApPdfImportConvertor.d.ts.map +1 -1
- package/lib/AcApPdfImportConvertor.js +999 -108
- package/lib/AcApPdfImportConvertor.js.map +1 -1
- package/lib/AcApPdfImportOptions.d.ts +116 -0
- package/lib/AcApPdfImportOptions.d.ts.map +1 -0
- package/lib/AcApPdfImportOptions.js +31 -0
- package/lib/AcApPdfImportOptions.js.map +1 -0
- package/lib/AcApPdfImportResources.d.ts +41 -0
- package/lib/AcApPdfImportResources.d.ts.map +1 -0
- package/lib/AcApPdfImportResources.js +52 -0
- package/lib/AcApPdfImportResources.js.map +1 -0
- package/lib/AcApPdfPlugin.d.ts +3 -3
- package/lib/AcApPdfPlugin.d.ts.map +1 -1
- package/lib/AcApPdfPlugin.js +23 -5
- package/lib/AcApPdfPlugin.js.map +1 -1
- package/lib/AcApPdfScaleCmd.d.ts +22 -0
- package/lib/AcApPdfScaleCmd.d.ts.map +1 -0
- package/lib/AcApPdfScaleCmd.js +185 -0
- package/lib/AcApPdfScaleCmd.js.map +1 -0
- package/lib/AcApPdfTextCmd.d.ts +73 -0
- package/lib/AcApPdfTextCmd.d.ts.map +1 -0
- package/lib/AcApPdfTextCmd.js +777 -0
- package/lib/AcApPdfTextCmd.js.map +1 -0
- package/lib/AcApPdfTextSession.d.ts +232 -0
- package/lib/AcApPdfTextSession.d.ts.map +1 -0
- package/lib/AcApPdfTextSession.js +826 -0
- package/lib/AcApPdfTextSession.js.map +1 -0
- package/lib/acapPdfI18n.d.ts +11 -0
- package/lib/acapPdfI18n.d.ts.map +1 -0
- package/lib/acapPdfI18n.js +57 -0
- package/lib/acapPdfI18n.js.map +1 -0
- package/lib/acapPdfPrompts.d.ts +12 -0
- package/lib/acapPdfPrompts.d.ts.map +1 -0
- package/lib/acapPdfPrompts.js +100 -0
- package/lib/acapPdfPrompts.js.map +1 -0
- package/lib/index.d.ts +28 -0
- package/lib/index.d.ts.map +1 -1
- package/lib/index.js +28 -0
- package/lib/index.js.map +1 -1
- package/lib/pdfDeprecatedMatching.d.ts +27 -0
- package/lib/pdfDeprecatedMatching.d.ts.map +1 -0
- package/lib/pdfDeprecatedMatching.js +20 -0
- package/lib/pdfDeprecatedMatching.js.map +1 -0
- package/lib/pdfDimStrokeTexts.d.ts +55 -0
- package/lib/pdfDimStrokeTexts.d.ts.map +1 -0
- package/lib/pdfDimStrokeTexts.js +274 -0
- package/lib/pdfDimStrokeTexts.js.map +1 -0
- package/lib/pdfDimensionConvert.d.ts +80 -0
- package/lib/pdfDimensionConvert.d.ts.map +1 -0
- package/lib/pdfDimensionConvert.js +566 -0
- package/lib/pdfDimensionConvert.js.map +1 -0
- package/lib/pdfEntityStrokes.d.ts +13 -0
- package/lib/pdfEntityStrokes.d.ts.map +1 -0
- package/lib/pdfEntityStrokes.js +86 -0
- package/lib/pdfEntityStrokes.js.map +1 -0
- package/lib/pdfHatchRecover.d.ts +57 -0
- package/lib/pdfHatchRecover.d.ts.map +1 -0
- package/lib/pdfHatchRecover.js +315 -0
- package/lib/pdfHatchRecover.js.map +1 -0
- package/lib/pdfImportAppend.d.ts +24 -0
- package/lib/pdfImportAppend.d.ts.map +1 -0
- package/lib/pdfImportAppend.js +35 -0
- package/lib/pdfImportAppend.js.map +1 -0
- package/lib/pdfImportEntities.d.ts +63 -0
- package/lib/pdfImportEntities.d.ts.map +1 -0
- package/lib/pdfImportEntities.js +307 -0
- package/lib/pdfImportEntities.js.map +1 -0
- package/lib/pdfImportImages.d.ts +90 -0
- package/lib/pdfImportImages.d.ts.map +1 -0
- package/lib/pdfImportImages.js +294 -0
- package/lib/pdfImportImages.js.map +1 -0
- package/lib/pdfImportShapes.d.ts +63 -0
- package/lib/pdfImportShapes.d.ts.map +1 -0
- package/lib/pdfImportShapes.js +248 -0
- package/lib/pdfImportShapes.js.map +1 -0
- package/lib/pdfVectorImport.d.ts +218 -5
- package/lib/pdfVectorImport.d.ts.map +1 -1
- package/lib/pdfVectorImport.js +566 -98
- package/lib/pdfVectorImport.js.map +1 -1
- package/lib/recognition/pdfCurveRecognition.d.ts +91 -0
- package/lib/recognition/pdfCurveRecognition.d.ts.map +1 -0
- package/lib/recognition/pdfCurveRecognition.js +506 -0
- package/lib/recognition/pdfCurveRecognition.js.map +1 -0
- package/lib/recognition/pdfDimDigitRecognition.d.ts +18 -0
- package/lib/recognition/pdfDimDigitRecognition.d.ts.map +1 -0
- package/lib/recognition/pdfDimDigitRecognition.js +520 -0
- package/lib/recognition/pdfDimDigitRecognition.js.map +1 -0
- package/lib/recognition/pdfDimensionPattern.d.ts +173 -0
- package/lib/recognition/pdfDimensionPattern.d.ts.map +1 -0
- package/lib/recognition/pdfDimensionPattern.js +1023 -0
- package/lib/recognition/pdfDimensionPattern.js.map +1 -0
- package/lib/recognition/pdfFormBlocks.d.ts +58 -0
- package/lib/recognition/pdfFormBlocks.d.ts.map +1 -0
- package/lib/recognition/pdfFormBlocks.js +260 -0
- package/lib/recognition/pdfFormBlocks.js.map +1 -0
- package/lib/recognition/pdfGlyphClustering.d.ts +81 -0
- package/lib/recognition/pdfGlyphClustering.d.ts.map +1 -0
- package/lib/recognition/pdfGlyphClustering.js +1005 -0
- package/lib/recognition/pdfGlyphClustering.js.map +1 -0
- package/lib/recognition/pdfGlyphDictionary.d.ts +49 -0
- package/lib/recognition/pdfGlyphDictionary.d.ts.map +1 -0
- package/lib/recognition/pdfGlyphDictionary.js +188 -0
- package/lib/recognition/pdfGlyphDictionary.js.map +1 -0
- package/lib/recognition/pdfHatchFaces.d.ts +84 -0
- package/lib/recognition/pdfHatchFaces.d.ts.map +1 -0
- package/lib/recognition/pdfHatchFaces.js +1285 -0
- package/lib/recognition/pdfHatchFaces.js.map +1 -0
- package/lib/recognition/pdfHatchRecognition.d.ts +222 -0
- package/lib/recognition/pdfHatchRecognition.d.ts.map +1 -0
- package/lib/recognition/pdfHatchRecognition.js +3781 -0
- package/lib/recognition/pdfHatchRecognition.js.map +1 -0
- package/lib/recognition/pdfRecGeometry.d.ts +67 -0
- package/lib/recognition/pdfRecGeometry.d.ts.map +1 -0
- package/lib/recognition/pdfRecGeometry.js +365 -0
- package/lib/recognition/pdfRecGeometry.js.map +1 -0
- package/lib/recognition/pdfTextFontKind.d.ts +16 -0
- package/lib/recognition/pdfTextFontKind.d.ts.map +1 -0
- package/lib/recognition/pdfTextFontKind.js +51 -0
- package/lib/recognition/pdfTextFontKind.js.map +1 -0
- package/lib/recognition/pdfTextMerge.d.ts +71 -0
- package/lib/recognition/pdfTextMerge.d.ts.map +1 -0
- package/lib/recognition/pdfTextMerge.js +382 -0
- package/lib/recognition/pdfTextMerge.js.map +1 -0
- package/lib/recognition/pdfTextRunMerge.d.ts +28 -0
- package/lib/recognition/pdfTextRunMerge.d.ts.map +1 -0
- package/lib/recognition/pdfTextRunMerge.js +90 -0
- package/lib/recognition/pdfTextRunMerge.js.map +1 -0
- package/lib/register.d.ts +8 -2
- package/lib/register.d.ts.map +1 -1
- package/lib/register.js +29 -4
- package/lib/register.js.map +1 -1
- package/lib/ui/AcUiPdfDimPanel.d.ts +55 -0
- package/lib/ui/AcUiPdfDimPanel.d.ts.map +1 -0
- package/lib/ui/AcUiPdfDimPanel.js +347 -0
- package/lib/ui/AcUiPdfDimPanel.js.map +1 -0
- package/lib/ui/AcUiPdfHatchPanel.d.ts +57 -0
- package/lib/ui/AcUiPdfHatchPanel.d.ts.map +1 -0
- package/lib/ui/AcUiPdfHatchPanel.js +420 -0
- package/lib/ui/AcUiPdfHatchPanel.js.map +1 -0
- package/lib/ui/AcUiPdfImportDialog.d.ts +120 -0
- package/lib/ui/AcUiPdfImportDialog.d.ts.map +1 -0
- package/lib/ui/AcUiPdfImportDialog.js +673 -0
- package/lib/ui/AcUiPdfImportDialog.js.map +1 -0
- package/lib/ui/AcUiPdfTextPanel.d.ts +95 -0
- package/lib/ui/AcUiPdfTextPanel.d.ts.map +1 -0
- package/lib/ui/AcUiPdfTextPanel.js +775 -0
- package/lib/ui/AcUiPdfTextPanel.js.map +1 -0
- package/package.json +11 -11
|
@@ -0,0 +1,826 @@
|
|
|
1
|
+
var __assign = (this && this.__assign) || function () {
|
|
2
|
+
__assign = Object.assign || function(t) {
|
|
3
|
+
for (var s, i = 1, n = arguments.length; i < n; i++) {
|
|
4
|
+
s = arguments[i];
|
|
5
|
+
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
|
|
6
|
+
t[p] = s[p];
|
|
7
|
+
}
|
|
8
|
+
return t;
|
|
9
|
+
};
|
|
10
|
+
return __assign.apply(this, arguments);
|
|
11
|
+
};
|
|
12
|
+
var __values = (this && this.__values) || function(o) {
|
|
13
|
+
var s = typeof Symbol === "function" && Symbol.iterator, m = s && o[s], i = 0;
|
|
14
|
+
if (m) return m.call(o);
|
|
15
|
+
if (o && typeof o.length === "number") return {
|
|
16
|
+
next: function () {
|
|
17
|
+
if (o && i >= o.length) o = void 0;
|
|
18
|
+
return { value: o && o[i++], done: !o };
|
|
19
|
+
}
|
|
20
|
+
};
|
|
21
|
+
throw new TypeError(s ? "Object is not iterable." : "Symbol.iterator is not defined.");
|
|
22
|
+
};
|
|
23
|
+
var __read = (this && this.__read) || function (o, n) {
|
|
24
|
+
var m = typeof Symbol === "function" && o[Symbol.iterator];
|
|
25
|
+
if (!m) return o;
|
|
26
|
+
var i = m.call(o), r, ar = [], e;
|
|
27
|
+
try {
|
|
28
|
+
while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value);
|
|
29
|
+
}
|
|
30
|
+
catch (error) { e = { error: error }; }
|
|
31
|
+
finally {
|
|
32
|
+
try {
|
|
33
|
+
if (r && !r.done && (m = i["return"])) m.call(i);
|
|
34
|
+
}
|
|
35
|
+
finally { if (e) throw e.error; }
|
|
36
|
+
}
|
|
37
|
+
return ar;
|
|
38
|
+
};
|
|
39
|
+
var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) {
|
|
40
|
+
if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
|
|
41
|
+
if (ar || !(i in from)) {
|
|
42
|
+
if (!ar) ar = Array.prototype.slice.call(from, 0, i);
|
|
43
|
+
ar[i] = from[i];
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
return to.concat(ar || Array.prototype.slice.call(from));
|
|
47
|
+
};
|
|
48
|
+
import { AcDbMText, AcDbText, AcDbTextStyleTableRecord, AcGePoint3d, AcGiMTextAttachmentPoint } from '@mlightcad/data-model';
|
|
49
|
+
import { acapPdfFitWidthFactor, PDF_SHX_BIG_FONT, PDF_SHX_FONT, PDF_SHX_TEXT_STYLE, PDF_TEXT_STYLE_PREFIX } from './pdfImportEntities';
|
|
50
|
+
import { arePdfTextLinesAdjacent, mergePdfTextLines } from './recognition/pdfTextMerge';
|
|
51
|
+
/** TrueType face suggested for recovered outline text. */
|
|
52
|
+
export var PDF_MESH_FONT = 'simsun';
|
|
53
|
+
/** Text style suggested for recovered outline text. */
|
|
54
|
+
export var PDF_MESH_TEXT_STYLE = "".concat(PDF_TEXT_STYLE_PREFIX).concat(PDF_MESH_FONT);
|
|
55
|
+
var KINDS = ['shx', 'mesh'];
|
|
56
|
+
/**
|
|
57
|
+
* State of a `pdftext` review: the lines with their text, and one text style
|
|
58
|
+
* choice per font kind. UI-free, so the panel stays a thin view over it.
|
|
59
|
+
*
|
|
60
|
+
* Style choices are written to the database by {@link syncStyles} so the
|
|
61
|
+
* preview draws with them; {@link restoreStyles} undoes that on Cancel.
|
|
62
|
+
*/
|
|
63
|
+
var AcApPdfTextSession = /** @class */ (function () {
|
|
64
|
+
function AcApPdfTextSession(input) {
|
|
65
|
+
var e_1, _a;
|
|
66
|
+
this.choices = new Map();
|
|
67
|
+
/** Original fonts of existing styles changed by {@link syncStyles}. */
|
|
68
|
+
this.snapshots = new Map();
|
|
69
|
+
/** Styles created by {@link syncStyles}. */
|
|
70
|
+
this.created = new Set();
|
|
71
|
+
this.db = input.db;
|
|
72
|
+
this.rows = input.rows;
|
|
73
|
+
this.fontKind = input.fontKind;
|
|
74
|
+
try {
|
|
75
|
+
for (var KINDS_1 = __values(KINDS), KINDS_1_1 = KINDS_1.next(); !KINDS_1_1.done; KINDS_1_1 = KINDS_1.next()) {
|
|
76
|
+
var kind = KINDS_1_1.value;
|
|
77
|
+
this.choices.set(kind, this.defaultChoice(kind));
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
catch (e_1_1) { e_1 = { error: e_1_1 }; }
|
|
81
|
+
finally {
|
|
82
|
+
try {
|
|
83
|
+
if (KINDS_1_1 && !KINDS_1_1.done && (_a = KINDS_1.return)) _a.call(KINDS_1);
|
|
84
|
+
}
|
|
85
|
+
finally { if (e_1) throw e_1.error; }
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
Object.defineProperty(AcApPdfTextSession.prototype, "kinds", {
|
|
89
|
+
/** Font kinds used by at least one line. */
|
|
90
|
+
get: function () {
|
|
91
|
+
var _this = this;
|
|
92
|
+
return KINDS.filter(function (kind) { return _this.rows.some(function (row) { return row.kind === kind; }); });
|
|
93
|
+
},
|
|
94
|
+
enumerable: false,
|
|
95
|
+
configurable: true
|
|
96
|
+
});
|
|
97
|
+
/** Style settings of a font kind. */
|
|
98
|
+
AcApPdfTextSession.prototype.choice = function (kind) {
|
|
99
|
+
return this.choices.get(kind);
|
|
100
|
+
};
|
|
101
|
+
/** Names of the text styles in the drawing, sorted. */
|
|
102
|
+
AcApPdfTextSession.prototype.styleNames = function () {
|
|
103
|
+
var e_2, _a;
|
|
104
|
+
var names = [];
|
|
105
|
+
try {
|
|
106
|
+
for (var _b = __values(this.db.tables.textStyleTable.newIterator()), _c = _b.next(); !_c.done; _c = _b.next()) {
|
|
107
|
+
var record = _c.value;
|
|
108
|
+
if (!this.created.has(record.name))
|
|
109
|
+
names.push(record.name);
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
catch (e_2_1) { e_2 = { error: e_2_1 }; }
|
|
113
|
+
finally {
|
|
114
|
+
try {
|
|
115
|
+
if (_c && !_c.done && (_a = _b.return)) _a.call(_b);
|
|
116
|
+
}
|
|
117
|
+
finally { if (e_2) throw e_2.error; }
|
|
118
|
+
}
|
|
119
|
+
return names.sort(function (a, b) { return a.localeCompare(b); });
|
|
120
|
+
};
|
|
121
|
+
/** Uses an existing text style (and its fonts) for a font kind. */
|
|
122
|
+
AcApPdfTextSession.prototype.selectStyle = function (kind, name) {
|
|
123
|
+
var _a, _b;
|
|
124
|
+
var record = this.originalRecord(name);
|
|
125
|
+
if (!record)
|
|
126
|
+
return;
|
|
127
|
+
var choice = this.choices.get(kind);
|
|
128
|
+
choice.styleName = record.name;
|
|
129
|
+
choice.isNew = false;
|
|
130
|
+
var original = this.snapshots.get(record.name);
|
|
131
|
+
choice.font = (_a = original === null || original === void 0 ? void 0 : original.fileName) !== null && _a !== void 0 ? _a : record.fileName;
|
|
132
|
+
choice.bigFont = (_b = original === null || original === void 0 ? void 0 : original.bigFontFileName) !== null && _b !== void 0 ? _b : record.bigFontFileName;
|
|
133
|
+
};
|
|
134
|
+
/**
|
|
135
|
+
* Checks a name for a new text style (AutoCAD rules, no duplicate).
|
|
136
|
+
*
|
|
137
|
+
* @returns The reason it is rejected, or `undefined` when it is valid.
|
|
138
|
+
*/
|
|
139
|
+
AcApPdfTextSession.prototype.validateNewStyleName = function (name, kind) {
|
|
140
|
+
var trimmed = name.trim();
|
|
141
|
+
if (!trimmed)
|
|
142
|
+
return 'empty';
|
|
143
|
+
if (/[;=<>`\\/,|*?":]/.test(trimmed))
|
|
144
|
+
return 'invalid';
|
|
145
|
+
var lower = trimmed.toLowerCase();
|
|
146
|
+
if (this.styleNames().some(function (item) { return item.toLowerCase() === lower; })) {
|
|
147
|
+
return 'exists';
|
|
148
|
+
}
|
|
149
|
+
// The other kind cannot create a style with the same name.
|
|
150
|
+
var other = KINDS.find(function (item) { return item !== kind; });
|
|
151
|
+
var otherChoice = other ? this.choices.get(other) : undefined;
|
|
152
|
+
if ((otherChoice === null || otherChoice === void 0 ? void 0 : otherChoice.isNew) &&
|
|
153
|
+
this.kinds.includes(other) &&
|
|
154
|
+
otherChoice.styleName.toLowerCase() === lower) {
|
|
155
|
+
return 'exists';
|
|
156
|
+
}
|
|
157
|
+
return undefined;
|
|
158
|
+
};
|
|
159
|
+
/**
|
|
160
|
+
* Creates a new text style for a font kind, keeping the current fonts.
|
|
161
|
+
*
|
|
162
|
+
* @returns The reason the name is rejected, or `undefined` on success.
|
|
163
|
+
*/
|
|
164
|
+
AcApPdfTextSession.prototype.newStyle = function (kind, name) {
|
|
165
|
+
var error = this.validateNewStyleName(name, kind);
|
|
166
|
+
if (error)
|
|
167
|
+
return error;
|
|
168
|
+
var choice = this.choices.get(kind);
|
|
169
|
+
choice.styleName = name.trim();
|
|
170
|
+
choice.isNew = true;
|
|
171
|
+
return undefined;
|
|
172
|
+
};
|
|
173
|
+
/** Sets the primary font; a TrueType font drops the big font. */
|
|
174
|
+
AcApPdfTextSession.prototype.setFont = function (kind, font) {
|
|
175
|
+
var choice = this.choices.get(kind);
|
|
176
|
+
choice.font = font.trim();
|
|
177
|
+
if (this.fontKind(choice.font) === 'mesh')
|
|
178
|
+
choice.bigFont = '';
|
|
179
|
+
};
|
|
180
|
+
/** Sets the SHX big font (`''` for none). */
|
|
181
|
+
AcApPdfTextSession.prototype.setBigFont = function (kind, bigFont) {
|
|
182
|
+
this.choices.get(kind).bigFont = bigFont.trim();
|
|
183
|
+
};
|
|
184
|
+
/** Sets size options of a font kind. */
|
|
185
|
+
AcApPdfTextSession.prototype.setSize = function (kind, size) {
|
|
186
|
+
var choice = this.choices.get(kind);
|
|
187
|
+
if (size.heightScale !== undefined && size.heightScale > 0) {
|
|
188
|
+
choice.heightScale = size.heightScale;
|
|
189
|
+
}
|
|
190
|
+
if (size.autoWidth !== undefined)
|
|
191
|
+
choice.autoWidth = size.autoWidth;
|
|
192
|
+
if (size.widthFactor !== undefined && size.widthFactor > 0) {
|
|
193
|
+
choice.widthFactor = size.widthFactor;
|
|
194
|
+
}
|
|
195
|
+
};
|
|
196
|
+
/**
|
|
197
|
+
* Whether applying a kind's choice changes the fonts of an existing style,
|
|
198
|
+
* which also changes every text already using it.
|
|
199
|
+
*/
|
|
200
|
+
AcApPdfTextSession.prototype.changesExistingStyle = function (kind) {
|
|
201
|
+
var _a;
|
|
202
|
+
var choice = this.choices.get(kind);
|
|
203
|
+
if (choice.isNew)
|
|
204
|
+
return false;
|
|
205
|
+
var record = this.originalRecord(choice.styleName);
|
|
206
|
+
if (!record)
|
|
207
|
+
return false;
|
|
208
|
+
var original = (_a = this.snapshots.get(record.name)) !== null && _a !== void 0 ? _a : {
|
|
209
|
+
fileName: record.fileName,
|
|
210
|
+
bigFontFileName: record.bigFontFileName
|
|
211
|
+
};
|
|
212
|
+
return (!sameName(original.fileName, choice.font) ||
|
|
213
|
+
!sameName(original.bigFontFileName, choice.bigFont));
|
|
214
|
+
};
|
|
215
|
+
/** Sets the text of a line; text the user changed is marked typed. */
|
|
216
|
+
AcApPdfTextSession.prototype.setText = function (index, text) {
|
|
217
|
+
var row = this.rows[index];
|
|
218
|
+
if (!row || row.text === text)
|
|
219
|
+
return;
|
|
220
|
+
row.text = text;
|
|
221
|
+
row.source = 'typed';
|
|
222
|
+
if (text.trim())
|
|
223
|
+
row.included = true;
|
|
224
|
+
};
|
|
225
|
+
/**
|
|
226
|
+
* Fills lines still without text from glyphs learned meanwhile (a typed
|
|
227
|
+
* line teaches the glyphs other lines reuse).
|
|
228
|
+
*
|
|
229
|
+
* @param lookup - Reads a line from known glyphs.
|
|
230
|
+
* @returns Indexes of the lines filled.
|
|
231
|
+
*/
|
|
232
|
+
AcApPdfTextSession.prototype.fillUnread = function (lookup) {
|
|
233
|
+
var _this = this;
|
|
234
|
+
var filled = [];
|
|
235
|
+
this.rows.forEach(function (row, index) {
|
|
236
|
+
// Unread rows were not typed: partial text (a merge of read and
|
|
237
|
+
// unread characters) is replaced once the whole row can be read.
|
|
238
|
+
if (row.source !== 'unread')
|
|
239
|
+
return;
|
|
240
|
+
var text = lookupRow(row, lookup, _this.mergeMeasure(row.kind));
|
|
241
|
+
if (!text)
|
|
242
|
+
return;
|
|
243
|
+
row.text = text;
|
|
244
|
+
row.source = 'dictionary';
|
|
245
|
+
row.included = true;
|
|
246
|
+
filled.push(index);
|
|
247
|
+
});
|
|
248
|
+
return filled;
|
|
249
|
+
};
|
|
250
|
+
/**
|
|
251
|
+
* Sets the text measurer used when merging rows, so gaps between merged
|
|
252
|
+
* characters become the right number of spaces. Call it once the style
|
|
253
|
+
* fonts are loaded.
|
|
254
|
+
*/
|
|
255
|
+
AcApPdfTextSession.prototype.setMeasurer = function (measure) {
|
|
256
|
+
this.measurer = measure;
|
|
257
|
+
};
|
|
258
|
+
/** Measures text in a font kind's chosen fonts, for {@link merge}. */
|
|
259
|
+
AcApPdfTextSession.prototype.mergeMeasure = function (kind) {
|
|
260
|
+
var measure = this.measurer;
|
|
261
|
+
if (!measure)
|
|
262
|
+
return undefined;
|
|
263
|
+
var choice = this.choices.get(kind);
|
|
264
|
+
return function (text, height) {
|
|
265
|
+
return measure(text, choice.font, height, choice.bigFont);
|
|
266
|
+
};
|
|
267
|
+
};
|
|
268
|
+
/** Includes or skips a line. */
|
|
269
|
+
AcApPdfTextSession.prototype.setIncluded = function (index, included) {
|
|
270
|
+
var row = this.rows[index];
|
|
271
|
+
if (row)
|
|
272
|
+
row.included = included;
|
|
273
|
+
};
|
|
274
|
+
/** Switches the font kind a line is converted to. */
|
|
275
|
+
AcApPdfTextSession.prototype.setKind = function (index, kind) {
|
|
276
|
+
var row = this.rows[index];
|
|
277
|
+
if (row)
|
|
278
|
+
row.kind = kind;
|
|
279
|
+
};
|
|
280
|
+
Object.defineProperty(AcApPdfTextSession.prototype, "readyRows", {
|
|
281
|
+
/** Lines converted on Apply: included, with text. */
|
|
282
|
+
get: function () {
|
|
283
|
+
return this.rows.filter(function (row) { return row.included && row.text.trim(); });
|
|
284
|
+
},
|
|
285
|
+
enumerable: false,
|
|
286
|
+
configurable: true
|
|
287
|
+
});
|
|
288
|
+
Object.defineProperty(AcApPdfTextSession.prototype, "typedRows", {
|
|
289
|
+
/** Lines whose text the user typed, to teach the glyph dictionary. */
|
|
290
|
+
get: function () {
|
|
291
|
+
return this.readyRows.filter(function (row) { return row.source === 'typed'; });
|
|
292
|
+
},
|
|
293
|
+
enumerable: false,
|
|
294
|
+
configurable: true
|
|
295
|
+
});
|
|
296
|
+
Object.defineProperty(AcApPdfTextSession.prototype, "learnable", {
|
|
297
|
+
/** Typed lines as line/text pairs the glyph dictionary can learn. */
|
|
298
|
+
get: function () {
|
|
299
|
+
var _this = this;
|
|
300
|
+
return this.typedRows.flatMap(function (row) { return _this.learnableOf(row); });
|
|
301
|
+
},
|
|
302
|
+
enumerable: false,
|
|
303
|
+
configurable: true
|
|
304
|
+
});
|
|
305
|
+
/**
|
|
306
|
+
* Line/text pairs the glyph dictionary can learn from a row. A merged row
|
|
307
|
+
* on one baseline is one line. A merged block of several lines can only
|
|
308
|
+
* be paired with its parts while its text is unchanged.
|
|
309
|
+
*/
|
|
310
|
+
AcApPdfTextSession.prototype.learnableOf = function (row) {
|
|
311
|
+
var _this = this;
|
|
312
|
+
var text = row.text.trim();
|
|
313
|
+
if (!text)
|
|
314
|
+
return [];
|
|
315
|
+
var merge = row.merge;
|
|
316
|
+
if (!merge || merge.paragraphs.length === 1) {
|
|
317
|
+
return [{ line: row.line, text: text }];
|
|
318
|
+
}
|
|
319
|
+
if (row.text !== merge.text)
|
|
320
|
+
return [];
|
|
321
|
+
return merge.parts.flatMap(function (part) {
|
|
322
|
+
return part.source === 'typed' ? _this.learnableOf(part) : [];
|
|
323
|
+
});
|
|
324
|
+
};
|
|
325
|
+
/**
|
|
326
|
+
* Merges rows into one row that becomes a single MTEXT: rows on one
|
|
327
|
+
* baseline join into one line, rows on different baselines into separate
|
|
328
|
+
* lines of the block. Already merged rows are merged by their parts.
|
|
329
|
+
*
|
|
330
|
+
* @param indexes - Rows to merge (at least two).
|
|
331
|
+
* @returns Index of the merged row, or `undefined` when nothing merged.
|
|
332
|
+
*/
|
|
333
|
+
AcApPdfTextSession.prototype.merge = function (indexes) {
|
|
334
|
+
var _this = this;
|
|
335
|
+
var unique = __spreadArray([], __read(new Set(indexes)), false).filter(function (index) { return _this.rows[index]; })
|
|
336
|
+
.sort(function (a, b) { return a - b; });
|
|
337
|
+
if (unique.length < 2)
|
|
338
|
+
return undefined;
|
|
339
|
+
var selected = unique.map(function (index) { return _this.rows[index]; });
|
|
340
|
+
var parts = selected.flatMap(function (row) { return _this.partsOf(row); });
|
|
341
|
+
var kind = majorityKind(parts);
|
|
342
|
+
var result = mergePdfTextLines(parts, {
|
|
343
|
+
measure: this.mergeMeasure(kind)
|
|
344
|
+
});
|
|
345
|
+
var text = result.text;
|
|
346
|
+
var anyUnread = parts.some(function (part) { return part.source === 'unread' && !part.text.trim(); });
|
|
347
|
+
var merged = {
|
|
348
|
+
line: result.line,
|
|
349
|
+
kind: kind,
|
|
350
|
+
text: text,
|
|
351
|
+
source: anyUnread || !text.trim()
|
|
352
|
+
? 'unread'
|
|
353
|
+
: parts.some(function (part) { return part.source === 'typed'; })
|
|
354
|
+
? 'typed'
|
|
355
|
+
: parts.every(function (part) { return part.source === 'dictionary'; })
|
|
356
|
+
? 'dictionary'
|
|
357
|
+
: 'ocr',
|
|
358
|
+
included: !!text.trim(),
|
|
359
|
+
merge: {
|
|
360
|
+
parts: parts,
|
|
361
|
+
paragraphs: result.paragraphs,
|
|
362
|
+
lineSpacing: result.lineSpacing,
|
|
363
|
+
text: text
|
|
364
|
+
}
|
|
365
|
+
};
|
|
366
|
+
for (var i = unique.length - 1; i >= 0; i--)
|
|
367
|
+
this.rows.splice(unique[i], 1);
|
|
368
|
+
this.rows.splice(unique[0], 0, merged);
|
|
369
|
+
return unique[0];
|
|
370
|
+
};
|
|
371
|
+
/**
|
|
372
|
+
* Splits a merged row back into the rows it was made of.
|
|
373
|
+
*
|
|
374
|
+
* @returns Indexes of the restored rows (empty when the row is not merged).
|
|
375
|
+
*/
|
|
376
|
+
AcApPdfTextSession.prototype.split = function (index) {
|
|
377
|
+
var _a;
|
|
378
|
+
var row = this.rows[index];
|
|
379
|
+
if (!(row === null || row === void 0 ? void 0 : row.merge))
|
|
380
|
+
return [];
|
|
381
|
+
var parts = row.merge.parts;
|
|
382
|
+
(_a = this.rows).splice.apply(_a, __spreadArray([index, 1], __read(parts), false));
|
|
383
|
+
return parts.map(function (_, i) { return index + i; });
|
|
384
|
+
};
|
|
385
|
+
/**
|
|
386
|
+
* Merges rows that read as one line: on the same baseline, in the same
|
|
387
|
+
* direction and close together (typically characters the clustering left
|
|
388
|
+
* apart). Blocks of several lines are left alone.
|
|
389
|
+
*
|
|
390
|
+
* @returns Number of merged rows created.
|
|
391
|
+
*/
|
|
392
|
+
AcApPdfTextSession.prototype.mergeAdjacent = function () {
|
|
393
|
+
var e_3, _a;
|
|
394
|
+
var _this = this;
|
|
395
|
+
var candidates = this.rows.filter(function (row) { return !row.merge || row.merge.paragraphs.length === 1; });
|
|
396
|
+
var boxes = candidates.map(function (row) { return worldBox(row.line); });
|
|
397
|
+
var parent = candidates.map(function (_, i) { return i; });
|
|
398
|
+
var find = function (i) {
|
|
399
|
+
return parent[i] === i ? i : (parent[i] = find(parent[i]));
|
|
400
|
+
};
|
|
401
|
+
for (var i = 0; i < candidates.length; i++) {
|
|
402
|
+
for (var j = i + 1; j < candidates.length; j++) {
|
|
403
|
+
// Cheap reject before the exact test: boxes too far apart.
|
|
404
|
+
var reach = 2 * Math.max(candidates[i].line.height, candidates[j].line.height);
|
|
405
|
+
if (boxes[i].minX - boxes[j].maxX > reach ||
|
|
406
|
+
boxes[j].minX - boxes[i].maxX > reach ||
|
|
407
|
+
boxes[i].minY - boxes[j].maxY > reach ||
|
|
408
|
+
boxes[j].minY - boxes[i].maxY > reach) {
|
|
409
|
+
continue;
|
|
410
|
+
}
|
|
411
|
+
if (arePdfTextLinesAdjacent(candidates[i].line, candidates[j].line)) {
|
|
412
|
+
parent[find(i)] = find(j);
|
|
413
|
+
}
|
|
414
|
+
}
|
|
415
|
+
}
|
|
416
|
+
var groups = new Map();
|
|
417
|
+
candidates.forEach(function (row, i) {
|
|
418
|
+
var _a;
|
|
419
|
+
var root = find(i);
|
|
420
|
+
groups.set(root, __spreadArray(__spreadArray([], __read(((_a = groups.get(root)) !== null && _a !== void 0 ? _a : [])), false), [row], false));
|
|
421
|
+
});
|
|
422
|
+
var count = 0;
|
|
423
|
+
try {
|
|
424
|
+
for (var _b = __values(groups.values()), _c = _b.next(); !_c.done; _c = _b.next()) {
|
|
425
|
+
var group = _c.value;
|
|
426
|
+
if (group.length < 2)
|
|
427
|
+
continue;
|
|
428
|
+
this.merge(group.map(function (row) { return _this.rows.indexOf(row); }));
|
|
429
|
+
count++;
|
|
430
|
+
}
|
|
431
|
+
}
|
|
432
|
+
catch (e_3_1) { e_3 = { error: e_3_1 }; }
|
|
433
|
+
finally {
|
|
434
|
+
try {
|
|
435
|
+
if (_c && !_c.done && (_a = _b.return)) _a.call(_b);
|
|
436
|
+
}
|
|
437
|
+
finally { if (e_3) throw e_3.error; }
|
|
438
|
+
}
|
|
439
|
+
return count;
|
|
440
|
+
};
|
|
441
|
+
/** The original rows a row stands for (itself unless merged). */
|
|
442
|
+
AcApPdfTextSession.prototype.partsOf = function (row) {
|
|
443
|
+
var _this = this;
|
|
444
|
+
var merge = row.merge;
|
|
445
|
+
if (!merge)
|
|
446
|
+
return [row];
|
|
447
|
+
// An edited single-line merge keeps its text as one part.
|
|
448
|
+
if (merge.paragraphs.length === 1 && row.text !== merge.text) {
|
|
449
|
+
return [__assign(__assign({}, row), { merge: undefined })];
|
|
450
|
+
}
|
|
451
|
+
return merge.parts.flatMap(function (part) { return _this.partsOf(part); });
|
|
452
|
+
};
|
|
453
|
+
/**
|
|
454
|
+
* Writes the style choices of the used font kinds to the database: creates
|
|
455
|
+
* new styles and updates the fonts of existing ones (originals are kept for
|
|
456
|
+
* {@link restoreStyles}). New styles no longer chosen are removed.
|
|
457
|
+
*
|
|
458
|
+
* @returns The fonts the styles use, to be loaded before drawing.
|
|
459
|
+
*/
|
|
460
|
+
AcApPdfTextSession.prototype.syncStyles = function () {
|
|
461
|
+
var e_4, _a, e_5, _b, e_6, _c, e_7, _d;
|
|
462
|
+
var _this = this;
|
|
463
|
+
var table = this.db.tables.textStyleTable;
|
|
464
|
+
var wanted = new Set();
|
|
465
|
+
var fonts = new Set();
|
|
466
|
+
try {
|
|
467
|
+
for (var _e = __values(this.kinds), _f = _e.next(); !_f.done; _f = _e.next()) {
|
|
468
|
+
var kind = _f.value;
|
|
469
|
+
var choice = this.choices.get(kind);
|
|
470
|
+
if (choice.font)
|
|
471
|
+
fonts.add(choice.font);
|
|
472
|
+
if (choice.bigFont)
|
|
473
|
+
fonts.add(choice.bigFont);
|
|
474
|
+
if (choice.isNew)
|
|
475
|
+
wanted.add(choice.styleName);
|
|
476
|
+
}
|
|
477
|
+
}
|
|
478
|
+
catch (e_4_1) { e_4 = { error: e_4_1 }; }
|
|
479
|
+
finally {
|
|
480
|
+
try {
|
|
481
|
+
if (_f && !_f.done && (_a = _e.return)) _a.call(_e);
|
|
482
|
+
}
|
|
483
|
+
finally { if (e_4) throw e_4.error; }
|
|
484
|
+
}
|
|
485
|
+
try {
|
|
486
|
+
for (var _g = __values(__spreadArray([], __read(this.created), false)), _h = _g.next(); !_h.done; _h = _g.next()) {
|
|
487
|
+
var name_1 = _h.value;
|
|
488
|
+
if (!wanted.has(name_1)) {
|
|
489
|
+
table.remove(name_1);
|
|
490
|
+
this.created.delete(name_1);
|
|
491
|
+
}
|
|
492
|
+
}
|
|
493
|
+
}
|
|
494
|
+
catch (e_5_1) { e_5 = { error: e_5_1 }; }
|
|
495
|
+
finally {
|
|
496
|
+
try {
|
|
497
|
+
if (_h && !_h.done && (_b = _g.return)) _b.call(_g);
|
|
498
|
+
}
|
|
499
|
+
finally { if (e_5) throw e_5.error; }
|
|
500
|
+
}
|
|
501
|
+
// Existing styles whose choice moved elsewhere get their fonts back.
|
|
502
|
+
var edited = new Set(this.kinds
|
|
503
|
+
.map(function (kind) { return _this.choices.get(kind); })
|
|
504
|
+
.filter(function (choice) { return !choice.isNew; })
|
|
505
|
+
.map(function (choice) { return choice.styleName; }));
|
|
506
|
+
try {
|
|
507
|
+
for (var _j = __values(__spreadArray([], __read(this.snapshots), false)), _k = _j.next(); !_k.done; _k = _j.next()) {
|
|
508
|
+
var _l = __read(_k.value, 2), name_2 = _l[0], original = _l[1];
|
|
509
|
+
if (edited.has(name_2))
|
|
510
|
+
continue;
|
|
511
|
+
var record = table.getAt(name_2);
|
|
512
|
+
if (record) {
|
|
513
|
+
this.setFonts(record, original.fileName, original.bigFontFileName);
|
|
514
|
+
}
|
|
515
|
+
this.snapshots.delete(name_2);
|
|
516
|
+
}
|
|
517
|
+
}
|
|
518
|
+
catch (e_6_1) { e_6 = { error: e_6_1 }; }
|
|
519
|
+
finally {
|
|
520
|
+
try {
|
|
521
|
+
if (_k && !_k.done && (_c = _j.return)) _c.call(_j);
|
|
522
|
+
}
|
|
523
|
+
finally { if (e_6) throw e_6.error; }
|
|
524
|
+
}
|
|
525
|
+
try {
|
|
526
|
+
for (var _m = __values(this.kinds), _o = _m.next(); !_o.done; _o = _m.next()) {
|
|
527
|
+
var kind = _o.value;
|
|
528
|
+
var choice = this.choices.get(kind);
|
|
529
|
+
var record = table.getAt(choice.styleName);
|
|
530
|
+
if (!record) {
|
|
531
|
+
// Fonts are set before the record joins the database, which needs
|
|
532
|
+
// no open-for-write.
|
|
533
|
+
table.add(createStyleRecord(choice.styleName, choice));
|
|
534
|
+
this.created.add(choice.styleName);
|
|
535
|
+
continue;
|
|
536
|
+
}
|
|
537
|
+
if (!this.created.has(record.name) && !this.snapshots.has(record.name)) {
|
|
538
|
+
this.snapshots.set(record.name, {
|
|
539
|
+
fileName: record.fileName,
|
|
540
|
+
bigFontFileName: record.bigFontFileName
|
|
541
|
+
});
|
|
542
|
+
}
|
|
543
|
+
this.setFonts(record, choice.font, choice.bigFont);
|
|
544
|
+
}
|
|
545
|
+
}
|
|
546
|
+
catch (e_7_1) { e_7 = { error: e_7_1 }; }
|
|
547
|
+
finally {
|
|
548
|
+
try {
|
|
549
|
+
if (_o && !_o.done && (_d = _m.return)) _d.call(_m);
|
|
550
|
+
}
|
|
551
|
+
finally { if (e_7) throw e_7.error; }
|
|
552
|
+
}
|
|
553
|
+
return __spreadArray([], __read(fonts), false);
|
|
554
|
+
};
|
|
555
|
+
/** Undoes {@link syncStyles}: removes new styles, restores fonts. */
|
|
556
|
+
AcApPdfTextSession.prototype.restoreStyles = function () {
|
|
557
|
+
var e_8, _a, e_9, _b;
|
|
558
|
+
var table = this.db.tables.textStyleTable;
|
|
559
|
+
try {
|
|
560
|
+
for (var _c = __values(this.created), _d = _c.next(); !_d.done; _d = _c.next()) {
|
|
561
|
+
var name_3 = _d.value;
|
|
562
|
+
table.remove(name_3);
|
|
563
|
+
}
|
|
564
|
+
}
|
|
565
|
+
catch (e_8_1) { e_8 = { error: e_8_1 }; }
|
|
566
|
+
finally {
|
|
567
|
+
try {
|
|
568
|
+
if (_d && !_d.done && (_a = _c.return)) _a.call(_c);
|
|
569
|
+
}
|
|
570
|
+
finally { if (e_8) throw e_8.error; }
|
|
571
|
+
}
|
|
572
|
+
this.created.clear();
|
|
573
|
+
try {
|
|
574
|
+
for (var _e = __values(this.snapshots), _f = _e.next(); !_f.done; _f = _e.next()) {
|
|
575
|
+
var _g = __read(_f.value, 2), name_4 = _g[0], original = _g[1];
|
|
576
|
+
var record = table.getAt(name_4);
|
|
577
|
+
if (record) {
|
|
578
|
+
this.setFonts(record, original.fileName, original.bigFontFileName);
|
|
579
|
+
}
|
|
580
|
+
}
|
|
581
|
+
}
|
|
582
|
+
catch (e_9_1) { e_9 = { error: e_9_1 }; }
|
|
583
|
+
finally {
|
|
584
|
+
try {
|
|
585
|
+
if (_f && !_f.done && (_b = _e.return)) _b.call(_e);
|
|
586
|
+
}
|
|
587
|
+
finally { if (e_9) throw e_9.error; }
|
|
588
|
+
}
|
|
589
|
+
this.snapshots.clear();
|
|
590
|
+
};
|
|
591
|
+
/**
|
|
592
|
+
* Sets the fonts of a style record when they differ, opening it for write
|
|
593
|
+
* first: inside a command's transaction, database records may only change
|
|
594
|
+
* once opened for write.
|
|
595
|
+
*/
|
|
596
|
+
AcApPdfTextSession.prototype.setFonts = function (record, font, bigFont) {
|
|
597
|
+
var _a;
|
|
598
|
+
if (record.fileName === font && record.bigFontFileName === bigFont)
|
|
599
|
+
return;
|
|
600
|
+
var writable = (_a = this.db.openObjectForWrite(record.objectId)) !== null && _a !== void 0 ? _a : record;
|
|
601
|
+
writable.fileName = font;
|
|
602
|
+
writable.bigFontFileName = bigFont;
|
|
603
|
+
};
|
|
604
|
+
/**
|
|
605
|
+
* Builds the text entity of a line with its kind's style choice.
|
|
606
|
+
*
|
|
607
|
+
* @param row - The line.
|
|
608
|
+
* @param measure - Measures natural text width for the width auto-fit.
|
|
609
|
+
*/
|
|
610
|
+
AcApPdfTextSession.prototype.createText = function (row, measure) {
|
|
611
|
+
var choice = this.choices.get(row.kind);
|
|
612
|
+
var height = row.line.height * choice.heightScale;
|
|
613
|
+
var text = new AcDbText();
|
|
614
|
+
text.textString = row.text.trim();
|
|
615
|
+
text.styleName = choice.styleName;
|
|
616
|
+
text.position = new AcGePoint3d(row.line.position.x, row.line.position.y, 0);
|
|
617
|
+
text.height = height;
|
|
618
|
+
text.rotation = row.line.rotation;
|
|
619
|
+
text.widthFactor = choice.autoWidth
|
|
620
|
+
? acapPdfFitWidthFactor(1, row.line.width, measure === null || measure === void 0 ? void 0 : measure(text.textString, choice.font, height, choice.bigFont))
|
|
621
|
+
: choice.widthFactor;
|
|
622
|
+
return text;
|
|
623
|
+
};
|
|
624
|
+
/**
|
|
625
|
+
* Builds the entity of a row: an MTEXT for a merged row, a TEXT otherwise.
|
|
626
|
+
*
|
|
627
|
+
* @param row - The row.
|
|
628
|
+
* @param measure - Measures natural text width for the width auto-fit.
|
|
629
|
+
*/
|
|
630
|
+
AcApPdfTextSession.prototype.createEntity = function (row, measure) {
|
|
631
|
+
return row.merge
|
|
632
|
+
? this.createMText(row, row.merge, measure)
|
|
633
|
+
: this.createText(row, measure);
|
|
634
|
+
};
|
|
635
|
+
/**
|
|
636
|
+
* Builds the MTEXT of a merged row: one paragraph per line, exact line
|
|
637
|
+
* spacing as measured, no word wrap. With width auto-fit each paragraph
|
|
638
|
+
* gets the `\W` width factor that makes it span its original width.
|
|
639
|
+
*
|
|
640
|
+
* It is attached bottom-left at the lowest ink of its last line, like a
|
|
641
|
+
* TEXT at its baseline. The viewer anchors MTEXT on the drawn glyphs, so
|
|
642
|
+
* this keeps the text where it was even when the glyphs are shorter than
|
|
643
|
+
* the cap height (a top-left anchor at the cap height moved such text
|
|
644
|
+
* down); for capitals and CJK the ink bottom also is the baseline.
|
|
645
|
+
*/
|
|
646
|
+
AcApPdfTextSession.prototype.createMText = function (row, merge, measure) {
|
|
647
|
+
var choice = this.choices.get(row.kind);
|
|
648
|
+
var height = row.line.height * choice.heightScale;
|
|
649
|
+
var angle = row.line.rotation;
|
|
650
|
+
var last = merge.paragraphs[merge.paragraphs.length - 1];
|
|
651
|
+
var minU = Math.min.apply(Math, __spreadArray([], __read(merge.paragraphs.map(function (item) { return item.minU; })), false));
|
|
652
|
+
var lines = row.text.replace(/\s+$/, '').split('\n');
|
|
653
|
+
// Paragraph widths only match while the lines are the merged ones.
|
|
654
|
+
var widths = lines.length === merge.paragraphs.length
|
|
655
|
+
? merge.paragraphs.map(function (item) { return item.maxU - item.minU; })
|
|
656
|
+
: lines.map(function () { return row.line.width; });
|
|
657
|
+
var contents = lines.map(function (line, i) {
|
|
658
|
+
var text = line.trim();
|
|
659
|
+
var factor = choice.autoWidth
|
|
660
|
+
? acapPdfFitWidthFactor(1, widths[i], text
|
|
661
|
+
? measure === null || measure === void 0 ? void 0 : measure(text, choice.font, height, choice.bigFont)
|
|
662
|
+
: undefined)
|
|
663
|
+
: choice.widthFactor;
|
|
664
|
+
var escaped = mtextEscape(text);
|
|
665
|
+
return Math.abs(factor - 1) < 0.005 || !escaped
|
|
666
|
+
? escaped
|
|
667
|
+
: "{\\W".concat(Number(factor.toFixed(3)), ";").concat(escaped, "}");
|
|
668
|
+
});
|
|
669
|
+
var mtext = new AcDbMText();
|
|
670
|
+
mtext.contents = contents.join('\\P');
|
|
671
|
+
mtext.styleName = choice.styleName;
|
|
672
|
+
mtext.height = height;
|
|
673
|
+
mtext.width = 0;
|
|
674
|
+
mtext.rotation = angle;
|
|
675
|
+
mtext.attachmentPoint = AcGiMTextAttachmentPoint.BottomLeft;
|
|
676
|
+
mtext.location = toWorld(minU, last.bottom, angle);
|
|
677
|
+
if (lines.length > 1) {
|
|
678
|
+
// AutoCAD single spacing is 5/3 of the text height; "exactly" keeps
|
|
679
|
+
// the measured spacing regardless of the characters.
|
|
680
|
+
var spacing = merge.lineSpacing || (height * 5) / 3;
|
|
681
|
+
mtext.lineSpacingStyle = 2;
|
|
682
|
+
mtext.lineSpacingFactor = spacing / ((height * 5) / 3);
|
|
683
|
+
}
|
|
684
|
+
return mtext;
|
|
685
|
+
};
|
|
686
|
+
/**
|
|
687
|
+
* Default for a kind: the current style when it already draws with that
|
|
688
|
+
* engine, else the `PDF_SHX` / `PDF_simsun` style (created if missing).
|
|
689
|
+
*/
|
|
690
|
+
AcApPdfTextSession.prototype.defaultChoice = function (kind) {
|
|
691
|
+
var _a;
|
|
692
|
+
var table = this.db.tables.textStyleTable;
|
|
693
|
+
var current = table.resolveAt(this.db.textstyle);
|
|
694
|
+
var name = current && this.fontKind(current.fileName) === kind
|
|
695
|
+
? current.name
|
|
696
|
+
: kind === 'shx'
|
|
697
|
+
? PDF_SHX_TEXT_STYLE
|
|
698
|
+
: PDF_MESH_TEXT_STYLE;
|
|
699
|
+
var record = table.getAt(name);
|
|
700
|
+
return {
|
|
701
|
+
styleName: (_a = record === null || record === void 0 ? void 0 : record.name) !== null && _a !== void 0 ? _a : name,
|
|
702
|
+
isNew: !record,
|
|
703
|
+
font: record
|
|
704
|
+
? record.fileName
|
|
705
|
+
: kind === 'shx'
|
|
706
|
+
? PDF_SHX_FONT
|
|
707
|
+
: PDF_MESH_FONT,
|
|
708
|
+
bigFont: record
|
|
709
|
+
? record.bigFontFileName
|
|
710
|
+
: kind === 'shx'
|
|
711
|
+
? PDF_SHX_BIG_FONT
|
|
712
|
+
: '',
|
|
713
|
+
heightScale: 1,
|
|
714
|
+
autoWidth: true,
|
|
715
|
+
widthFactor: 1
|
|
716
|
+
};
|
|
717
|
+
};
|
|
718
|
+
/** An existing style record not created by this session. */
|
|
719
|
+
AcApPdfTextSession.prototype.originalRecord = function (name) {
|
|
720
|
+
if (this.created.has(name))
|
|
721
|
+
return undefined;
|
|
722
|
+
return this.db.tables.textStyleTable.getAt(name);
|
|
723
|
+
};
|
|
724
|
+
return AcApPdfTextSession;
|
|
725
|
+
}());
|
|
726
|
+
export { AcApPdfTextSession };
|
|
727
|
+
/**
|
|
728
|
+
* Reads a row from known glyphs: a merged block line by line, everything
|
|
729
|
+
* else as one line.
|
|
730
|
+
*/
|
|
731
|
+
function lookupRow(row, lookup, measure) {
|
|
732
|
+
var merge = row.merge;
|
|
733
|
+
if (!merge || merge.paragraphs.length === 1)
|
|
734
|
+
return lookup(row.line);
|
|
735
|
+
var texts = merge.parts.map(function (part) { return lookupRow(part, lookup, measure); });
|
|
736
|
+
if (texts.some(function (text) { return !text; }))
|
|
737
|
+
return undefined;
|
|
738
|
+
return mergePdfTextLines(merge.parts.map(function (part, i) { return ({ line: part.line, text: texts[i] }); }), { measure: measure }).text;
|
|
739
|
+
}
|
|
740
|
+
/** Kind of most glyphs (a single glyph is often misdetected). */
|
|
741
|
+
function majorityKind(rows) {
|
|
742
|
+
var e_10, _a;
|
|
743
|
+
var shx = 0;
|
|
744
|
+
var mesh = 0;
|
|
745
|
+
try {
|
|
746
|
+
for (var rows_1 = __values(rows), rows_1_1 = rows_1.next(); !rows_1_1.done; rows_1_1 = rows_1.next()) {
|
|
747
|
+
var row = rows_1_1.value;
|
|
748
|
+
var weight = Math.max(1, row.line.glyphs.length);
|
|
749
|
+
if (row.kind === 'shx')
|
|
750
|
+
shx += weight;
|
|
751
|
+
else
|
|
752
|
+
mesh += weight;
|
|
753
|
+
}
|
|
754
|
+
}
|
|
755
|
+
catch (e_10_1) { e_10 = { error: e_10_1 }; }
|
|
756
|
+
finally {
|
|
757
|
+
try {
|
|
758
|
+
if (rows_1_1 && !rows_1_1.done && (_a = rows_1.return)) _a.call(rows_1);
|
|
759
|
+
}
|
|
760
|
+
finally { if (e_10) throw e_10.error; }
|
|
761
|
+
}
|
|
762
|
+
return mesh > shx ? 'mesh' : 'shx';
|
|
763
|
+
}
|
|
764
|
+
/** Axis-aligned world box of a line's strokes. */
|
|
765
|
+
function worldBox(line) {
|
|
766
|
+
var e_11, _a, e_12, _b;
|
|
767
|
+
var minX = Infinity;
|
|
768
|
+
var minY = Infinity;
|
|
769
|
+
var maxX = -Infinity;
|
|
770
|
+
var maxY = -Infinity;
|
|
771
|
+
try {
|
|
772
|
+
for (var _c = __values(line.strokes), _d = _c.next(); !_d.done; _d = _c.next()) {
|
|
773
|
+
var stroke = _d.value;
|
|
774
|
+
try {
|
|
775
|
+
for (var _e = (e_12 = void 0, __values(stroke.points)), _f = _e.next(); !_f.done; _f = _e.next()) {
|
|
776
|
+
var p = _f.value;
|
|
777
|
+
minX = Math.min(minX, p.x);
|
|
778
|
+
minY = Math.min(minY, p.y);
|
|
779
|
+
maxX = Math.max(maxX, p.x);
|
|
780
|
+
maxY = Math.max(maxY, p.y);
|
|
781
|
+
}
|
|
782
|
+
}
|
|
783
|
+
catch (e_12_1) { e_12 = { error: e_12_1 }; }
|
|
784
|
+
finally {
|
|
785
|
+
try {
|
|
786
|
+
if (_f && !_f.done && (_b = _e.return)) _b.call(_e);
|
|
787
|
+
}
|
|
788
|
+
finally { if (e_12) throw e_12.error; }
|
|
789
|
+
}
|
|
790
|
+
}
|
|
791
|
+
}
|
|
792
|
+
catch (e_11_1) { e_11 = { error: e_11_1 }; }
|
|
793
|
+
finally {
|
|
794
|
+
try {
|
|
795
|
+
if (_d && !_d.done && (_a = _c.return)) _a.call(_c);
|
|
796
|
+
}
|
|
797
|
+
finally { if (e_11) throw e_11.error; }
|
|
798
|
+
}
|
|
799
|
+
return { minX: minX, minY: minY, maxX: maxX, maxY: maxY };
|
|
800
|
+
}
|
|
801
|
+
/** MTEXT contents for plain text: escapes backslashes and braces. */
|
|
802
|
+
function mtextEscape(text) {
|
|
803
|
+
return text.replace(/[\\{}]/g, function (char) { return "\\".concat(char); });
|
|
804
|
+
}
|
|
805
|
+
function toWorld(u, v, angle) {
|
|
806
|
+
var c = Math.cos(angle);
|
|
807
|
+
var s = Math.sin(angle);
|
|
808
|
+
return new AcGePoint3d(u * c - v * s, u * s + v * c, 0);
|
|
809
|
+
}
|
|
810
|
+
function sameName(a, b) {
|
|
811
|
+
return a.trim().toLowerCase() === b.trim().toLowerCase();
|
|
812
|
+
}
|
|
813
|
+
function createStyleRecord(name, fonts) {
|
|
814
|
+
return new AcDbTextStyleTableRecord({
|
|
815
|
+
name: name,
|
|
816
|
+
standardFlag: 0,
|
|
817
|
+
fixedTextHeight: 0,
|
|
818
|
+
widthFactor: 1,
|
|
819
|
+
obliqueAngle: 0,
|
|
820
|
+
textGenerationFlag: 0,
|
|
821
|
+
lastHeight: 2.5,
|
|
822
|
+
font: fonts.font,
|
|
823
|
+
bigFont: fonts.bigFont
|
|
824
|
+
});
|
|
825
|
+
}
|
|
826
|
+
//# sourceMappingURL=AcApPdfTextSession.js.map
|