Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Bug: Basic text clips portions of glyphs at the start or end of lines. #10792

Open
clucier-reve opened this issue Jul 24, 2024 · 4 comments
Open

Comments

@clucier-reve
Copy link

clucier-reve commented Jul 24, 2024

Current Behavior

With certain fonts, Pixi basic text clips portions of the characters. In this example not the leading a and last two characters are clipped. The bottom red text is using MSDF and is not clipped. See image below (click to zoom).

(Ignore the red text vertical positioning issue I've filed that issue separately).

image

Expected Behavior

Bounds of canvas 2d text should be accurate and resulting texture should not miss content.

Steps to Reproduce

 const basicText = new Text({
    text: "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ ff fi if fl",
    style: {
      fontFamily: "PinyonScript",
      fontSize: 64,
      fill: "white",
    },
  });

PinyonScript-Regular.ttf.zip

Environment

  • pixi.js version: 8.2.3
  • Browser & Version: Chrome
  • OS & Version: Mac Sonoma 14.4

Possible Solution

I noticed when using measureText myself that the "actual" bounding box computed for the font doesn't match the text width and is accurate (at least much more so):

Text width: 1998.5625
Actual bounding box left: 0.625
Actual bounding box right: 2018.1875
Actual bounding box ascent: 49.84375
Actual bounding box descent: 24.59375

The 1998.5625 width is what pixi is using for the texture size (rounded up) but note the "actual" width is 2017.5625. Also note the padding defined in the font (2, 2, 2, 2) which you'll need to account for in your captured texture so as not to clip the leading 'a'.

Additional Information

No response

@CoreyDotCom
Copy link

Note #9663 relates to this issue and was closed as NAB but I do feel you are using measureText improperly in Pixi as prior when I've implemented this approach I've had to consider "actual" bounding box metrics returned from measureText in order to inflate my capturing offscreen appropriately without clipping.

@clucier-reve
Copy link
Author

clucier-reve commented Jul 24, 2024

Please Note:

TextMetrics.width:

  • The width property represents the advance width of the text, which is the distance to advance the current position in the horizontal direction for the next character.
  • This value includes the total space the text will occupy horizontally but doesn’t consider any additional spacing that might be applied to individual glyphs beyond their bounding boxes.

TextMetrics.actualBoundingBoxRight - TextsMetrics.actualBoundingBoxLeft:

  • The actualBoundingBoxRight and actualBoundingBoxLeft properties represent the rightmost and leftmost points of the text’s actual bounding box, respectively.
  • actualBoundingBoxRight - actualBoundingBoxLeft gives the precise width of the text’s bounding box, which includes the furthest extent of the rendered glyphs.
  • This value can be slightly different from width because it measures the exact rendered area, including parts of glyphs that extend beyond the normal advance width.

@GoodBoyDigital
Copy link
Member

actualBoundingBoxRight

this is pretty cool! We missed the existance of these props! I just tested it out but did not see precise results when trying to use actualBoundingBoxRight - actualBoundingBoxLeft instead of width. You would think Canvas would be better at this :D

using actualBoundingBox Values:
image

using width:

image

Its still an improvment though! To double check, where the bounds 100% accurate for you?

We are pretty time poor at the mo - would be happy to accept a PR when you have the time to correct this! Thanks @CoreyDotCom and @clucier-reve !!

@clucier-reve
Copy link
Author

clucier-reve commented Jul 25, 2024

@GoodBoyDigital Sorry I was accidentally logged in with two accounts, lol. So I am not sure why your right edge is not bounded properly but I do understand why your left edge isn't.

The read-only actualBoundingBoxLeft property of the TextMetrics interface is a double giving the distance parallel to the baseline from the alignment point given by the CanvasRenderingContext2D.textAlign property to the left side of the bounding rectangle of the given text, in CSS pixels; >> positive numbers indicating a distance going left from the given alignment point <<.

Here is a fiddle that seems to have the bounds correct, I've included SVG as well , as this is another option not only for the metrics but for the source of the texture. https://jsfiddle.net/CoreyDotCom/n8rg2cdL/21/

Look for 'BOUNDS COMPUTATION' tag in the code.

Also note, the SVG bounds are inaccurate on Safari (of course they are right?) , so ignore that idea for now.

I am fully unfamiliar with Pixi internals, so might be best for someone in the know to tackle - seems like a pretty impactful fix though.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants