Pages: « 1 2 3 4
  Print  
Author Topic: GML: All draw_text functions +(string_width, _height, _width_ext, _height_ext)  (Read 61804 times)
Offline (Unknown gender) TheExDeus
Reply #45 Posted on: July 09, 2011, 03:12:37 pm

Developer
Joined: Apr 2008
Posts: 1860

View Profile
Quote
That code doesn't consider newlines.
Yes, the full code is this (tested and works):
Code: [Select]
void draw_text(int x,int y,string str)
{
  font *fnt = fontstructarray[currentfont];

  if (bound_texture != fnt->texture)
    glBindTexture(GL_TEXTURE_2D, bound_texture = fnt->texture);

  int xx, yy = y+fnt->yoffset, line = 0;
  if (halign == fa_left){
    xx = x;
  }else if (halign == fa_middle){
    xx = x-string_width_line(str,0)/2;
  }else{ //fa_right
    xx = x-string_width_line(str,0);
  }
  glBegin(GL_QUADS);
  for (unsigned i = 0; i < str.length(); i++)
  {
    if (str[i] == '\r'){
      line +=1, yy += fnt->height, i += str[i+1] == '\n';
      if (halign == fa_left){
          xx = x;
      }else if (halign == fa_middle){
          xx = x-string_width_line(str,line)/2;
      }else{ //fa_right
          xx = x-string_width_line(str,line);
      }
    }else if (str[i] == '\n'){
      line +=1, yy += fnt->height;
      if (halign == fa_left){
          xx = x;
      }else if (halign == fa_middle){
          xx = x-string_width_line(str,line)/2;
      }else{ //fa_right
          xx = x-string_width_line(str,line);
      }
    }else if (str[i] == ' ')
      xx += fnt->height/3; // FIXME: what's GM do about this?
    else
    {
      fontglyph &g = fnt->glyphs[(unsigned char)(str[i] - fnt->glyphstart) % fnt->glyphcount];
        glTexCoord2f(g.tx,  g.ty);
          glVertex2i(xx + g.x,  yy + g.y);
        glTexCoord2f(g.tx2, g.ty);
          glVertex2i(xx + g.x2, yy + g.y);
        glTexCoord2f(g.tx2, g.ty2);
          glVertex2i(xx + g.x2, yy + g.y2);
        glTexCoord2f(g.tx,  g.ty2);
          glVertex2i(xx + g.x,  yy + g.y2);
      xx += g.xs;
    }
  }
  glEnd();
}
Quote
Not having the code as fa_left fucks everything up, efficiency wise.
Agreed.
Quote
You're best to fork up front.
Could you elaborate? You mean having separate drawing functions for all six alignments? Then how will that be backwards compatible with GM? Or how will draw_set_halign/valign actually work in that case?
Quote
There should be functions added for draw_get_halign / valign these are missing from gml.
I will. That is easy.

edit: Also, why do I need this:
Code: [Select]
    if (str[i] == '\r')
      xx = x, yy += fnt->height, i += str[i+1] == '\n';
    else if (str[i] == '\n')
      xx = x, yy += fnt->height;
and can't have simply:
Code: [Select]
    if (str[i] == '\r' or str[i] == '\n')
      xx = x, yy += fnt->height;
I left that in legacy sake and I know that there are several end line characters, but why I have to  i += str[i+1] == '\n' which actually doesn't make sense (I insert \n as far as I know, but that's funny way to write that). This part was written by Josh or TGMG a long time ago.
« Last Edit: July 09, 2011, 03:24:17 pm by HaRRiKiRi » Logged
Offline (Male) Josh @ Dreamland
Reply #46 Posted on: July 09, 2011, 03:39:00 pm

Prince of all Goldfish
Developer
Location: Pittsburgh, PA, USA
Joined: Feb 2008
Posts: 2950

View Profile Email
Quote
Could you elaborate? You mean having separate drawing functions for all six alignments? Then how will that be backwards compatible with GM? Or how will draw_set_halign/valign actually work in that case?
No, just put the original function in a big if for align being top-left, and then put the rest of the code in the else with whatever hackery is required, that way you don't have to iterate the string for draw_text() when the aligns are default.

Quote
Also, why do I need this: ...
Otherwise, \r\n will put two newlines, or if you place ", u+= str[i]=='\n';" at the end of the proposed replacement, '\n\n' will be treated as one line.
Logged
"That is the single most cryptic piece of code I have ever seen." -Master PobbleWobble
"I disapprove of what you say, but I will defend to the death your right to say it." -Evelyn Beatrice Hall, Friends of Voltaire
Offline (Unknown gender) TheExDeus
Reply #47 Posted on: July 09, 2011, 04:14:22 pm

Developer
Joined: Apr 2008
Posts: 1860

View Profile
Quote
No, just put the original function in a big if for align being top-left, and then put the rest of the code in the else with whatever hackery is required, that way you don't have to iterate the string for draw_text() when the aligns are default.
So like this?
Code: [Select]
void draw_text(int x,int y,string str)
{
  font *fnt = fontstructarray[currentfont];

  if (bound_texture != fnt->texture)
    glBindTexture(GL_TEXTURE_2D, bound_texture = fnt->texture);

  if (halign == fa_left){
      int xx = x, yy = y+fnt->yoffset;
      glBegin(GL_QUADS);
      for (unsigned i = 0; i < str.length(); i++)
      {
        if (str[i] == '\r')
          xx = x, yy += fnt->height, i += str[i+1] == '\n';
        else if (str[i] == '\n')
          xx = x, yy += fnt->height;
        else if (str[i] == ' ')
          xx += fnt->height/3; // FIXME: what's GM do about this?
        else
        {
          fontglyph &g = fnt->glyphs[(unsigned char)(str[i] - fnt->glyphstart) % fnt->glyphcount];
            glTexCoord2f(g.tx,  g.ty);
              glVertex2i(xx + g.x,  yy + g.y);
            glTexCoord2f(g.tx2, g.ty);
              glVertex2i(xx + g.x2, yy + g.y);
            glTexCoord2f(g.tx2, g.ty2);
              glVertex2i(xx + g.x2, yy + g.y2);
            glTexCoord2f(g.tx,  g.ty2);
              glVertex2i(xx + g.x,  yy + g.y2);
          xx += g.xs;
        }
      }
      glEnd();
  }else{
      int xx, yy = y+fnt->yoffset, line = 0;
      if (halign == fa_middle){
        xx = x-string_width_line(str,0)/2;
      }else{ //fa_right
        xx = x-string_width_line(str,0);
      }
      glBegin(GL_QUADS);
      for (unsigned i = 0; i < str.length(); i++)
      {
        if (str[i] == '\r'){
          line +=1, yy += fnt->height, i += str[i+1] == '\n';
          if (halign == fa_middle){
              xx = x-string_width_line(str,line)/2;
          }else{ //fa_right
              xx = x-string_width_line(str,line);
          }
        }else if (str[i] == '\n'){
          line +=1, yy += fnt->height;
          if (halign == fa_middle){
              xx = x-string_width_line(str,line)/2;
          }else{ //fa_right
              xx = x-string_width_line(str,line);
          }
        }else if (str[i] == ' ')
          xx += fnt->height/3; // FIXME: what's GM do about this?
        else
        {
          fontglyph &g = fnt->glyphs[(unsigned char)(str[i] - fnt->glyphstart) % fnt->glyphcount];
            glTexCoord2f(g.tx,  g.ty);
              glVertex2i(xx + g.x,  yy + g.y);
            glTexCoord2f(g.tx2, g.ty);
              glVertex2i(xx + g.x2, yy + g.y);
            glTexCoord2f(g.tx2, g.ty2);
              glVertex2i(xx + g.x2, yy + g.y2);
            glTexCoord2f(g.tx,  g.ty2);
              glVertex2i(xx + g.x,  yy + g.y2);
          xx += g.xs;
        }
      }
      glEnd();
  }
}
Logged
Offline (Male) Josh @ Dreamland
Reply #48 Posted on: July 09, 2011, 04:33:03 pm

Prince of all Goldfish
Developer
Location: Pittsburgh, PA, USA
Joined: Feb 2008
Posts: 2950

View Profile Email
Yep. That way, string_width is never called for simple left-aligned text.
Logged
"That is the single most cryptic piece of code I have ever seen." -Master PobbleWobble
"I disapprove of what you say, but I will defend to the death your right to say it." -Evelyn Beatrice Hall, Friends of Voltaire
Offline (Unknown gender) TheExDeus
Reply #49 Posted on: July 09, 2011, 05:07:07 pm

Developer
Joined: Apr 2008
Posts: 1860

View Profile
It actually wasn't called in the previous example code either. Though there was an if statement at every newline character while in this code there isn't. So that's something I guess. Now about valign. That actually requires a lot less code, and it doesn't require anything in the for loop. So should I write like this:
Code: [Select]
void draw_text(int x,int y,string str)
{
  font *fnt = fontstructarray[currentfont];

  if (bound_texture != fnt->texture)
    glBindTexture(GL_TEXTURE_2D, bound_texture = fnt->texture);

  if (halign == fa_left){
      int xx = x, yy = y+fnt->yoffset;
      if (valign == fa_middle)
        yy -= string_height(str)/2;
      else if (valign == fa_bottom)
        yy -= string_height(str);
      glBegin(GL_QUADS);
      for (unsigned i = 0; i < str.length(); i++)
      {
        if (str[i] == '\r')
          xx = x, yy += fnt->height, i += str[i+1] == '\n';
        else if (str[i] == '\n')
          xx = x, yy += fnt->height;
        else if (str[i] == ' ')
          xx += fnt->height/3; // FIXME: what's GM do about this?
        else
        {
          fontglyph &g = fnt->glyphs[(unsigned char)(str[i] - fnt->glyphstart) % fnt->glyphcount];
            glTexCoord2f(g.tx,  g.ty);
              glVertex2i(xx + g.x,  yy + g.y);
            glTexCoord2f(g.tx2, g.ty);
              glVertex2i(xx + g.x2, yy + g.y);
            glTexCoord2f(g.tx2, g.ty2);
              glVertex2i(xx + g.x2, yy + g.y2);
            glTexCoord2f(g.tx,  g.ty2);
              glVertex2i(xx + g.x,  yy + g.y2);
          xx += g.xs;
        }
      }
      glEnd();
  }else{
      int xx, yy = y+fnt->yoffset, line = 0;
      if (valign == fa_middle)
        yy -= string_height(str)/2;
      else if (valign == fa_bottom)
        yy -= string_height(str);
      if (halign == fa_center){
        xx = x-string_width_line(str,0)/2;
      }else{ //fa_right
        xx = x-string_width_line(str,0);
      }
      glBegin(GL_QUADS);
      for (unsigned i = 0; i < str.length(); i++)
      {
        if (str[i] == '\r'){
          line +=1, yy += fnt->height, i += str[i+1] == '\n';
          if (halign == fa_center){
              xx = x-string_width_line(str,line)/2;
          }else{ //fa_right
              xx = x-string_width_line(str,line);
          }
        }else if (str[i] == '\n'){
          line +=1, yy += fnt->height;
          if (halign == fa_center){
              xx = x-string_width_line(str,line)/2;
          }else{ //fa_right
              xx = x-string_width_line(str,line);
          }
        }else if (str[i] == ' ')
          xx += fnt->height/3; // FIXME: what's GM do about this?
        else
        {
          fontglyph &g = fnt->glyphs[(unsigned char)(str[i] - fnt->glyphstart) % fnt->glyphcount];
            glTexCoord2f(g.tx,  g.ty);
              glVertex2i(xx + g.x,  yy + g.y);
            glTexCoord2f(g.tx2, g.ty);
              glVertex2i(xx + g.x2, yy + g.y);
            glTexCoord2f(g.tx2, g.ty2);
              glVertex2i(xx + g.x2, yy + g.y2);
            glTexCoord2f(g.tx,  g.ty2);
              glVertex2i(xx + g.x,  yy + g.y2);
          xx += g.xs;
        }
      }
      glEnd();
  }
}
Or split again? The code size will double if I split.
edit: Fixed "thou" into "though". I know I use it wrong, but no one corrects me so its hard to learn.
Anyway, sleep time. If this code is good then I will implement draw_set_halign and valign tomorrow. There will just be a question about declarations out of the functions (because I need to declare fa_ constants in both .h and .cpp file.. more on that later).
« Last Edit: July 09, 2011, 05:24:10 pm by HaRRiKiRi » Logged
Offline (Male) Josh @ Dreamland
Reply #50 Posted on: July 09, 2011, 08:46:59 pm

Prince of all Goldfish
Developer
Location: Pittsburgh, PA, USA
Joined: Feb 2008
Posts: 2950

View Profile Email
How on earth does valign have any effect on draw_text? O_o
If it just centers the text around the given y coordinate, then there's no need to fork again. Just set the initial yy to valign == fa_top ? y : valign == fa_middle ? y - string_height(str)/2 : y - string_height(str).

And yeah, it's "though." But no one really cares if you abbreviate, even unintentionally. :P
Logged
"That is the single most cryptic piece of code I have ever seen." -Master PobbleWobble
"I disapprove of what you say, but I will defend to the death your right to say it." -Evelyn Beatrice Hall, Friends of Voltaire
Offline (Unknown gender) TheExDeus
Reply #51 Posted on: July 10, 2011, 07:52:15 am

Developer
Joined: Apr 2008
Posts: 1860

View Profile
Quote
valign == fa_top ? y : valign == fa_middle ? y - string_height(str)/2 : y - string_height(str)
That's basically what I did, though I typed the whole if statement. Does it actually increase speed with using the shorter if statement then the long one?
The end code is this:
Code: [Select]
void draw_text(int x,int y,string str)
{
  font *fnt = fontstructarray[currentfont];

  if (bound_texture != fnt->texture)
    glBindTexture(GL_TEXTURE_2D, bound_texture = fnt->texture);
  int yy = valign == fa_top ? y+fnt->yoffset : valign == fa_middle ? y +fnt->yoffset - string_height(str)/2 : y + fnt->yoffset - string_height(str);
  if (halign == fa_left){
      int xx = x;
      glBegin(GL_QUADS);
      for (unsigned i = 0; i < str.length(); i++)
      {
        if (str[i] == '\r')
          xx = x, yy += fnt->height, i += str[i+1] == '\n';
        else if (str[i] == '\n')
          xx = x, yy += fnt->height;
        else if (str[i] == ' ')
          xx += fnt->height/3; // FIXME: what's GM do about this?
        else
        {
          fontglyph &g = fnt->glyphs[(unsigned char)(str[i] - fnt->glyphstart) % fnt->glyphcount];
            glTexCoord2f(g.tx,  g.ty);
              glVertex2i(xx + g.x,  yy + g.y);
            glTexCoord2f(g.tx2, g.ty);
              glVertex2i(xx + g.x2, yy + g.y);
            glTexCoord2f(g.tx2, g.ty2);
              glVertex2i(xx + g.x2, yy + g.y2);
            glTexCoord2f(g.tx,  g.ty2);
              glVertex2i(xx + g.x,  yy + g.y2);
          xx += g.xs;
        }
      }
      glEnd();
  }else{
      int xx = halign == fa_center ? x-string_width_line(str,0)/2 : x-string_width_line(str,0), line = 0;
      glBegin(GL_QUADS);
      for (unsigned i = 0; i < str.length(); i++)
      {
        if (str[i] == '\r'){
          line +=1, yy += fnt->height, i += str[i+1] == '\n';
          xx = halign == fa_center ? x-string_width_line(str,line)/2 : x-string_width_line(str,line);
        }else if (str[i] == '\n'){
          line +=1, yy += fnt->height;
          xx = halign == fa_center ? x-string_width_line(str,line)/2 : x-string_width_line(str,line);
        }else if (str[i] == ' ')
          xx += fnt->height/3; // FIXME: what's GM do about this?
        else
        {
          fontglyph &g = fnt->glyphs[(unsigned char)(str[i] - fnt->glyphstart) % fnt->glyphcount];
            glTexCoord2f(g.tx,  g.ty);
              glVertex2i(xx + g.x,  yy + g.y);
            glTexCoord2f(g.tx2, g.ty);
              glVertex2i(xx + g.x2, yy + g.y);
            glTexCoord2f(g.tx2, g.ty2);
              glVertex2i(xx + g.x2, yy + g.y2);
            glTexCoord2f(g.tx,  g.ty2);
              glVertex2i(xx + g.x,  yy + g.y2);
          xx += g.xs;
        }
      }
      glEnd();
  }
}
Quote
But no one really cares if you abbreviate
That's not an abbreviation, I just thought its how its spelled. The word thou is a second person singular pronoun in English.
« Last Edit: July 10, 2011, 08:08:01 am by HaRRiKiRi » Logged
Offline (Female) IsmAvatar
Reply #52 Posted on: July 10, 2011, 11:51:40 am

LateralGM Developer
LGM Developer
Location: Pennsylvania/USA
Joined: Apr 2008
Posts: 877

View Profile Email
Quote
That's not an abbreviation, I just thought its how its spelled. The word thou is a second person singular pronoun in English.
It is now largely archaic.

"Thou shalt not eat from the tree of knowledge."
Nobody talks like that anymore unless you're trying to sound biblical. In other contexts, if you use the word "thou" or "tho", we assume you're abbreviating "though" (actually, the more recognized abbreviation on the interwebs is "tho", so we assume the "u" is an accidental extra).
Logged
Pages: « 1 2 3 4
  Print