From a1a2542a9b574e9a568f657a4df0804b3b5dffa9 Mon Sep 17 00:00:00 2001 From: anne-gropler Date: Mon, 11 Mar 2019 17:18:09 +0100 Subject: [PATCH 1/8] compute calculate using pen while typesetting (error prone, returns different height for different line anchors) --- source/text/glyph.frag | 2 +- source/text/glyph.vert | 2 +- source/text/label.ts | 21 +++++++++++++++++++-- source/text/typesetter.ts | 33 +++++++++++++++++++++++++++++++-- 4 files changed, 52 insertions(+), 6 deletions(-) diff --git a/source/text/glyph.frag b/source/text/glyph.frag index 2f99beae..35b335bf 100644 --- a/source/text/glyph.frag +++ b/source/text/glyph.frag @@ -35,7 +35,7 @@ float aastep(float t, float value) /* float afwidth = length(vec2(dFdx(value), dFdy(value))) * u_aaStepScale; */ float afwidth = fwidth(value) * u_aaStepScale; /* The aa step scale is more of a hack to provide seemingly smoother (e.g., >= 1.0) or crisper (e.g., between 0.0 - * and 1.0) contours without specific sampling. Its just scaling the outcome of the derivatives. + * and 1.0) contours without specific sampling. It's just scaling the outcome of the derivatives. */ return smoothstep(t - afwidth, t + afwidth, value); diff --git a/source/text/glyph.vert b/source/text/glyph.vert index ee24aaef..ded35c32 100644 --- a/source/text/glyph.vert +++ b/source/text/glyph.vert @@ -45,7 +45,7 @@ void main(void) v_uv = a_vertex * texExt + vec2(a_texCoord[0], 1.0 - a_texCoord[1]); - /* POSITIONING*/ + /* POSITIONING */ /* quad data as flat array: [0, 0, 0, 1, 1, 0, 1, 1] (a_vertex), which translates to ll, lr, ul, ur corners. * 2-------4 * | \ | diff --git a/source/text/label.ts b/source/text/label.ts index 31413b87..600ba797 100644 --- a/source/text/label.ts +++ b/source/text/label.ts @@ -56,7 +56,7 @@ export abstract class Label { /** @see {@link type} */ protected _type: Label.Type; - /** @see {@link transform} */ + /** @see {@link staticTransform} */ protected _staticTransform: mat4; /** @see {@link dynamicTransform} */ @@ -460,15 +460,32 @@ export abstract class Label { } /** - * The typesetter sets this extent after typesetting and applying the transform. + * The typesetter sets this extent after typesetting and applying the static transform. */ set extent(e: [number, number]) { + console.log('set extent', e); + // console.log('transforms:', this._type, this._staticTransform, this._dynamicTransform); this._extent = e; + + // const w = vec4.fromValues(this._extent[0], 0, 0, 0); + // // vec3.scale(w, w, mat4.getScaling(vec3.create(), this._dynamicTransform)[0]); + // vec4.transformMat4(w, w, this._dynamicTransform); + // const h = vec4.fromValues(0, this._extent[1], 0, 0); + // // vec3.scale(h, h, mat4.getScaling(vec3.create(), this._dynamicTransform)[1]); + // vec4.transformMat4(h, h, this._dynamicTransform); + // console.log('get extent:', vec4.length(w), vec4.length(h)); } /** * Returns the width and height of the typset label. Both are zero if not typeset yet. */ get extent(): [number, number] { + // console.log('get extent: dynami scale is', mat4.getScaling(vec3.create(), this._dynamicTransform)); + + // const w = vec3.fromValues(this._extent[0], 0, 0); + // vec3.scale(w, w, mat4.getScaling(vec3.create(), this._dynamicTransform)[0]); + // const h = vec3.fromValues(0, this._extent[1], 0); + // vec3.scale(h, h, mat4.getScaling(vec3.create(), this._dynamicTransform)[1]); + // console.log('get extent:', w[0], h[1]); return this._extent; } diff --git a/source/text/typesetter.ts b/source/text/typesetter.ts index f35848e2..39357782 100644 --- a/source/text/typesetter.ts +++ b/source/text/typesetter.ts @@ -1,7 +1,7 @@ /* spellchecker: disable */ -import { mat4, vec2, vec3 } from 'gl-matrix'; +import { mat4, vec2, vec3, vec4 } from 'gl-matrix'; import { assert } from '../auxiliaries'; import { v3 } from '../gl-matrix-extensions'; @@ -216,7 +216,6 @@ export class Typesetter { switch (label.elide) { case Label.Elide.Right: return [label.lineWidth - ellipsisWidth, 0.0]; - break; case Label.Elide.Middle: const threshold = label.lineWidth / 2 - ellipsisWidth / 2; return [threshold, threshold]; @@ -396,6 +395,16 @@ export class Typesetter { // const pen: vec2 = vec2.fromValues(-fontFace.glyphTexturePadding[3], -Typesetter.lineAnchorOffset(label)); const pen: vec2 = vec2.fromValues(0.0, -Typesetter.lineAnchorOffset(label)); + const penMin = vec2.create(); + const penMax = vec2.create(); + console.log('line pen start', pen[1]); + const setMinMaxPen = (p: vec2) => { + penMax[0] = Math.max(p[0], penMax[0]); + penMax[1] = Math.max(p[1], penMax[1]); + penMin[0] = Math.min(p[0], penMin[0]); + penMin[1] = Math.min(p[1], penMin[1]); + }; + const lines = new Array(); let vertexIndex = 0; @@ -448,6 +457,7 @@ export class Typesetter { lines.push([firstIndexOfLine, vertexIndex, pen[0]]); firstIndexOfLine = vertexIndex; + setMinMaxPen(pen); pen[0] = 0.0; pen[1] -= fontFace.lineHeight; @@ -464,6 +474,7 @@ export class Typesetter { ++vertexIndex; } pen[0] += advances[i - offset] + kernings[i - offset]; + setMinMaxPen(pen); } } if (firstIndexOfLine < vertexIndex) { @@ -526,6 +537,24 @@ export class Typesetter { Typesetter.transform(label, vertices, lines); vertices.shrink(vertexIndex); + + const extent = vec2.fromValues(penMax[0] - penMin[0], penMax[1] - penMin[1]); + console.log('line anchor' + label.lineAnchor, extent, Typesetter.lineAnchorOffset(label)); + // vec2.sub(extent, extent, vec2.fromValues(0.0, Typesetter.lineAnchorOffset(label))); + // console.log('done: line anchor?', extent); + + // transform extent + const ll = vec4.transformMat4(vec4.create(), vec4.fromValues(0, 0, 0, 1), label.staticTransform); + const lr = vec4.transformMat4(vec4.create(), vec4.fromValues(extent[0], 0, 0, 1), label.staticTransform); + const ul = vec4.transformMat4(vec4.create(), vec4.fromValues(0, extent[1], 0, 1), label.staticTransform); + + vec2.set(extent, vec4.distance(lr, ll), vec4.distance(ul, ll)); + + + console.log('line set', extent); + label.extent = [extent[0], extent[1]]; + + return vertexIndex; } From 9e48428dc0a78d480f8b115222defed81eb470b2 Mon Sep 17 00:00:00 2001 From: anne-gropler Date: Tue, 12 Mar 2019 17:30:23 +0100 Subject: [PATCH 2/8] calculate label extent on glyph vertices line-by-line, before transform is applied (does not work well with multi-line label yet) --- source/text/typesetter.ts | 112 +++++++++++++++++++++++++++++++++++++- 1 file changed, 111 insertions(+), 1 deletion(-) diff --git a/source/text/typesetter.ts b/source/text/typesetter.ts index 39357782..01e7aebf 100644 --- a/source/text/typesetter.ts +++ b/source/text/typesetter.ts @@ -322,6 +322,93 @@ export class Typesetter { } } + /** + * @param currentRectangle - [minX, minY, minZ, maxX, maxY, maxZ] is updated in-place + * @param newRectangle - [minX, minY, minZ, maxX, maxY, maxZ] used to update currentRectangle + */ + private static updateRectangleMinMax(currentRectangle: number[], newRectangle: number[]): void { + assert(currentRectangle.length === 6 && newRectangle.length === 6, `expected the rectangles to have 6 values!`); + + console.log('>>>', currentRectangle[1], newRectangle[1], currentRectangle[4], newRectangle[4]); + + let i = 0; + for (; i < 3; i++) { + currentRectangle[i] = Math.min(currentRectangle[i], newRectangle[i]); + } + for (; i < 6; i++) { + currentRectangle[i] = Math.max(currentRectangle[i], newRectangle[i]); + } + } + + /** + * Returns [minX, minY, minZ, maxX, maxY, maxZ] of the vertices coordinates, i.e., origins, + * origins + tangents, origins + ups, from which a bounding rectangle can be calculated. + * @param vertices - Glyph vertices to be transformed (expected untransformed, in typesetting space). + * @param begin - Vertex index to start alignment at. + * @param end - Vertex index to stop alignment at. + */ + private static getMinMax(vertices: GlyphVertices, begin: number, end: number) + : [number, number, number, number, number, number] { + + let minX = Math.min( + vertices.origins[begin], + vertices.origins[begin] + vertices.ups[begin], + vertices.origins[begin] + vertices.tangents[begin]); + let maxX = Math.max( + vertices.origins[begin], + vertices.origins[begin] + vertices.ups[begin], + vertices.origins[begin] + vertices.tangents[begin]); + + let minY = Math.min( + vertices.origins[begin + 1], + vertices.origins[begin + 1] + vertices.ups[begin + 1], + vertices.origins[begin + 1] + vertices.tangents[begin + 1]); + let maxY = Math.max( + vertices.origins[begin + 1], + vertices.origins[begin + 1] + vertices.ups[begin + 1], + vertices.origins[begin + 1] + vertices.tangents[begin + 1]); + + let minZ = Math.min( + vertices.origins[begin + 2], + vertices.origins[begin + 2] + vertices.ups[begin + 2], + vertices.origins[begin + 2] + vertices.tangents[begin + 2]); + let maxZ = Math.max( + vertices.origins[begin + 2], + vertices.origins[begin + 2] + vertices.ups[begin + 2], + vertices.origins[begin + 2] + vertices.tangents[begin + 2]); + + for (let i = begin + 3; i < end; i += 3) { + minX = Math.min(minX, + vertices.origins[i], + vertices.origins[i] + vertices.ups[i], + vertices.origins[i] + vertices.tangents[i]); + maxX = Math.max(maxX, + vertices.origins[i], + vertices.origins[i] + vertices.ups[i], + vertices.origins[i] + vertices.tangents[i]); + + minY = Math.min(minY, + vertices.origins[i + 1], + vertices.origins[i + 1] + vertices.ups[i + 1], + vertices.origins[i + 1] + vertices.tangents[i + 1]); + maxY = Math.max(maxY, + vertices.origins[i + 1], + vertices.origins[i + 1] + vertices.ups[i + 1], + vertices.origins[i + 1] + vertices.tangents[i + 1]); + + minZ = Math.min(minZ, + vertices.origins[i + 2], + vertices.origins[i + 2] + vertices.ups[i + 2], + vertices.origins[i + 2] + vertices.tangents[i + 2]); + maxZ = Math.max(maxZ, + vertices.origins[i + 2], + vertices.origins[i + 2] + vertices.ups[i + 2], + vertices.origins[i + 2] + vertices.tangents[i + 2]); + } + + return [minX, minY, minZ, maxX, maxY, maxZ]; + } + /** * Adjusts the vertices for a line after typesetting (done due to line feed, word wrap, or end of line) w.r.t. * the targeted line alignment. @@ -355,10 +442,33 @@ export class Typesetter { * @param lines - Indices of glyph vertices on same lines to apply line-based transformations. */ private static transform(label: Label, vertices: GlyphVertices, lines: Array): void { + + const boundingRectangle = [ + Number.MAX_VALUE, Number.MAX_VALUE, Number.MAX_VALUE, + -Number.MAX_VALUE, -Number.MAX_VALUE, -Number.MAX_VALUE]; + for (const line of lines) { Typesetter.transformAlignment(line[2], label.alignment, vertices, line[0], line[1]); + Typesetter.updateRectangleMinMax(boundingRectangle, Typesetter.getMinMax(vertices, line[0], line[1])); Typesetter.transformVertices(label.staticTransform, vertices, line[0], line[1]); } + + console.log('>bb rect', boundingRectangle); + + // transform extent + const width = boundingRectangle[3] - boundingRectangle[0]; + const height = boundingRectangle[4] - boundingRectangle[1]; + + console.log('>>bb w h', width, height); + + const ll = vec4.transformMat4(vec4.create(), vec4.fromValues(0, 0, 0, 1), label.staticTransform); + const lr = vec4.transformMat4(vec4.create(), vec4.fromValues(width, 0, 0, 1), label.staticTransform); + const ul = vec4.transformMat4(vec4.create(), vec4.fromValues(0, height, 0, 1), label.staticTransform); + + const extent = vec2.fromValues(vec4.distance(lr, ll), vec4.distance(ul, ll)); + + console.log('>>bb extent', extent); + label.extent = [extent[0], extent[1]]; } @@ -551,7 +661,7 @@ export class Typesetter { vec2.set(extent, vec4.distance(lr, ll), vec4.distance(ul, ll)); - console.log('line set', extent); + console.log('>>pen extent', extent); label.extent = [extent[0], extent[1]]; From c2886a368f9b059ac2bfcf0a4c55262af6a0ac7d Mon Sep 17 00:00:00 2001 From: anne-gropler Date: Tue, 12 Mar 2019 18:19:37 +0100 Subject: [PATCH 3/8] now extent works for multi-line labels, too (both for 2D and 3D space) --- source/text/typesetter.ts | 114 +++++++++++++------------------------- 1 file changed, 39 insertions(+), 75 deletions(-) diff --git a/source/text/typesetter.ts b/source/text/typesetter.ts index 01e7aebf..39f1e676 100644 --- a/source/text/typesetter.ts +++ b/source/text/typesetter.ts @@ -329,8 +329,6 @@ export class Typesetter { private static updateRectangleMinMax(currentRectangle: number[], newRectangle: number[]): void { assert(currentRectangle.length === 6 && newRectangle.length === 6, `expected the rectangles to have 6 values!`); - console.log('>>>', currentRectangle[1], newRectangle[1], currentRectangle[4], newRectangle[4]); - let i = 0; for (; i < 3; i++) { currentRectangle[i] = Math.min(currentRectangle[i], newRectangle[i]); @@ -351,59 +349,59 @@ export class Typesetter { : [number, number, number, number, number, number] { let minX = Math.min( - vertices.origins[begin], - vertices.origins[begin] + vertices.ups[begin], - vertices.origins[begin] + vertices.tangents[begin]); + vertices.origin(begin)[0], + vertices.origin(begin)[0], + vertices.up(begin)[0], + vertices.origin(begin)[0], + vertices.tangent(begin)[0]); let maxX = Math.max( - vertices.origins[begin], - vertices.origins[begin] + vertices.ups[begin], - vertices.origins[begin] + vertices.tangents[begin]); + vertices.origin(begin)[0], + vertices.origin(begin)[0] + vertices.up(begin)[0], + vertices.origin(begin)[0] + vertices.tangent(begin)[0]); let minY = Math.min( - vertices.origins[begin + 1], - vertices.origins[begin + 1] + vertices.ups[begin + 1], - vertices.origins[begin + 1] + vertices.tangents[begin + 1]); + vertices.origin(begin)[1], + vertices.origin(begin)[1] + vertices.up(begin)[1], + vertices.origin(begin)[1] + vertices.tangent(begin)[1]); let maxY = Math.max( - vertices.origins[begin + 1], - vertices.origins[begin + 1] + vertices.ups[begin + 1], - vertices.origins[begin + 1] + vertices.tangents[begin + 1]); + vertices.origin(begin)[1], + vertices.origin(begin)[1] + vertices.up(begin)[1], + vertices.origin(begin)[1] + vertices.tangent(begin)[1]); let minZ = Math.min( - vertices.origins[begin + 2], - vertices.origins[begin + 2] + vertices.ups[begin + 2], - vertices.origins[begin + 2] + vertices.tangents[begin + 2]); + vertices.origin(begin)[2], + vertices.origin(begin)[2] + vertices.up(begin)[2], + vertices.origin(begin)[2] + vertices.tangent(begin)[2]); let maxZ = Math.max( - vertices.origins[begin + 2], - vertices.origins[begin + 2] + vertices.ups[begin + 2], - vertices.origins[begin + 2] + vertices.tangents[begin + 2]); + vertices.origin(begin)[2], + vertices.origin(begin)[2] + vertices.up(begin)[2], + vertices.origin(begin)[2] + vertices.tangent(begin)[2]); - for (let i = begin + 3; i < end; i += 3) { + for (let i: number = begin + 1; i < end; ++i) { minX = Math.min(minX, - vertices.origins[i], - vertices.origins[i] + vertices.ups[i], - vertices.origins[i] + vertices.tangents[i]); + vertices.origin(i)[0], + vertices.origin(i)[0] + vertices.up(i)[0], + vertices.origin(i)[0] + vertices.tangent(i)[0]); maxX = Math.max(maxX, - vertices.origins[i], - vertices.origins[i] + vertices.ups[i], - vertices.origins[i] + vertices.tangents[i]); + vertices.origin(i)[0], + vertices.origin(i)[0] + vertices.up(i)[0], + vertices.origin(i)[0] + vertices.tangent(i)[0]); minY = Math.min(minY, - vertices.origins[i + 1], - vertices.origins[i + 1] + vertices.ups[i + 1], - vertices.origins[i + 1] + vertices.tangents[i + 1]); + vertices.origin(i)[1], + vertices.origin(i)[1] + vertices.up(i)[1], + vertices.origin(i)[1] + vertices.tangent(i)[1]); maxY = Math.max(maxY, - vertices.origins[i + 1], - vertices.origins[i + 1] + vertices.ups[i + 1], - vertices.origins[i + 1] + vertices.tangents[i + 1]); + vertices.origin(i)[1], + vertices.origin(i)[1] + vertices.up(i)[1], + vertices.origin(i)[1] + vertices.tangent(i)[1]); minZ = Math.min(minZ, - vertices.origins[i + 2], - vertices.origins[i + 2] + vertices.ups[i + 2], - vertices.origins[i + 2] + vertices.tangents[i + 2]); + vertices.origin(i)[2], + vertices.origin(i)[2] + vertices.up(i)[2], + vertices.origin(i)[2] + vertices.tangent(i)[2]); maxZ = Math.max(maxZ, - vertices.origins[i + 2], - vertices.origins[i + 2] + vertices.ups[i + 2], - vertices.origins[i + 2] + vertices.tangents[i + 2]); + vertices.origin(i)[2], + vertices.origin(i)[2] + vertices.up(i)[2], + vertices.origin(i)[2] + vertices.tangent(i)[2]); } return [minX, minY, minZ, maxX, maxY, maxZ]; @@ -453,21 +451,17 @@ export class Typesetter { Typesetter.transformVertices(label.staticTransform, vertices, line[0], line[1]); } - console.log('>bb rect', boundingRectangle); - - // transform extent + // transform extent from Typesetting Space to label space (depending on the label, e.g. screen space (px) or + // world space) const width = boundingRectangle[3] - boundingRectangle[0]; const height = boundingRectangle[4] - boundingRectangle[1]; - console.log('>>bb w h', width, height); - const ll = vec4.transformMat4(vec4.create(), vec4.fromValues(0, 0, 0, 1), label.staticTransform); const lr = vec4.transformMat4(vec4.create(), vec4.fromValues(width, 0, 0, 1), label.staticTransform); const ul = vec4.transformMat4(vec4.create(), vec4.fromValues(0, height, 0, 1), label.staticTransform); const extent = vec2.fromValues(vec4.distance(lr, ll), vec4.distance(ul, ll)); - console.log('>>bb extent', extent); label.extent = [extent[0], extent[1]]; } @@ -505,16 +499,6 @@ export class Typesetter { // const pen: vec2 = vec2.fromValues(-fontFace.glyphTexturePadding[3], -Typesetter.lineAnchorOffset(label)); const pen: vec2 = vec2.fromValues(0.0, -Typesetter.lineAnchorOffset(label)); - const penMin = vec2.create(); - const penMax = vec2.create(); - console.log('line pen start', pen[1]); - const setMinMaxPen = (p: vec2) => { - penMax[0] = Math.max(p[0], penMax[0]); - penMax[1] = Math.max(p[1], penMax[1]); - penMin[0] = Math.min(p[0], penMin[0]); - penMin[1] = Math.min(p[1], penMin[1]); - }; - const lines = new Array(); let vertexIndex = 0; @@ -567,7 +551,6 @@ export class Typesetter { lines.push([firstIndexOfLine, vertexIndex, pen[0]]); firstIndexOfLine = vertexIndex; - setMinMaxPen(pen); pen[0] = 0.0; pen[1] -= fontFace.lineHeight; @@ -584,7 +567,6 @@ export class Typesetter { ++vertexIndex; } pen[0] += advances[i - offset] + kernings[i - offset]; - setMinMaxPen(pen); } } if (firstIndexOfLine < vertexIndex) { @@ -647,24 +629,6 @@ export class Typesetter { Typesetter.transform(label, vertices, lines); vertices.shrink(vertexIndex); - - const extent = vec2.fromValues(penMax[0] - penMin[0], penMax[1] - penMin[1]); - console.log('line anchor' + label.lineAnchor, extent, Typesetter.lineAnchorOffset(label)); - // vec2.sub(extent, extent, vec2.fromValues(0.0, Typesetter.lineAnchorOffset(label))); - // console.log('done: line anchor?', extent); - - // transform extent - const ll = vec4.transformMat4(vec4.create(), vec4.fromValues(0, 0, 0, 1), label.staticTransform); - const lr = vec4.transformMat4(vec4.create(), vec4.fromValues(extent[0], 0, 0, 1), label.staticTransform); - const ul = vec4.transformMat4(vec4.create(), vec4.fromValues(0, extent[1], 0, 1), label.staticTransform); - - vec2.set(extent, vec4.distance(lr, ll), vec4.distance(ul, ll)); - - - console.log('>>pen extent', extent); - label.extent = [extent[0], extent[1]]; - - return vertexIndex; } From 23438f4d9b1ad7a8903cfbd2b2bb8f6ed24a97ef Mon Sep 17 00:00:00 2001 From: anne-gropler Date: Tue, 12 Mar 2019 18:49:53 +0100 Subject: [PATCH 4/8] refactoring --- source/text/typesetter.ts | 97 ++++++++++++++++----------------------- 1 file changed, 39 insertions(+), 58 deletions(-) diff --git a/source/text/typesetter.ts b/source/text/typesetter.ts index 39f1e676..4d69271a 100644 --- a/source/text/typesetter.ts +++ b/source/text/typesetter.ts @@ -338,6 +338,18 @@ export class Typesetter { } } + /** + * Returns a vec2 [min, max] containing the minimum and the maximum of the given values. + * @param currentMin - the current minimum (e.g., initialized to +Infinity) + * @param currentMax - the current maximum (e.g., initialized to -Infinity) + * @param values - find the maximum and minimum of the given values + */ + private static minMax(currentMin: number, currentMax: number, values: number[]): vec2 { + const min = Math.min(currentMin, ...values); + const max = Math.max(currentMax, ...values); + return vec2.fromValues(min, max); + } + /** * Returns [minX, minY, minZ, maxX, maxY, maxZ] of the vertices coordinates, i.e., origins, * origins + tangents, origins + ups, from which a bounding rectangle can be calculated. @@ -345,63 +357,31 @@ export class Typesetter { * @param begin - Vertex index to start alignment at. * @param end - Vertex index to stop alignment at. */ - private static getMinMax(vertices: GlyphVertices, begin: number, end: number) + private static getMinMaxVertices(vertices: GlyphVertices, begin: number, end: number) : [number, number, number, number, number, number] { - let minX = Math.min( - vertices.origin(begin)[0], - vertices.origin(begin)[0], + vertices.up(begin)[0], - vertices.origin(begin)[0], + vertices.tangent(begin)[0]); - let maxX = Math.max( - vertices.origin(begin)[0], - vertices.origin(begin)[0] + vertices.up(begin)[0], - vertices.origin(begin)[0] + vertices.tangent(begin)[0]); - - let minY = Math.min( - vertices.origin(begin)[1], - vertices.origin(begin)[1] + vertices.up(begin)[1], - vertices.origin(begin)[1] + vertices.tangent(begin)[1]); - let maxY = Math.max( - vertices.origin(begin)[1], - vertices.origin(begin)[1] + vertices.up(begin)[1], - vertices.origin(begin)[1] + vertices.tangent(begin)[1]); - - let minZ = Math.min( - vertices.origin(begin)[2], - vertices.origin(begin)[2] + vertices.up(begin)[2], - vertices.origin(begin)[2] + vertices.tangent(begin)[2]); - let maxZ = Math.max( - vertices.origin(begin)[2], - vertices.origin(begin)[2] + vertices.up(begin)[2], - vertices.origin(begin)[2] + vertices.tangent(begin)[2]); - - for (let i: number = begin + 1; i < end; ++i) { - minX = Math.min(minX, - vertices.origin(i)[0], - vertices.origin(i)[0] + vertices.up(i)[0], - vertices.origin(i)[0] + vertices.tangent(i)[0]); - maxX = Math.max(maxX, - vertices.origin(i)[0], - vertices.origin(i)[0] + vertices.up(i)[0], - vertices.origin(i)[0] + vertices.tangent(i)[0]); - - minY = Math.min(minY, - vertices.origin(i)[1], - vertices.origin(i)[1] + vertices.up(i)[1], - vertices.origin(i)[1] + vertices.tangent(i)[1]); - maxY = Math.max(maxY, - vertices.origin(i)[1], - vertices.origin(i)[1] + vertices.up(i)[1], - vertices.origin(i)[1] + vertices.tangent(i)[1]); - - minZ = Math.min(minZ, - vertices.origin(i)[2], - vertices.origin(i)[2] + vertices.up(i)[2], - vertices.origin(i)[2] + vertices.tangent(i)[2]); - maxZ = Math.max(maxZ, - vertices.origin(i)[2], - vertices.origin(i)[2] + vertices.up(i)[2], - vertices.origin(i)[2] + vertices.tangent(i)[2]); + let minX = Number.POSITIVE_INFINITY; + let maxX = Number.NEGATIVE_INFINITY; + let minY = Number.POSITIVE_INFINITY; + let maxY = Number.NEGATIVE_INFINITY; + let minZ = Number.POSITIVE_INFINITY; + let maxZ = Number.NEGATIVE_INFINITY; + + for (let i: number = begin; i < end; ++i) { + const x = Typesetter.minMax(minX, maxX, [vertices.origin(i)[0], vertices.origin(i)[0] + vertices.up(i)[0], + vertices.origin(i)[0] + vertices.tangent(i)[0]]); + minX = x[0]; + maxX = x[1]; + + const y = Typesetter.minMax(minY, maxY, [vertices.origin(i)[1], vertices.origin(i)[1] + vertices.up(i)[1], + vertices.origin(i)[1] + vertices.tangent(i)[1]]); + minY = y[0]; + maxY = y[1]; + + const z = Typesetter.minMax(minZ, maxZ, [vertices.origin(i)[2], vertices.origin(i)[2] + vertices.up(i)[2], + vertices.origin(i)[2] + vertices.tangent(i)[2]]); + minZ = z[0]; + maxZ = z[1]; } return [minX, minY, minZ, maxX, maxY, maxZ]; @@ -442,12 +422,13 @@ export class Typesetter { private static transform(label: Label, vertices: GlyphVertices, lines: Array): void { const boundingRectangle = [ - Number.MAX_VALUE, Number.MAX_VALUE, Number.MAX_VALUE, - -Number.MAX_VALUE, -Number.MAX_VALUE, -Number.MAX_VALUE]; + Number.POSITIVE_INFINITY, Number.POSITIVE_INFINITY, Number.POSITIVE_INFINITY, + Number.NEGATIVE_INFINITY, Number.NEGATIVE_INFINITY, Number.NEGATIVE_INFINITY]; for (const line of lines) { Typesetter.transformAlignment(line[2], label.alignment, vertices, line[0], line[1]); - Typesetter.updateRectangleMinMax(boundingRectangle, Typesetter.getMinMax(vertices, line[0], line[1])); + Typesetter.updateRectangleMinMax(boundingRectangle, + Typesetter.getMinMaxVertices(vertices, line[0], line[1])); Typesetter.transformVertices(label.staticTransform, vertices, line[0], line[1]); } From a7ada1d97604ea1094653dbd4b8910d16606b3c3 Mon Sep 17 00:00:00 2001 From: anne-gropler Date: Tue, 12 Mar 2019 19:32:49 +0100 Subject: [PATCH 5/8] get extent with dynamic transform applied (I don't know if the values make sense, though...) --- source/text/label.ts | 33 +++++++++++++++------------------ source/text/typesetter.ts | 2 ++ 2 files changed, 17 insertions(+), 18 deletions(-) diff --git a/source/text/label.ts b/source/text/label.ts index 600ba797..8a4fe909 100644 --- a/source/text/label.ts +++ b/source/text/label.ts @@ -1,7 +1,7 @@ /* spellchecker: disable */ -import { mat4, vec3 } from 'gl-matrix'; +import { mat4, vec3, vec4 } from 'gl-matrix'; import { ChangeLookup } from '../changelookup'; import { Color } from '../color'; @@ -460,33 +460,30 @@ export abstract class Label { } /** - * The typesetter sets this extent after typesetting and applying the static transform. + * The typesetter sets this extent after typesetting and applying the static transform. Don't set this manually + * without typesetting. */ set extent(e: [number, number]) { console.log('set extent', e); - // console.log('transforms:', this._type, this._staticTransform, this._dynamicTransform); this._extent = e; - // const w = vec4.fromValues(this._extent[0], 0, 0, 0); - // // vec3.scale(w, w, mat4.getScaling(vec3.create(), this._dynamicTransform)[0]); - // vec4.transformMat4(w, w, this._dynamicTransform); - // const h = vec4.fromValues(0, this._extent[1], 0, 0); - // // vec3.scale(h, h, mat4.getScaling(vec3.create(), this._dynamicTransform)[1]); - // vec4.transformMat4(h, h, this._dynamicTransform); - // console.log('get extent:', vec4.length(w), vec4.length(h)); + // TODO I don't understand these values for labels in screen space + const ll = vec4.transformMat4(vec4.create(), vec4.fromValues(0, 0, 0, 1), this._dynamicTransform); + const lr = vec4.transformMat4(vec4.create(), vec4.fromValues(e[0], 0, 0, 1), this._dynamicTransform); + const ul = vec4.transformMat4(vec4.create(), vec4.fromValues(0, e[1], 0, 1), this._dynamicTransform); + console.log('get extent:', vec4.distance(lr, ll), vec4.distance(ul, ll)); + } /** * Returns the width and height of the typset label. Both are zero if not typeset yet. + * The static transform and the dynamic transform are already applied. */ get extent(): [number, number] { - // console.log('get extent: dynami scale is', mat4.getScaling(vec3.create(), this._dynamicTransform)); - - // const w = vec3.fromValues(this._extent[0], 0, 0); - // vec3.scale(w, w, mat4.getScaling(vec3.create(), this._dynamicTransform)[0]); - // const h = vec3.fromValues(0, this._extent[1], 0); - // vec3.scale(h, h, mat4.getScaling(vec3.create(), this._dynamicTransform)[1]); - // console.log('get extent:', w[0], h[1]); - return this._extent; + + const ll = vec4.transformMat4(vec4.create(), vec4.fromValues(0, 0, 0, 1), this._dynamicTransform); + const lr = vec4.transformMat4(vec4.create(), vec4.fromValues(this._extent[0], 0, 0, 1), this._dynamicTransform); + const ul = vec4.transformMat4(vec4.create(), vec4.fromValues(0, this._extent[1], 0, 1), this._dynamicTransform); + return [vec4.distance(lr, ll), vec4.distance(ul, ll)]; } /* diff --git a/source/text/typesetter.ts b/source/text/typesetter.ts index 4d69271a..dad45eb0 100644 --- a/source/text/typesetter.ts +++ b/source/text/typesetter.ts @@ -427,8 +427,10 @@ export class Typesetter { for (const line of lines) { Typesetter.transformAlignment(line[2], label.alignment, vertices, line[0], line[1]); + Typesetter.updateRectangleMinMax(boundingRectangle, Typesetter.getMinMaxVertices(vertices, line[0], line[1])); + Typesetter.transformVertices(label.staticTransform, vertices, line[0], line[1]); } From e296015cd54e3b51471d70f0091610599f768aa5 Mon Sep 17 00:00:00 2001 From: anne-gropler Date: Wed, 13 Mar 2019 13:25:35 +0100 Subject: [PATCH 6/8] remove logs and unused code --- source/text/label.ts | 18 +++--------------- 1 file changed, 3 insertions(+), 15 deletions(-) diff --git a/source/text/label.ts b/source/text/label.ts index 8a4fe909..ee13c0a1 100644 --- a/source/text/label.ts +++ b/source/text/label.ts @@ -464,26 +464,14 @@ export abstract class Label { * without typesetting. */ set extent(e: [number, number]) { - console.log('set extent', e); this._extent = e; - - // TODO I don't understand these values for labels in screen space - const ll = vec4.transformMat4(vec4.create(), vec4.fromValues(0, 0, 0, 1), this._dynamicTransform); - const lr = vec4.transformMat4(vec4.create(), vec4.fromValues(e[0], 0, 0, 1), this._dynamicTransform); - const ul = vec4.transformMat4(vec4.create(), vec4.fromValues(0, e[1], 0, 1), this._dynamicTransform); - console.log('get extent:', vec4.distance(lr, ll), vec4.distance(ul, ll)); - } /** - * Returns the width and height of the typset label. Both are zero if not typeset yet. - * The static transform and the dynamic transform are already applied. + * Returns the width and height of the typset label in fontSizeUnit. Both are zero if not typeset yet. The static + * transform is already applied. */ get extent(): [number, number] { - - const ll = vec4.transformMat4(vec4.create(), vec4.fromValues(0, 0, 0, 1), this._dynamicTransform); - const lr = vec4.transformMat4(vec4.create(), vec4.fromValues(this._extent[0], 0, 0, 1), this._dynamicTransform); - const ul = vec4.transformMat4(vec4.create(), vec4.fromValues(0, this._extent[1], 0, 1), this._dynamicTransform); - return [vec4.distance(lr, ll), vec4.distance(ul, ll)]; + return this._extent; } /* From a5b2ea097b130fe23b3256c839a56b8c06ee2a9b Mon Sep 17 00:00:00 2001 From: anne-gropler Date: Wed, 13 Mar 2019 13:30:32 +0100 Subject: [PATCH 7/8] remove unused import --- source/text/label.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/text/label.ts b/source/text/label.ts index ee13c0a1..ff56df52 100644 --- a/source/text/label.ts +++ b/source/text/label.ts @@ -1,7 +1,7 @@ /* spellchecker: disable */ -import { mat4, vec3, vec4 } from 'gl-matrix'; +import { mat4, vec3 } from 'gl-matrix'; import { ChangeLookup } from '../changelookup'; import { Color } from '../color'; From 004d5ceed196b7b73a15225718f4399e08d5d558 Mon Sep 17 00:00:00 2001 From: anne-gropler Date: Wed, 13 Mar 2019 13:34:12 +0100 Subject: [PATCH 8/8] refine comment --- source/text/typesetter.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source/text/typesetter.ts b/source/text/typesetter.ts index dad45eb0..29f32a85 100644 --- a/source/text/typesetter.ts +++ b/source/text/typesetter.ts @@ -434,8 +434,8 @@ export class Typesetter { Typesetter.transformVertices(label.staticTransform, vertices, line[0], line[1]); } - // transform extent from Typesetting Space to label space (depending on the label, e.g. screen space (px) or - // world space) + // transform extent from Typesetting Space to the label's fontUnitSize space (depending on the label, e.g. + // screen space (px) or world space) const width = boundingRectangle[3] - boundingRectangle[0]; const height = boundingRectangle[4] - boundingRectangle[1];