UNPKG

molstar

Version:

A comprehensive macromolecular library.

284 lines 14.8 kB
"use strict"; /** * Copyright (c) 2019-2020 mol* contributors, licensed under MIT, See LICENSE file for more info. * * @author Alexander Rose <alexander.rose@weirdbyte.de> */ Object.defineProperty(exports, "__esModule", { value: true }); exports.TextBuilder = void 0; var tslib_1 = require("tslib"); var param_definition_1 = require("../../../mol-util/param-definition"); var util_1 = require("../../../mol-data/util"); var text_1 = require("./text"); var font_atlas_1 = require("./font-atlas"); var quadIndices = new Uint16Array([ 0, 1, 2, 1, 3, 2 ]); // avoiding namespace lookup improved performance in Chrome (Aug 2020) var caAdd3 = util_1.ChunkedArray.add3; var caAdd2 = util_1.ChunkedArray.add2; var caAdd = util_1.ChunkedArray.add; var TextBuilder; (function (TextBuilder) { function create(props, initialCount, chunkSize, text) { if (props === void 0) { props = {}; } if (initialCount === void 0) { initialCount = 2048; } if (chunkSize === void 0) { chunkSize = 1024; } initialCount *= 2; chunkSize *= 2; var centers = util_1.ChunkedArray.create(Float32Array, 3, chunkSize, text ? text.centerBuffer.ref.value : initialCount); var mappings = util_1.ChunkedArray.create(Float32Array, 2, chunkSize, text ? text.mappingBuffer.ref.value : initialCount); var depths = util_1.ChunkedArray.create(Float32Array, 1, chunkSize, text ? text.depthBuffer.ref.value : initialCount); var indices = util_1.ChunkedArray.create(Uint32Array, 3, chunkSize, text ? text.indexBuffer.ref.value : initialCount); var groups = util_1.ChunkedArray.create(Float32Array, 1, chunkSize, text ? text.groupBuffer.ref.value : initialCount); var tcoords = util_1.ChunkedArray.create(Float32Array, 2, chunkSize, text ? text.tcoordBuffer.ref.value : initialCount); var p = (0, tslib_1.__assign)((0, tslib_1.__assign)({}, param_definition_1.ParamDefinition.getDefaultValues(text_1.Text.Params)), props); var attachment = p.attachment, background = p.background, backgroundMargin = p.backgroundMargin, tether = p.tether, tetherLength = p.tetherLength, tetherBaseWidth = p.tetherBaseWidth; var fontAtlas = (0, font_atlas_1.getFontAtlas)(p); var margin = (1 / 2.5) * backgroundMargin; var outline = fontAtlas.buffer / fontAtlas.lineHeight; var add = function (x, y, z, depth, group) { caAdd3(centers, x, y, z); caAdd(depths, depth); caAdd(groups, group); }; return { add: function (str, x, y, z, depth, scale, group) { var bWidth = 0; var nChar = str.length; // calculate width for (var iChar = 0; iChar < nChar; ++iChar) { var c = fontAtlas.get(str[iChar]); bWidth += c.nw - 2 * outline; } var bHeight = 1 / 1.25; // attachment var yShift, xShift; // vertical if (attachment.startsWith('top')) { yShift = bHeight; } else if (attachment.startsWith('middle')) { yShift = bHeight / 2; } else { yShift = 0; // "bottom" } // horizontal if (attachment.endsWith('right')) { xShift = bWidth; } else if (attachment.endsWith('center')) { xShift = bWidth / 2; } else { xShift = 0; // "left" } if (tether) { switch (attachment) { case 'bottom-left': xShift -= tetherLength / 2 + margin + 0.1; yShift -= tetherLength / 2 + margin; break; case 'bottom-center': yShift -= tetherLength + margin; break; case 'bottom-right': xShift += tetherLength / 2 + margin + 0.1; yShift -= tetherLength / 2 + margin; break; case 'middle-left': xShift -= tetherLength + margin + 0.1; break; case 'middle-center': break; case 'middle-right': xShift += tetherLength + margin + 0.1; break; case 'top-left': xShift -= tetherLength / 2 + margin + 0.1; yShift += tetherLength / 2 + margin; break; case 'top-center': yShift += tetherLength + margin; break; case 'top-right': xShift += tetherLength / 2 + margin + 0.1; yShift += tetherLength / 2 + margin; break; } } var xLeft = (-xShift - margin - 0.1) * scale; var xRight = (bWidth - xShift + margin + 0.1) * scale; var yTop = (bHeight - yShift + margin) * scale; var yBottom = (-yShift - margin) * scale; // background if (background) { caAdd2(mappings, xLeft, yTop); // top left caAdd2(mappings, xLeft, yBottom); // bottom left caAdd2(mappings, xRight, yTop); // top right caAdd2(mappings, xRight, yBottom); // bottom right var offset = centers.elementCount; for (var i = 0; i < 4; ++i) { caAdd2(tcoords, 10, 10); add(x, y, z, depth, group); } caAdd3(indices, offset + quadIndices[0], offset + quadIndices[1], offset + quadIndices[2]); caAdd3(indices, offset + quadIndices[3], offset + quadIndices[4], offset + quadIndices[5]); } if (tether) { var xTip = void 0, yTip = void 0; var xBaseA = void 0, yBaseA = void 0; var xBaseB = void 0, yBaseB = void 0; var xBaseCenter = void 0, yBaseCenter = void 0; var scaledTetherLength = tetherLength * scale; var scaledTetherBaseWidth = tetherBaseWidth * scale; switch (attachment) { case 'bottom-left': xTip = xLeft - scaledTetherLength / 2; xBaseA = xLeft + scaledTetherBaseWidth / 2; xBaseB = xLeft; xBaseCenter = xLeft; yTip = yBottom - scaledTetherLength / 2; yBaseA = yBottom; yBaseB = yBottom + scaledTetherBaseWidth / 2; yBaseCenter = yBottom; break; case 'bottom-center': xTip = 0; xBaseA = scaledTetherBaseWidth / 2; xBaseB = -scaledTetherBaseWidth / 2; xBaseCenter = 0; yTip = yBottom - scaledTetherLength; yBaseA = yBottom; yBaseB = yBottom; yBaseCenter = yBottom; break; case 'bottom-right': xTip = xRight + scaledTetherLength / 2; xBaseA = xRight; xBaseB = xRight - scaledTetherBaseWidth / 2; xBaseCenter = xRight; yTip = yBottom - scaledTetherLength / 2; yBaseA = yBottom + scaledTetherBaseWidth / 2; yBaseB = yBottom; yBaseCenter = yBottom; break; case 'middle-left': xTip = xLeft - scaledTetherLength; xBaseA = xLeft; xBaseB = xLeft; xBaseCenter = xLeft; yTip = 0; yBaseA = -scaledTetherBaseWidth / 2; yBaseB = scaledTetherBaseWidth / 2; yBaseCenter = 0; break; case 'middle-center': xTip = 0; xBaseA = 0; xBaseB = 0; xBaseCenter = 0; yTip = 0; yBaseA = 0; yBaseB = 0; yBaseCenter = 0; break; case 'middle-right': xTip = xRight + scaledTetherLength; xBaseA = xRight; xBaseB = xRight; xBaseCenter = xRight; yTip = 0; yBaseA = scaledTetherBaseWidth / 2; yBaseB = -scaledTetherBaseWidth / 2; yBaseCenter = 0; break; case 'top-left': xTip = xLeft - scaledTetherLength / 2; xBaseA = xLeft + scaledTetherBaseWidth / 2; xBaseB = xLeft; xBaseCenter = xLeft; yTip = yTop + scaledTetherLength / 2; yBaseA = yTop; yBaseB = yTop - scaledTetherBaseWidth / 2; yBaseCenter = yTop; break; case 'top-center': xTip = 0; xBaseA = scaledTetherBaseWidth / 2; xBaseB = -scaledTetherBaseWidth / 2; xBaseCenter = 0; yTip = yTop + scaledTetherLength; yBaseA = yTop; yBaseB = yTop; yBaseCenter = yTop; break; case 'top-right': xTip = xRight + scaledTetherLength / 2; xBaseA = xRight; xBaseB = xRight - scaledTetherBaseWidth / 2; xBaseCenter = xRight; yTip = yTop + scaledTetherLength / 2; yBaseA = yTop - scaledTetherBaseWidth / 2; yBaseB = yTop; yBaseCenter = yTop; break; default: throw new Error('unsupported attachment'); } caAdd2(mappings, xTip, yTip); // tip caAdd2(mappings, xBaseA, yBaseA); // base A caAdd2(mappings, xBaseB, yBaseB); // base B caAdd2(mappings, xBaseCenter, yBaseCenter); // base center var offset = centers.elementCount; for (var i = 0; i < 4; ++i) { caAdd2(tcoords, 10, 10); add(x, y, z, depth, group); } caAdd3(indices, offset, offset + 1, offset + 3); caAdd3(indices, offset, offset + 3, offset + 2); } xShift += outline; yShift += outline; var xadvance = 0; for (var iChar = 0; iChar < nChar; ++iChar) { var c = fontAtlas.get(str[iChar]); var left = (xadvance - xShift) * scale; var right = (xadvance + c.nw - xShift) * scale; var top_1 = (c.nh - yShift) * scale; var bottom = (-yShift) * scale; caAdd2(mappings, left, top_1); caAdd2(mappings, left, bottom); caAdd2(mappings, right, top_1); caAdd2(mappings, right, bottom); var texWidth = fontAtlas.texture.width; var texHeight = fontAtlas.texture.height; caAdd2(tcoords, c.x / texWidth, c.y / texHeight); // top left caAdd2(tcoords, c.x / texWidth, (c.y + c.h) / texHeight); // bottom left caAdd2(tcoords, (c.x + c.w) / texWidth, c.y / texHeight); // top right caAdd2(tcoords, (c.x + c.w) / texWidth, (c.y + c.h) / texHeight); // bottom right xadvance += c.nw - 2 * outline; var offset = centers.elementCount; for (var i = 0; i < 4; ++i) add(x, y, z, depth, group); caAdd3(indices, offset + quadIndices[0], offset + quadIndices[1], offset + quadIndices[2]); caAdd3(indices, offset + quadIndices[3], offset + quadIndices[4], offset + quadIndices[5]); } }, getText: function () { var ft = fontAtlas.texture; var cb = util_1.ChunkedArray.compact(centers, true); var mb = util_1.ChunkedArray.compact(mappings, true); var db = util_1.ChunkedArray.compact(depths, true); var ib = util_1.ChunkedArray.compact(indices, true); var gb = util_1.ChunkedArray.compact(groups, true); var tb = util_1.ChunkedArray.compact(tcoords, true); return text_1.Text.create(ft, cb, mb, db, ib, gb, tb, indices.elementCount / 2, text); } }; } TextBuilder.create = create; })(TextBuilder = exports.TextBuilder || (exports.TextBuilder = {})); //# sourceMappingURL=text-builder.js.map