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

Summary: Fixing corner case with underline / strike-through
Product: SDL_ttf Reporter: Sylvain <sylvain.becker>
Component: miscAssignee: Sam Lantinga <slouken>
Status: RESOLVED FIXED QA Contact: Sam Lantinga <slouken>
Severity: normal    
Priority: P2    
Version: unspecified   
Hardware: x86_64   
OS: Linux   
Attachments: patch

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