@itwin/core-backend 5.2.0-dev.8 → 5.3.0-dev.1
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/CHANGELOG.md +31 -1
- package/lib/cjs/BackendHubAccess.d.ts +2 -0
- package/lib/cjs/BackendHubAccess.d.ts.map +1 -1
- package/lib/cjs/BackendHubAccess.js.map +1 -1
- package/lib/cjs/BackendLoggerCategory.d.ts +6 -0
- package/lib/cjs/BackendLoggerCategory.d.ts.map +1 -1
- package/lib/cjs/BackendLoggerCategory.js +6 -0
- package/lib/cjs/BackendLoggerCategory.js.map +1 -1
- package/lib/cjs/BriefcaseManager.d.ts +57 -3
- package/lib/cjs/BriefcaseManager.d.ts.map +1 -1
- package/lib/cjs/BriefcaseManager.js +151 -42
- package/lib/cjs/BriefcaseManager.js.map +1 -1
- package/lib/cjs/CloudSqlite.d.ts +4 -0
- package/lib/cjs/CloudSqlite.d.ts.map +1 -1
- package/lib/cjs/CloudSqlite.js.map +1 -1
- package/lib/cjs/ECDb.d.ts +8 -0
- package/lib/cjs/ECDb.d.ts.map +1 -1
- package/lib/cjs/ECDb.js +22 -0
- package/lib/cjs/ECDb.js.map +1 -1
- package/lib/cjs/IModelDb.d.ts +54 -3
- package/lib/cjs/IModelDb.d.ts.map +1 -1
- package/lib/cjs/IModelDb.js +87 -9
- package/lib/cjs/IModelDb.js.map +1 -1
- package/lib/cjs/IModelHost.d.ts +11 -1
- package/lib/cjs/IModelHost.d.ts.map +1 -1
- package/lib/cjs/IModelHost.js +5 -0
- package/lib/cjs/IModelHost.js.map +1 -1
- package/lib/cjs/IModelIncrementalSchemaLocater.d.ts +1 -5
- package/lib/cjs/IModelIncrementalSchemaLocater.d.ts.map +1 -1
- package/lib/cjs/IModelIncrementalSchemaLocater.js +0 -6
- package/lib/cjs/IModelIncrementalSchemaLocater.js.map +1 -1
- package/lib/cjs/SqliteChangesetReader.d.ts +8 -0
- package/lib/cjs/SqliteChangesetReader.d.ts.map +1 -1
- package/lib/cjs/SqliteChangesetReader.js +11 -0
- package/lib/cjs/SqliteChangesetReader.js.map +1 -1
- package/lib/cjs/StashManager.d.ts +175 -0
- package/lib/cjs/StashManager.d.ts.map +1 -0
- package/lib/cjs/StashManager.js +306 -0
- package/lib/cjs/StashManager.js.map +1 -0
- package/lib/cjs/TxnManager.d.ts +226 -15
- package/lib/cjs/TxnManager.d.ts.map +1 -1
- package/lib/cjs/TxnManager.js +249 -23
- package/lib/cjs/TxnManager.js.map +1 -1
- package/lib/cjs/annotations/ElementDrivesTextAnnotation.d.ts +10 -1
- package/lib/cjs/annotations/ElementDrivesTextAnnotation.d.ts.map +1 -1
- package/lib/cjs/annotations/ElementDrivesTextAnnotation.js +15 -6
- package/lib/cjs/annotations/ElementDrivesTextAnnotation.js.map +1 -1
- package/lib/cjs/annotations/LeaderGeometry.d.ts +3 -2
- package/lib/cjs/annotations/LeaderGeometry.d.ts.map +1 -1
- package/lib/cjs/annotations/LeaderGeometry.js +5 -4
- package/lib/cjs/annotations/LeaderGeometry.js.map +1 -1
- package/lib/cjs/annotations/TextAnnotationElement.d.ts +52 -24
- package/lib/cjs/annotations/TextAnnotationElement.d.ts.map +1 -1
- package/lib/cjs/annotations/TextAnnotationElement.js +49 -59
- package/lib/cjs/annotations/TextAnnotationElement.js.map +1 -1
- package/lib/cjs/annotations/TextAnnotationGeometry.d.ts +2 -0
- package/lib/cjs/annotations/TextAnnotationGeometry.d.ts.map +1 -1
- package/lib/cjs/annotations/TextAnnotationGeometry.js +26 -19
- package/lib/cjs/annotations/TextAnnotationGeometry.js.map +1 -1
- package/lib/cjs/annotations/TextBlockGeometry.d.ts.map +1 -1
- package/lib/cjs/annotations/TextBlockGeometry.js +8 -0
- package/lib/cjs/annotations/TextBlockGeometry.js.map +1 -1
- package/lib/cjs/annotations/TextBlockLayout.d.ts +49 -36
- package/lib/cjs/annotations/TextBlockLayout.d.ts.map +1 -1
- package/lib/cjs/annotations/TextBlockLayout.js +204 -135
- package/lib/cjs/annotations/TextBlockLayout.js.map +1 -1
- package/lib/cjs/internal/ChannelAdmin.js +1 -1
- package/lib/cjs/internal/ChannelAdmin.js.map +1 -1
- package/lib/cjs/internal/Symbols.d.ts +1 -0
- package/lib/cjs/internal/Symbols.d.ts.map +1 -1
- package/lib/cjs/internal/Symbols.js +2 -1
- package/lib/cjs/internal/Symbols.js.map +1 -1
- package/lib/cjs/internal/annotations/fields.d.ts +2 -12
- package/lib/cjs/internal/annotations/fields.d.ts.map +1 -1
- package/lib/cjs/internal/annotations/fields.js +49 -45
- package/lib/cjs/internal/annotations/fields.js.map +1 -1
- package/lib/cjs/workspace/Workspace.d.ts +1 -1
- package/lib/cjs/workspace/Workspace.js.map +1 -1
- package/lib/esm/BackendHubAccess.d.ts +2 -0
- package/lib/esm/BackendHubAccess.d.ts.map +1 -1
- package/lib/esm/BackendHubAccess.js.map +1 -1
- package/lib/esm/BackendLoggerCategory.d.ts +6 -0
- package/lib/esm/BackendLoggerCategory.d.ts.map +1 -1
- package/lib/esm/BackendLoggerCategory.js +6 -0
- package/lib/esm/BackendLoggerCategory.js.map +1 -1
- package/lib/esm/BriefcaseManager.d.ts +57 -3
- package/lib/esm/BriefcaseManager.d.ts.map +1 -1
- package/lib/esm/BriefcaseManager.js +152 -43
- package/lib/esm/BriefcaseManager.js.map +1 -1
- package/lib/esm/CloudSqlite.d.ts +4 -0
- package/lib/esm/CloudSqlite.d.ts.map +1 -1
- package/lib/esm/CloudSqlite.js.map +1 -1
- package/lib/esm/ECDb.d.ts +8 -0
- package/lib/esm/ECDb.d.ts.map +1 -1
- package/lib/esm/ECDb.js +22 -0
- package/lib/esm/ECDb.js.map +1 -1
- package/lib/esm/IModelDb.d.ts +54 -3
- package/lib/esm/IModelDb.d.ts.map +1 -1
- package/lib/esm/IModelDb.js +88 -10
- package/lib/esm/IModelDb.js.map +1 -1
- package/lib/esm/IModelHost.d.ts +11 -1
- package/lib/esm/IModelHost.d.ts.map +1 -1
- package/lib/esm/IModelHost.js +5 -0
- package/lib/esm/IModelHost.js.map +1 -1
- package/lib/esm/IModelIncrementalSchemaLocater.d.ts +1 -5
- package/lib/esm/IModelIncrementalSchemaLocater.d.ts.map +1 -1
- package/lib/esm/IModelIncrementalSchemaLocater.js +0 -6
- package/lib/esm/IModelIncrementalSchemaLocater.js.map +1 -1
- package/lib/esm/SqliteChangesetReader.d.ts +8 -0
- package/lib/esm/SqliteChangesetReader.d.ts.map +1 -1
- package/lib/esm/SqliteChangesetReader.js +11 -0
- package/lib/esm/SqliteChangesetReader.js.map +1 -1
- package/lib/esm/StashManager.d.ts +175 -0
- package/lib/esm/StashManager.d.ts.map +1 -0
- package/lib/esm/StashManager.js +301 -0
- package/lib/esm/StashManager.js.map +1 -0
- package/lib/esm/TxnManager.d.ts +226 -15
- package/lib/esm/TxnManager.d.ts.map +1 -1
- package/lib/esm/TxnManager.js +247 -21
- package/lib/esm/TxnManager.js.map +1 -1
- package/lib/esm/annotations/ElementDrivesTextAnnotation.d.ts +10 -1
- package/lib/esm/annotations/ElementDrivesTextAnnotation.d.ts.map +1 -1
- package/lib/esm/annotations/ElementDrivesTextAnnotation.js +13 -5
- package/lib/esm/annotations/ElementDrivesTextAnnotation.js.map +1 -1
- package/lib/esm/annotations/LeaderGeometry.d.ts +3 -2
- package/lib/esm/annotations/LeaderGeometry.d.ts.map +1 -1
- package/lib/esm/annotations/LeaderGeometry.js +5 -4
- package/lib/esm/annotations/LeaderGeometry.js.map +1 -1
- package/lib/esm/annotations/TextAnnotationElement.d.ts +52 -24
- package/lib/esm/annotations/TextAnnotationElement.d.ts.map +1 -1
- package/lib/esm/annotations/TextAnnotationElement.js +51 -61
- package/lib/esm/annotations/TextAnnotationElement.js.map +1 -1
- package/lib/esm/annotations/TextAnnotationGeometry.d.ts +2 -0
- package/lib/esm/annotations/TextAnnotationGeometry.d.ts.map +1 -1
- package/lib/esm/annotations/TextAnnotationGeometry.js +26 -19
- package/lib/esm/annotations/TextAnnotationGeometry.js.map +1 -1
- package/lib/esm/annotations/TextBlockGeometry.d.ts.map +1 -1
- package/lib/esm/annotations/TextBlockGeometry.js +8 -0
- package/lib/esm/annotations/TextBlockGeometry.js.map +1 -1
- package/lib/esm/annotations/TextBlockLayout.d.ts +49 -36
- package/lib/esm/annotations/TextBlockLayout.d.ts.map +1 -1
- package/lib/esm/annotations/TextBlockLayout.js +205 -136
- package/lib/esm/annotations/TextBlockLayout.js.map +1 -1
- package/lib/esm/internal/ChannelAdmin.js +1 -1
- package/lib/esm/internal/ChannelAdmin.js.map +1 -1
- package/lib/esm/internal/Symbols.d.ts +1 -0
- package/lib/esm/internal/Symbols.d.ts.map +1 -1
- package/lib/esm/internal/Symbols.js +1 -0
- package/lib/esm/internal/Symbols.js.map +1 -1
- package/lib/esm/internal/annotations/fields.d.ts +2 -12
- package/lib/esm/internal/annotations/fields.d.ts.map +1 -1
- package/lib/esm/internal/annotations/fields.js +51 -47
- package/lib/esm/internal/annotations/fields.js.map +1 -1
- package/lib/esm/test/AnnotationTestUtils.d.ts +5 -1
- package/lib/esm/test/AnnotationTestUtils.d.ts.map +1 -1
- package/lib/esm/test/AnnotationTestUtils.js +6 -1
- package/lib/esm/test/AnnotationTestUtils.js.map +1 -1
- package/lib/esm/test/annotations/Fields.test.js +163 -46
- package/lib/esm/test/annotations/Fields.test.js.map +1 -1
- package/lib/esm/test/annotations/LeaderGeometry.test.js +12 -10
- package/lib/esm/test/annotations/LeaderGeometry.test.js.map +1 -1
- package/lib/esm/test/annotations/TextAnnotation.test.js +299 -43
- package/lib/esm/test/annotations/TextAnnotation.test.js.map +1 -1
- package/lib/esm/test/annotations/TextBlock.test.js +453 -86
- package/lib/esm/test/annotations/TextBlock.test.js.map +1 -1
- package/lib/esm/test/assets/IncrementalSchemaLocater/configs/simple.config.d.ts +46 -0
- package/lib/esm/test/assets/IncrementalSchemaLocater/configs/simple.config.d.ts.map +1 -1
- package/lib/esm/test/assets/IncrementalSchemaLocater/configs/simple.config.js +20 -2
- package/lib/esm/test/assets/IncrementalSchemaLocater/configs/simple.config.js.map +1 -1
- package/lib/esm/test/ecdb/ECDb.test.js +71 -1
- package/lib/esm/test/ecdb/ECDb.test.js.map +1 -1
- package/lib/esm/test/hubaccess/Rebase.test.d.ts +2 -0
- package/lib/esm/test/hubaccess/Rebase.test.d.ts.map +1 -0
- package/lib/esm/test/hubaccess/Rebase.test.js +640 -0
- package/lib/esm/test/hubaccess/Rebase.test.js.map +1 -0
- package/lib/esm/test/incrementalSchemaLocater/ECSqlQueries.test.js +20 -20
- package/lib/esm/test/incrementalSchemaLocater/ECSqlQueries.test.js.map +1 -1
- package/lib/esm/test/incrementalSchemaLocater/IncrementalLoading.test.js +3 -3
- package/lib/esm/test/incrementalSchemaLocater/IncrementalLoading.test.js.map +1 -1
- package/lib/esm/test/incrementalSchemaLocater/utils/TestSqlSchemaLocater.d.ts +16 -1
- package/lib/esm/test/incrementalSchemaLocater/utils/TestSqlSchemaLocater.d.ts.map +1 -1
- package/lib/esm/test/incrementalSchemaLocater/utils/TestSqlSchemaLocater.js +47 -0
- package/lib/esm/test/incrementalSchemaLocater/utils/TestSqlSchemaLocater.js.map +1 -1
- package/lib/esm/test/standalone/ChangeMerge.test.js +15 -19
- package/lib/esm/test/standalone/ChangeMerge.test.js.map +1 -1
- package/lib/esm/test/standalone/ChangesetReader.test.js +131 -1
- package/lib/esm/test/standalone/ChangesetReader.test.js.map +1 -1
- package/lib/esm/test/standalone/MergeConflict.test.js +3 -3
- package/lib/esm/test/standalone/MergeConflict.test.js.map +1 -1
- package/lib/esm/workspace/Workspace.d.ts +1 -1
- package/lib/esm/workspace/Workspace.js.map +1 -1
- package/package.json +13 -13
|
@@ -16,7 +16,6 @@ const core_geometry_1 = require("@itwin/core-geometry");
|
|
|
16
16
|
const core_bentley_1 = require("@itwin/core-bentley");
|
|
17
17
|
const LineBreaker = require("linebreak");
|
|
18
18
|
const TextAnnotationElement_1 = require("./TextAnnotationElement");
|
|
19
|
-
const Element_1 = require("../Element");
|
|
20
19
|
/** @internal */
|
|
21
20
|
function createFindTextStyleImpl(iModel) {
|
|
22
21
|
return function findTextStyleImpl(id) {
|
|
@@ -60,11 +59,10 @@ function computeLayoutTextBlockResult(args) {
|
|
|
60
59
|
* @beta
|
|
61
60
|
*/
|
|
62
61
|
function computeGraphemeOffsets(args) {
|
|
63
|
-
const {
|
|
62
|
+
const { source, runLayoutResult, graphemeCharIndexes, iModel } = args;
|
|
64
63
|
const findFontId = args.findFontId ?? ((name, type) => iModel.fonts.findId({ name, type }) ?? 0);
|
|
65
64
|
const computeTextRange = args.computeTextRange ?? ((x) => iModel.computeRangesForText(x));
|
|
66
|
-
|
|
67
|
-
if (source.type !== "text" || runLayoutResult.characterCount === 0) {
|
|
65
|
+
if (!(source instanceof core_common_1.TextRun) || runLayoutResult.characterCount === 0) {
|
|
68
66
|
return [];
|
|
69
67
|
}
|
|
70
68
|
const style = core_common_1.TextStyleSettings.fromJSON(runLayoutResult.textStyle);
|
|
@@ -116,59 +114,39 @@ function applyBlockSettings(target, source, isLeader = false) {
|
|
|
116
114
|
return target;
|
|
117
115
|
}
|
|
118
116
|
/**
|
|
119
|
-
* Resolves the effective style of TextBlockComponents and Leaders, taking into account overrides
|
|
117
|
+
* Resolves the effective style of TextBlockComponents and Leaders, taking into account overrides of the instance and its parent(s).
|
|
120
118
|
* @beta
|
|
121
119
|
*/
|
|
122
120
|
class TextStyleResolver {
|
|
123
|
-
_textStyles = new Map();
|
|
124
|
-
_findTextStyle;
|
|
125
121
|
/** The resolved style of the TextBlock. */
|
|
126
122
|
blockSettings;
|
|
127
|
-
/** The scale factor of the model containing the TextBlock. */
|
|
128
|
-
scaleFactor;
|
|
129
123
|
constructor(args) {
|
|
130
|
-
|
|
131
|
-
this.
|
|
132
|
-
if (args.modelId) {
|
|
133
|
-
const element = args.iModel.elements.getElement(args.modelId);
|
|
134
|
-
if (element instanceof Element_1.Drawing)
|
|
135
|
-
this.scaleFactor = element.scaleFactor;
|
|
136
|
-
}
|
|
137
|
-
this.blockSettings = this.findTextStyle(args.textBlock.styleId);
|
|
124
|
+
const findTextStyle = args.findTextStyle ?? createFindTextStyleImpl(args.iModel);
|
|
125
|
+
this.blockSettings = findTextStyle(args.textStyleId);
|
|
138
126
|
if (args.textBlock.styleOverrides)
|
|
139
127
|
this.blockSettings = this.blockSettings.clone(args.textBlock.styleOverrides);
|
|
140
128
|
}
|
|
141
|
-
|
|
129
|
+
/**
|
|
130
|
+
* Resolves the effective text style settings for a given TextBlockComponent, applying block-level overrides.
|
|
131
|
+
*/
|
|
132
|
+
resolveSettings(overrides, isLeader = false) {
|
|
142
133
|
let settings = this.blockSettings;
|
|
143
|
-
if (
|
|
144
|
-
settings = settings.clone(
|
|
145
|
-
return settings;
|
|
146
|
-
}
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
settings = settings.clone(leader.styleOverrides);
|
|
160
|
-
return applyBlockSettings(settings, this.blockSettings, true);
|
|
161
|
-
}
|
|
162
|
-
/** Resolves the effective style for a [Paragraph]($common). Paragraph should be child of provided TextBlock. */
|
|
163
|
-
resolveParagraphSettings(paragraph) {
|
|
164
|
-
return applyBlockSettings(this.resolveParagraphSettingsImpl(paragraph), this.blockSettings);
|
|
165
|
-
}
|
|
166
|
-
/** Resolves the effective style for a [Run]($common). Run should be child of provided Paragraph and TextBlock. */
|
|
167
|
-
resolveRunSettings(paragraph, run) {
|
|
168
|
-
let settings = this.resolveParagraphSettingsImpl(paragraph);
|
|
169
|
-
if (run.overridesStyle)
|
|
170
|
-
settings = settings.clone(run.styleOverrides);
|
|
171
|
-
return applyBlockSettings(settings, this.blockSettings);
|
|
134
|
+
if (overrides)
|
|
135
|
+
settings = settings.clone(overrides);
|
|
136
|
+
return applyBlockSettings(settings, this.blockSettings, isLeader);
|
|
137
|
+
}
|
|
138
|
+
resolveMarkerText(overrides, index) {
|
|
139
|
+
const markerSettings = overrides.listMarker ?? this.blockSettings.listMarker;
|
|
140
|
+
return (0, core_common_1.getMarkerText)(markerSettings, index);
|
|
141
|
+
}
|
|
142
|
+
/**
|
|
143
|
+
* Computes the indentation based on its style and nesting depth.
|
|
144
|
+
*/
|
|
145
|
+
resolveIndentation(styleOverrides, depth) {
|
|
146
|
+
const overrides = this.resolveSettings(styleOverrides);
|
|
147
|
+
const indentation = overrides.indentation;
|
|
148
|
+
const tabInterval = overrides.tabInterval;
|
|
149
|
+
return indentation + tabInterval * depth;
|
|
172
150
|
}
|
|
173
151
|
}
|
|
174
152
|
exports.TextStyleResolver = TextStyleResolver;
|
|
@@ -259,9 +237,9 @@ class LayoutContext {
|
|
|
259
237
|
layout.extendRange(denominator);
|
|
260
238
|
return { layout, numerator, denominator };
|
|
261
239
|
}
|
|
262
|
-
computeRangeForTabRun(style, source,
|
|
240
|
+
computeRangeForTabRun(style, source, lengthFromLastTab) {
|
|
263
241
|
const interval = source.styleOverrides.tabInterval ?? style.tabInterval;
|
|
264
|
-
const tabEndX = interval -
|
|
242
|
+
const tabEndX = interval - lengthFromLastTab % interval;
|
|
265
243
|
const range = new core_geometry_1.Range2d(0, 0, 0, style.lineHeight);
|
|
266
244
|
range.extendXY(tabEndX, range.low.y);
|
|
267
245
|
return range;
|
|
@@ -317,8 +295,8 @@ class RunLayout {
|
|
|
317
295
|
this.style = props.style;
|
|
318
296
|
this.fontId = props.fontId;
|
|
319
297
|
}
|
|
320
|
-
static create(source,
|
|
321
|
-
const style = context.textStyleResolver.
|
|
298
|
+
static create(source, context, cumulativeOverrides) {
|
|
299
|
+
const style = context.textStyleResolver.resolveSettings(cumulativeOverrides);
|
|
322
300
|
const fontId = context.findFontId(style.fontName);
|
|
323
301
|
const charOffset = 0;
|
|
324
302
|
const offsetFromLine = { x: 0, y: 0 };
|
|
@@ -387,9 +365,8 @@ class RunLayout {
|
|
|
387
365
|
});
|
|
388
366
|
});
|
|
389
367
|
}
|
|
390
|
-
toResult(
|
|
368
|
+
toResult() {
|
|
391
369
|
const result = {
|
|
392
|
-
sourceRunIndex: paragraph.runs.indexOf(this.source),
|
|
393
370
|
fontId: this.fontId,
|
|
394
371
|
characterOffset: this.charOffset,
|
|
395
372
|
characterCount: this.numChars,
|
|
@@ -419,32 +396,47 @@ exports.RunLayout = RunLayout;
|
|
|
419
396
|
class LineLayout {
|
|
420
397
|
source;
|
|
421
398
|
range = new core_geometry_1.Range2d(0, 0, 0, 0);
|
|
399
|
+
runRange = new core_geometry_1.Range2d(0, 0, 0, 0); // Range of all runs excluding marker.
|
|
422
400
|
justificationRange = new core_geometry_1.Range2d(0, 0, 0, 0);
|
|
423
|
-
offsetFromDocument
|
|
401
|
+
offsetFromDocument;
|
|
402
|
+
depth;
|
|
424
403
|
lengthFromLastTab = 0; // Used to track the length from the last tab for tab runs.
|
|
425
404
|
_runs = [];
|
|
426
|
-
|
|
405
|
+
_marker;
|
|
406
|
+
constructor(source, style, context, depth = 0) {
|
|
427
407
|
this.source = source;
|
|
408
|
+
this.depth = depth;
|
|
409
|
+
this.offsetFromDocument = { x: context?.textStyleResolver.resolveIndentation(style, depth) ?? 0, y: 0 };
|
|
428
410
|
}
|
|
429
411
|
/** Compute a string representation, primarily for debugging purposes. */
|
|
430
412
|
stringify() {
|
|
431
413
|
const runs = this._runs.map((run) => run.stringify());
|
|
432
414
|
return `${runs.join("")}`;
|
|
433
415
|
}
|
|
416
|
+
/** Gets the array of RunLayout objects contained in this line. */
|
|
434
417
|
get runs() { return this._runs; }
|
|
418
|
+
/** Indicates whether this line contains any runs. */
|
|
435
419
|
get isEmpty() { return this._runs.length === 0; }
|
|
420
|
+
/** Gets the last RunLayout in this line. */
|
|
436
421
|
get back() {
|
|
437
422
|
(0, core_bentley_1.assert)(!this.isEmpty);
|
|
438
423
|
return this._runs[this._runs.length - 1];
|
|
439
424
|
}
|
|
425
|
+
/**
|
|
426
|
+
* Gets or sets the marker RunLayout for this line, used for lists.
|
|
427
|
+
* A marker is the symbol or character that appears before each list item in a list, bullets, numbers, etc.
|
|
428
|
+
* */
|
|
429
|
+
get marker() { return this._marker; }
|
|
430
|
+
set marker(value) { this._marker = value; }
|
|
440
431
|
append(run) {
|
|
441
432
|
this._runs.push(run);
|
|
442
433
|
this.computeRanges();
|
|
443
434
|
}
|
|
444
435
|
/** Invoked every time a run is appended,. */
|
|
445
436
|
computeRanges() {
|
|
446
|
-
this.
|
|
447
|
-
this.
|
|
437
|
+
this.runRange.low.setZero();
|
|
438
|
+
this.runRange.high.setZero();
|
|
439
|
+
this.lengthFromLastTab = 0;
|
|
448
440
|
// Some runs (fractions) are taller than others.
|
|
449
441
|
// We want to center each run vertically inside the line.
|
|
450
442
|
let lineHeight = 0;
|
|
@@ -453,26 +445,39 @@ class LineLayout {
|
|
|
453
445
|
}
|
|
454
446
|
for (const run of this._runs) {
|
|
455
447
|
const runHeight = run.range.yLength();
|
|
456
|
-
const runOffset = { x: this.
|
|
448
|
+
const runOffset = { x: this.runRange.high.x, y: (lineHeight - runHeight) / 2 };
|
|
457
449
|
run.offsetFromLine = runOffset;
|
|
458
450
|
const runLayoutRange = run.range.cloneTranslated(runOffset);
|
|
459
|
-
this.
|
|
451
|
+
this.runRange.extendRange(runLayoutRange);
|
|
460
452
|
if ("linebreak" !== run.source.type) {
|
|
461
453
|
const runJustificationRange = run.justificationRange?.cloneTranslated(runOffset);
|
|
462
454
|
this.justificationRange.extendRange(runJustificationRange ?? runLayoutRange);
|
|
463
455
|
}
|
|
464
|
-
if (run.source.type
|
|
456
|
+
if ("tab" === run.source.type) {
|
|
465
457
|
this.lengthFromLastTab = 0;
|
|
466
458
|
}
|
|
467
459
|
else {
|
|
468
460
|
this.lengthFromLastTab += run.range.xLength();
|
|
469
461
|
}
|
|
470
462
|
}
|
|
463
|
+
this.range.setFrom(this.runRange);
|
|
464
|
+
if (this._marker) {
|
|
465
|
+
const indentation = this.range.low.x;
|
|
466
|
+
const x = indentation - (this._marker.style.tabInterval / 2) - this._marker.range.xLength();
|
|
467
|
+
const runHeight = this._marker.range.yLength();
|
|
468
|
+
const runOffset = {
|
|
469
|
+
x,
|
|
470
|
+
y: (lineHeight - runHeight) / 2 // Center the marker vertically in the line.
|
|
471
|
+
};
|
|
472
|
+
this._marker.offsetFromLine = runOffset;
|
|
473
|
+
const markerRange = this._marker.range.cloneTranslated(this._marker.offsetFromLine);
|
|
474
|
+
this.range.extendRange(markerRange);
|
|
475
|
+
}
|
|
471
476
|
}
|
|
472
|
-
toResult(
|
|
477
|
+
toResult() {
|
|
473
478
|
return {
|
|
474
|
-
|
|
475
|
-
|
|
479
|
+
runs: this.runs.map((x) => x.toResult()),
|
|
480
|
+
marker: this.marker?.toResult(),
|
|
476
481
|
range: this.range.toJSON(),
|
|
477
482
|
justificationRange: this.justificationRange.toJSON(),
|
|
478
483
|
offsetFromDocument: this.offsetFromDocument,
|
|
@@ -507,7 +512,7 @@ class TextBlockLayout {
|
|
|
507
512
|
}
|
|
508
513
|
toResult() {
|
|
509
514
|
return {
|
|
510
|
-
lines: this.lines.map((x) => x.toResult(
|
|
515
|
+
lines: this.lines.map((x) => x.toResult()),
|
|
511
516
|
range: this.range.toJSON(),
|
|
512
517
|
};
|
|
513
518
|
}
|
|
@@ -521,59 +526,151 @@ class TextBlockLayout {
|
|
|
521
526
|
}
|
|
522
527
|
populateLines(context) {
|
|
523
528
|
const doc = this.source;
|
|
524
|
-
if (doc.
|
|
529
|
+
if (!doc.children || doc.children.length === 0) {
|
|
525
530
|
return;
|
|
526
531
|
}
|
|
527
|
-
|
|
528
|
-
let
|
|
529
|
-
for (
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
532
|
+
let curLine = new LineLayout(doc.children[0], doc.children[0].styleOverrides, context);
|
|
533
|
+
let childIndex = 0;
|
|
534
|
+
for (const child of doc.children) {
|
|
535
|
+
curLine = this.populateComponent(child, childIndex++, context, doc.width, curLine, doc, doc.styleOverrides);
|
|
536
|
+
}
|
|
537
|
+
if (curLine.runs.length > 0) {
|
|
538
|
+
this.flushLine(context, curLine, doc.styleOverrides);
|
|
539
|
+
}
|
|
540
|
+
}
|
|
541
|
+
populateComponent(component, componentIndex, context, docWidth, curLine, parent, cumulativeOverrides, depth = 0) {
|
|
542
|
+
cumulativeOverrides = { ...cumulativeOverrides, ...component.styleOverrides };
|
|
543
|
+
switch (component.type) {
|
|
544
|
+
case "list": {
|
|
545
|
+
// If we have any runs in the current line, flush it before starting the list.
|
|
546
|
+
if (curLine.runs.length > 0) {
|
|
547
|
+
curLine = this.flushLine(context, curLine, cumulativeOverrides, component.children[0], true, depth + 1);
|
|
548
|
+
}
|
|
549
|
+
else {
|
|
550
|
+
// If not, we need to apply the indentation for the list to the first line.
|
|
551
|
+
curLine.offsetFromDocument.x = context.textStyleResolver.resolveIndentation(cumulativeOverrides, depth + 1);
|
|
552
|
+
curLine.depth = depth + 1;
|
|
543
553
|
}
|
|
544
|
-
//
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
curLine.
|
|
549
|
-
|
|
554
|
+
// Iterate through each list item, setting the marker and populating its contents.
|
|
555
|
+
component.children.forEach((child, index) => {
|
|
556
|
+
const markerContent = context.textStyleResolver.resolveMarkerText(cumulativeOverrides, index + 1);
|
|
557
|
+
const markerRun = core_common_1.TextRun.create({ content: markerContent });
|
|
558
|
+
curLine.marker = RunLayout.create(markerRun, context, cumulativeOverrides);
|
|
559
|
+
curLine = this.populateComponent(child, index, context, docWidth, curLine, component, cumulativeOverrides, depth + 1);
|
|
560
|
+
});
|
|
561
|
+
// Lastly flush the line.
|
|
562
|
+
const nextSibling = parent?.children[componentIndex + 1];
|
|
563
|
+
if (curLine && nextSibling) {
|
|
564
|
+
curLine = this.flushLine(context, curLine, cumulativeOverrides, nextSibling, true, depth);
|
|
550
565
|
}
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
//
|
|
555
|
-
|
|
556
|
-
curLine.
|
|
557
|
-
|
|
566
|
+
break;
|
|
567
|
+
}
|
|
568
|
+
case "paragraph": {
|
|
569
|
+
// Iterate through each paragraph child (either a list or a run), populating its contents.
|
|
570
|
+
component.children.forEach((child, index) => {
|
|
571
|
+
curLine = this.populateComponent(child, index, context, docWidth, curLine, component, cumulativeOverrides, depth);
|
|
572
|
+
});
|
|
573
|
+
// Lastly flush the line.
|
|
574
|
+
const nextSibling = parent?.children[componentIndex + 1];
|
|
575
|
+
if (curLine && nextSibling) {
|
|
576
|
+
curLine = this.flushLine(context, curLine, cumulativeOverrides, nextSibling, true, depth);
|
|
558
577
|
}
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
578
|
+
break;
|
|
579
|
+
}
|
|
580
|
+
case "text": {
|
|
581
|
+
const layout = RunLayout.create(component, context, cumulativeOverrides);
|
|
582
|
+
// Text can be word-wrapped, so we need to split it into multiple runs if necessary.
|
|
583
|
+
if (docWidth > 0) {
|
|
584
|
+
layout.split(context).forEach(r => { curLine = this.populateRun(curLine, r, context, cumulativeOverrides, docWidth); });
|
|
564
585
|
}
|
|
565
586
|
else {
|
|
566
|
-
|
|
567
|
-
curLine = this.flushLine(context, curLine);
|
|
568
|
-
// Recompute tab shift if applicable
|
|
569
|
-
applyTabShift(run, curLine, context);
|
|
570
|
-
curLine.append(run);
|
|
587
|
+
curLine = this.populateRun(curLine, layout, context, cumulativeOverrides, docWidth);
|
|
571
588
|
}
|
|
589
|
+
break;
|
|
590
|
+
}
|
|
591
|
+
case "fraction":
|
|
592
|
+
case "tab": {
|
|
593
|
+
const layout = RunLayout.create(component, context, cumulativeOverrides);
|
|
594
|
+
curLine = this.populateRun(curLine, layout, context, cumulativeOverrides, docWidth);
|
|
595
|
+
break;
|
|
572
596
|
}
|
|
597
|
+
case "linebreak": {
|
|
598
|
+
const layout = RunLayout.create(component, context, cumulativeOverrides);
|
|
599
|
+
curLine.append(layout);
|
|
600
|
+
curLine = this.flushLine(context, curLine, cumulativeOverrides, undefined, undefined, depth);
|
|
601
|
+
break;
|
|
602
|
+
}
|
|
603
|
+
default: break;
|
|
573
604
|
}
|
|
574
|
-
|
|
575
|
-
|
|
605
|
+
return curLine;
|
|
606
|
+
}
|
|
607
|
+
;
|
|
608
|
+
populateRun(curLine, run, context, cumulativeOverrides, docWidth) {
|
|
609
|
+
// If this is a tab, we need to apply the tab shift first, and then we can treat it like a text run.
|
|
610
|
+
applyTabShift(run, curLine, context);
|
|
611
|
+
// If our width is not set, then we don't have to compute word wrapping, so just append the run, and continue.
|
|
612
|
+
if (docWidth <= 0) {
|
|
613
|
+
curLine.append(run);
|
|
614
|
+
return curLine;
|
|
615
|
+
}
|
|
616
|
+
// If not, we need to determine if we can append this run to the current line without exceeding the document width or if we need to word wrap.
|
|
617
|
+
const runWidth = run.justificationRange?.xLength() ?? run.range.xLength();
|
|
618
|
+
const lineWidth = curLine.runRange.xLength();
|
|
619
|
+
const newWidth = runWidth + lineWidth + curLine.offsetFromDocument.x;
|
|
620
|
+
// If true, then no word wrapping is required, so we can append to the current line.
|
|
621
|
+
if (newWidth < docWidth || core_geometry_1.Geometry.isAlmostEqualNumber(newWidth, docWidth, core_geometry_1.Geometry.smallMetricDistance)) {
|
|
622
|
+
curLine.append(run);
|
|
623
|
+
return curLine;
|
|
576
624
|
}
|
|
625
|
+
// If not, do word wrapping
|
|
626
|
+
if (curLine.runs.length === 0) {
|
|
627
|
+
curLine.append(run);
|
|
628
|
+
// Lastly, flush line
|
|
629
|
+
curLine = this.flushLine(context, curLine, cumulativeOverrides, undefined, undefined, curLine.depth);
|
|
630
|
+
}
|
|
631
|
+
else {
|
|
632
|
+
// First, flush line
|
|
633
|
+
curLine = this.flushLine(context, curLine, cumulativeOverrides, undefined, undefined, curLine.depth);
|
|
634
|
+
// Recompute tab shift if applicable
|
|
635
|
+
applyTabShift(run, curLine, context);
|
|
636
|
+
curLine.append(run);
|
|
637
|
+
}
|
|
638
|
+
return curLine;
|
|
639
|
+
}
|
|
640
|
+
;
|
|
641
|
+
flushLine(context, curLine, cumulativeOverrides, next, newParagraph = false, depth = 0) {
|
|
642
|
+
next = next ?? curLine.source;
|
|
643
|
+
// We want to guarantee that each layout line has at least one run.
|
|
644
|
+
if (curLine.runs.length === 0) {
|
|
645
|
+
if (this.lines.length === 0 || this._back.runs.length === 0) {
|
|
646
|
+
return new LineLayout(next, cumulativeOverrides, context, depth);
|
|
647
|
+
}
|
|
648
|
+
if (curLine.source.type !== "linebreak") {
|
|
649
|
+
const newLine = new LineLayout(next, cumulativeOverrides, context, depth);
|
|
650
|
+
newLine.offsetFromDocument.y -= context.textStyleResolver.blockSettings.paragraphSpacingFactor * context.textStyleResolver.blockSettings.lineHeight;
|
|
651
|
+
return newLine;
|
|
652
|
+
}
|
|
653
|
+
const run = curLine.source.clone();
|
|
654
|
+
curLine.append(RunLayout.create(run, context, cumulativeOverrides));
|
|
655
|
+
}
|
|
656
|
+
// Line origin is its baseline.
|
|
657
|
+
const lineOffset = { ...curLine.offsetFromDocument }; // Start with the line's original offset, which includes indentation.
|
|
658
|
+
lineOffset.y -= curLine.range.yLength(); // Shift down the baseline
|
|
659
|
+
// Place it below any existing lines
|
|
660
|
+
if (this.lines.length > 0) {
|
|
661
|
+
lineOffset.y += this._back.offsetFromDocument.y;
|
|
662
|
+
lineOffset.y -= context.textStyleResolver.blockSettings.lineSpacingFactor * context.textStyleResolver.blockSettings.lineHeight;
|
|
663
|
+
}
|
|
664
|
+
curLine.offsetFromDocument = lineOffset;
|
|
665
|
+
// Update document range from computed line range and position
|
|
666
|
+
this.textRange.extendRange(curLine.range.cloneTranslated(lineOffset));
|
|
667
|
+
this.lines.push(curLine);
|
|
668
|
+
if (newParagraph) {
|
|
669
|
+
const newLine = new LineLayout(next, cumulativeOverrides, context, depth);
|
|
670
|
+
newLine.offsetFromDocument.y -= context.textStyleResolver.blockSettings.paragraphSpacingFactor * context.textStyleResolver.blockSettings.lineHeight;
|
|
671
|
+
return newLine;
|
|
672
|
+
}
|
|
673
|
+
return new LineLayout(next, cumulativeOverrides, context, depth);
|
|
577
674
|
}
|
|
578
675
|
justifyLines() {
|
|
579
676
|
// We don't want to justify empty text, or a single line of text whose width is 0. By default text is already left justified.
|
|
@@ -584,7 +681,7 @@ class TextBlockLayout {
|
|
|
584
681
|
const docWidth = this.source.width;
|
|
585
682
|
let minOffset = Number.MAX_VALUE;
|
|
586
683
|
for (const line of this.lines) {
|
|
587
|
-
const lineWidth = line.justificationRange.xLength();
|
|
684
|
+
const lineWidth = line.justificationRange.xLength() + line.offsetFromDocument.x;
|
|
588
685
|
let offset = docWidth - lineWidth;
|
|
589
686
|
if ("center" === this.source.justification) {
|
|
590
687
|
offset = offset / 2;
|
|
@@ -598,34 +695,6 @@ class TextBlockLayout {
|
|
|
598
695
|
this.textRange.high.x += minOffset;
|
|
599
696
|
}
|
|
600
697
|
}
|
|
601
|
-
flushLine(context, line, nextParagraph) {
|
|
602
|
-
nextParagraph = nextParagraph ?? line.source;
|
|
603
|
-
// We want to guarantee that each layout line has at least one run.
|
|
604
|
-
if (line.runs.length === 0) {
|
|
605
|
-
// If we're empty, there should always be a preceding run, and it should be a line break.
|
|
606
|
-
if (this.lines.length === 0 || this._back.runs.length === 0) {
|
|
607
|
-
return new LineLayout(nextParagraph);
|
|
608
|
-
}
|
|
609
|
-
const prevRun = this._back.back.source;
|
|
610
|
-
(0, core_bentley_1.assert)(prevRun.type === "linebreak");
|
|
611
|
-
if (prevRun.type !== "linebreak") {
|
|
612
|
-
return new LineLayout(nextParagraph);
|
|
613
|
-
}
|
|
614
|
-
line.append(RunLayout.create(prevRun.clone(), line.source, context));
|
|
615
|
-
}
|
|
616
|
-
// Line origin is its baseline.
|
|
617
|
-
const lineOffset = { x: 0, y: -line.range.yLength() };
|
|
618
|
-
// Place it below any existing lines
|
|
619
|
-
if (this.lines.length > 0) {
|
|
620
|
-
lineOffset.y += this._back.offsetFromDocument.y;
|
|
621
|
-
lineOffset.y -= context.textStyleResolver.blockSettings.lineSpacingFactor * context.textStyleResolver.blockSettings.lineHeight;
|
|
622
|
-
}
|
|
623
|
-
line.offsetFromDocument = lineOffset;
|
|
624
|
-
// Update document range from computed line range and position
|
|
625
|
-
this.textRange.extendRange(line.range.cloneTranslated(lineOffset));
|
|
626
|
-
this.lines.push(line);
|
|
627
|
-
return new LineLayout(nextParagraph);
|
|
628
|
-
}
|
|
629
698
|
applyMargins(margins) {
|
|
630
699
|
this.range = this.textRange.clone();
|
|
631
700
|
if (this.range.isNull)
|