We are currently migrating Bugzilla to GitHub issues.
Any changes made to the bug tracker now will be lost, so please do not post new bugs or make changes to them.
When we're done, all bug URLs will redirect to their equivalent location on the new bug tracker.

Bug 4351 - Fixing corner case with underline / strike-through
Summary: Fixing corner case with underline / strike-through
Status: RESOLVED FIXED
Alias: None
Product: SDL_ttf
Classification: Unclassified
Component: misc (show other bugs)
Version: unspecified
Hardware: x86_64 Linux
: P2 normal
Assignee: Sam Lantinga
QA Contact: Sam Lantinga
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2018-11-01 20:41 UTC by Sylvain
Modified: 2018-11-02 23:40 UTC (History)
0 users

See Also:


Attachments
patch (9.11 KB, patch)
2018-11-01 20:45 UTC, Sylvain
Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Sylvain 2018-11-01 20:41:27 UTC
When applying small size and big outline and underline and strike through, it happens nasty corner cases.
that would make the code crash if there were not boundary check.


- we have already increased the limit for underline style set by something like this:
 font->height = SDL_max(font->height, bottom_row);

I added the same update of font->height also for strike-through. 
(big outline makes the lines thickness be greater than height/2 and then bottom_row writes than surface height).

- Then now, there is a circular dependency, because: 
  TTF_strikethrough_top_row() returns (height/2)
  bottom_row = TTF_strikethrough_top_row() + thickness
  new height is SDL_max(font->height, bottom_row);
  when it renders, TTF_strikethrough_top_row() returns (new_height/2). which can write out of bounds.

So I just move the strike/underline_to_row in the font structure. They are initialized when style changes.
And not recomputed any more each time it renders.


We just need to make sure the TTF_Size() is set correctly. Since the line can be of any thickness.
it's inside a boundary box of miny=0 maxy=font->height at yoffset 0. 
We can virtually treat it as glyph by adding the same check:
  maxy = SDL_max(maxy, glyph->yoffset + glyph->maxy - glyph->miny);
ie
  maxy = SDL_max(maxy, font->height);
finally simply initializing
  maxy = font->height;

and also the height surface 
  *h = SDL_max(font->height, maxy - miny); 
as maxy >= font->height, and miny <=0, becames only:
  *h = (maxy - miny);


In the modification: 
- create underline/strikethrough_top_row into TTF_FONT structure, and remove TTF_underline/strikethrough_top_row() private functions.
- remove the boundary check of DrawLines
- merge together TTF_drawLine_Solid() & TTF_drawLine_Shaded() as there are similar. (color 1, vers NUMGRAY - 1)
- inline TTF_initLineMectrics just initializing two vars.
- remove a duplicate "maxx = SDL_max(maxx, x + glyph->advance);"
Comment 1 Sylvain 2018-11-01 20:45:41 UTC
Created attachment 3433 [details]
patch
Comment 2 Sam Lantinga 2018-11-02 23:40:05 UTC
Patch added, thanks!
https://hg.libsdl.org/SDL_ttf/rev/5e7364ca19fe