Adventure Game Studio

AGS Support => Advanced Technical Forum => Topic started by: Trapezoid on Wed 11/02/2015 22:36:38

Title: Get text width after wrapping?
Post by: Trapezoid on Wed 11/02/2015 22:36:38
I'm replacing the Say function using overlays from DrawStringWrapped. I'm able to pretty accurately mimic the way the built-in Say option wraps and positions dialog, but I'm having trouble getting the dialog to align to the edge of the screen if the character is standing there.

(http://i.imgur.com/GIdcmSY.png)

For example, the text displayed by DrawStringWrapped is set to wrap to 160px wide. This results in text that's actually 130 pixels wide, but I can't figure out how to get that number in script, so it's aligned based on the 160px value, which results in awkward placement.

Here's how .Say normally displays it:
(http://i.imgur.com/gVT2Tc6.png)
(ignore the disembodied head)

Is there some way to do this?
Title: Re: Get text width after wrapping?
Post by: Gurok on Wed 11/02/2015 23:06:10
Two ways I can think of:

Write a function that progressively measures the width of each line using GetTextWidth and mimics AGS' own text wrapping. Return the maximum value found for the width of a line.

Given that you know the line height (and the height of the text via GetTextHeight), write a function that scans blank pixels on the right of the surface until it finds a non-blank (not COLOR_TRANSPARENT) pixel. You could scan just the baseline of each line to find a black pixel, so in your example, that's two tests per column.

I don't think there's a built-in way. Older threads on similar subjects suggest the use of a StrCutByWidth function, similar to the first method I outlined.
Title: Re: Get text width after wrapping?
Post by: Trapezoid on Thu 12/02/2015 02:57:27
Yeah, I just ended up writing a function doing exactly that.

Code (ags) Select

function GetTextWidthX(String message, FontType whatfont, int wrapwidth) {
  String line = "";
  String remaining = message;
  int maxwidth = 0;

  int ind = remaining.IndexOf(" ");

  if (GetTextWidth(message, whatfont) <= wrapwidth) return GetTextWidth(message, whatfont);
  if (ind==-1) return GetTextWidth(message, whatfont);
  while (ind!=-1) {
    String newremaining = remaining.Truncate(ind+1);
    line = line.Append(newremaining);
    remaining = remaining.Substring(ind+1, remaining.Length);
    int linewidth = GetTextWidth(line, whatfont);
    if (linewidth >= wrapwidth) line = "";
    else if (linewidth > maxwidth) maxwidth = linewidth;
    ind = remaining.IndexOf(" ");
  }
  return maxwidth;
}
Seems to work well enough.