示例#1
0
void TextEntry::draw()
{
   const Theme & theme = dialog->get_theme();
   SaveState state;
   ALLEGRO_COLOR bg = theme.bg;

   if (is_disabled()) {
      bg = al_map_rgb(64, 64, 64);
   }

   al_draw_filled_rectangle(x1, y1, x2, y2, bg);

   al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_INVERSE_ALPHA);

   if (!focused) {
      al_draw_ustr(theme.font, theme.fg, x1, y1, 0, UString(text, left_pos));
   }
   else {
      int x = x1;

      if (cursor_pos > 0) {
         UString sub(text, left_pos, cursor_pos);
         al_draw_ustr(theme.font, theme.fg, x1, y1, 0, sub);
         x += al_get_ustr_width(theme.font, sub);
      }

      if ((unsigned) cursor_pos == al_ustr_size(text)) {
         al_draw_filled_rectangle(x, y1, x + CURSOR_WIDTH,
            y1 + al_get_font_line_height(theme.font), theme.fg);
      }
      else {
         int post_cursor = cursor_pos;
         al_ustr_next(text, &post_cursor);

         UString sub(text, cursor_pos, post_cursor);
         int subw = al_get_ustr_width(theme.font, sub);
         al_draw_filled_rectangle(x, y1, x + subw,
            y1 + al_get_font_line_height(theme.font), theme.fg);
         al_draw_ustr(theme.font, theme.bg, x, y1, 0, sub);
         x += subw;

         al_draw_ustr(theme.font, theme.fg, x, y1, 0,
            UString(text, post_cursor));
      }
   }
}
示例#2
0
文件: theme.c 项目: beoran/WidgetZ
//return the new start
int wz_find_eol(ALLEGRO_USTR* text, ALLEGRO_FONT* font, float max_width, int start, int* end)
{
	int a, b;
	int first = 1;
	int last = 0;
	a = start;
	
	while(1)
	{
		ALLEGRO_USTR_INFO info;
		ALLEGRO_USTR* token;
		float len;

		/*
		Find the end of current token
		*/
		b = al_ustr_find_set_cstr(text, a, "\t\n ");
		if(b == -1) //found nothing
		{
			b = al_ustr_size(text); //this is the last whole word
			last = 1;
		}
		
		/*
		Check to see if the token fits
		*/
		token = al_ref_ustr(&info, text, start, b);

		len = al_get_ustr_width(font, token);
		if (len < max_width || first)
		{
			if(last)
			{
				*end = b + 1;
				return -1;
			}
		}
		else   //we return the last num
		{
			*end = a - 1;
			return a;
		}
		
		/*
		Check what character we found
		*/
		{
		int character = al_ustr_get(text, b);
		if(character == '\n')
		{
			*end = b;
			return b + 1;
		}
		}
		a = b + 1;
		first = 0;
	}
}
示例#3
0
文件: Font.cpp 项目: ArekX/RAGE
		int Font::get_text_width(ALLEGRO_USTR *text)
		{
			RAGE_CHECK_DISPOSED_RET(disposed, 0);

			if (font == nullptr)
				return 0;

			return al_get_ustr_width(font, text);
		}
示例#4
0
文件: theme.c 项目: beoran/WidgetZ
void wz_def_draw_editbox(struct WZ_THEME* theme, float x, float y, float w, float h, int cursor_pos, ALLEGRO_USTR* text, int style)
{
	WZ_DEF_THEME* thm = (WZ_DEF_THEME*)theme;
	int len = wz_get_text_pos(thm->font, text, w - 4);
	int cx,cy,cw,ch;
	int len2 = al_ustr_length(text);
	int offset;
	ALLEGRO_USTR_INFO info;
	ALLEGRO_USTR* token;
	ALLEGRO_COLOR border_col;
	ALLEGRO_COLOR text_col;
	len = len + 1 > len2 ? len2 : len + 1;
	
	offset = al_ustr_offset(text, len);
	
	token = al_ref_ustr(&info, text, 0, offset);
	
	border_col = thm->color1;
	text_col = thm->color2;
	
	if (style & WZ_STYLE_FOCUSED)
	{
		border_col = wz_scale_color(thm->color1, 1.5);
	}
	if (style & WZ_STYLE_DISABLED)
	{
		border_col = wz_scale_color(thm->color1, 0.5);
		text_col = wz_scale_color(thm->color2, 0.5);
	}
	
	wz_draw_3d_rectangle(x, y, x + w, y + h, 1, border_col, true);
	
	al_get_clipping_rectangle(&cx, &cy, &cw, &ch);
	al_set_clipping_rectangle(x + 2, y + 2, w - 4, h - 4);
	wz_draw_single_text(x + 2, y + 2, w - 4, h - 4, WZ_ALIGN_LEFT, WZ_ALIGN_CENTRE, text_col, thm->font, token);
	al_set_clipping_rectangle(cx, cy, cw, ch);
	
	if (style & WZ_STYLE_FOCUSED)
	{
		if (((int)(al_get_time() / 0.5f)) % 2 == 0)
		{
			float len;
			float halfheight;
			offset = al_ustr_offset(text, cursor_pos);
			token = al_ref_ustr(&info, text, 0, offset);
			len = al_get_ustr_width(thm->font, token);
			halfheight = al_get_font_line_height(thm->font) / 2.0f;
			al_draw_line(x + 2 + len, y + 2 + h / 2 - halfheight, x + 2 + len, y + 2 + h / 2 + halfheight, text_col, 1);
		}
	}
}
示例#5
0
/*
Function: wz_get_text_pos

Parameters:

text - the text you want to search
x - the length you want to match

Returns:

The character position such that the text length of the string up to that character
is as close as possible to the passed length.
*/
int wz_get_text_pos(ALLEGRO_FONT* font, ALLEGRO_USTR* text, float x)
{
	int ii = 0;
	int len = al_ustr_length(text);
	float width = al_get_ustr_width(font, text);

	if(x > width)
	{
		return len + 1;
	}

	if(x < 0)
	{
		return 0;
	}
	else
	{
		float old_diff = x;
		float diff;
		ALLEGRO_USTR_INFO info;

		for(ii = 0; ii <= len; ii++)
		{
			int offset = al_ustr_offset(text, ii);
			const ALLEGRO_USTR* str = al_ref_ustr(&info, text, 0, offset);
			diff = fabs(x - al_get_ustr_width(font, str));

			if(diff > old_diff)
			{
				return ii - 1;
			}

			old_diff = diff;
		}
	}

	return ii - 1;
}
示例#6
0
文件: widget.c 项目: beoran/eruta
/** Gets the positions of the next line of text fort he given Unicode string 
and store them in the given info. If the info's from is set to 0 or less, 
the first line is assumed, otherwise, the line will be started from "from".
Uses the given font to determine the width of the text as it is built.
*/
BBTextInfo * 
bbtextinfo_linefromtext(BBTextInfo * self, USTR * ustr, Font * font) {
  BBTextInfo wordinfo;
  USTR_INFO  lineuinfo;
  const USTR     * line;

  USTR_INFO  worduinfo = { 0, 0, 0};
  const USTR     * word;
  int ch;
  int index;
  int width;
  int last_stop;
  self->start_char   = self->from_char;
  wordinfo.from_char = self->from_char;
  
  while(bbtextinfo_wordfromtext(&wordinfo, ustr, font)) {
    word = bbtextinfo_refustr(&wordinfo, &worduinfo, ustr);
    line = ustrinfo_newref(&lineuinfo, ustr, self->start_char, wordinfo.stop_char);
    width = al_get_ustr_width(font, line);
    if (width > self->maxwidth) { 
      /* XXX: handle case of text overflow by bluntly retuning the word as is.
      Should split single word based on length too.
      There is overflow if this is still the first word as see from wordinfo_start_char.
      */
      if (wordinfo.start_char == self->start_char) {
        self->stop_char  = wordinfo.stop_char;
      } else { 
        self->stop_char  = wordinfo.start_char;
      }
      return self;
    }
    // If we get here, the word way still end on a newline character 
    // check this case. XXX: It works like this because 
    // stop_char is a bit wonky... it points at the first character of the 
    // next word in this case...
    ch = ustr_get(ustr, wordinfo.stop_char - 1);
    if (ch == '\n') {
      self->start_char = self->from_char;
      self->stop_char  = wordinfo.stop_char - 1;
      return self;
    }
    wordinfo.from_char = wordinfo.stop_char;
  }
  /* if we get here, the whole string fits. */
  self->start_char = self->from_char;
  self->stop_char  = wordinfo.stop_char;
  /* Return NULL to tell caller text has been completely split up. */
  return NULL;
}
示例#7
0
void TextEntry::draw()
{
   const Theme & theme = dialog->get_theme();
   SaveState state;

   al_draw_filled_rectangle(x1, y1, x2, y2, theme.bg);

   al_set_blender(ALLEGRO_ADD, ALLEGRO_ALPHA, ALLEGRO_INVERSE_ALPHA, theme.fg);

   if (!focused) {
      al_draw_ustr(theme.font, x1, y1, 0, UString(text, left_pos));
   }
   else {
      int x = x1;

      if (cursor_pos > 0) {
         UString sub(text, left_pos, cursor_pos);
         al_draw_ustr(theme.font, x1, y1, 0, sub);
         x += al_get_ustr_width(theme.font, sub);
      }

      if (cursor_pos == text.size()) {
         al_draw_filled_rectangle(x, y1, x + CURSOR_WIDTH,
            y1 + al_get_font_line_height(theme.font), theme.fg);
      }
      else {
         UString sub(text, cursor_pos, 1);
         al_set_blender(ALLEGRO_ADD, ALLEGRO_INVERSE_ALPHA, ALLEGRO_ALPHA, theme.fg);
         al_draw_ustr(theme.font, x, y1, 0, sub);
         x += al_get_ustr_width(theme.font, sub);

         al_set_blender(ALLEGRO_ADD, ALLEGRO_ALPHA, ALLEGRO_INVERSE_ALPHA, theme.fg);
         al_draw_ustr(theme.font, x, y1, 0, UString(text, cursor_pos + 1));
      }
   }
}
示例#8
0
文件: editbox.c 项目: beoran/WidgetZ
void wz_snap_editbox(WZ_EDITBOX* box)
{
	WZ_WIDGET* wgt = (WZ_WIDGET*)box;
	ALLEGRO_FONT* font = wgt->theme->get_font(wgt->theme, 0);
	int len = al_ustr_length(box->text);
	int size = al_ustr_size(box->text);
	
	int scroll_offset = al_ustr_offset(box->text, box->scroll_pos);
	int cursor_offset;
	ALLEGRO_USTR_INFO info;
	ALLEGRO_USTR* text = al_ref_ustr(&info, box->text, scroll_offset, size);
	
	int max_rel_cursor_pos = wz_get_text_pos(font, text, wgt->w);
	
	if (box->cursor_pos < box->scroll_pos)
	{
		box->scroll_pos = box->cursor_pos;
	}
	if (box->cursor_pos > box->scroll_pos + max_rel_cursor_pos)
	{
		box->scroll_pos = box->cursor_pos - max_rel_cursor_pos;
	}
	
	if (box->cursor_pos > 0 && box->cursor_pos - box->scroll_pos < 1)
	{
		box->scroll_pos--;
	}
	
	if (box->cursor_pos > len)
	{
		box->cursor_pos = len;
	}
	if (box->cursor_pos < 0)
	{
		box->cursor_pos = 0;
	}
	
	scroll_offset = al_ustr_offset(box->text, box->scroll_pos);
	cursor_offset = al_ustr_offset(box->text, box->cursor_pos);
	
	text = al_ref_ustr(&info, box->text, scroll_offset, cursor_offset);
	if (al_get_ustr_width(font, text) > wgt->w)
	{
		box->scroll_pos++;
	}
}
示例#9
0
文件: widget.c 项目: beoran/eruta
/** Draws a console. */
int bbconsole_draw(BBWidget * widget, void * data) {
  BBConsole * self  ;
  Font * font       ;
  Color color       ;
  USTRListNode * now;
  int high, linehigh, index, x, y, skip;
  int linew;
  if (!bbwidget_visible(widget)) return BBWIDGET_HANDLE_IGNORE;
  
  self  = bbwidget_console(widget);
  font  = bbwidget_font(widget);
  color = bbwidget_forecolor(widget);
  
  bbwidget_drawroundframe(widget);
  high        = bbwidget_h(widget) - 10;
  x           = bbwidget_x(widget) +  5;
  y           = bbwidget_y(widget) -  5;
  linehigh    = font_lineheight(font);
  
  now         = ustrlist_head(&self->text);
  // skip start lines (to allow scrolling backwards) 
  now         = ustrlist_skipnode(&self->text, self->start);
  
  for (index = high-(linehigh*2); index > 0; index -= linehigh) {
    USTR * textstr;
    if(!now) break;
    textstr = ustrlistnode_ustr(now);
    if(textstr) {
      font_drawstr(font, color, x, y + index, 0, textstr);
    }
    now = ustrlistnode_next(now);
  }
  // draw input string
  font_drawstr(font, color, x, y + high - linehigh, 0, self->input);
  // Draw cursor
  linew = al_get_ustr_width(font, self->input);
  al_draw_line(x + linew, y + high - linehigh, x + linew, y + high, color, 1);
  // draw start for debugging
  al_draw_textf(font, color, x, y, 0, "start: %d, size: %d", self->start, 
                ustrlist_size(&self->text));
  return BBWIDGET_HANDLE_OK;
}
示例#10
0
void TextEntry::maybe_scroll()
{
   const Theme & theme = dialog->get_theme();

   if (cursor_pos < left_pos + 3) {
      if (cursor_pos < 3)
         left_pos = 0;
      else
         left_pos = cursor_pos - 3;
   }
   else {
      for (;;) {
         const int tw = al_get_ustr_width(theme.font,
            UString(text, left_pos, cursor_pos));
         if (x1 + tw + CURSOR_WIDTH < x2) {
            break;
         }
         al_ustr_next(text, &left_pos);
      }
   }
}
示例#11
0
int SpritesCreateText(char *text, int fontnum, int text_r, int text_g,
                      int text_b, int wrapLength)
{
    Sprite[Sprites.spritesCount].name = malloc(sizeof(char) * (strlen(text) + 1));
    Sprite[Sprites.spritesCount].name = strcpy(Sprite[Sprites.spritesCount].name,
                                               (const char *)text);
    LogWrite("Dummying text sprite", 0, MT_INFO,
             Sprite[Sprites.spritesCount].name);

    Sprites.spritesCount += 1; /* Увеличиваем кол-во спрайтов на 1 */

    Sprite[Sprites.spritesCount - 1].text = al_ustr_new((const char *)text);
    Sprite[Sprites.spritesCount - 1].fontNum = fontnum;
    Sprite[Sprites.spritesCount - 1].textR = text_r;
    Sprite[Sprites.spritesCount - 1].textG = text_g;
    Sprite[Sprites.spritesCount - 1].textB = text_b;
    Sprite[Sprites.spritesCount - 1].wrapLength = wrapLength;

    Sprite[Sprites.spritesCount - 1].width =  al_get_ustr_width((const ALLEGRO_FONT *)Fonts.font[fontnum], Sprite[Sprites.spritesCount - 1].text);
    Sprite[Sprites.spritesCount - 1].height = al_get_font_ascent((const ALLEGRO_FONT *)Fonts.font[fontnum]);
    /* обнуляем поверхность спрайта */
    Sprite[Sprites.spritesCount - 1].texture = NULL;

    /* устанавливаем число кадров для спрайта - для текста 1 кадр */
    Sprite[Sprites.spritesCount - 1].clip = malloc(sizeof(Rect) * 1);
    /* разбиваем спрайтшит на кадры */
    Sprite[Sprites.spritesCount - 1].clip[0].x = 0;
    Sprite[Sprites.spritesCount - 1].clip[0].y = 0;
    Sprite[Sprites.spritesCount - 1].clip[0].w = Sprite[Sprites.spritesCount - 1].width;
    Sprite[Sprites.spritesCount - 1].clip[0].h = Sprite[Sprites.spritesCount - 1].height;

    Sprite[Sprites.spritesCount - 1].clipsCount = 1;

    LogWrite("Text sprite dummied", 0, MT_INFO, NULL);

    return Sprites.spritesCount - 1;
}
示例#12
0
文件: Font.hpp 项目: SpaceManiac/ALX
 /**
     Returns the pixel width of the given string for this font.
     @param str string.
     @return pixel width of the given text.
  */
 int getWidth(const String &str) const {
     return al_get_ustr_width(get(), str.get());
 }