1. Hey! Guest! The 35th GMC Jam will take place between November 28th, 12:00 UTC - December 2nd, 12:00 UTC. Why not join in! Click here to find out more!
    Dismiss Notice

GML Solved - String Width but ignoring line breaks

Discussion in 'Programming' started by Michael Stearns, Nov 6, 2019.

  1. Michael Stearns

    Michael Stearns Member

    Joined:
    Jul 3, 2017
    Posts:
    20
    Hello! I've got a text box that gradually fills with text, typewriter-style. I wanted to draw a little "cursor" at the end of the string being displayed, but I seem to be having some trouble.

    The problem is that string_width (and string_width_ext) does not seem to actually return the line width, instead it returns the width of the "box" containing the string. When my displayed string "breaks" (like by using \n) to a new line, string_width doesn't change its value until the length of the new line exceeds the earlier one (that is, the "box" width has increased).

    I can think of some workarounds here (breaking up the strings more, using a fixed-width font) but it seems like there must just be some function or feature of a function that I'm missing?
     
  2. Yal

    Yal GMC Memer GMC Elder

    Joined:
    Jun 20, 2016
    Posts:
    3,867
    string_width is the width of the entire string. You could get the effect you want by splitting the text at the final newline, get the height of the part before the final newline (which is where the top of the cursor would be) and get the width of the part after the final newline (which is the left side of the cursor).

    (Rather than splitting the actual string you're using, you'll have an easier time if you create two copies of it for the two substrings)
     
    Bentley and Michael Stearns like this.
  3. Michael Stearns

    Michael Stearns Member

    Joined:
    Jul 3, 2017
    Posts:
    20
    Thanks! Disappointing but I'm glad to know I'm not missing something.

    Since my strings can contain multiple \n's (and I want the cursor to follow the end of the text as it types in), I'll create a copy of the string, split out each line into a new string, count up the widths of each, and then just store those results rather than keeping multiple strings around.
     
    Pat Ferguson likes this.
  4. NightFrost

    NightFrost Member

    Joined:
    Jun 24, 2016
    Posts:
    1,977
    Optimally, you'd want to write a script that does line feeding for you, so you can quickly move it from project to another. You'd preprocess the string by splitting it into individual words at spaces. Then the draw routine loops through the word array and counts the position of each word as it is drawn and the total width of current line. When width is reached that would exceed maximum width given to the script, the draw position would be set to start of next line and the word is drawn there instead. This also means if your UI changes, you don't need to do needless busywork repositioning all the manual line breaks you set.
     
    Michael Stearns likes this.
  5. TsukaYuriko

    TsukaYuriko Q&A Spawn Camper Forum Staff Moderator

    Joined:
    Apr 21, 2016
    Posts:
    1,707
    string_width_ext should - and, according to a test I did just now, does - by all means take line breaks into account, whether that's induced by the w argument or by manual insertion of line breaks in the string. Did you change the font to the one that will be used during drawing before calling it?
     
    Michael Stearns likes this.
  6. Michael Stearns

    Michael Stearns Member

    Joined:
    Jul 3, 2017
    Posts:
    20
    textYes.gif

    (edit: well, almost the way I want! It appears in the wrong spot for a moment, but that should be easy to fix.)

    I realized the method I described didn't really make sense, in my defense it was getting kind of late, ha ha. What I ended up doing was pretty simple, I just made a little text manipulator that cut out the lines of the string that had \n's in them, so as the message "types" in, the string_width is only checking the remaining text.

    Code:
    ///CurrentLineWidth()
    var baseString = argument0;
    var n = 0;
    var qPos = string_pos("\n", baseString);
    while (qPos != 0)
        {
        baseString = string_delete(baseString, 1, qPos);
        n++;
        qPos = string_pos("\n", baseString);
        }
    return string_width(baseString);
    I appreciate the explanation of making my own word wrapper and may do that later, it's definitely in my wheelhouse now, ha ha.

    Thanks, but I don't understand? And maybe I didn't explain clearly what I was trying to do. Here's what I get when I use string_width_ext (or the non-ext, for that matter) instead of the script I made, presumably functioning as intended, just not meant for this usage:
    textNo.gif
     
    Last edited: Nov 6, 2019
  7. Mert

    Mert Member

    Joined:
    Jul 20, 2016
    Posts:
    412
    For shorter calculations, you can try

    Code:
    var strw = string_length(text) * font_get_size(font);
     
  8. Yal

    Yal GMC Memer GMC Elder

    Joined:
    Jun 20, 2016
    Posts:
    3,867
    It works for monospaced fonts, but the font OP is using clearly has different widths for different letters, so this quickly becomes inaccurate as string length grows (especially for strings with many M-like or I-like glyphs)
     
    Bentley, Mert and Michael Stearns like this.

Share This Page

  1. This site uses cookies to help personalise content, tailor your experience and to keep you logged in if you register.
    By continuing to use this site, you are consenting to our use of cookies.
    Dismiss Notice