@lightningjs/renderer 0.6.1 → 0.7.0
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/dist/src/common/CommonTypes.d.ts +8 -0
- package/dist/src/core/CoreNode.js +45 -16
- package/dist/src/core/CoreNode.js.map +1 -1
- package/dist/src/core/CoreTextNode.d.ts +10 -0
- package/dist/src/core/CoreTextNode.js +45 -0
- package/dist/src/core/CoreTextNode.js.map +1 -1
- package/dist/src/core/CoreTextureManager.d.ts +3 -1
- package/dist/src/core/CoreTextureManager.js +4 -1
- package/dist/src/core/CoreTextureManager.js.map +1 -1
- package/dist/src/core/Stage.d.ts +6 -0
- package/dist/src/core/Stage.js +12 -3
- package/dist/src/core/Stage.js.map +1 -1
- package/dist/src/core/lib/ImageWorker.d.ts +16 -0
- package/dist/src/core/lib/ImageWorker.js +111 -0
- package/dist/src/core/lib/ImageWorker.js.map +1 -0
- package/dist/src/core/lib/WebGlContextWrapper.d.ts +4 -0
- package/dist/src/core/lib/WebGlContextWrapper.js +7 -2
- package/dist/src/core/lib/WebGlContextWrapper.js.map +1 -1
- package/dist/src/core/renderers/webgl/WebGlCoreCtxSubTexture.d.ts +2 -1
- package/dist/src/core/renderers/webgl/WebGlCoreCtxSubTexture.js +2 -2
- package/dist/src/core/renderers/webgl/WebGlCoreCtxSubTexture.js.map +1 -1
- package/dist/src/core/renderers/webgl/WebGlCoreCtxTexture.d.ts +3 -2
- package/dist/src/core/renderers/webgl/WebGlCoreCtxTexture.js +23 -21
- package/dist/src/core/renderers/webgl/WebGlCoreCtxTexture.js.map +1 -1
- package/dist/src/core/renderers/webgl/WebGlCoreRenderOp.d.ts +3 -2
- package/dist/src/core/renderers/webgl/WebGlCoreRenderOp.js +9 -13
- package/dist/src/core/renderers/webgl/WebGlCoreRenderOp.js.map +1 -1
- package/dist/src/core/renderers/webgl/WebGlCoreRenderer.d.ts +4 -1
- package/dist/src/core/renderers/webgl/WebGlCoreRenderer.js +25 -24
- package/dist/src/core/renderers/webgl/WebGlCoreRenderer.js.map +1 -1
- package/dist/src/core/renderers/webgl/WebGlCoreShader.d.ts +2 -1
- package/dist/src/core/renderers/webgl/WebGlCoreShader.js +24 -24
- package/dist/src/core/renderers/webgl/WebGlCoreShader.js.map +1 -1
- package/dist/src/core/renderers/webgl/internal/RendererUtils.d.ts +8 -5
- package/dist/src/core/renderers/webgl/internal/RendererUtils.js +11 -13
- package/dist/src/core/renderers/webgl/internal/RendererUtils.js.map +1 -1
- package/dist/src/core/renderers/webgl/internal/ShaderUtils.d.ts +3 -2
- package/dist/src/core/renderers/webgl/internal/ShaderUtils.js +15 -15
- package/dist/src/core/renderers/webgl/internal/ShaderUtils.js.map +1 -1
- package/dist/src/core/renderers/webgl/shaders/DefaultShader.js +3 -6
- package/dist/src/core/renderers/webgl/shaders/DefaultShader.js.map +1 -1
- package/dist/src/core/renderers/webgl/shaders/DefaultShaderBatched.js +3 -3
- package/dist/src/core/renderers/webgl/shaders/DefaultShaderBatched.js.map +1 -1
- package/dist/src/core/renderers/webgl/shaders/DynamicShader.d.ts +1 -0
- package/dist/src/core/renderers/webgl/shaders/DynamicShader.js +32 -12
- package/dist/src/core/renderers/webgl/shaders/DynamicShader.js.map +1 -1
- package/dist/src/core/renderers/webgl/shaders/RoundedRectangle.js +3 -3
- package/dist/src/core/renderers/webgl/shaders/RoundedRectangle.js.map +1 -1
- package/dist/src/core/renderers/webgl/shaders/SdfShader.js +3 -3
- package/dist/src/core/renderers/webgl/shaders/SdfShader.js.map +1 -1
- package/dist/src/core/renderers/webgl/shaders/effects/BorderEffect.js +1 -1
- package/dist/src/core/renderers/webgl/shaders/effects/GrayscaleEffect.d.ts +14 -1
- package/dist/src/core/renderers/webgl/shaders/effects/GrayscaleEffect.js +15 -5
- package/dist/src/core/renderers/webgl/shaders/effects/GrayscaleEffect.js.map +1 -1
- package/dist/src/core/text-rendering/font-face-types/SdfTrFontFace/SdfTrFontFace.js +3 -3
- package/dist/src/core/text-rendering/font-face-types/SdfTrFontFace/SdfTrFontFace.js.map +1 -1
- package/dist/src/core/text-rendering/font-face-types/SdfTrFontFace/internal/SdfFontShaper.d.ts +2 -1
- package/dist/src/core/text-rendering/font-face-types/SdfTrFontFace/internal/SdfFontShaper.js +4 -2
- package/dist/src/core/text-rendering/font-face-types/SdfTrFontFace/internal/SdfFontShaper.js.map +1 -1
- package/dist/src/core/text-rendering/renderers/CanvasTextRenderer.js +25 -0
- package/dist/src/core/text-rendering/renderers/CanvasTextRenderer.js.map +1 -1
- package/dist/src/core/text-rendering/renderers/LightningTextTextureRenderer.d.ts +1 -1
- package/dist/src/core/text-rendering/renderers/LightningTextTextureRenderer.js +6 -6
- package/dist/src/core/text-rendering/renderers/LightningTextTextureRenderer.js.map +1 -1
- package/dist/src/core/text-rendering/renderers/SdfTextRenderer/SdfTextRenderer.d.ts +3 -2
- package/dist/src/core/text-rendering/renderers/SdfTextRenderer/SdfTextRenderer.js +82 -50
- package/dist/src/core/text-rendering/renderers/SdfTextRenderer/SdfTextRenderer.js.map +1 -1
- package/dist/src/core/text-rendering/renderers/SdfTextRenderer/internal/findNearestMultiple.d.ts +8 -0
- package/dist/src/core/text-rendering/renderers/SdfTextRenderer/internal/findNearestMultiple.js +29 -0
- package/dist/src/core/text-rendering/renderers/SdfTextRenderer/internal/findNearestMultiple.js.map +1 -0
- package/dist/src/core/text-rendering/renderers/SdfTextRenderer/internal/getStartConditions.d.ts +4 -3
- package/dist/src/core/text-rendering/renderers/SdfTextRenderer/internal/getStartConditions.js +15 -11
- package/dist/src/core/text-rendering/renderers/SdfTextRenderer/internal/getStartConditions.js.map +1 -1
- package/dist/src/core/text-rendering/renderers/SdfTextRenderer/internal/layoutText.d.ts +3 -2
- package/dist/src/core/text-rendering/renderers/SdfTextRenderer/internal/layoutText.js +30 -26
- package/dist/src/core/text-rendering/renderers/SdfTextRenderer/internal/layoutText.js.map +1 -1
- package/dist/src/core/text-rendering/renderers/SdfTextRenderer/internal/layoutText2/SdfBufferHelper.d.ts +19 -0
- package/dist/src/core/text-rendering/renderers/SdfTextRenderer/internal/layoutText2/SdfBufferHelper.js +84 -0
- package/dist/src/core/text-rendering/renderers/SdfTextRenderer/internal/layoutText2/SdfBufferHelper.js.map +1 -0
- package/dist/src/core/text-rendering/renderers/SdfTextRenderer/internal/layoutText2/layoutLine.d.ts +8 -0
- package/dist/src/core/text-rendering/renderers/SdfTextRenderer/internal/layoutText2/layoutLine.js +40 -0
- package/dist/src/core/text-rendering/renderers/SdfTextRenderer/internal/layoutText2/layoutLine.js.map +1 -0
- package/dist/src/core/text-rendering/renderers/SdfTextRenderer/internal/layoutText2/layoutText2.d.ts +2 -0
- package/dist/src/core/text-rendering/renderers/SdfTextRenderer/internal/layoutText2/layoutText2.js +41 -0
- package/dist/src/core/text-rendering/renderers/SdfTextRenderer/internal/layoutText2/layoutText2.js.map +1 -0
- package/dist/src/core/text-rendering/renderers/SdfTextRenderer/internal/layoutText2/utils.d.ts +1 -0
- package/dist/src/core/text-rendering/renderers/SdfTextRenderer/internal/layoutText2/utils.js +4 -0
- package/dist/src/core/text-rendering/renderers/SdfTextRenderer/internal/layoutText2/utils.js.map +1 -0
- package/dist/src/core/text-rendering/renderers/SdfTextRenderer/internal/layoutText2.d.ts +1 -0
- package/dist/src/core/text-rendering/renderers/SdfTextRenderer/internal/layoutText2.js +2 -0
- package/dist/src/core/text-rendering/renderers/SdfTextRenderer/internal/layoutText2.js.map +1 -0
- package/dist/src/core/text-rendering/renderers/SdfTextRenderer/internal/roundUpToMultiple.d.ts +9 -0
- package/dist/src/core/text-rendering/renderers/SdfTextRenderer/internal/roundUpToMultiple.js +32 -0
- package/dist/src/core/text-rendering/renderers/SdfTextRenderer/internal/roundUpToMultiple.js.map +1 -0
- package/dist/src/core/text-rendering/renderers/SdfTextRenderer/internal/setRenderWindow.d.ts +26 -0
- package/dist/src/core/text-rendering/renderers/SdfTextRenderer/internal/setRenderWindow.js +70 -0
- package/dist/src/core/text-rendering/renderers/SdfTextRenderer/internal/setRenderWindow.js.map +1 -0
- package/dist/src/core/text-rendering/renderers/SdfTextRenderer/internal/util.d.ts +16 -0
- package/dist/src/core/text-rendering/renderers/SdfTextRenderer/internal/util.js +39 -0
- package/dist/src/core/text-rendering/renderers/SdfTextRenderer/internal/util.js.map +1 -0
- package/dist/src/core/text-rendering/renderers/TextRenderer.d.ts +50 -0
- package/dist/src/core/text-rendering/renderers/TextRenderer.js +19 -0
- package/dist/src/core/text-rendering/renderers/TextRenderer.js.map +1 -1
- package/dist/src/core/textures/ImageTexture.js +14 -9
- package/dist/src/core/textures/ImageTexture.js.map +1 -1
- package/dist/src/core/utils.d.ts +1 -6
- package/dist/src/core/utils.js +3 -2
- package/dist/src/core/utils.js.map +1 -1
- package/dist/src/main-api/ICoreDriver.d.ts +2 -1
- package/dist/src/main-api/RendererMain.d.ts +25 -0
- package/dist/src/main-api/RendererMain.js +14 -5
- package/dist/src/main-api/RendererMain.js.map +1 -1
- package/dist/src/render-drivers/main/MainCoreDriver.d.ts +2 -1
- package/dist/src/render-drivers/main/MainCoreDriver.js +6 -4
- package/dist/src/render-drivers/main/MainCoreDriver.js.map +1 -1
- package/dist/src/render-drivers/main/MainOnlyTextNode.d.ts +10 -0
- package/dist/src/render-drivers/main/MainOnlyTextNode.js +45 -0
- package/dist/src/render-drivers/main/MainOnlyTextNode.js.map +1 -1
- package/dist/src/render-drivers/threadx/TextNodeStruct.d.ts +10 -0
- package/dist/src/render-drivers/threadx/TextNodeStruct.js +45 -0
- package/dist/src/render-drivers/threadx/TextNodeStruct.js.map +1 -1
- package/dist/src/render-drivers/threadx/ThreadXCoreDriver.d.ts +2 -1
- package/dist/src/render-drivers/threadx/ThreadXCoreDriver.js +8 -1
- package/dist/src/render-drivers/threadx/ThreadXCoreDriver.js.map +1 -1
- package/dist/src/render-drivers/threadx/ThreadXMainTextNode.d.ts +5 -0
- package/dist/src/render-drivers/threadx/ThreadXMainTextNode.js +5 -0
- package/dist/src/render-drivers/threadx/ThreadXMainTextNode.js.map +1 -1
- package/dist/src/render-drivers/threadx/ThreadXRendererMessage.d.ts +4 -1
- package/dist/src/render-drivers/threadx/ThreadXRendererMessage.js.map +1 -1
- package/dist/src/render-drivers/threadx/worker/ThreadXRendererTextNode.d.ts +5 -0
- package/dist/src/render-drivers/threadx/worker/ThreadXRendererTextNode.js +10 -0
- package/dist/src/render-drivers/threadx/worker/ThreadXRendererTextNode.js.map +1 -1
- package/dist/src/render-drivers/threadx/worker/renderer.js +5 -3
- package/dist/src/render-drivers/threadx/worker/renderer.js.map +1 -1
- package/dist/src/utils.d.ts +2 -1
- package/dist/src/utils.js +22 -3
- package/dist/src/utils.js.map +1 -1
- package/dist/tsconfig.dist.tsbuildinfo +1 -1
- package/package.json +3 -2
- package/src/common/CommonTypes.ts +9 -0
- package/src/core/CoreNode.ts +67 -34
- package/src/core/CoreTextNode.ts +56 -0
- package/src/core/CoreTextureManager.ts +4 -2
- package/src/core/Stage.ts +32 -3
- package/src/core/lib/ContextSpy.ts +41 -0
- package/src/core/lib/ImageWorker.ts +124 -0
- package/src/core/lib/WebGlContextWrapper.ts +965 -0
- package/src/core/renderers/webgl/WebGlCoreCtxSubTexture.ts +3 -2
- package/src/core/renderers/webgl/WebGlCoreCtxTexture.ts +29 -28
- package/src/core/renderers/webgl/WebGlCoreRenderOp.ts +10 -14
- package/src/core/renderers/webgl/WebGlCoreRenderer.ts +26 -24
- package/src/core/renderers/webgl/WebGlCoreShader.ts +34 -25
- package/src/core/renderers/webgl/internal/RendererUtils.ts +13 -16
- package/src/core/renderers/webgl/internal/ShaderUtils.ts +16 -15
- package/src/core/renderers/webgl/shaders/DefaultShader.ts +3 -7
- package/src/core/renderers/webgl/shaders/DefaultShaderBatched.ts +3 -3
- package/src/core/renderers/webgl/shaders/DynamicShader.ts +42 -14
- package/src/core/renderers/webgl/shaders/RoundedRectangle.ts +3 -3
- package/src/core/renderers/webgl/shaders/SdfShader.ts +3 -3
- package/src/core/renderers/webgl/shaders/effects/BorderEffect.ts +1 -1
- package/src/core/renderers/webgl/shaders/effects/GrayscaleEffect.ts +35 -5
- package/src/core/text-rendering/font-face-types/SdfTrFontFace/SdfTrFontFace.ts +3 -3
- package/src/core/text-rendering/font-face-types/SdfTrFontFace/internal/SdfFontShaper.test.ts +9 -3
- package/src/core/text-rendering/font-face-types/SdfTrFontFace/internal/SdfFontShaper.ts +4 -2
- package/src/core/text-rendering/renderers/CanvasTextRenderer.ts +25 -0
- package/src/core/text-rendering/renderers/LightningTextTextureRenderer.ts +7 -7
- package/src/core/text-rendering/renderers/SdfTextRenderer/SdfTextRenderer.ts +115 -63
- package/src/core/text-rendering/renderers/SdfTextRenderer/internal/getStartConditions.ts +26 -18
- package/src/core/text-rendering/renderers/SdfTextRenderer/internal/layoutText.ts +40 -28
- package/src/core/text-rendering/renderers/SdfTextRenderer/internal/measureText.test.ts +6 -1
- package/src/core/text-rendering/renderers/SdfTextRenderer/internal/setRenderWindow.test.ts +205 -0
- package/src/core/text-rendering/renderers/SdfTextRenderer/internal/{makeRenderWindow.ts → setRenderWindow.ts} +50 -21
- package/src/core/text-rendering/renderers/SdfTextRenderer/internal/util.ts +40 -0
- package/src/core/text-rendering/renderers/TextRenderer.ts +73 -0
- package/src/core/textures/ImageTexture.ts +17 -9
- package/src/core/utils.ts +87 -85
- package/src/env.d.ts +7 -0
- package/src/main-api/ICoreDriver.ts +2 -1
- package/src/main-api/RendererMain.ts +43 -5
- package/src/render-drivers/main/MainCoreDriver.ts +8 -5
- package/src/render-drivers/main/MainOnlyTextNode.ts +55 -1
- package/src/render-drivers/threadx/TextNodeStruct.ts +45 -0
- package/src/render-drivers/threadx/ThreadXCoreDriver.ts +10 -2
- package/src/render-drivers/threadx/ThreadXMainTextNode.ts +10 -0
- package/src/render-drivers/threadx/ThreadXRendererMessage.ts +5 -1
- package/src/render-drivers/threadx/worker/ThreadXRendererTextNode.ts +15 -0
- package/src/render-drivers/threadx/worker/renderer.ts +6 -4
- package/src/utils.ts +25 -4
- package/src/core/text-rendering/renderers/SdfTextRenderer/internal/makeRenderWindow.test.ts +0 -136
|
@@ -23,6 +23,8 @@ import {
|
|
|
23
23
|
type Rect,
|
|
24
24
|
createBound,
|
|
25
25
|
type BoundWithValid,
|
|
26
|
+
intersectRect,
|
|
27
|
+
isBoundPositive,
|
|
26
28
|
} from '../../../lib/utils.js';
|
|
27
29
|
import {
|
|
28
30
|
TextRenderer,
|
|
@@ -35,7 +37,10 @@ import { SdfTrFontFace } from '../../font-face-types/SdfTrFontFace/SdfTrFontFace
|
|
|
35
37
|
import { FLOATS_PER_GLYPH } from './internal/constants.js';
|
|
36
38
|
import { getStartConditions } from './internal/getStartConditions.js';
|
|
37
39
|
import { layoutText } from './internal/layoutText.js';
|
|
38
|
-
import {
|
|
40
|
+
import {
|
|
41
|
+
setRenderWindow,
|
|
42
|
+
type SdfRenderWindow,
|
|
43
|
+
} from './internal/setRenderWindow.js';
|
|
39
44
|
import type { TrFontFace } from '../../font-face-types/TrFontFace.js';
|
|
40
45
|
import { TrFontManager, type FontFamilyMap } from '../../TrFontManager.js';
|
|
41
46
|
import { assertTruthy, mergeColorAlpha } from '../../../../utils.js';
|
|
@@ -77,7 +82,7 @@ export interface SdfTextRendererState extends TextRendererState {
|
|
|
77
82
|
*/
|
|
78
83
|
lineCache: LineCacheItem[];
|
|
79
84
|
|
|
80
|
-
renderWindow:
|
|
85
|
+
renderWindow: SdfRenderWindow;
|
|
81
86
|
|
|
82
87
|
visibleWindow: BoundWithValid;
|
|
83
88
|
|
|
@@ -209,6 +214,26 @@ export class SdfTextRenderer extends TextRenderer<SdfTextRendererState> {
|
|
|
209
214
|
state.props.letterSpacing = value;
|
|
210
215
|
this.invalidateLayoutCache(state);
|
|
211
216
|
},
|
|
217
|
+
lineHeight: (state, value) => {
|
|
218
|
+
state.props.lineHeight = value;
|
|
219
|
+
this.invalidateLayoutCache(state);
|
|
220
|
+
},
|
|
221
|
+
maxLines: (state, value) => {
|
|
222
|
+
state.props.maxLines = value;
|
|
223
|
+
this.invalidateLayoutCache(state);
|
|
224
|
+
},
|
|
225
|
+
textBaseline: (state, value) => {
|
|
226
|
+
state.props.textBaseline = value;
|
|
227
|
+
this.invalidateLayoutCache(state);
|
|
228
|
+
},
|
|
229
|
+
verticalAlign: (state, value) => {
|
|
230
|
+
state.props.verticalAlign = value;
|
|
231
|
+
this.invalidateLayoutCache(state);
|
|
232
|
+
},
|
|
233
|
+
overflowSuffix: (state, value) => {
|
|
234
|
+
state.props.overflowSuffix = value;
|
|
235
|
+
this.invalidateLayoutCache(state);
|
|
236
|
+
},
|
|
212
237
|
debug: (state, value) => {
|
|
213
238
|
state.props.debug = value;
|
|
214
239
|
},
|
|
@@ -262,7 +287,23 @@ export class SdfTextRenderer extends TextRenderer<SdfTextRendererState> {
|
|
|
262
287
|
emitter: new EventEmitter(),
|
|
263
288
|
lineCache: [],
|
|
264
289
|
forceFullLayoutCalc: false,
|
|
265
|
-
renderWindow:
|
|
290
|
+
renderWindow: {
|
|
291
|
+
screen: {
|
|
292
|
+
x1: 0,
|
|
293
|
+
y1: 0,
|
|
294
|
+
x2: 0,
|
|
295
|
+
y2: 0,
|
|
296
|
+
},
|
|
297
|
+
sdf: {
|
|
298
|
+
x1: 0,
|
|
299
|
+
y1: 0,
|
|
300
|
+
x2: 0,
|
|
301
|
+
y2: 0,
|
|
302
|
+
},
|
|
303
|
+
firstLineIdx: 0,
|
|
304
|
+
numLines: 0,
|
|
305
|
+
valid: false,
|
|
306
|
+
},
|
|
266
307
|
visibleWindow: {
|
|
267
308
|
x1: 0,
|
|
268
309
|
y1: 0,
|
|
@@ -325,22 +366,39 @@ export class SdfTextRenderer extends TextRenderer<SdfTextRendererState> {
|
|
|
325
366
|
// If the font is loaded then so should the data
|
|
326
367
|
assertTruthy(trFontFace.data, 'Font face data should be loaded');
|
|
327
368
|
|
|
328
|
-
const {
|
|
329
|
-
|
|
369
|
+
const {
|
|
370
|
+
text,
|
|
371
|
+
fontSize,
|
|
372
|
+
x,
|
|
373
|
+
y,
|
|
374
|
+
contain,
|
|
375
|
+
width,
|
|
376
|
+
height,
|
|
377
|
+
lineHeight,
|
|
378
|
+
verticalAlign,
|
|
379
|
+
scrollable,
|
|
380
|
+
overflowSuffix,
|
|
381
|
+
maxLines,
|
|
382
|
+
} = state.props;
|
|
330
383
|
|
|
331
384
|
// scrollY only has an effect when contain === 'both' and scrollable === true
|
|
332
385
|
const scrollY = contain === 'both' && scrollable ? state.props.scrollY : 0;
|
|
333
386
|
|
|
334
|
-
|
|
387
|
+
const { renderWindow } = state;
|
|
335
388
|
|
|
336
|
-
|
|
337
|
-
|
|
389
|
+
/**
|
|
390
|
+
* The font size of the SDF font face (the basis for SDF space units)
|
|
391
|
+
*/
|
|
392
|
+
const sdfFontSize = trFontFace.data.info.size;
|
|
338
393
|
|
|
339
394
|
/**
|
|
340
|
-
* Divide screen space
|
|
341
|
-
* Mulitple SDF space
|
|
395
|
+
* Divide screen space units by this to get the SDF space units
|
|
396
|
+
* Mulitple SDF space units by this to get screen space units
|
|
342
397
|
*/
|
|
343
|
-
const fontSizeRatio = fontSize /
|
|
398
|
+
const fontSizeRatio = fontSize / sdfFontSize;
|
|
399
|
+
|
|
400
|
+
// Needed in renderWindow calculation
|
|
401
|
+
const sdfLineHeight = lineHeight / fontSizeRatio;
|
|
344
402
|
|
|
345
403
|
state.distanceRange =
|
|
346
404
|
fontSizeRatio * trFontFace.data.distanceField.distanceRange;
|
|
@@ -373,44 +431,46 @@ export class SdfTextRenderer extends TextRenderer<SdfTextRendererState> {
|
|
|
373
431
|
// Return early if we're still viewing inside the established render window
|
|
374
432
|
// No need to re-render what we've already rendered
|
|
375
433
|
// (Only if there's an established renderWindow and we're not suppressing early exit)
|
|
376
|
-
if (!forceFullLayoutCalc && renderWindow) {
|
|
434
|
+
if (!forceFullLayoutCalc && renderWindow.valid) {
|
|
435
|
+
const rwScreen = renderWindow.screen;
|
|
377
436
|
if (
|
|
378
|
-
x +
|
|
379
|
-
x +
|
|
380
|
-
y - scrollY +
|
|
381
|
-
y - scrollY +
|
|
437
|
+
x + rwScreen.x1 <= visibleWindow.x1 &&
|
|
438
|
+
x + rwScreen.x2 >= visibleWindow.x2 &&
|
|
439
|
+
y - scrollY + rwScreen.y1 <= visibleWindow.y1 &&
|
|
440
|
+
y - scrollY + rwScreen.y2 >= visibleWindow.y2
|
|
382
441
|
) {
|
|
383
442
|
this.setStatus(state, 'loaded');
|
|
384
443
|
return;
|
|
385
444
|
}
|
|
386
|
-
// Otherwise
|
|
387
|
-
renderWindow
|
|
445
|
+
// Otherwise invalidate the renderWindow so it can be redone
|
|
446
|
+
renderWindow.valid = false;
|
|
388
447
|
this.setStatus(state, 'loading');
|
|
389
448
|
}
|
|
390
449
|
|
|
391
450
|
const { offsetY, textAlign } = state.props;
|
|
392
451
|
|
|
393
452
|
// Create a new renderWindow if needed
|
|
394
|
-
if (!renderWindow) {
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
visibleWindowHeight / sdfLineHeight,
|
|
398
|
-
);
|
|
399
|
-
renderWindow = makeRenderWindow(
|
|
453
|
+
if (!renderWindow.valid) {
|
|
454
|
+
setRenderWindow(
|
|
455
|
+
renderWindow,
|
|
400
456
|
x,
|
|
401
457
|
y,
|
|
402
458
|
scrollY,
|
|
403
|
-
|
|
404
|
-
|
|
459
|
+
lineHeight,
|
|
460
|
+
visibleWindow.y2 - visibleWindow.y1,
|
|
405
461
|
visibleWindow,
|
|
462
|
+
fontSizeRatio,
|
|
406
463
|
);
|
|
464
|
+
// console.log('newRenderWindow', renderWindow);
|
|
407
465
|
}
|
|
408
466
|
|
|
409
467
|
const start = getStartConditions(
|
|
410
|
-
|
|
468
|
+
sdfFontSize,
|
|
469
|
+
sdfLineHeight,
|
|
470
|
+
lineHeight,
|
|
471
|
+
verticalAlign,
|
|
411
472
|
offsetY,
|
|
412
473
|
fontSizeRatio,
|
|
413
|
-
sdfLineHeight,
|
|
414
474
|
renderWindow,
|
|
415
475
|
lineCache,
|
|
416
476
|
textH,
|
|
@@ -427,21 +487,24 @@ export class SdfTextRenderer extends TextRenderer<SdfTextRendererState> {
|
|
|
427
487
|
|
|
428
488
|
const out2 = layoutText(
|
|
429
489
|
start.lineIndex,
|
|
430
|
-
start.
|
|
431
|
-
start.
|
|
490
|
+
start.sdfX,
|
|
491
|
+
start.sdfY,
|
|
432
492
|
text,
|
|
433
493
|
textAlign,
|
|
434
494
|
width,
|
|
435
495
|
height,
|
|
436
496
|
fontSize,
|
|
497
|
+
lineHeight,
|
|
437
498
|
letterSpacing,
|
|
438
499
|
vertexBuffer,
|
|
439
500
|
contain,
|
|
440
501
|
lineCache,
|
|
441
|
-
renderWindow,
|
|
502
|
+
renderWindow.sdf,
|
|
442
503
|
trFontFace,
|
|
443
504
|
forceFullLayoutCalc,
|
|
444
505
|
scrollable,
|
|
506
|
+
overflowSuffix,
|
|
507
|
+
maxLines,
|
|
445
508
|
);
|
|
446
509
|
|
|
447
510
|
state.bufferUploaded = false;
|
|
@@ -476,14 +539,8 @@ export class SdfTextRenderer extends TextRenderer<SdfTextRendererState> {
|
|
|
476
539
|
return;
|
|
477
540
|
}
|
|
478
541
|
|
|
479
|
-
const drawStartTime = performance.now();
|
|
480
|
-
|
|
481
|
-
const { sdfShader } = this;
|
|
482
|
-
|
|
483
542
|
const { renderer } = this.stage;
|
|
484
543
|
|
|
485
|
-
const { appWidth, appHeight } = this.stage.options;
|
|
486
|
-
|
|
487
544
|
const { fontSize, color, contain, scrollable, zIndex, debug } = state.props;
|
|
488
545
|
|
|
489
546
|
// scrollY only has an effect when contain === 'both' and scrollable === true
|
|
@@ -501,9 +558,9 @@ export class SdfTextRenderer extends TextRenderer<SdfTextRendererState> {
|
|
|
501
558
|
let { webGlBuffers } = state;
|
|
502
559
|
|
|
503
560
|
if (!webGlBuffers) {
|
|
504
|
-
const
|
|
561
|
+
const glw = renderer.glw;
|
|
505
562
|
const stride = 4 * Float32Array.BYTES_PER_ELEMENT;
|
|
506
|
-
const webGlBuffer =
|
|
563
|
+
const webGlBuffer = glw.createBuffer();
|
|
507
564
|
assertTruthy(webGlBuffer);
|
|
508
565
|
state.webGlBuffers = new BufferCollection([
|
|
509
566
|
{
|
|
@@ -512,7 +569,7 @@ export class SdfTextRenderer extends TextRenderer<SdfTextRendererState> {
|
|
|
512
569
|
a_position: {
|
|
513
570
|
name: 'a_position',
|
|
514
571
|
size: 2, // 2 components per iteration
|
|
515
|
-
type:
|
|
572
|
+
type: glw.FLOAT, // the data is 32bit floats
|
|
516
573
|
normalized: false, // don't normalize the data
|
|
517
574
|
stride, // 0 = move forward size * sizeof(type) each iteration to get the next position
|
|
518
575
|
offset: 0, // start at the beginning of the buffer
|
|
@@ -520,7 +577,7 @@ export class SdfTextRenderer extends TextRenderer<SdfTextRendererState> {
|
|
|
520
577
|
a_textureCoordinate: {
|
|
521
578
|
name: 'a_textureCoordinate',
|
|
522
579
|
size: 2,
|
|
523
|
-
type:
|
|
580
|
+
type: glw.FLOAT,
|
|
524
581
|
normalized: false,
|
|
525
582
|
stride,
|
|
526
583
|
offset: 2 * Float32Array.BYTES_PER_ELEMENT,
|
|
@@ -534,18 +591,30 @@ export class SdfTextRenderer extends TextRenderer<SdfTextRendererState> {
|
|
|
534
591
|
}
|
|
535
592
|
|
|
536
593
|
if (!bufferUploaded) {
|
|
537
|
-
const
|
|
594
|
+
const glw = renderer.glw;
|
|
538
595
|
|
|
539
596
|
const buffer = webGlBuffers?.getBuffer('a_textureCoordinate') ?? null;
|
|
540
|
-
|
|
541
|
-
gl.bufferData(gl.ARRAY_BUFFER, vertexBuffer, gl.STATIC_DRAW);
|
|
597
|
+
glw.arrayBufferData(buffer, vertexBuffer, glw.STATIC_DRAW);
|
|
542
598
|
state.bufferUploaded = true;
|
|
543
599
|
}
|
|
544
600
|
|
|
545
601
|
assertTruthy(trFontFace);
|
|
546
602
|
|
|
603
|
+
if (scrollable && contain === 'both') {
|
|
604
|
+
const visibleWindowRect: Rect = {
|
|
605
|
+
x: state.visibleWindow.x1,
|
|
606
|
+
y: state.visibleWindow.y1,
|
|
607
|
+
width: state.visibleWindow.x2 - state.visibleWindow.x1,
|
|
608
|
+
height: state.visibleWindow.y2 - state.visibleWindow.y1,
|
|
609
|
+
};
|
|
610
|
+
|
|
611
|
+
clippingRect = clippingRect
|
|
612
|
+
? intersectRect(clippingRect, visibleWindowRect)
|
|
613
|
+
: visibleWindowRect;
|
|
614
|
+
}
|
|
615
|
+
|
|
547
616
|
const renderOp = new WebGlCoreRenderOp(
|
|
548
|
-
renderer.
|
|
617
|
+
renderer.glw,
|
|
549
618
|
renderer.options,
|
|
550
619
|
webGlBuffers,
|
|
551
620
|
this.sdfShader,
|
|
@@ -577,23 +646,6 @@ export class SdfTextRenderer extends TextRenderer<SdfTextRendererState> {
|
|
|
577
646
|
|
|
578
647
|
renderer.addRenderOp(renderOp);
|
|
579
648
|
|
|
580
|
-
// const elementRect = {
|
|
581
|
-
// x: x,
|
|
582
|
-
// y: y,
|
|
583
|
-
// w: contain !== 'none' ? width : textW,
|
|
584
|
-
// h: contain === 'both' ? height : textH,
|
|
585
|
-
// };
|
|
586
|
-
|
|
587
|
-
// const visibleRect = intersectRect(
|
|
588
|
-
// {
|
|
589
|
-
// x: 0,
|
|
590
|
-
// y: 0,
|
|
591
|
-
// w: renderer.w,
|
|
592
|
-
// h: renderer.h,
|
|
593
|
-
// },
|
|
594
|
-
// elementRect,
|
|
595
|
-
// );
|
|
596
|
-
|
|
597
649
|
// if (!debug.disableScissor) {
|
|
598
650
|
// renderer.enableScissor(
|
|
599
651
|
// visibleRect.x,
|
|
@@ -677,7 +729,7 @@ export class SdfTextRenderer extends TextRenderer<SdfTextRendererState> {
|
|
|
677
729
|
*/
|
|
678
730
|
protected invalidateLayoutCache(state: SdfTextRendererState): void {
|
|
679
731
|
state.visibleWindow.valid = false;
|
|
680
|
-
state.renderWindow =
|
|
732
|
+
state.renderWindow.valid = false;
|
|
681
733
|
state.textH = undefined;
|
|
682
734
|
state.textW = undefined;
|
|
683
735
|
state.lineCache = [];
|
|
@@ -17,8 +17,10 @@
|
|
|
17
17
|
* limitations under the License.
|
|
18
18
|
*/
|
|
19
19
|
|
|
20
|
+
import type { Bound } from '../../../../lib/utils.js';
|
|
20
21
|
import type { TrProps, TextRendererState } from '../../TextRenderer.js';
|
|
21
22
|
import type { SdfTextRendererState } from '../SdfTextRenderer.js';
|
|
23
|
+
import type { SdfRenderWindow } from './setRenderWindow.js';
|
|
22
24
|
|
|
23
25
|
/**
|
|
24
26
|
* Gets the start conditions for the layout loop.
|
|
@@ -35,42 +37,48 @@ import type { SdfTextRendererState } from '../SdfTextRenderer.js';
|
|
|
35
37
|
* @returns
|
|
36
38
|
*/
|
|
37
39
|
export function getStartConditions(
|
|
38
|
-
|
|
40
|
+
sdfFontSize: number,
|
|
41
|
+
sdfLineHeight: number,
|
|
42
|
+
lineHeight: number,
|
|
43
|
+
verticalAlign: TrProps['verticalAlign'],
|
|
39
44
|
offsetY: TrProps['offsetY'],
|
|
40
45
|
fontSizeRatio: number,
|
|
41
|
-
|
|
42
|
-
renderWindow: SdfTextRendererState['renderWindow'],
|
|
46
|
+
renderWindow: SdfRenderWindow,
|
|
43
47
|
lineCache: SdfTextRendererState['lineCache'],
|
|
44
48
|
textH: TextRendererState['textH'],
|
|
45
49
|
):
|
|
46
50
|
| {
|
|
47
|
-
|
|
48
|
-
|
|
51
|
+
sdfX: number;
|
|
52
|
+
sdfY: number;
|
|
49
53
|
lineIndex: number;
|
|
50
54
|
}
|
|
51
55
|
| undefined {
|
|
52
56
|
// State variables
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
lineCache.length,
|
|
58
|
-
);
|
|
59
|
-
}
|
|
57
|
+
const startLineIndex = Math.min(
|
|
58
|
+
Math.max(renderWindow.firstLineIdx, 0),
|
|
59
|
+
lineCache.length,
|
|
60
|
+
);
|
|
60
61
|
|
|
61
|
-
// TODO: Possibly break out startX / startY into a separate function
|
|
62
62
|
// TODO: (fontSize / 6.4286 / fontSizeRatio) Adding this to the startY helps the text line up better with Canvas rendered text
|
|
63
|
-
const
|
|
64
|
-
|
|
63
|
+
const sdfStartX = 0;
|
|
64
|
+
let sdfVerticalAlignYOffset = 0;
|
|
65
|
+
if (verticalAlign === 'middle') {
|
|
66
|
+
sdfVerticalAlignYOffset = (sdfLineHeight - sdfFontSize) / 2;
|
|
67
|
+
} else if (verticalAlign === 'bottom') {
|
|
68
|
+
sdfVerticalAlignYOffset = sdfLineHeight - sdfFontSize;
|
|
69
|
+
}
|
|
70
|
+
const sdfOffsetY = offsetY / fontSizeRatio;
|
|
71
|
+
const sdfStartY =
|
|
72
|
+
sdfOffsetY + startLineIndex * sdfLineHeight + sdfVerticalAlignYOffset; // TODO: Figure out what determines the initial y offset of text.
|
|
65
73
|
|
|
66
74
|
// Don't attempt to render anything if we know we're starting past the established end of the text
|
|
67
|
-
if (textH &&
|
|
75
|
+
if (textH && sdfStartY >= textH / fontSizeRatio) {
|
|
68
76
|
return;
|
|
69
77
|
}
|
|
70
78
|
|
|
71
79
|
return {
|
|
72
|
-
|
|
73
|
-
|
|
80
|
+
sdfX: sdfStartX,
|
|
81
|
+
sdfY: sdfStartY,
|
|
74
82
|
lineIndex: startLineIndex,
|
|
75
83
|
};
|
|
76
84
|
}
|
|
@@ -18,6 +18,7 @@
|
|
|
18
18
|
*/
|
|
19
19
|
|
|
20
20
|
import { assertTruthy } from '../../../../../utils.js';
|
|
21
|
+
import type { Bound } from '../../../../lib/utils.js';
|
|
21
22
|
import type {
|
|
22
23
|
FontShaperProps,
|
|
23
24
|
MappedGlyphInfo,
|
|
@@ -38,6 +39,7 @@ export function layoutText(
|
|
|
38
39
|
width: TrProps['width'],
|
|
39
40
|
height: TrProps['height'],
|
|
40
41
|
fontSize: TrProps['fontSize'],
|
|
42
|
+
lineHeight: TrProps['lineHeight'],
|
|
41
43
|
letterSpacing: TrProps['letterSpacing'],
|
|
42
44
|
/**
|
|
43
45
|
* Mutated
|
|
@@ -48,10 +50,12 @@ export function layoutText(
|
|
|
48
50
|
* Mutated
|
|
49
51
|
*/
|
|
50
52
|
lineCache: SdfTextRendererState['lineCache'],
|
|
51
|
-
|
|
53
|
+
rwSdf: Bound,
|
|
52
54
|
trFontFace: SdfTextRendererState['trFontFace'],
|
|
53
55
|
forceFullLayoutCalc: TextRendererState['forceFullLayoutCalc'],
|
|
54
56
|
scrollable: TrProps['scrollable'],
|
|
57
|
+
overflowSuffix: TrProps['overflowSuffix'],
|
|
58
|
+
maxLines: TrProps['maxLines'],
|
|
55
59
|
): {
|
|
56
60
|
bufferNumFloats: number;
|
|
57
61
|
bufferNumQuads: number;
|
|
@@ -75,13 +79,13 @@ export function layoutText(
|
|
|
75
79
|
// We convert these to the vertex space by dividing them the `fontSizeRatio` factor.
|
|
76
80
|
|
|
77
81
|
/**
|
|
78
|
-
*
|
|
82
|
+
* See above
|
|
79
83
|
*/
|
|
80
|
-
const
|
|
84
|
+
const fontSizeRatio = fontSize / trFontFace.data.info.size;
|
|
81
85
|
/**
|
|
82
|
-
*
|
|
86
|
+
* `lineHeight` in vertex coordinates
|
|
83
87
|
*/
|
|
84
|
-
const
|
|
88
|
+
const vertexLineHeight = lineHeight / fontSizeRatio;
|
|
85
89
|
/**
|
|
86
90
|
* `w` in vertex coordinates
|
|
87
91
|
*/
|
|
@@ -142,24 +146,32 @@ export function layoutText(
|
|
|
142
146
|
bufferEnd: number;
|
|
143
147
|
}[] = [];
|
|
144
148
|
|
|
145
|
-
const truncateSeq = '...';
|
|
146
149
|
const vertexTruncateHeight = height / fontSizeRatio;
|
|
147
|
-
const
|
|
150
|
+
const overflowSuffVertexWidth = measureText(
|
|
151
|
+
overflowSuffix,
|
|
152
|
+
shaperProps,
|
|
153
|
+
shaper,
|
|
154
|
+
);
|
|
148
155
|
|
|
149
156
|
// Line-by-line layout
|
|
150
157
|
let moreLines = true;
|
|
151
158
|
while (moreLines) {
|
|
152
159
|
const nextLineWillFit =
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
160
|
+
(maxLines === 0 || curLineIndex + 1 < maxLines) &&
|
|
161
|
+
(contain !== 'both' ||
|
|
162
|
+
scrollable ||
|
|
163
|
+
curY + vertexLineHeight + vertexLineHeight <= vertexTruncateHeight);
|
|
156
164
|
const lineVertexW = nextLineWillFit
|
|
157
165
|
? vertexW
|
|
158
|
-
: vertexW -
|
|
166
|
+
: vertexW - overflowSuffVertexWidth;
|
|
159
167
|
/**
|
|
160
168
|
* Vertex X position to the beginning of the last word boundary. This becomes -1 when we start traversing a word.
|
|
161
169
|
*/
|
|
162
170
|
let xStartLastWordBoundary = 0;
|
|
171
|
+
|
|
172
|
+
const lineIsBelowWindowTop = curY + vertexLineHeight >= rwSdf.y1;
|
|
173
|
+
const lineIsAboveWindowBottom = curY <= rwSdf.y2;
|
|
174
|
+
const lineIsWithinWindow = lineIsBelowWindowTop && lineIsAboveWindowBottom;
|
|
163
175
|
// Layout glyphs in this line
|
|
164
176
|
// Any break statements in this while loop will trigger a line break
|
|
165
177
|
while ((glyphResult = glyphs.next()) && !glyphResult.done) {
|
|
@@ -220,7 +232,7 @@ export function layoutText(
|
|
|
220
232
|
} else {
|
|
221
233
|
glyphs = shaper.shapeText(
|
|
222
234
|
shaperProps,
|
|
223
|
-
new PeekableIterator(getUnicodeCodepoints(
|
|
235
|
+
new PeekableIterator(getUnicodeCodepoints(overflowSuffix, 0), 0),
|
|
224
236
|
);
|
|
225
237
|
curX = lastWord.xStart;
|
|
226
238
|
bufferOffset = lastWord.bufferOffset;
|
|
@@ -230,15 +242,8 @@ export function layoutText(
|
|
|
230
242
|
const quadX = curX + glyph.xOffset;
|
|
231
243
|
const quadY = curY + glyph.yOffset;
|
|
232
244
|
|
|
233
|
-
const lineIsBelowWindowTop = renderWindow
|
|
234
|
-
? curY + vertexLineHeight >= renderWindow.y1 / fontSizeRatio
|
|
235
|
-
: true;
|
|
236
|
-
const lineIsAboveWindowBottom = renderWindow
|
|
237
|
-
? curY <= renderWindow.y2 / fontSizeRatio
|
|
238
|
-
: true;
|
|
239
|
-
|
|
240
245
|
// Only add to buffer for rendering if the line is within the render window
|
|
241
|
-
if (
|
|
246
|
+
if (lineIsWithinWindow) {
|
|
242
247
|
if (curLineBufferStart === -1) {
|
|
243
248
|
curLineBufferStart = bufferOffset;
|
|
244
249
|
}
|
|
@@ -288,7 +293,19 @@ export function layoutText(
|
|
|
288
293
|
|
|
289
294
|
// Handle newlines
|
|
290
295
|
if (glyph.codepoint === 10) {
|
|
291
|
-
|
|
296
|
+
if (nextLineWillFit) {
|
|
297
|
+
// The whole line fit, so we can break to the next line
|
|
298
|
+
break;
|
|
299
|
+
} else {
|
|
300
|
+
// The whole line won't fit, so we need to add the overflow suffix
|
|
301
|
+
glyphs = shaper.shapeText(
|
|
302
|
+
shaperProps,
|
|
303
|
+
new PeekableIterator(getUnicodeCodepoints(overflowSuffix, 0), 0),
|
|
304
|
+
);
|
|
305
|
+
// HACK: For the rest of the line when inserting the overflow suffix,
|
|
306
|
+
// set contain = 'none' to prevent an infinite loop.
|
|
307
|
+
contain = 'none';
|
|
308
|
+
}
|
|
292
309
|
}
|
|
293
310
|
}
|
|
294
311
|
}
|
|
@@ -308,12 +325,7 @@ export function layoutText(
|
|
|
308
325
|
xStartLastWordBoundary = 0;
|
|
309
326
|
|
|
310
327
|
// Figure out if there are any more lines to render...
|
|
311
|
-
if (
|
|
312
|
-
!forceFullLayoutCalc &&
|
|
313
|
-
contain === 'both' &&
|
|
314
|
-
renderWindow &&
|
|
315
|
-
curY > renderWindow.y2 / fontSizeRatio
|
|
316
|
-
) {
|
|
328
|
+
if (!forceFullLayoutCalc && contain === 'both' && curY > rwSdf.y2) {
|
|
317
329
|
// Stop layout calculation early (for performance purposes) if:
|
|
318
330
|
// - We're not forcing a full layout calculation (for width/height calculation)
|
|
319
331
|
// - ...and we're containing the text vertically+horizontally (contain === 'both')
|
|
@@ -323,7 +335,7 @@ export function layoutText(
|
|
|
323
335
|
} else if (glyphResult && glyphResult.done) {
|
|
324
336
|
// If we've reached the end of the text, we know we're done
|
|
325
337
|
moreLines = false;
|
|
326
|
-
} else if (
|
|
338
|
+
} else if (!nextLineWillFit) {
|
|
327
339
|
// If we're contained vertically+horizontally (contain === 'both')
|
|
328
340
|
// but not scrollable and the next line won't fit, we're done.
|
|
329
341
|
moreLines = false;
|
|
@@ -25,10 +25,15 @@ import {
|
|
|
25
25
|
type SdfFontData,
|
|
26
26
|
} from '../../../font-face-types/SdfTrFontFace/internal/SdfFontShaper.js';
|
|
27
27
|
|
|
28
|
+
const glyphMap = new Map<number, SdfFontData['chars'][0]>();
|
|
29
|
+
sdfData.chars.forEach((glyph) => {
|
|
30
|
+
glyphMap.set(glyph.id, glyph);
|
|
31
|
+
});
|
|
32
|
+
|
|
28
33
|
describe('measureText', () => {
|
|
29
34
|
it('should measure text width', () => {
|
|
30
35
|
const PERIOD_WIDTH = 10.332;
|
|
31
|
-
const shaper = new SdfFontShaper(sdfData as unknown as SdfFontData);
|
|
36
|
+
const shaper = new SdfFontShaper(sdfData as unknown as SdfFontData, glyphMap);
|
|
32
37
|
expect(measureText('', { letterSpacing: 0 }, shaper)).toBe(0);
|
|
33
38
|
expect(measureText('.', { letterSpacing: 0 }, shaper)).toBe(PERIOD_WIDTH);
|
|
34
39
|
expect(measureText('..', { letterSpacing: 0 }, shaper)).toBeCloseTo(
|