static void 
i7_cell_renderer_transcript_get_size(GtkCellRenderer *self, GtkWidget *widget, GdkRectangle *cell_area, int *x_offset, int *y_offset, int *width, int *height) 
{
	I7_CELL_RENDERER_TRANSCRIPT_USE_PRIVATE;

	PangoRectangle command_rect, transcript_rect, expected_rect;
	PangoLayout *layout;
	unsigned xpad, ypad, transcript_width, calc_width, calc_height;
	
	g_object_get(self, "xpad", &xpad, "ypad", &ypad, NULL);
	transcript_width = (priv->default_width / 2) - xpad;

	/* Get size of command */
	layout = gtk_widget_create_pango_layout(widget, priv->command);
	pango_layout_get_pixel_extents(layout, NULL, &command_rect);
	g_object_unref(layout);

	/* Get size of transcript text */
	layout = gtk_widget_create_pango_layout(widget, priv->transcript_text);
	pango_layout_set_width(layout, (int)(transcript_width - priv->text_padding * 2) * PANGO_SCALE);
	pango_layout_set_wrap(layout, PANGO_WRAP_WORD_CHAR);
	pango_layout_get_pixel_extents(layout, NULL, &transcript_rect);
	g_object_unref(layout);

	/* Get size of expected text */
	layout = gtk_widget_create_pango_layout(widget, priv->expected_text);
	pango_layout_set_width(layout, (int)(transcript_width - priv->text_padding * 2) * PANGO_SCALE);
	pango_layout_set_wrap(layout, PANGO_WRAP_WORD_CHAR);
	pango_layout_get_pixel_extents(layout, NULL, &expected_rect);
	g_object_unref (layout);

	/* Calculate the required width and height for the cell */
	calc_width = priv->default_width;
	calc_height = (unsigned)(command_rect.height + MAX(transcript_rect.height, expected_rect.height)) + ypad * 2 + priv->text_padding * 4;

	/* Set the passed-in parameters; if the available cell area is larger than
	 the required width and height, just use that instead */
	if(cell_area) {
		if(width)
			*width = MAX(cell_area->width, (int)calc_width);
		if(height)
			*height = MAX(cell_area->height, (int)calc_height);
	} else {
		if(width)
			*width = (int)calc_width;
		if(height)
			*height = (int)calc_height;
	}
	if(x_offset)
		*x_offset = 0;
	if(y_offset)
		*y_offset = 0;
}
TextAsset::Size
TextAsset::computeSizeOfText(cairo_t* cairoContext,
                             const std::string textString,
                             int bounds,
                             PangoFontDescription* font,
                             Rect* tight,
                             float* lineHeightOut)
{
    PangoLayout* layout = pango_cairo_create_layout(cairoContext);

    // Kerning
    PangoAttrList* attr_list = pango_attr_list_new();
    PangoAttribute* spacing_attr = pango_attr_letter_spacing_new(pango_units_from_double(_kern));
    pango_attr_list_insert(attr_list, spacing_attr);
    pango_layout_set_attributes(layout, attr_list);

    pango_cairo_context_set_resolution(pango_layout_get_context(layout), DISPLAY_RESOLUTION);
    pango_layout_set_text(layout, textString.c_str(), (int)textString.length());
    pango_layout_set_alignment(layout, _alignment);
    pango_layout_set_wrap(layout, PANGO_WRAP_WORD_CHAR);

    const Size maxTextureSize(bounds, 1024);
    pango_layout_set_width(layout, pango_units_from_double(maxTextureSize.width));
    pango_layout_set_height(layout, pango_units_from_double(maxTextureSize.height));
    pango_layout_set_font_description(layout, font);
    applyLeading(cairoContext, layout, font);

    PangoRectangle estimateSize;
    PangoRectangle ink;
    pango_layout_get_pixel_extents(layout, &ink, &estimateSize);

    // If the text is right or center aligned the offsets will contain all the
    // leading space.  We ignore that for the size because drawText will draw
    // in the larger box.  The tight box below will get the offsets so we know
    // where to draw so the text lands in the same tight box.
    Size res(estimateSize.width, estimateSize.height);

    if (tight != NULL) {
        float lineHeight;
        float xHeight = charHeight(cairoContext, font, 'x', &lineHeight);
        if (lineHeightOut != NULL) {
            *lineHeightOut = lineHeight;
        }
        const float capHeight = charHeight(cairoContext, font, 'Y');
        const float ascender = pango_units_to_double(pango_layout_get_baseline(layout));
        const float topSpace = ascender - capHeight;
        const float bottomSpace = MAX(lineHeight - ascender - (capHeight - xHeight), 0);
        if (res.height > topSpace + bottomSpace) {
            *tight = Rect(estimateSize.x,
                          estimateSize.y + topSpace,
                          res.width,
                          res.height - topSpace - bottomSpace);
        } else {
            *tight = Rect(0, 0, res.width, res.height);
        }
    }
    g_object_unref(layout);

    return res;
}
Exemple #3
0
void draw_clock(void *obj, cairo_t *c)
{
	Clock *clock = obj;
	PangoLayout *layout = pango_cairo_create_layout(c);

	pango_layout_set_font_description(layout, time1_font_desc);
	pango_layout_set_width(layout, clock->area.width * PANGO_SCALE);
	pango_layout_set_alignment(layout, PANGO_ALIGN_CENTER);
	pango_layout_set_wrap(layout, PANGO_WRAP_WORD_CHAR);
	pango_layout_set_ellipsize(layout, PANGO_ELLIPSIZE_NONE);
	pango_layout_set_text(layout, buf_time, strlen(buf_time));

	cairo_set_source_rgba(c, clock->font.rgb[0], clock->font.rgb[1], clock->font.rgb[2], clock->font.alpha);

	pango_cairo_update_layout(c, layout);
	draw_text(layout, c, 0, clock->time1_posy, &clock->font, ((Panel *)clock->area.panel)->font_shadow);

	if (time2_format) {
		pango_layout_set_font_description(layout, time2_font_desc);
		pango_layout_set_indent(layout, 0);
		pango_layout_set_text(layout, buf_date, strlen(buf_date));
		pango_layout_set_width(layout, clock->area.width * PANGO_SCALE);

		pango_cairo_update_layout(c, layout);
		draw_text(layout, c, 0, clock->time2_posy, &clock->font, ((Panel *)clock->area.panel)->font_shadow);
	}

	g_object_unref(layout);
}
Exemple #4
0
void
content_draw (GtkWidget *widget,
              cairo_t   *cr)
{
        PangoContext *context;
        PangoLayout *title_layout;
        PangoLayout *sub_layout;
        PangoFontDescription *desc;
        int width, height;
        int sub_width;

        width = gdk_window_get_width (gtk_widget_get_window (widget));
        height = gdk_window_get_height (gtk_widget_get_window (widget));

        cairo_translate (cr, width / 2, height / 2);

        context = gdk_pango_context_get_for_screen (gtk_widget_get_screen (widget));

        title_layout = pango_layout_new (context);
        pango_layout_set_text (title_layout, _("This session is locked"), -1);
        desc = pango_font_description_from_string (TITLE_FONT);
        pango_layout_set_font_description (title_layout, desc);
        pango_font_description_free (desc);

        cairo_set_source_rgba (cr, 1.0, 1.0, 1.0, 1.0);

        pango_cairo_update_layout (cr, title_layout);
        pango_layout_get_size (title_layout, &width, &height);

        cairo_save (cr);
        /* Adjust the translation to the middle left of the icon */
        cairo_translate (cr, - width / PANGO_SCALE / 2 - height / PANGO_SCALE, - height / PANGO_SCALE / 2);
        draw_lock_icon (cr, height / PANGO_SCALE);
        cairo_restore (cr);

        cairo_move_to (cr, - width / PANGO_SCALE / 2 + height / PANGO_SCALE, - height / PANGO_SCALE);
        pango_cairo_show_layout (cr, title_layout);

        g_object_unref (title_layout);

        sub_layout = pango_layout_new (context);
        pango_layout_set_text (sub_layout, _("You'll be redirected to the unlock dialog automatically in a few seconds"), -1);
        pango_layout_set_wrap (sub_layout, PANGO_WRAP_WORD_CHAR);
        pango_layout_set_width (sub_layout, width + 2 * height);
        desc = pango_font_description_from_string (MESSAGE_FONT);
        pango_layout_set_font_description (sub_layout, desc);
        pango_font_description_free (desc);

        cairo_set_source_rgba (cr, 0.6, 0.6, 0.6, 1.0);

        pango_cairo_update_layout (cr, sub_layout);
        pango_layout_get_size (sub_layout, &sub_width, NULL);

        cairo_move_to (cr, - (width + 2 * height) / PANGO_SCALE / 2, height / PANGO_SCALE);
        cairo_scale (cr, (width + 2 * height) / (gdouble)sub_width, (width + 2 * height) / (gdouble)sub_width);
        pango_cairo_show_layout (cr, sub_layout);

        g_object_unref (sub_layout);
        g_object_unref (context);
}
Exemple #5
0
static
void mw_paint_tip(GtkWidget *widget, GdkEventExpose *event)
{
	GtkStyle *style;
	GdkWindow *window;
	char *tooltiptext = get_tooltip_text();

	if(tooltiptext == NULL) tooltiptext = g_strdup("oeps");
	pango_layout_set_markup(layout, tooltiptext, strlen(tooltiptext));
	pango_layout_set_wrap(layout, PANGO_WRAP_WORD);
	pango_layout_set_width(layout, 300000);
	style = gtk_widget_get_style (tipwindow);
	window = gtk_widget_get_window (tipwindow);

	gtk_paint_flat_box (style, window, GTK_STATE_NORMAL, GTK_SHADOW_OUT,
			NULL, tipwindow, "tooltip", 0, 0, -1, -1);


	gtk_paint_layout (style, window, GTK_STATE_NORMAL, TRUE,
			NULL, tipwindow, "tooltip", 4, 4, layout);
	/*
	   g_object_unref(layout);
	   */
	g_free(tooltiptext);
	return;
}
Exemple #6
0
textbox* textbox_create ( TextboxFlags flags, short x, short y, short w, short h,
                          TextBoxFontType tbft, const char *text )
{
    textbox *tb = g_malloc0 ( sizeof ( textbox ) );

    tb->flags = flags;

    tb->x = x;
    tb->y = y;
    tb->w = MAX ( 1, w );
    tb->h = MAX ( 1, h );

    tb->changed = FALSE;

    tb->main_surface = cairo_image_surface_create ( get_format (), tb->w, tb->h );
    tb->main_draw    = cairo_create ( tb->main_surface );
    tb->layout       = pango_cairo_create_layout ( tb->main_draw );
    PangoFontDescription *pfd = pango_font_description_from_string ( config.menu_font );
    pango_layout_set_font_description ( tb->layout, pfd );
    pango_font_description_free ( pfd );
    textbox_font ( tb, tbft );

    if ( ( flags & TB_WRAP ) == TB_WRAP ) {
        pango_layout_set_wrap ( tb->layout, PANGO_WRAP_WORD_CHAR );
    }
    textbox_text ( tb, text ? text : "" );
    textbox_cursor_end ( tb );

    // auto height/width modes get handled here
    textbox_moveresize ( tb, tb->x, tb->y, tb->w, tb->h );

    return tb;
}
Exemple #7
0
static void
e_contact_output (GtkPrintContext *context,
                  PangoFontDescription *font,
                  gdouble x,
                  gdouble y,
                  gdouble width,
                  const gchar *text)
{
	PangoLayout *layout;
	gdouble indent;
	cairo_t *cr;

	layout = gtk_print_context_create_pango_layout (context);

	if (width == -1 || get_font_width (context, font, text) <= width)
		indent = .0;
	else
		indent = get_font_width (context, font, "     ");

	pango_layout_set_font_description (layout, font);
	pango_layout_set_text (layout, text, -1);
	pango_layout_set_width (layout, pango_units_from_double (width));
	pango_layout_set_indent (layout, pango_units_from_double (indent));
	pango_layout_set_wrap (layout, PANGO_WRAP_WORD_CHAR);

	cr = gtk_print_context_get_cairo_context (context);

	cairo_save (cr);
	cairo_move_to (cr, x, y);
	pango_cairo_show_layout (cr, layout);
	cairo_restore (cr);

	g_object_unref (layout);
}
static PangoLayout *
create_layout_with_attrs (GtkWidget *widget,
                          GdTwoLinesRenderer *self,
                          PangoEllipsizeMode ellipsize)
{
  PangoLayout *layout;
  gint wrap_width;
  PangoWrapMode wrap_mode;
  PangoAlignment alignment;

  g_object_get (self,
                "wrap-width", &wrap_width,
                "wrap-mode", &wrap_mode,
                "alignment", &alignment,
                NULL);

  layout = pango_layout_new (gtk_widget_get_pango_context (widget));

  pango_layout_set_ellipsize (layout, ellipsize);
  pango_layout_set_wrap (layout, wrap_mode);
  pango_layout_set_alignment (layout, alignment);

  if (wrap_width != -1)
    pango_layout_set_width (layout, wrap_width * PANGO_SCALE);

  return layout;
}
Exemple #9
0
/*
 * max_window_name_width
 *
 * Returns: gint
 * Description: Calculate the width of the decoration required to display
 * the window name using pango (with 6px padding)
 * Returns zero if window has no name.
 */
gint
max_window_name_width (WnckWindow *win)
{
    decor_t     *d = g_object_get_data (G_OBJECT (win), "decor");
    const gchar *name;
    gint	w;

    /* Ensure that a layout is created */
    if (!d->layout)
    {
	d->layout = pango_layout_new (d->frame->pango_context);
	if (!d->layout)
	    return 0;

	pango_layout_set_wrap (d->layout, PANGO_WRAP_CHAR);
    }

    /* Return zero if window has no name */
    name = wnck_window_get_name (win);
    if (!name)
	return 0;

    /* Reset the width, set hte text and get the size required */
    pango_layout_set_auto_dir (d->layout, FALSE);
    pango_layout_set_width (d->layout, -1);
    pango_layout_set_text (d->layout, name, strlen (name));
    pango_layout_get_pixel_size (d->layout, &w, NULL);

    if (d->name)
	pango_layout_set_text (d->layout, d->name, strlen (d->name));

    return w + 6;
}
Exemple #10
0
ttext::ttext() :
#if PANGO_VERSION_CHECK(1,22,0)
	context_(pango_font_map_create_context(pango_cairo_font_map_get_default())),
#else
	context_(pango_cairo_font_map_create_context((
		reinterpret_cast<PangoCairoFontMap*>(pango_cairo_font_map_get_default())))),
#endif
	layout_(pango_layout_new(context_)),
	rect_(),
	surface_(),
#ifdef SDL_GPU
	texture_(),
#endif
	text_(),
	markedup_text_(false),
	link_aware_(false),
	link_color_(),
	font_class_(font::FONT_SANS_SERIF),
	font_size_(14),
	font_style_(STYLE_NORMAL),
	foreground_color_(0xFFFFFFFF), // solid white
	maximum_width_(-1),
	characters_per_line_(0),
	maximum_height_(-1),
	ellipse_mode_(PANGO_ELLIPSIZE_END),
	alignment_(PANGO_ALIGN_LEFT),
	maximum_length_(std::string::npos),
	calculation_dirty_(true),
	length_(0),
	surface_dirty_(true),
	surface_buffer_(nullptr)
{
	// With 72 dpi the sizes are the same as with SDL_TTF so hardcoded.
	pango_cairo_context_set_resolution(context_, 72.0);

	pango_layout_set_ellipsize(layout_, ellipse_mode_);
	pango_layout_set_alignment(layout_, alignment_);
	pango_layout_set_wrap(layout_, PANGO_WRAP_WORD_CHAR);

	/*
	 * Set the pango spacing a bit bigger since the default is deemed to small
	 * http://www.wesnoth.org/forum/viewtopic.php?p=358832#p358832
	 */
	pango_layout_set_spacing(layout_, 2 * PANGO_SCALE);

	cairo_font_options_t *fo = cairo_font_options_create();
	cairo_font_options_set_hint_style(fo, CAIRO_HINT_STYLE_FULL);
	cairo_font_options_set_hint_metrics(fo, CAIRO_HINT_METRICS_ON);
#ifdef _WIN32
	// Cairo on Windows (at least the latest available version from gtk.org
	// as of 2014-02-22, version 1.10.2) has issues with ClearType resulting
	// in glitchy anti-aliasing with CAIRO_ANTIALIAS_SUBPIXEL or
	// CAIRO_ANTIALIAS_DEFAULT, but not CAIRO_ANTIALIAS_GRAY, so we use that
	// as a workaround until the Windows package is updated to use a newer
	// version of Cairo (see Wesnoth bug #21648).
	cairo_font_options_set_antialias(fo, CAIRO_ANTIALIAS_GRAY);
#endif
	pango_cairo_context_set_font_options(context_, fo);
	cairo_font_options_destroy(fo);
}
Exemple #11
0
void Text::SetString(const string& String)
{
    cairo_surface_t* TempSurface = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, 0, 0);
    cairo_t* LayoutContext = cairo_create(TempSurface);
    cairo_surface_destroy(TempSurface);

    PangoLayout* Layout = pango_cairo_create_layout(LayoutContext);
    pango_layout_set_width(Layout, LayoutWidth * PANGO_SCALE);
    pango_layout_set_wrap(Layout, PANGO_WRAP_WORD_CHAR);
    pango_layout_set_text(Layout, String.c_str(), -1);

    PangoFontDescription* Desc = pango_font_description_from_string("Sans 18");
    pango_font_description_set_absolute_size(Desc, Size * PANGO_SCALE);
    pango_font_description_set_weight(Desc, PANGO_WEIGHT_MEDIUM);
    pango_layout_set_font_description(Layout, Desc);
    pango_font_description_free(Desc);

    pango_layout_get_pixel_size(Layout, &Width, &Height);
    uint8_t* pData = (uint8_t*)calloc(4 * Width * Height, sizeof(uint8_t));
    cairo_surface_t* Surface = cairo_image_surface_create_for_data(pData, CAIRO_FORMAT_ARGB32, Width, Height, 4 * Width);
    cairo_t* RenderContext = cairo_create(Surface);

    cairo_set_source_rgba(RenderContext, Color & 0xFF, (Color >> 8) & 0xFF, (Color >> 16) & 0xFF, Color >> 24);
    pango_cairo_show_layout(RenderContext, Layout);
    Create(pData, GL_RGBA, Width, Height);

    free(pData);
    g_object_unref(Layout);
    cairo_destroy(LayoutContext);
    cairo_destroy(RenderContext);
    cairo_surface_destroy(Surface);
}
Exemple #12
0
void tooltip_update()
{
	if (!g_tooltip.tooltip_text) {
		tooltip_hide(0);
		return;
	}

	tooltip_update_geometry();
	if (just_shown) {
		if (!panel_horizontal)
			y -= height / 2; // center vertically
		just_shown = FALSE;
	}
	tooltip_adjust_geometry();
	XMoveResizeWindow(server.display, g_tooltip.window, x, y, width, height);

	// Stuff for drawing the tooltip
	cairo_surface_t *cs = cairo_xlib_surface_create(server.display, g_tooltip.window, server.visual, width, height);
	cairo_t *c = cairo_create(cs);
	Color bc = g_tooltip.bg->fill_color;
	Border b = g_tooltip.bg->border;
	if (server.real_transparency) {
		clear_pixmap(g_tooltip.window, 0, 0, width, height);
		draw_rect(c, b.width, b.width, width - 2 * b.width, height - 2 * b.width, b.radius - b.width / 1.571);
		cairo_set_source_rgba(c, bc.rgb[0], bc.rgb[1], bc.rgb[2], bc.alpha);
	} else {
		cairo_rectangle(c, 0., 0, width, height);
		cairo_set_source_rgb(c, bc.rgb[0], bc.rgb[1], bc.rgb[2]);
	}
	cairo_fill(c);
	cairo_set_line_width(c, b.width);
	if (server.real_transparency)
		draw_rect(c, b.width / 2.0, b.width / 2.0, width - b.width, height - b.width, b.radius);
	else
		cairo_rectangle(c, b.width / 2.0, b.width / 2.0, width - b.width, height - b.width);
	cairo_set_source_rgba(c, b.color.rgb[0], b.color.rgb[1], b.color.rgb[2], b.color.alpha);
	cairo_stroke(c);

	Color fc = g_tooltip.font_color;
	cairo_set_source_rgba(c, fc.rgb[0], fc.rgb[1], fc.rgb[2], fc.alpha);
	PangoLayout *layout = pango_cairo_create_layout(c);
	pango_layout_set_font_description(layout, g_tooltip.font_desc);
	pango_layout_set_wrap(layout, PANGO_WRAP_WORD);
	pango_layout_set_text(layout, g_tooltip.tooltip_text, -1);
	PangoRectangle r1, r2;
	pango_layout_get_pixel_extents(layout, &r1, &r2);
	pango_layout_set_width(layout, width * PANGO_SCALE);
	pango_layout_set_height(layout, height * PANGO_SCALE);
	pango_layout_set_ellipsize(layout, PANGO_ELLIPSIZE_END);
	// I do not know why this is the right way, but with the below cairo_move_to it seems to be centered (horiz. and
	// vert.)
	cairo_move_to(c,
				  -r1.x / 2 + g_tooltip.bg->border.width + g_tooltip.paddingx,
				  -r1.y / 2 + 1 + g_tooltip.bg->border.width + g_tooltip.paddingy);
	pango_cairo_show_layout(c, layout);

	g_object_unref(layout);
	cairo_destroy(c);
	cairo_surface_destroy(cs);
}
/* Updates the pango layout width */
static void
update_pango_layout (MateIconTextItem *iti)
{
    MateIconTextItemPrivate *priv;
    PangoRectangle bounds;
    const char *text;

    priv = iti->_priv;

    if (iti->editing) {
        text = gtk_entry_get_text (GTK_ENTRY (priv->entry));
    } else {
        text = iti->text;
    }

    pango_layout_set_wrap (priv->layout, PANGO_WRAP_WORD_CHAR);
    pango_layout_set_text (priv->layout, text, strlen (text));
    pango_layout_set_width (priv->layout, iti->width * PANGO_SCALE);

    /* In PANGO_WRAP_WORD mode, words wider than a line of text make
     * PangoLayout overflow the layout width.  If this happens, switch to
     * character-based wrapping.
     */

    pango_layout_get_pixel_extents (iti->_priv->layout, NULL, &bounds);

    priv->layout_width = bounds.width;
    priv->layout_height = bounds.height;
}
Exemple #14
0
void tooltip_update_geometry()
{
	Panel *panel = g_tooltip.panel;
	int screen_width = server.monitors[panel->monitor].x + server.monitors[panel->monitor].width;

	cairo_surface_t *cs = cairo_xlib_surface_create(server.display, g_tooltip.window, server.visual, width, height);
	cairo_t *c = cairo_create(cs);
	PangoLayout *layout = pango_cairo_create_layout(c);

	pango_layout_set_font_description(layout, g_tooltip.font_desc);
	PangoRectangle r1, r2;
	pango_layout_set_text(layout, "1234567890", -1);
	pango_layout_get_pixel_extents(layout, &r1, &r2);
	int max_width = MIN(r2.width * 7, screen_width * 2 / 3);
	pango_layout_set_width(layout, max_width * PANGO_SCALE);

	pango_layout_set_text(layout, g_tooltip.tooltip_text, -1);
	pango_layout_set_wrap(layout, PANGO_WRAP_WORD);
	pango_layout_get_pixel_extents(layout, &r1, &r2);
	width = 2 * g_tooltip.bg->border.width + 2 * g_tooltip.paddingx + r2.width;
	height = 2 * g_tooltip.bg->border.width + 2 * g_tooltip.paddingy + r2.height;

	if (panel_horizontal && panel_position & BOTTOM)
		y = panel->posy - height;
	else if (panel_horizontal && panel_position & TOP)
		y = panel->posy + panel->area.height;
	else if (panel_position & LEFT)
		x = panel->posx + panel->area.width;
	else
		x = panel->posx - width;

	g_object_unref(layout);
	cairo_destroy(c);
	cairo_surface_destroy(cs);
}
Exemple #15
0
void ui_insert_text(char *s, int x, int y, int h, int w, double *rgba,
		    enum alignment align)
{
	PangoTabArray *tabs;
	int height;

	pango_layout_set_width(ui->w[ui->cur].pangolayout, w * PANGO_SCALE);
	switch (align) {
	case RIGHT:
		pango_layout_set_alignment(ui->w[ui->cur].pangolayout, PANGO_ALIGN_RIGHT);
		break;
	case CENTER:
		pango_layout_set_alignment(ui->w[ui->cur].pangolayout, PANGO_ALIGN_CENTER);
		break;
	default:
		pango_layout_set_alignment(ui->w[ui->cur].pangolayout, PANGO_ALIGN_LEFT);
	}
	tabs = pango_tab_array_new_with_positions(1, TRUE, PANGO_TAB_LEFT, config.tabs);
	pango_layout_set_wrap(ui->w[ui->cur].pangolayout, PANGO_WRAP_WORD_CHAR);
	pango_layout_set_ellipsize(ui->w[ui->cur].pangolayout, PANGO_ELLIPSIZE_END);
	pango_layout_set_font_description(ui->w[ui->cur].pangolayout, ui->w[ui->cur].pangofont);
	pango_layout_set_tabs(ui->w[ui->cur].pangolayout, tabs);
	pango_layout_set_markup(ui->w[ui->cur].pangolayout, s, -1);
	cairo_set_source_rgba(ui->w[ui->cur].c, rgba[0], rgba[1], rgba[2], rgba[3]);
	pango_cairo_update_layout(ui->w[ui->cur].c, ui->w[ui->cur].pangolayout);
	pango_layout_get_pixel_size(ui->w[ui->cur].pangolayout, NULL, &height);
	/* use (h - height) / 2 to center-align vertically */
	cairo_move_to(ui->w[ui->cur].c, x, y + (h - height) / 2);
	pango_cairo_show_layout(ui->w[ui->cur].c, ui->w[ui->cur].pangolayout);
	pango_tab_array_free(tabs);
}
Exemple #16
0
void draw_execp(void *obj, cairo_t *c)
{
	Execp *execp = obj;
	PangoLayout *layout = pango_cairo_create_layout(c);

	if (execp->backend->has_icon && execp->backend->icon) {
		imlib_context_set_image(execp->backend->icon);
		// Render icon
		render_image(execp->area.pix, execp->frontend->iconx, execp->frontend->icony);
	}

	// draw layout
	pango_layout_set_font_description(layout, execp->backend->font_desc);
	pango_layout_set_width(layout, execp->frontend->textw * PANGO_SCALE);
	pango_layout_set_alignment(layout, execp->backend->centered ? PANGO_ALIGN_CENTER : PANGO_ALIGN_LEFT);
	pango_layout_set_wrap(layout, PANGO_WRAP_WORD_CHAR);
	pango_layout_set_ellipsize(layout, PANGO_ELLIPSIZE_NONE);
	if (!execp->backend->has_markup)
		pango_layout_set_text(layout, execp->backend->text, strlen(execp->backend->text));
	else
		pango_layout_set_markup(layout, execp->backend->text, strlen(execp->backend->text));

	pango_cairo_update_layout(c, layout);
	draw_text(layout,
	          c,
	          execp->frontend->textx,
	          execp->frontend->texty,
	          &execp->backend->font_color,
	          panel_config.font_shadow);

	g_object_unref(layout);
}
Exemple #17
0
static void
test_file (const gchar *filename, GString *string)
{
  gchar *contents;
  gchar *markup;
  gsize  length;
  GError *error = NULL;
  PangoLayout *layout;
  gchar *p;
  gint width = 0;
  gint ellipsize_at = 0;
  PangoEllipsizeMode ellipsize = PANGO_ELLIPSIZE_NONE;
  PangoWrapMode wrap = PANGO_WRAP_WORD;
  PangoFontDescription *desc;

  if (!g_file_get_contents (filename, &contents, &length, &error))
    {
      fprintf (stderr, "%s\n", error->message);
      g_error_free (error);
      return;
    }

  p = strchr (contents, '\n');
  g_assert (p);
  markup = p + 1;
  *p = '\0';

  parse_params (contents, &width, &ellipsize_at, &ellipsize, &wrap);

  layout = pango_layout_new (context);

  desc = pango_font_description_from_string ("Cantarell 11");
  pango_layout_set_font_description (layout, desc);
  pango_font_description_free (desc); 

  pango_layout_set_markup (layout, markup, length);
  g_free (contents);

  if (width != 0)
    pango_layout_set_width (layout, width * PANGO_SCALE);
  pango_layout_set_ellipsize (layout, ellipsize);
  pango_layout_set_wrap (layout, wrap);

  g_string_append (string, pango_layout_get_text (layout));
  g_string_append (string, "\n---\n\n");
  g_string_append_printf (string, "wrapped: %d\n", pango_layout_is_wrapped (layout));
  g_string_append_printf (string, "ellipsized: %d\n", pango_layout_is_ellipsized (layout));
  g_string_append_printf (string, "lines: %d\n", pango_layout_get_line_count (layout));
  if (width != 0)
    g_string_append_printf (string, "width: %d\n", pango_layout_get_width (layout));
  g_string_append (string, "\n---\n\n");
   dump_attrs (pango_layout_get_attributes (layout), string);
  g_string_append (string, "\n---\n\n");
  dump_lines (layout, string);
  g_string_append (string, "\n---\n\n");
  dump_runs (layout, string);

  g_object_unref (layout);
}
Exemple #18
0
Fichier : draw.c Projet : wm4/dunst
void
initfont(DC *dc, const char *fontstr) {
    dc->pgc = pango_xft_get_context(dc->dpy, screen);
    dc->pfd = pango_font_description_from_string(fontstr);

    dc->plo = pango_layout_new(dc->pgc);
    pango_layout_set_font_description(dc->plo, dc->pfd);
    pango_layout_set_wrap(dc->plo, PANGO_WRAP_WORD_CHAR);
    pango_layout_set_alignment(dc->plo, PANGO_ALIGN_LEFT);
}
Exemple #19
0
RrFont *RrFontOpen(const RrInstance *inst, const gchar *name, gint size,
                   RrFontWeight weight, RrFontSlant slant)
{
    RrFont *out;
    PangoWeight pweight;
    PangoStyle pstyle;
    PangoAttrList *attrlist;

    out = g_slice_new(RrFont);
    out->inst = inst;
    out->ref = 1;
    out->font_desc = pango_font_description_new();
    out->layout = pango_layout_new(inst->pango);
    out->shortcut_underline = pango_attr_underline_new(PANGO_UNDERLINE_LOW);
    out->shortcut_underline->start_index = 0;
    out->shortcut_underline->end_index = 0;

    attrlist = pango_attr_list_new();
    /* shortcut_underline is owned by the attrlist */
    pango_attr_list_insert(attrlist, out->shortcut_underline);
    /* the attributes are owned by the layout */
    pango_layout_set_attributes(out->layout, attrlist);
    pango_attr_list_unref(attrlist);

    switch (weight) {
    case RR_FONTWEIGHT_LIGHT:     pweight = PANGO_WEIGHT_LIGHT;     break;
    case RR_FONTWEIGHT_NORMAL:    pweight = PANGO_WEIGHT_NORMAL;    break;
    case RR_FONTWEIGHT_SEMIBOLD:  pweight = PANGO_WEIGHT_SEMIBOLD;  break;
    case RR_FONTWEIGHT_BOLD:      pweight = PANGO_WEIGHT_BOLD;      break;
    case RR_FONTWEIGHT_ULTRABOLD: pweight = PANGO_WEIGHT_ULTRABOLD; break;
    default: g_assert_not_reached();
    }

    switch (slant) {
    case RR_FONTSLANT_NORMAL:  pstyle = PANGO_STYLE_NORMAL;    break;
    case RR_FONTSLANT_ITALIC:  pstyle = PANGO_STYLE_ITALIC;    break;
    case RR_FONTSLANT_OBLIQUE: pstyle = PANGO_STYLE_OBLIQUE;   break;
    default: g_assert_not_reached();
    }

    /* setup the font */
    pango_font_description_set_family(out->font_desc, name);
    pango_font_description_set_weight(out->font_desc, pweight);
    pango_font_description_set_style(out->font_desc, pstyle);
    pango_font_description_set_size(out->font_desc, size * PANGO_SCALE);

    /* setup the layout */
    pango_layout_set_font_description(out->layout, out->font_desc);
    pango_layout_set_wrap(out->layout, PANGO_WRAP_WORD_CHAR);

    /* get the ascent and descent */
    measure_font(inst, out);

    return out;
}
Exemple #20
0
gboolean mw_tooltip_timeout(GtkWidget *tv)
{
	GtkAllocation allocation;
	int scr_w,scr_h, w, h, x, y;
	char *tooltiptext = NULL;

	tooltiptext = get_tooltip_text();

	tipwindow = gtk_window_new(GTK_WINDOW_POPUP);
	gtk_widget_set_parent(tipwindow, tv);
	gtk_widget_set_app_paintable(tipwindow, TRUE);
	gtk_window_set_resizable(GTK_WINDOW(tipwindow), FALSE);
	gtk_widget_set_name(tipwindow, "gtk-tooltips");
	g_signal_connect(G_OBJECT(tipwindow), "expose_event",
			G_CALLBACK(mw_paint_tip), NULL);
	gtk_widget_ensure_style (tipwindow);

	layout = gtk_widget_create_pango_layout (tipwindow, NULL);
	pango_layout_set_wrap(layout, PANGO_WRAP_WORD);
	pango_layout_set_width(layout, 300000);
	pango_layout_set_markup(layout, tooltiptext, strlen(tooltiptext));
	scr_w = gdk_screen_width();
	scr_h = gdk_screen_height();
	pango_layout_get_size (layout, &w, &h);
	w = PANGO_PIXELS(w) + 8;
	h = PANGO_PIXELS(h) + 8;

	gdk_window_get_pointer(NULL, &x, &y, NULL);
	if (!gtk_widget_get_has_window (mw.vbox))
	{
		gtk_widget_get_allocation (mw.vbox, &allocation);
		y += allocation.y;
	}

	x -= ((w >> 1) + 4);

	if ((x + w) > scr_w)
		x -= (x + w) - scr_w;
	else if (x < 0)
		x = 0;

	if ((y + h + 4) > scr_h)
		y = y - h;
	else
		y = y + 6;
	/*
	   g_object_unref(layout);
	   */
	g_free(tooltiptext);
	gtk_widget_set_size_request(tipwindow, w, h);
	gtk_window_move(GTK_WINDOW(tipwindow), x, y);
	gtk_widget_show(tipwindow);

	return FALSE;
}
Exemple #21
0
/* creates a commonly used layout object from the given context for use in get_page_count and
 * draw_page */
static PangoLayout *setup_pango_layout(GtkPrintContext *context, PangoFontDescription *desc)
{
	PangoLayout *layout;

	layout = gtk_print_context_create_pango_layout(context);
	pango_layout_set_wrap(layout, PANGO_WRAP_WORD_CHAR);
	pango_layout_set_spacing(layout, 0);
	pango_layout_set_attributes(layout, NULL);
	pango_layout_set_font_description(layout, desc);

	return layout;
}
static PangoLayout *
create_layout_with_attrs (GtkWidget *widget,
                          const GdkRectangle *cell_area,
                          GdTwoLinesRenderer *self,
                          PangoEllipsizeMode ellipsize)
{
  PangoLayout *layout;
  gint wrap_width, xpad;
  PangoWrapMode wrap_mode;
  PangoAlignment alignment;

  g_object_get (self,
                "wrap-width", &wrap_width,
                "wrap-mode", &wrap_mode,
                "alignment", &alignment,
                "xpad", &xpad,
                NULL);

  layout = pango_layout_new (gtk_widget_get_pango_context (widget));

  pango_layout_set_ellipsize (layout, ellipsize);
  pango_layout_set_alignment (layout, alignment);

  if (wrap_width != -1)
    {
      pango_layout_set_width (layout, wrap_width * PANGO_SCALE);
      pango_layout_set_wrap (layout, wrap_mode);
    }
  else
    {
      if (cell_area != NULL)
        pango_layout_set_width (layout, (cell_area->width - 2 * xpad) * PANGO_SCALE);
      else
        pango_layout_set_width (layout, -1);

      pango_layout_set_wrap (layout, PANGO_WRAP_CHAR);
    }

  return layout;
}
	Ptr<ISubtitlesItem> CPangoCairoRenderer::render(Ptr<ISubtitlesItem> i_item)
	{
		Ptr<CSubtitlesTextItem> text = i_item;

		if (text.isNull() || i_item->getType() != SUBTITLES_TYPE_TEXT)
		{
			return Ptr<ISubtitlesItem>();
		}

		Ptr<CCairoSurface> surface = new CCairoSurface(m_displaySize.Height, m_displaySize.Width, SURFACE_FORMAT_ARGB32);

		cairo_t * cairo = cairo_create(surface->getSurface());
		
		cairo_set_source_rgba(cairo, 0.0, 0.0, 0.0, 0.0);
		cairo_paint(cairo);
		
		PangoLayout * layout = pango_cairo_create_layout(cairo);

		pango_layout_set_width(layout, m_displaySize.Width*PANGO_SCALE);
		pango_layout_set_wrap(layout, PANGO_WRAP_WORD);
		pango_layout_set_alignment(layout, PANGO_ALIGN_CENTER);
		pango_layout_set_text(layout, text->getText().c_str(), -1);

		PangoFontDescription * font = pango_font_description_from_string(m_font.c_str());
		pango_layout_set_font_description(layout, font);
		pango_font_description_free(font);

		cairo_set_source_rgb(cairo, 1.0, 1.0, 1.0);

		pango_cairo_update_layout(cairo, layout);
		pango_cairo_show_layout(cairo, layout);

		CValue<CRectangle> rect = getPixelRectangle(layout);
		
		cairo_destroy(cairo);

		g_object_unref(layout);

		if (rect.isValid())
		{

			Ptr<CCairoSurface> textSurface = new CCairoSurface(*surface, rect.getValue()); 
			
			CSize size = rect.getValue().Size;
			CPoint position = computePosition(size);
			CRectangle newRect(position, size);
			
			return new CSubtitlesGraphicsItem(textSurface, newRect, text->getBeginTime(), text->getEndTime());
		}

		return Ptr<ISubtitlesItem>();
	}
Exemple #24
0
ttext::ttext() :
#if PANGO_VERSION_CHECK(1,22,0)
	context_(pango_font_map_create_context(pango_cairo_font_map_get_default())),
#else
	context_(pango_cairo_font_map_create_context((
		reinterpret_cast<PangoCairoFontMap*>(pango_cairo_font_map_get_default())))),
#endif
	layout_(pango_layout_new(context_)),
	rect_(),
	surface_(),
	text_(),
	markedup_text_(false),
	link_aware_(false),
	link_color_(),
	font_class_(font::FONT_SANS_SERIF),
	font_size_(14),
	font_style_(STYLE_NORMAL),
	foreground_color_(0xFFFFFFFF), // solid white
	maximum_width_(-1),
	characters_per_line_(0),
	maximum_height_(-1),
	ellipse_mode_(PANGO_ELLIPSIZE_END),
	alignment_(PANGO_ALIGN_LEFT),
	maximum_length_(std::string::npos),
	calculation_dirty_(true),
	length_(0),
	surface_dirty_(true),
	surface_buffer_(nullptr)
{
	// With 72 dpi the sizes are the same as with SDL_TTF so hardcoded.
	pango_cairo_context_set_resolution(context_, 72.0);

	pango_layout_set_ellipsize(layout_, ellipse_mode_);
	pango_layout_set_alignment(layout_, alignment_);
	pango_layout_set_wrap(layout_, PANGO_WRAP_WORD_CHAR);

	/*
	 * Set the pango spacing a bit bigger since the default is deemed to small
	 * http://www.wesnoth.org/forum/viewtopic.php?p=358832#p358832
	 */
	pango_layout_set_spacing(layout_, 4 * PANGO_SCALE);

	cairo_font_options_t *fo = cairo_font_options_create();
	cairo_font_options_set_hint_style(fo, CAIRO_HINT_STYLE_FULL);
	cairo_font_options_set_hint_metrics(fo, CAIRO_HINT_METRICS_ON);
	cairo_font_options_set_antialias(fo, CAIRO_ANTIALIAS_DEFAULT);

	pango_cairo_context_set_font_options(context_, fo);
	cairo_font_options_destroy(fo);
}
void
TextAsset::drawText(cairo_t* cairoContext,
                    const std::string& textString,
                    const Rect& rect,
                    PangoFontDescription* inFontDescription,
                    bool outlineEnabled)
{
    cairo_move_to(cairoContext, rect.x, rect.y);

    PangoLayout* layout = pango_cairo_create_layout(cairoContext);

    // Kerning
    PangoAttrList* attr_list = pango_attr_list_new();
    PangoAttribute* spacing_attr = pango_attr_letter_spacing_new(pango_units_from_double(_kern));
    pango_attr_list_insert(attr_list, spacing_attr);
    pango_layout_set_attributes(layout, attr_list);

    pango_cairo_context_set_resolution(pango_layout_get_context(layout), DISPLAY_RESOLUTION);
    pango_layout_set_text(layout, textString.c_str(), textString.length());
    pango_layout_set_font_description(layout, inFontDescription);
    pango_layout_set_wrap(layout, PANGO_WRAP_WORD_CHAR);
    pango_layout_set_width(layout, pango_units_from_double(rect.size.width + WIDTH_PADDING));
    pango_layout_set_height(layout, pango_units_from_double(rect.size.height + HEIGHT_PADDING));
    pango_layout_set_alignment(layout, _alignment);
    applyLeading(cairoContext, layout, inFontDescription);

    pango_cairo_show_layout(cairoContext, layout);

    // Core Text defines positive outline width values as stroke only
    if (_outlineThickness <= 0.0f) {
        cairo_fill_preserve(cairoContext);
    }

    // Outline
    if (outlineEnabled && _outlineThickness != 0.0f) {
        const float outlineThickness = (fabsf(_outlineThickness) / 100.0f) * _fontSize * CLIENT_TO_SERVER_SCALE;
        cairo_set_source_rgba(cairoContext,
                              _outlineColor.red,
                              _outlineColor.green,
                              _outlineColor.blue,
                              _outlineColor.alpha);
        pango_cairo_layout_path(cairoContext, layout);
        cairo_set_line_width(cairoContext, outlineThickness);
        cairo_stroke(cairoContext);
    } else {
        cairo_new_path(cairoContext);
    }

    g_object_unref(layout);
}
Exemple #26
0
/**
 * Find where to split a string to make it fit a width.
 *
 * \param[in] fstyle       style for this text
 * \param[in] string       UTF-8 string to measure
 * \param[in] length       length of string, in bytes
 * \param[in] x            width available
 * \param[out] char_offset updated to offset in string of actual_x, [1..length]
 * \param[out] actual_x updated to x coordinate of character closest to x
 * \return NSERROR_OK or appropriate error code on faliure
 *
 * On exit, char_offset indicates first character after split point.
 *
 * \note char_offset of 0 must never be returned.
 *
 *   Returns:
 *     char_offset giving split point closest to x, where actual_x <= x
 *   else
 *     char_offset giving split point closest to x, where actual_x > x
 *
 * Returning char_offset == length means no split possible
 */
static nserror
nsfont_split(const plot_font_style_t *fstyle,
	     const char *string,
	     size_t length,
	     int x,
	     size_t *char_offset,
	     int *actual_x)
{
	int index = length;
	PangoFontDescription *desc;
	PangoContext *context;
	PangoLayout *layout;
	PangoLayoutLine *line;

	context = gdk_pango_context_get();
	layout = pango_layout_new(context);

	desc = nsfont_style_to_description(fstyle);
	pango_layout_set_font_description(layout, desc);
	pango_font_description_free(desc);

	pango_layout_set_text(layout, string, length);

	/* Limit width of layout to the available width */
	pango_layout_set_width(layout, x * PANGO_SCALE);

	/* Request word wrapping */
	pango_layout_set_wrap(layout, PANGO_WRAP_WORD);

	/* Prevent pango treating linebreak characters as line breaks */
	pango_layout_set_single_paragraph_mode(layout, TRUE);

	/* Obtain the second line of the layout (if there is one) */
	line = pango_layout_get_line(layout, 1);
	if (line != NULL) {
		/* Pango split the text. The line's start_index indicates the 
		 * start of the character after the line break. */
		index = line->start_index;
	}

	g_object_unref(layout);
	g_object_unref(context);

	*char_offset = index;
	/* Obtain the pixel offset of the split character */
	nsfont_width(fstyle, string, index, actual_x);

	return NSERROR_OK;
}
Exemple #27
0
static PangoLayout *
make_new_page (PangoContext * context, PangoFontDescription * desc,
				gdouble height, gdouble width)
{
	PangoLayout *layout;

	layout = pango_layout_new (context);
	pango_layout_set_justify (layout, TRUE);
	pango_layout_set_spacing (layout, 1.5 * PANGO_SCALE);
	pango_layout_set_width (layout, pango_units_from_double(width - SIDE_MARGIN));
	pango_layout_set_height (layout, pango_units_from_double(height - EDGE_MARGIN));
	pango_layout_set_wrap (layout, PANGO_WRAP_WORD_CHAR);
	pango_layout_set_font_description (layout, desc);
	return layout;
}
Exemple #28
0
void draw_task (void *obj, cairo_t *c)
{
	Task *tsk = obj;
	tsk->state_pix[tsk->current_state] = tsk->area.pixmap;
	PangoLayout *layout;
	int width=0, height;
	Panel *panel = (Panel*)tsk->area.panel;
	//printf("draw_task %d %d\n", tsk->area.posx, tsk->area.posy);

	if (panel->g_task.text) {
		/* Layout */
		layout = pango_cairo_create_layout (c);
		pango_layout_set_font_description (layout, panel->g_task.font_desc);
		pango_layout_set_text(layout, tsk->title, -1);

		/* Drawing width and Cut text */
		// pango use U+22EF or U+2026
		pango_layout_set_width(layout, ((Taskbar*)tsk->area.parent)->text_width * PANGO_SCALE);
		pango_layout_set_height(layout, panel->g_task.text_height * PANGO_SCALE);
		pango_layout_set_wrap(layout, PANGO_WRAP_CHAR);
		pango_layout_set_ellipsize (layout, PANGO_ELLIPSIZE_END);

		/* Center text */
		if (panel->g_task.centered) pango_layout_set_alignment (layout, PANGO_ALIGN_CENTER);
		else pango_layout_set_alignment (layout, PANGO_ALIGN_LEFT);

		pango_layout_get_pixel_size (layout, &width, &height);

    color_rgba_t text_color = panel->g_task.font_colors[tsk->current_state];

    double text_posy = (panel->g_task.area.bounds.height - height) / 2.0;

    draw_text (layout, c, panel->g_task.text_posx, text_posy, &text_color, panel->font_shadow);

		g_object_unref (layout);
	}

	if (panel->g_task.icon) {
		draw_task_icon (tsk, width);
	}
}
/*
static internal_calculate_text_extents(GtkWidget *widget, CustomCellRendererFlexi *cellflexi, PangoRectangle *rect)
{
    PangoFontDescription* font_desc = NULL;
    PangoLayout* layout = NULL;

    if (cellflexi->default_width<0)
    {
        layout = gtk_widget_create_pango_layout(widget,"0123456789ABCDEF");

        font_desc = pango_font_description_from_string("Monospace");
        if (font_desc)
            pango_layout_set_font_description(layout, font_desc);

        pango_layout_get_pixel_extents(layout,NULL,&rect);

        cellflexi->default_width = rect.width*4;
        cellflexi->default_line_height = rect.height;

        if (cellflexi->default_width <= 0)
        {
            cellflexi->default_width = 400;
            cellflexi->default_line_height = 12;
        }

        if (font_desc)
            pango_font_description_free(font_desc);

        g_object_unref(layout);
    }
}
*/
static PangoLayout* internal_text_create_layout(GtkWidget *widget, CustomCellRendererFlexi *cellflexi)
{
    PangoContext* p_context = gtk_widget_get_pango_context(widget);
    PangoFontDescription* font_desc = NULL;
    PangoLayout* layout = NULL;
    PangoRectangle rect;

    if (cellflexi->default_width < 0)
    {
        layout = gtk_widget_create_pango_layout(widget,"0123456789ABCDEF");

        font_desc = pango_font_description_from_string("Monospace");
        if (font_desc)
            pango_layout_set_font_description(layout, font_desc);

        pango_layout_get_pixel_extents(layout,NULL,&rect);

        cellflexi->default_width = rect.width*4;

        /* catch-all, if any conditions fails */
        if (cellflexi->default_width <= 0)
        {
            cellflexi->default_width = 400;
        }

        if (font_desc)
            pango_font_description_free(font_desc);

        g_object_unref(layout);
    }

    layout = pango_layout_new(p_context);

    pango_layout_set_width(layout,cellflexi->default_width*PANGO_SCALE);

    pango_layout_set_wrap(layout,PANGO_WRAP_WORD_CHAR);

    pango_layout_set_markup(layout,a_strval((a_string_t*)cellflexi->rendered_value),-1);

    return layout;
}
Exemple #30
0
textbox* textbox_create ( const char *name, TextboxFlags flags, TextBoxFontType tbft, const char *text )
{
    textbox *tb = g_slice_new0 ( textbox );

    widget_init ( WIDGET ( tb ), name );

    tb->widget.draw               = textbox_draw;
    tb->widget.free               = textbox_free;
    tb->widget.resize             = textbox_resize;
    tb->widget.get_width          = textbox_get_width;
    tb->widget.get_height         = _textbox_get_height;
    tb->widget.get_desired_height = textbox_get_desired_height;
    tb->flags                     = flags;

    tb->changed = FALSE;

    tb->main_surface = cairo_image_surface_create ( CAIRO_FORMAT_ARGB32, tb->widget.w, tb->widget.h );
    tb->main_draw    = cairo_create ( tb->main_surface );
    tb->layout       = pango_layout_new ( p_context );
    textbox_font ( tb, tbft );

    if ( ( flags & TB_WRAP ) == TB_WRAP ) {
        pango_layout_set_wrap ( tb->layout, PANGO_WRAP_WORD_CHAR );
    }
    textbox_text ( tb, text ? text : "" );
    textbox_cursor_end ( tb );

    // auto height/width modes get handled here
    textbox_moveresize ( tb, tb->widget.x, tb->widget.y, tb->widget.w, tb->widget.h );

    tb->blink_timeout = 0;
    tb->blink         = 1;
    if ( ( flags & TB_EDITABLE ) == TB_EDITABLE ) {
        tb->blink_timeout = g_timeout_add ( 1200, textbox_blink, tb );
    }

    // Enabled by default
    tb->widget.enabled = TRUE;
    return tb;
}