Example #1
0
static int bbulk_set(struct kmscon_text *txt)
{
	struct bbulk *bb = txt->data;
	unsigned int sw, sh, i, j;
	struct uterm_video_blend_req *req;
	struct uterm_mode *mode;

	memset(bb, 0, sizeof(*bb));

	mode = uterm_display_get_current(txt->disp);
	if (!mode)
		return -EINVAL;
	sw = uterm_mode_get_width(mode);
	sh = uterm_mode_get_height(mode);

	txt->cols = sw / FONT_WIDTH(txt);
	txt->rows = sh / FONT_HEIGHT(txt);

	bb->reqs = malloc(sizeof(*bb->reqs) * txt->cols * txt->rows);
	if (!bb->reqs)
		return -ENOMEM;
	memset(bb->reqs, 0, sizeof(*bb->reqs) * txt->cols * txt->rows);

	for (i = 0; i < txt->rows; ++i) {
		for (j = 0; j < txt->cols; ++j) {
			req = &bb->reqs[i * txt->cols + j];
			req->x = j * FONT_WIDTH(txt);
			req->y = i * FONT_HEIGHT(txt);
		}
	}

	return 0;
}
Example #2
0
static void
update_input_window (rp_screen *s, rp_input_line *line)
{
  int prompt_width, input_width, total_width;
  int char_len = 0, height;
  GC lgc;
  XGCValues gcv;

  prompt_width = rp_text_width (s, line->prompt, -1);
  input_width  = rp_text_width (s, line->buffer, line->length);
  total_width = defaults.bar_x_padding * 2 + prompt_width + input_width + MAX_FONT_WIDTH (defaults.font);
  height = (FONT_HEIGHT (s) + defaults.bar_y_padding * 2);

  if (RP_IS_UTF8_START (line->buffer[line->position]))
    do
      char_len++;
    while (RP_IS_UTF8_CONT (line->buffer[line->position + char_len]));
  else
    char_len = 1;

  if (total_width < defaults.input_window_size + prompt_width)
    {
      total_width = defaults.input_window_size + prompt_width;
    }

  XMoveResizeWindow (dpy, s->input_window,
                     bar_x (s, total_width), bar_y (s, height), total_width,
                     (FONT_HEIGHT (s) + defaults.bar_y_padding * 2));

  XClearWindow (dpy, s->input_window);
  XSync (dpy, False);

  rp_draw_string (s, s->input_window, STYLE_NORMAL,
                  defaults.bar_x_padding,
                  defaults.bar_y_padding + FONT_ASCENT(s),
                  line->prompt, 
                  -1);

  rp_draw_string (s, s->input_window, STYLE_NORMAL, 
                  defaults.bar_x_padding + prompt_width,
                  defaults.bar_y_padding + FONT_ASCENT(s),
                  line->buffer, 
                  line->length);

  gcv.function = GXxor;
  gcv.foreground = s->fg_color ^ s->bg_color;
  lgc = XCreateGC (dpy, s->input_window, GCFunction | GCForeground, &gcv);

  /* Draw a cheap-o cursor - MkIII */
  XFillRectangle (dpy, s->input_window, lgc,
		  defaults.bar_x_padding + prompt_width +
		  rp_text_width (s, line->buffer, line->position),
                  defaults.bar_y_padding,
		  rp_text_width (s, &line->buffer[line->position], char_len),
                  FONT_HEIGHT (s));

  XFlush (dpy);
  XFreeGC (dpy, lgc);
}
Example #3
0
void
menu_draw_string(Rwindow_t *window)
{
    unsigned int winw, winh;
    unsigned int dummyui;
    int dummyi;
    size_t len;
    char *str;
    Window dummywin;

    if (window == NULL) {

	return;
    }

    XGetGeometry(window->app->display, window->id, &dummywin,
		 &dummyi, &dummyi, &winw, &winh, &dummyui, &dummyui);

    XDrawString(window->app->display, window->id, window->gc,
		window->menu->lefttextoffset,
		(winh + FONT_HEIGHT(window->fontinfo)) / 2, 
		window->title, window->titlelen);

    if (window->menuitem) {
	if (window->menuitem->type == MENUITEM_TOGGLE) {
	    if (*((unsigned long *)window->menuitem->option.valueptr)
		& window->menuitem->option.flag) {
		str = window->menuitem->truetext;
	    } else {
		str = window->menuitem->falsetext;
	    }
	    
	    len = strlen(str);
	    if (len) {
		XDrawString(window->app->display, window->id, window->gc,
			    winw - window->menu->righttextoffset
			    - len * FONT_WIDTH(window->fontinfo),
			    (winh + FONT_HEIGHT(window->fontinfo)) / 2,
			    str, len);
	    }
	} else if (window->menuitem->righttext) {
	    str = window->menuitem->righttext;

	    len = strlen(str);
	    if (len) {
		XDrawString(window->app->display, window->id, window->gc,
			    winw - window->menu->righttextoffset
			    - len * FONT_WIDTH(window->fontinfo),
			    (winh + FONT_HEIGHT(window->fontinfo)) / 2,
			    str, len);
	    }
	}
    }

    return;
}
Example #4
0
File: bar.c Project: ivoarch/antiwm
void
update_window_names (screen_info *s)
{
  char str[100];		/* window names <= 99 char */
  int i;
  int width = calc_bar_width (s->font);
  a_window *cur;
  int cur_x = 5;
  if (!s->bar_is_raised) return;
  XMoveResizeWindow (dpy, s->bar_window, 
		     bar_x (s, width), bar_y (s),
		     width,
		     (FONT_HEIGHT (s->font) + BAR_PADDING * 2));
  XClearWindow (dpy, s->bar_window);
  XRaiseWindow (dpy, s->bar_window);
  if (a_window_head == NULL) return;
  for (i=0, cur = a_window_head; cur; cur = cur->next)
    {
      if (cur->state == STATE_UNMAPPED) continue;
      sprintf (str, "%d-%s", i, cur->name);
      if ( a_current_window == cur) 
	{
	  XDrawString (dpy, s->bar_window, s->bold_gc, cur_x, 
		       BAR_PADDING + s->font->max_bounds.ascent, str, strlen (str));
	}
      else
	{
	  XDrawString (dpy, s->bar_window, s->normal_gc, cur_x, 
		       BAR_PADDING + s->font->max_bounds.ascent, str, strlen (str));
	}
      cur_x += 10 + XTextWidth (s->font, str, strlen (str));
      i++;
    }
}
Example #5
0
static void
marked_message_internal (char *msg, int mark_start, int mark_end)
{
  rp_screen *s = current_screen ();
  int num_lines;
  int width;
  int height;

  PRINT_DEBUG (("msg = %s\n", msg?msg:"NULL"));
  PRINT_DEBUG (("mark_start = %d, mark_end = %d\n", mark_start, mark_end));

  /* Calculate the width and height of the window. */
  num_lines = count_lines (msg, strlen(msg));
  width = defaults.bar_x_padding * 2 + max_line_length(msg);
  height = FONT_HEIGHT (s) * num_lines + defaults.bar_y_padding * 2;

  prepare_bar (s, width, height, num_lines > 1 ? 1 : 0);

  if (defaults.bar_sticky)
    /* Sticky bar is only showing the current window title, don't mark it */
    mark_start = mark_end = -1;
  else
    {
      /* Draw the mark over the designated part of the string. */
      correct_mark (strlen (msg), &mark_start, &mark_end);
      draw_mark (s, msg, mark_start, mark_end);
    }

  draw_string (s, msg, mark_start, mark_end);

  /* Keep a record of the message. */
  update_last_message (msg, mark_start, mark_end);
}
Example #6
0
File: menu.c Project: Cougar/pwm
/* Calculate the desired height of a menu window
 */
static int menu_height(WMenuData *mdata)
{
	int height;

	height=FONT_HEIGHT(GRDATA->menu_font)+2*CF_MENUENT_V_SPACE;
	height*=mdata->nentries;
	height+=CF_MENU_V_SPACE*2;

	return height;
}
Example #7
0
static void
draw_partial_string (rp_screen *s, char *msg, int line_no, int start, int end, int style)
{
  int line_height = FONT_HEIGHT (s);

  rp_draw_string (s, s->bar_window, style,
                  defaults.bar_x_padding,
                  defaults.bar_y_padding + FONT_ASCENT(s)
                  + line_no * line_height,
                  msg + start, end - start + 1);
}
Example #8
0
/**
 * Render a button.
 * @param button
 * Button to render.
 * @param text
 * Optional text to render.
 */
void button_show(button_struct *button, const char *text)
{
    SDL_Surface *texture;

    (void) button_need_redraw(button);

    if (button->pressed_forced) {
        button->pressed = 1;
    }

    texture = texture_surface(button_determine_texture(button));
    surface_show(button->surface, button->x, button->y, NULL, texture);

    if (text) {
        const char *color, *color_shadow;
        int x, y;

        if (button->disabled) {
            color = COLOR_GRAY;
            color_shadow = COLOR_BLACK;
        } else if (button->mouse_over) {
            color = button->color_over;
            color_shadow = button->color_over_shadow;
        } else {
            color = button->color;
            color_shadow = button->color_shadow;
        }

        x = button->x;
        y = button->y;

        if (button->center) {
            x += texture->w / 2 - text_get_width(button->font, text, button->flags) / 2;
            y += texture->h / 2 - FONT_HEIGHT(button->font) / 2;
        }

        if (!color_shadow) {
            text_show(button->surface, button->font, text, x, y, color, button->flags, NULL);
        } else {
            text_show_shadow(button->surface, button->font, text, x, y - 2, color, color_shadow, button->flags, NULL);
        }
    }

    if (button->repeat_func && button->pressed && SDL_GetTicks() - button->pressed_ticks > button->pressed_repeat_ticks) {
        button->repeat_func(button);
        button->pressed_ticks = SDL_GetTicks();
        button->pressed_repeat_ticks = 150;
    }

    button->redraw = 0;
}
Example #9
0
void setup_listing(WListing *l, XFontStruct *font,
				   char **strs, int nstrs)
{
	int maxw;
	
	if(l->strs!=NULL)
		deinit_listing(l);

	l->itemrows=ALLOC_N(int, nstrs);
	
	maxw=strings_maxw(font, strs, nstrs);
	
	l->strs=strs;
	l->nstrs=nstrs;
	l->itemw=maxw+COL_SPACING;
	l->itemh=FONT_HEIGHT(font);
}
Example #10
0
File: bar.c Project: ivoarch/antiwm
static int
bar_y (screen_info *s)
{
  if (BAR_LOCATION % 2) return 0;
  else return s->root_attr.height - (FONT_HEIGHT (s->font) + BAR_PADDING * 2) - 2;
}
Example #11
0
static int
xftfont_draw (struct glyph_string *s, int from, int to, int x, int y,
              bool with_background)
{
  struct frame *f = s->f;
  struct face *face = s->face;
  struct xftfont_info *xftfont_info = (struct xftfont_info *) s->font;
  struct xftface_info *xftface_info = NULL;
  XftDraw *xft_draw = xftfont_get_xft_draw (f);
  FT_UInt *code;
  XftColor fg, bg;
  int len = to - from;
  int i;

  if (s->font == face->font)
    xftface_info = (struct xftface_info *) face->extra;
  xftfont_get_colors (f, face, s->gc, xftface_info,
		      &fg, with_background ? &bg : NULL);
  block_input ();
  if (s->num_clips > 0)
    XftDrawSetClipRectangles (xft_draw, 0, 0, s->clip, s->num_clips);
  else
    XftDrawSetClip (xft_draw, NULL);

  if (with_background)
    {
      int height = FONT_HEIGHT (s->font), ascent = FONT_BASE (s->font);

      /* Font's global height and ascent values might be
	 preposterously large for some fonts.  We fix here the case
	 when those fonts are used for display of glyphless
	 characters, because drawing background with font dimensions
	 in those cases makes the display illegible.  There's only one
	 more call to the draw method with with_background set to
	 true, and that's in x_draw_glyph_string_foreground, when
	 drawing the cursor, where we have no such heuristics
	 available.  FIXME.  */
      if (s->first_glyph->type == GLYPHLESS_GLYPH
	  && (s->first_glyph->u.glyphless.method == GLYPHLESS_DISPLAY_HEX_CODE
	      || s->first_glyph->u.glyphless.method == GLYPHLESS_DISPLAY_ACRONYM))
	height = ascent =
	  s->first_glyph->slice.glyphless.lower_yoff
	  - s->first_glyph->slice.glyphless.upper_yoff;
      XftDrawRect (xft_draw, &bg, x, y - ascent, s->width, height);
    }
  code = alloca (sizeof (FT_UInt) * len);
  for (i = 0; i < len; i++)
    code[i] = ((XCHAR2B_BYTE1 (s->char2b + from + i) << 8)
	       | XCHAR2B_BYTE2 (s->char2b + from + i));

  if (s->padding_p)
    for (i = 0; i < len; i++)
      XftDrawGlyphs (xft_draw, &fg, xftfont_info->xftfont,
		     x + i, y, code + i, 1);
  else
    XftDrawGlyphs (xft_draw, &fg, xftfont_info->xftfont,
		   x, y, code, len);
  unblock_input ();

  return len;
}
Example #12
0
static void
get_mark_box (char *msg, size_t mark_start, size_t mark_end,
              int *x, int *y, int *width, int *height)
{
  rp_screen *s = current_screen ();
  int start, end;
  int mark_end_is_new_line = 0;
  int start_line;
  int end_line;
  int start_pos_in_line;
  int end_pos_in_line;
  int start_line_beginning;
  int end_line_beginning;

  /* If the mark_end is on a new line or the end of the string, then
     back it up one character. */
  if (msg[mark_end-1] == '\n' || mark_end == strlen (msg))
    {
      mark_end--;
      mark_end_is_new_line = 1;
    }

  start_line = count_lines(msg, mark_start);
  end_line = count_lines(msg, mark_end);

  start_pos_in_line = pos_in_line(msg, mark_start);
  end_pos_in_line = pos_in_line(msg, mark_end);

  start_line_beginning = line_beginning(msg, mark_start);
  end_line_beginning = line_beginning(msg, mark_end);

  PRINT_DEBUG (("start_line = %d, end_line = %d\n", start_line, end_line));
  PRINT_DEBUG (("start_line_beginning = %d, end_line_beginning = %d\n",
                start_line_beginning, end_line_beginning));

  if (mark_start == 0 || start_pos_in_line == 0)
    start = 0;
  else
    start = rp_text_width (s, defaults.font,
                           &msg[start_line_beginning],
                           start_pos_in_line) + defaults.bar_x_padding;
   
  end = rp_text_width (s, defaults.font,
                       &msg[end_line_beginning],
                       end_pos_in_line) + defaults.bar_x_padding * 2;

  if (mark_end != strlen (msg))
    end -= defaults.bar_x_padding;

  /* A little hack to highlight to the end of the line, if the
     mark_end is at the end of a line. */
  if (mark_end_is_new_line)
    {
      *width = max_line_length(msg) + defaults.bar_x_padding * 2;
    }
  else
    {
      *width = end - start;
    }

  *x = start;
  *y = (start_line - 1) * FONT_HEIGHT (s) + defaults.bar_y_padding;
  *height = (end_line - start_line + 1) * FONT_HEIGHT (s);
}
Example #13
0
File: menu.c Project: Cougar/pwm
/* Create a menu window
 */
static WMenu* create_menu(WMenuData *mdata, WThing *context, int x, int y,
						  WMenu *parent)
{
	int w, h, th, eh;
	int flags=0;
	Window win;
	WMenu *menu;
	
	if(mdata->init_func!=NULL && mdata->nref==0)
		mdata->init_func(mdata, context);

	if(mdata->flags&WMENUDATA_CONTEXTUAL){
		if(context==NULL || WTHING_IS(context, WTHING_SCREEN) ||
		   WTHING_IS(context, WTHING_MENU))
			return NULL;
		flags|=(WMENU_NOTITLE|WMENU_CONTEXTUAL);
	}else{
		context=NULL;
	}
	
	if(mdata->nref!=0)
		flags|=(WMENU_NOTITLE|WMENU_CONTEXTUAL);
	
	if(mdata->title==NULL)
		flags|=(WMENU_NOTITLE|WMENU_CONTEXTUAL);
	
	if(parent!=NULL)
		flags|=parent->flags&(WMENU_NOTITLE|WMENU_CONTEXTUAL);

	/* */
	
	w=menu_width(mdata, flags);
	h=menu_height(mdata);	
	
	/* Don't display empty menus */
	if(w==0 || h==0)
		return NULL;
	
	/* */
	
	menu=ALLOC(WMenu);
	
	if(menu==NULL){
		warn_err();
		return NULL;
	}
	
	WTHING_INIT(menu, WTHING_MENU);
	
	th=FONT_HEIGHT(GRDATA->font)+2*CF_MENUTITLE_V_SPACE;
	eh=FONT_HEIGHT(GRDATA->menu_font)+2*CF_MENUENT_V_SPACE;

	if(parent==NULL){
		x-=w/2;
		y+=th/(flags&WMENU_NOTITLE ? 2 : -2 );
	}else if(!(flags&WMENU_NOTITLE)){
		y-=th;
	}

	if(flags&WMENU_NOTITLE)
		th=0;

	h+=th;

	win=create_simple_window(x, y, w, h,
							 GRDATA->base_colors.pixels[WCG_PIX_BG]);
	
	menu->menu_win=win;
	menu->x=x;
	menu->y=y;
	menu->w=w;
	menu->h=h;
	menu->title_height=th;
	menu->entry_height=eh;
	menu->flags=flags;
	menu->selected=NO_ENTRY;
	menu->data=mdata;
	menu->context=context;
	
	if(mdata->nref++==0)
		mdata->inst1=menu;

	XSelectInput(wglobal.dpy, win, MENU_MASK);
	XSaveContext(wglobal.dpy, win, wglobal.win_context, (XPointer)menu);

	if(parent==NULL)
		add_winobj((WWinObj*)menu, WORKSPACE_STICKY, LVL_MENU);
	else
		add_winobj_above((WWinObj*)menu, (WWinObj*)parent);

	map_winobj((WWinObj*)menu);

	return menu;
}
Example #14
0
void
menu_draw_string_imlib2(Rwindow_t *window)
{
    int textw, texth;
    unsigned int winw, winh;
    unsigned int dummyui;
    int dummyi;
    size_t len;
    char *str;
    Window dummywin;
    Imlib_Image textimg;
    char blend;

    if (window->im2title) {
        XGetGeometry(window->app->display, window->id, &dummywin,
                     &dummyi, &dummyi, &winw, &winh, &dummyui, &dummyui);
        imlib_context_set_image(window->im2title);
        imlib_context_set_drawable(window->id);
        blend = imlib_context_get_blend();
        imlib_context_set_blend(1);
        imlib_render_image_on_drawable(window->menu->lefttextoffset,
                                       (winh - window->im2titleh) / 2);
        if (window->menuitem) {
            textimg = NULL;
            if (window->menuitem->type == MENUITEM_TOGGLE) {
                if (!window->menuitem->im2true) {
                    imlib_context_set_font(window->im2font);
                    imlib_get_text_size(window->menuitem->truetext,
                                        &textw, &texth);
                    textimg = imlib_create_image(textw, texth);
                    if (textimg) {
                        imlib_context_set_image(textimg);
                        imlib_image_set_has_alpha(1);
                        imlib_image_clear();
                        imlib_context_set_color(204, 181, 59, 255);
                        imlib_text_draw(0, 0, window->menuitem->truetext);
                        window->menuitem->im2true = textimg;
                        window->menuitem->im2truew = textw;
                        window->menuitem->im2trueh = texth;
                    }
                }
                if (!window->menuitem->im2false) {
                    imlib_context_set_font(window->im2font);
                    imlib_get_text_size(window->menuitem->falsetext,
                                        &textw, &texth);
                    textimg = imlib_create_image(textw, texth);
                    if (textimg) {
                        imlib_context_set_image(textimg);
                        imlib_image_set_has_alpha(1);
                        imlib_image_clear();
                        imlib_context_set_color(204, 181, 59, 255);
                        imlib_text_draw(0, 0, window->menuitem->falsetext);
                        window->menuitem->im2false = textimg;
                        window->menuitem->im2falsew = textw;
                        window->menuitem->im2falseh = texth;
                    }
                }
                if (*((unsigned long *)window->menuitem->option.valueptr)
                    & window->menuitem->option.flag) {
                    str = window->menuitem->truetext;
                    textimg = window->menuitem->im2true;
                    textw = window->menuitem->im2truew;
                    texth = window->menuitem->im2trueh;
                } else {
                    str = window->menuitem->falsetext;
                    textimg = window->menuitem->im2false;
                    textw = window->menuitem->im2falsew;
                    texth = window->menuitem->im2falseh;
                }
            } else if (window->menuitem->righttext) {
                if (!window->menuitem->im2right) {
                    imlib_context_set_font(window->im2font);
                    imlib_get_text_size(window->menuitem->righttext,
                                        &textw, &texth);
                    textimg = imlib_create_image(textw, texth);
                    if (textimg) {
                        imlib_context_set_image(textimg);
                        imlib_image_set_has_alpha(1);
                        imlib_image_clear();
                        imlib_context_set_color(204, 181, 59, 255);
                        imlib_text_draw(0, 0, window->menuitem->righttext);
                        window->menuitem->im2right = textimg;
                        window->menuitem->im2rightw = textw;
                        window->menuitem->im2righth = texth;
                    }
                }
                str = window->menuitem->righttext;
                textimg = window->menuitem->im2right;
                textw = window->menuitem->im2rightw;
                texth = window->menuitem->im2righth;
            }
            if (textimg) {
                imlib_context_set_image(textimg);
                imlib_context_set_drawable(window->id);
                imlib_render_image_on_drawable(winw - window->menu->righttextoffset - textw,
                                               (winh - texth) / 2);
            } else {
#if 0
                len = strlen(str);
                if (len) {
                    XDrawString(window->app->display, window->id, window->gc,
                                winw - window->menu->righttextoffset
                                - len * FONT_WIDTH(window->fontinfo),
                                (winh + FONT_HEIGHT(window->fontinfo)) / 2,
                                str, len);
                }
#endif
            }
        }
        imlib_context_set_blend(blend);
    } else {
        menu_draw_string(window);
    }

    return;
}
Example #15
0
static int gltex_set(struct kmscon_text *txt)
{
	struct gltex *gt = txt->data;
	int ret;
	static char *attr[] = { "position", "texture_position",
				"fgcolor", "bgcolor" };
	GLint s;
	const char *ext;
	struct uterm_mode *mode;
	bool opengl;

	memset(gt, 0, sizeof(*gt));
	shl_dlist_init(&gt->atlases);

	ret = shl_hashtable_new(&gt->glyphs, shl_direct_hash,
				shl_direct_equal, NULL,
				free_glyph);
	if (ret)
		return ret;

	ret = shl_hashtable_new(&gt->bold_glyphs, shl_direct_hash,
				shl_direct_equal, NULL,
				free_glyph);
	if (ret)
		goto err_htable;

	ret = uterm_display_use(txt->disp, &opengl);
	if (ret < 0 || !opengl) {
		if (ret == -EOPNOTSUPP)
			log_error("display doesn't support hardware-acceleration");
		goto err_bold_htable;
	}

	gl_clear_error();

	ret = gl_shader_new(&gt->shader, gl_static_gltex_vert,
			    gl_static_gltex_frag, attr, 4, log_llog, NULL);
	if (ret)
		goto err_bold_htable;

	gt->uni_proj = gl_shader_get_uniform(gt->shader, "projection");
	gt->uni_atlas = gl_shader_get_uniform(gt->shader, "atlas");
	gt->uni_advance_htex = gl_shader_get_uniform(gt->shader,
						     "advance_htex");
	gt->uni_advance_vtex = gl_shader_get_uniform(gt->shader,
						     "advance_vtex");

	if (gl_has_error(gt->shader)) {
		log_warning("cannot create shader");
		goto err_shader;
	}

	mode = uterm_display_get_current(txt->disp);
	gt->sw = uterm_mode_get_width(mode);
	gt->sh = uterm_mode_get_height(mode);

	txt->cols = gt->sw / FONT_WIDTH(txt);
	txt->rows = gt->sh / FONT_HEIGHT(txt);

	glGetIntegerv(GL_MAX_TEXTURE_SIZE, &s);
	if (s <= 0)
		s = 64;
	else if (s > 2048)
		s = 2048;
	gt->max_tex_size = s;

	gl_clear_error();

	ext = (const char*)glGetString(GL_EXTENSIONS);
	if (ext && strstr((const char*)ext, "GL_EXT_unpack_subimage")) {
		gt->supports_rowlen = true;
	} else {
		log_warning("your GL implementation does not support GL_EXT_unpack_subimage, glyph-rendering may be slower than usual");
	}

	return 0;

err_shader:
	gl_shader_unref(gt->shader);
err_bold_htable:
	shl_hashtable_free(gt->bold_glyphs);
err_htable:
	shl_hashtable_free(gt->glyphs);
	return ret;
}