Get text width after wrapping?

Started by Trapezoid, Wed 11/02/2015 22:36:38

Previous topic - Next topic

Trapezoid

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.



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:

(ignore the disembodied head)

Is there some way to do this?

Gurok

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.
[img]http://7d4iqnx.gif;rWRLUuw.gi

Trapezoid

Yeah, I just ended up writing a function doing exactly that.

Code: ags

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.

SMF spam blocked by CleanTalk