UNPKG

@itwin/core-backend

Version:
184 lines • 8.36 kB
"use strict"; /*--------------------------------------------------------------------------------------------- * Copyright (c) Bentley Systems, Incorporated. All rights reserved. * See LICENSE.md in the project root for license terms and full copyright notice. *--------------------------------------------------------------------------------------------*/ /** @packageDocumentation * @module ElementGeometry */ Object.defineProperty(exports, "__esModule", { value: true }); exports.produceTextAnnotationGeometry = produceTextAnnotationGeometry; const core_common_1 = require("@itwin/core-common"); const TextAnnotationLayout_1 = require("./TextAnnotationLayout"); const core_geometry_1 = require("@itwin/core-geometry"); const core_bentley_1 = require("@itwin/core-bentley"); function setColor(color, context) { if (color !== context.curColor) { context.curColor = color; context.entries.push({ color }); } } function createTextString(text, run, origin) { (0, core_bentley_1.assert)(text.length > 0); const { lineHeight, widthFactor, isBold, isItalic, isUnderlined } = run.style; return new core_common_1.TextString({ text, font: run.fontId, height: lineHeight, widthFactor, bold: isBold, italic: isItalic, underline: isUnderlined, origin, }); } function processTextRun(run, transform, context) { (0, core_bentley_1.assert)(run.source.type === "text"); const text = run.source.content.substring(run.charOffset, run.charOffset + run.numChars); if (text.length === 0) { return; } const ts = createTextString(text, run); if ("none" !== run.source.baselineShift) { const isSub = "subscript" === run.source.baselineShift; const offsetFactor = run.style[isSub ? "subScriptOffsetFactor" : "superScriptOffsetFactor"]; const scale = run.style[isSub ? "subScriptScale" : "superScriptScale"]; ts.origin.y += offsetFactor * ts.height; ts.height *= scale; } ts.transformInPlace(transform); setColor(run.style.color, context); context.entries.push({ text: ts }); } function createFractionTextString(text, run, origin, transform) { const ts = createTextString(text, run, origin); (0, core_bentley_1.assert)(undefined !== ts.widthFactor); ts.height *= run.style.stackedFractionScale; ts.transformInPlace(transform); return ts; } function processFractionRun(run, transform, context) { const source = run.source; (0, core_bentley_1.assert)(source.type === "fraction"); if (source.numerator.length === 0 && source.denominator.length === 0) { return; } (0, core_bentley_1.assert)(undefined !== run.numeratorRange && undefined !== run.denominatorRange); const fontSize = new core_geometry_1.Vector2d(run.style.lineHeight * run.style.widthFactor, run.style.lineHeight); fontSize.scale(run.style.stackedFractionScale, fontSize); const numeratorOffset = new core_geometry_1.Point3d(run.numeratorRange.low.x, run.numeratorRange.low.y, 0); const denominatorOffset = new core_geometry_1.Point3d(run.denominatorRange.low.x, run.denominatorRange.low.y, 0); setColor(run.style.color, context); if (source.numerator.length > 0) { context.entries.push({ text: createFractionTextString(source.numerator, run, numeratorOffset, transform) }); } const numeratorRange = core_geometry_1.Range2d.fromJSON(run.numeratorRange); const denominatorRange = core_geometry_1.Range2d.fromJSON(run.denominatorRange); let separator; if (run.style.stackedFractionType === "horizontal") { const fractionWidth = Math.max(numeratorRange.xLength(), denominatorRange.xLength()); const y = 1.25 * denominatorRange.yLength(); separator = core_geometry_1.LineSegment3d.createXYXY(0, y, fractionWidth, y); } else { const p0 = new core_geometry_1.Point3d(denominatorRange.low.x - fontSize.x / 2, denominatorRange.low.y + fontSize.y * (1 / 3), 0); const p1 = new core_geometry_1.Point3d(p0.x + fontSize.x, p0.y + fontSize.y * 1.5, 0); separator = core_geometry_1.LineSegment3d.createCapture(p0, p1); } separator.tryTransformInPlace(transform); context.entries.push({ separator: { startPoint: separator.point0Ref.toJSON(), endPoint: separator.point1Ref.toJSON(), }, }); if (source.denominator.length > 0) { context.entries.push({ text: createFractionTextString(source.denominator, run, denominatorOffset, transform) }); } } function produceTextBlockGeometry(layout, documentTransform, debugAnchorPt) { const context = { entries: [] }; for (const line of layout.lines) { const lineTrans = core_geometry_1.Transform.createTranslationXYZ(line.offsetFromDocument.x, line.offsetFromDocument.y, 0); for (const run of line.runs) { if ("linebreak" === run.source.type) { continue; } const runTrans = core_geometry_1.Transform.createTranslationXYZ(run.offsetFromLine.x, run.offsetFromLine.y, 0); lineTrans.multiplyTransformTransform(runTrans, runTrans); documentTransform.multiplyTransformTransform(runTrans, runTrans); if ("text" === run.source.type) { processTextRun(run, runTrans, context); } else { processFractionRun(run, runTrans, context); } } } if (debugAnchorPt) { context.entries.push({ color: core_common_1.ColorDef.blue.toJSON() }); // Draw a blue box to show the element's margin const marginCorners = layout.range.corners3d(true); documentTransform.multiplyPoint3dArrayInPlace(marginCorners); marginCorners.forEach((corner, index) => { const next = marginCorners[index + 1]; if (!next) return; context.entries.push({ separator: { startPoint: [corner.x, corner.y, 0], endPoint: [next.x, next.y, 0], }, }); }); // Draw a blue x to show the anchor point - Rotation occurs around this point. The x will be 1 m by 1 m. context.entries.push({ separator: { startPoint: [debugAnchorPt.x - 1, debugAnchorPt.y - 1, 0], endPoint: [debugAnchorPt.x + 1, debugAnchorPt.y + 1, 0], }, }); context.entries.push({ separator: { startPoint: [debugAnchorPt.x + 1, debugAnchorPt.y - 1, 0], endPoint: [debugAnchorPt.x - 1, debugAnchorPt.y + 1, 0], }, }); // Draw a red box to show the text range context.entries.push({ color: core_common_1.ColorDef.red.toJSON(), }); const rangeCorners = layout.textRange.corners3d(true); documentTransform.multiplyPoint3dArrayInPlace(rangeCorners); rangeCorners.forEach((corner, index) => { const next = rangeCorners[index + 1]; if (!next) return; context.entries.push({ separator: { startPoint: [corner.x, corner.y, 0], endPoint: [next.x, next.y, 0], }, }); }); } return { entries: context.entries }; } /** Produce a geometric representation of a text annotation, with the annotation's anchor point at the origin. * The result can be supplied to [GeometryStreamBuilder.appendTextBlock]($common). * @see [[TextAnnotation2d.setAnnotation]] and [[TextAnnotation3d.setAnnotation]] to update the annotation, geometry, and placement of an annotation element. * @beta */ function produceTextAnnotationGeometry(args) { const layout = (0, TextAnnotationLayout_1.layoutTextBlock)({ ...args, textBlock: args.annotation.textBlock, }); const dimensions = layout.range; const transform = args.annotation.computeTransform(dimensions); const anchorPoint = args.debugAnchorPointAndRange ? transform.multiplyPoint3d(args.annotation.computeAnchorPoint(dimensions)) : undefined; return produceTextBlockGeometry(layout, transform, anchorPoint); } //# sourceMappingURL=TextAnnotationGeometry.js.map