troika icon indicating copy to clipboard operation
troika copied to clipboard

troika-three-text: mesh.textRenderInfo missing lineHeight and other font metrics

Open null77 opened this issue 1 year ago • 4 comments

I haven't tried extracting my code into a standalone test, but at a minimum I'm doing something wrong, and at worst there's a bug somewhere in how I'm using the library. Basically I'm setting up the text object parameters, calling sync, then when the callback hits, dumping the "mesh.textRenderInfo". The bounding boxes come through fine, but I'm missing a bunch of the font metrics:

{
  "parameters": {
    "text": "30/50",
    "font": [
      {
        "label": "user",
        "src": "ARIALN.TTF"
      }
    ],
    "lang": null,
    "fontSize": 5.333333333333334,
    "fontWeight": "normal",
    "fontStyle": "normal",
    "letterSpacing": 0,
    "lineHeight": "normal",
    "direction": "auto",
    "textAlign": "center",
    "textIndent": 0,
    "whiteSpace": "normal",
    "overflowWrap": "normal",
    "anchorX": "center",
    "anchorY": "middle",
    "colorRanges": null,
    "includeCaretPositions": true,
    "sdfGlyphSize": 64,
    "gpuAccelerateSDF": true,
    "unicodeFontsURL": null
  },
  "sdfTexture": {
    "metadata": {
      "version": 4.6,
      "type": "Texture",
      "generator": "Texture.toJSON"
    },
    "uuid": "395b5342-445e-4814-8b89-acb3280828b3",
    "name": "",
    "image": "4f888828-fc71-4765-8f87-861dd278c070",
    "mapping": 300,
    "channel": 0,
    "repeat": [
      1,
      1
    ],
    "offset": [
      0,
      0
    ],
    "center": [
      0,
      0
    ],
    "rotation": 0,
    "wrap": [
      1001,
      1001
    ],
    "format": 1023,
    "internalFormat": null,
    "type": 1009,
    "colorSpace": "",
    "minFilter": 1006,
    "magFilter": 1006,
    "anisotropy": 1,
    "flipY": true,
    "generateMipmaps": false,
    "premultiplyAlpha": false,
    "unpackAlignment": 4
  },
  "sdfGlyphSize": 64,
  "sdfExponent": 9,
  "glyphBounds": {
    "0": -5.569864749908447,
    "1": -1.7222087383270264,
    "2": -2.9718017578125,
    "3": 2.7274169921875,
    "4": -3.1399941444396973,
    "5": -1.71942138671875,
    "6": -0.5501098036766052,
    "7": 2.72723388671875,
    "8": -0.8856608271598816,
    "9": -1.722900390625,
    "10": 0.8856607675552368,
    "11": 2.7801921367645264,
    "12": 0.5132039785385132,
    "13": -1.71466064453125,
    "14": 3.1274211406707764,
    "15": 2.6547648906707764,
    "16": 2.94073486328125,
    "17": -1.71942138671875,
    "18": 5.530619144439697,
    "19": 2.72723388671875
  },
  "glyphAtlasIndices": {
    "0": 0,
    "1": 14,
    "2": 12,
    "3": 15,
    "4": 14
  },
  "glyphColors": null,
  "caretPositions": {
    "0": -5.47265625,
    "1": -3.0403645038604736,
    "2": -2.5026042461395264,
    "3": 2.5026042461395264,
    "4": -3.0403645038604736,
    "5": -0.6080729365348816,
    "6": -2.5026042461395264,
    "7": 2.5026042461395264,
    "8": -0.6080729365348816,
    "9": 0.6080729365348816,
    "10": -2.5026042461395264,
    "11": 2.5026042461395264,
    "12": 0.6080729365348816,
    "13": 3.0403645038604736,
    "14": -2.5026042461395264,
    "15": 2.5026042461395264,
    "16": 3.0403645038604736,
    "17": 5.47265625,
    "18": -2.5026042461395264,
    "19": 2.5026042461395264
  },
  "chunkedBounds": [
    {
      "start": 0,
      "end": 5,
      "rect": [
        -5.295572916666669,
        -1.4479166666666667,
        5.256510416666668,
        2.502604166666667
      ]
    }
  ],
  "topBaseline": -1.3802083333333335,
  "blockBounds": [
    -5.472656250000002,
    -2.8528645833333335,
    5.472656250000002,
    2.8528645833333335
  ],
  "visibleBounds": [
    -5.295572916666669,
    -1.4479166666666667,
    5.256510416666668,
    2.502604166666667
  ],
  "timings": {
    "fontLoad": 0,
    "typesetting": 0.10000002384185791,
    "quads": 0,
    "sdf": {},
    "sdfTotal": 0,
    "total": 92.10000002384186
  }
}

Not sure if you can guess as to what's going on here, but please let me know if you have any clues.

null77 avatar Jul 03 '24 21:07 null77

I noticed in getTextRenderInfo in TextBuilder.js:

https://github.com/protectwise/troika/blob/d23f360c4316fa782d351151062ea3b0c2629ca1/packages/troika-three-text/src/TextBuilder.js#L281

lineHeight is returned as lineHeight: result.lineHeight,.

But in TypeSetter.js:

https://github.com/protectwise/troika/blob/d23f360c4316fa782d351151062ea3b0c2629ca1/packages/troika-three-text/src/Typesetter.js#L618

The callback is fired with lineHeight available in fontData. Is there a bug where the TextBuilder should be instead using result.fontData.lineHeight?

null77 avatar Jul 05 '24 14:07 null77

Ahh, I see, thanks for digging in. It looks like what happened is that when support for multiple/fallback fonts was added, the assumption that there is one single set of font metrics became invalid, e.g. each line may resolve to different fonts with different line heights. So those values were removed from Typesetter's results, but the TextBuilder and docs weren't updated to match.

I think we've got a few options:

  1. Remove those properties from TextBuilder and the docs
  2. Add them back in but only populate them if they have a single value for the whole text
  3. Add them back in but choose a possibly-useful value for them, like the max value or the value from the first line
  4. Add new properties for them that contain an array of values, one for each line

...something else? What would be most useful for you?

lojjic avatar Jul 05 '24 15:07 lojjic

Ah, interesting, I wasn't aware of the fallback fonts for unicode. For my purposes I'm trying to compute the line height in troika-three-text to compare to PDF rendering library's line height. 2) in your list of options would be sufficient for me, though I could see a full solution being a bit more tricky.

null77 avatar Jul 05 '24 15:07 null77

I'm looking to get the lineHeight so I can offset the next line with different formatting. I came up with something by looking at the caretPositions but I have a feeling that it's only working by coincidence rather than being correct!

ssadler avatar Sep 13 '24 14:09 ssadler