Beispiel #1
0
static PangoLayout *
text_layout_new( PangoContext *context, 
	const char *text, const char *font, int width, 
	VipsAlign align, int dpi )
{
	PangoLayout *layout;
	PangoFontDescription *font_description;
	PangoAlignment palign;

	layout = pango_layout_new( context );
	pango_layout_set_markup( layout, text, -1 );

	font_description = pango_font_description_from_string( font );
	pango_layout_set_font_description( layout, font_description );
	pango_font_description_free( font_description );

	if( width > 0 )
		pango_layout_set_width( layout, width * PANGO_SCALE );

	switch( align ) {
	case VIPS_ALIGN_LOW:
		palign = PANGO_ALIGN_LEFT;
		break;

	case VIPS_ALIGN_CENTRE:
		palign = PANGO_ALIGN_CENTER;
		break;

	case VIPS_ALIGN_HIGH:
		palign = PANGO_ALIGN_RIGHT;
		break;

	default:
		palign = PANGO_ALIGN_LEFT;
		break;
	}
	pango_layout_set_alignment( layout, palign );

	return( layout );
}
/**
 * draw the title of the columns
 *
 * \param line_position	the position to insert the titles
 * 
 * \return the new line_position to continue to fill the page
 * */
static gint print_transactions_list_draw_columns_title ( GtkPrintContext *context,
							 gint line_position)
{
    gint column;

    if (!gsb_data_print_config_get_draw_columns_name ())
	return line_position;

    for (column=0 ; column<CUSTOM_MODEL_VISIBLE_COLUMNS ; column++)
    {
	PangoLayout *layout;
	gchar *text;
	gint column_position;

	column_position = columns_position[column];

	/* get the text */
	text = _(titres_colonnes_liste_operations[column]);
	if (!text)
	    continue;

	cairo_move_to (cr, column_position, line_position);

	/* create the new layout */
	layout = gtk_print_context_create_pango_layout (context);

	pango_layout_set_text (layout, text, -1);
	pango_layout_set_font_description (layout, gsb_data_print_config_get_font_transactions ());
	pango_layout_set_width (layout,columns_width[column]);
	pango_layout_set_alignment (layout, PANGO_ALIGN_CENTER);
	pango_layout_set_ellipsize (layout, PANGO_ELLIPSIZE_END);

	pango_cairo_show_layout (cr, layout);
	g_object_unref (layout);
    }
    line_position = line_position + size_row + gsb_data_print_config_get_draw_lines ();

    return line_position;
}
Beispiel #3
0
static void
_draw_footer(GtkHTML * html, GtkPrintOperation * operation,
	     GtkPrintContext * context,
	     gint page_nr, PangoRectangle * rec, EDITOR * e)
{
	PangoFontDescription *desc;
	PangoLayout *layout;
	gdouble x, y;
	gint n_pages;
	gchar *text;
	cairo_t *cr;

	g_object_get(operation, "n-pages", &n_pages, NULL);
	text = g_strdup_printf(_("Page %d of %d"), page_nr + 1, n_pages);

	desc = pango_font_description_from_string("Sans Regular 10");
	layout = gtk_print_context_create_pango_layout(context);
	pango_layout_set_alignment(layout, PANGO_ALIGN_CENTER);
	pango_layout_set_font_description(layout, desc);
	pango_layout_set_text(layout, text, -1);
	pango_layout_set_width(layout, rec->width);

	x = pango_units_to_double(rec->x);
	y = pango_units_to_double(rec->y);

	cr = gtk_print_context_get_cairo_context(context);

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

	g_object_unref(layout);
	pango_font_description_free(desc);

	g_free(text);
}
/**
 * draw the title if asked
 *
 * \param cr		the cairo_t
 * \param context	the GtkPrintContext
 * \param line_position	the position to insert the title
 * \param page_width	the pag
 *
 * \return the new line_position to continue to fill the page
 * */
static gint print_transactions_list_draw_title ( GtkPrintContext *context,
						 gint line_position )
{
    if (gsb_data_print_config_get_draw_title () && title_string && strlen (title_string))
    {
	PangoLayout *layout;

	cairo_move_to (cr, 0, line_position);

	/* create the new layout */
	layout = gtk_print_context_create_pango_layout (context);

	pango_layout_set_text (layout, title_string, -1);
	pango_layout_set_font_description (layout, gsb_data_print_config_get_font_title ());
	pango_layout_set_width (layout,page_width*PANGO_SCALE);
	pango_layout_set_alignment (layout, PANGO_ALIGN_CENTER);
	pango_layout_set_ellipsize (layout, PANGO_ELLIPSIZE_END);
	pango_cairo_show_layout (cr, layout);
	g_object_unref (layout);
	line_position = line_position + pango_font_description_get_size (gsb_data_print_config_get_font_title ())/PANGO_SCALE;
    }
    return line_position;
}
Beispiel #5
0
PangoLayout*
dia_font_build_layout(const char* string, DiaFont* font, real height)
{
  PangoLayout* layout;
  PangoAttrList* list;
  PangoAttribute* attr;
  guint length;
  PangoFontDescription *pfd;
  real factor;

  layout = pango_layout_new(dia_font_get_context());

  length = string ? strlen(string) : 0;
  pango_layout_set_text(layout, string, length);

  list = pango_attr_list_new();

  pfd = pango_font_description_copy (font->pfd);
  /* account for difference between size and height as well as between font height and given one */
  factor = dia_font_get_size(font) / dia_font_get_height (font);
  pango_font_description_set_absolute_size (pfd, dcm_to_pdu (height) * factor);
  attr = pango_attr_font_desc_new(pfd);
  pango_font_description_free (pfd);

  attr->start_index = 0;
  attr->end_index = length;
  pango_attr_list_insert(list,attr); /* eats attr */

  pango_layout_set_attributes(layout,list);
  pango_attr_list_unref(list);

  pango_layout_set_indent(layout,0);
  pango_layout_set_justify(layout,FALSE);
  pango_layout_set_alignment(layout,PANGO_ALIGN_LEFT);

  return layout;
}
Beispiel #6
0
/**
* @brief Draw increment display
*
* @param queue
*/
void drawIncrementDisplay(gboolean queue) {

    GdkGC* gc;
    PangoContext *context;
    PangoLayout *layout;
    char temp[128];

    if(incrementDisplay->window) {
        if(incrementPixmap) g_object_unref(incrementPixmap);

        incrementPixmap=gdk_pixmap_new(incrementDisplay->window,incrementDisplay->allocation.width,incrementDisplay->allocation.height,-1);

        gc=gdk_gc_new(incrementDisplay->window);
        gdk_gc_set_rgb_fg_color(gc,&black);
        gdk_draw_rectangle(incrementPixmap,
                           gc,
                           TRUE,
                           0,0,
                           incrementDisplay->allocation.width,
                           incrementDisplay->allocation.height);

        context = gdk_pango_context_get_for_screen (gdk_screen_get_default ());
        layout = pango_layout_new (context);
        pango_layout_set_width(layout,incrementDisplay->allocation.width*PANGO_SCALE);
        pango_layout_set_alignment(layout,PANGO_ALIGN_CENTER);
        sprintf(temp,"<span foreground='#7AAA6E' background='#2C2C2C' font_desc='Sans Bold 10'>%0ld</span>",frequencyIncrement);
        pango_layout_set_markup(layout,temp,-1);
        gdk_draw_layout(GDK_DRAWABLE(incrementPixmap),gc,0,0,layout);

        g_object_unref(context);
        g_object_unref(layout);
        g_object_unref(gc);

        if(queue) gtk_widget_queue_draw(incrementDisplay);
    }
}
Beispiel #7
0
static void
mail_printer_draw_footer_cb (GtkPrintOperation *operation,
                             GtkPrintContext *context,
                             gint page_nr)
{
    PangoFontDescription *desc;
    PangoLayout *layout;
    gint n_pages;
    gdouble width, height;
    gchar *text;
    cairo_t *cr;

    cr = gtk_print_context_get_cairo_context (context);
    width = gtk_print_context_get_width (context);
    height = gtk_print_context_get_height (context);

    g_object_get (operation, "n-pages", &n_pages, NULL);
    text = g_strdup_printf (_("Page %d of %d"), page_nr + 1, n_pages);

    cairo_set_source_rgb (cr, 0.1, 0.1, 0.1);
    cairo_fill (cr);

    desc = pango_font_description_from_string ("Sans Regular 10");
    layout = gtk_print_context_create_pango_layout (context);
    pango_layout_set_alignment (layout, PANGO_ALIGN_CENTER);
    pango_layout_set_font_description (layout, desc);
    pango_layout_set_text (layout, text, -1);
    pango_layout_set_width (layout, width * PANGO_SCALE);
    pango_font_description_free (desc);

    cairo_move_to (cr, 0, height + 5);
    pango_cairo_show_layout (cr, layout);

    g_object_unref (layout);
    g_free (text);
}
Beispiel #8
0
static void
gnc_header_draw (GnomeCanvasItem *item, GdkDrawable *drawable,
                 int x, int y, int width, int height)
{
    GncHeader *header = GNC_HEADER(item);
    SheetBlockStyle *style = header->style;
    Table *table = header->sheet->table;
    VirtualLocation virt_loc;
    VirtualCell *vcell;
    CellDimensions *cd;
    GdkColor *bg_color;
    int xpaint, ypaint;
    const char *text;
    CellBlock *cb;
    guint32 argb, color_type;
    int i, j;
    int w, h;
    PangoLayout *layout;

    virt_loc.vcell_loc.virt_row = 0;
    virt_loc.vcell_loc.virt_col = 0;
    virt_loc.phys_row_offset = 0;
    virt_loc.phys_col_offset = 0;

    if (header->sheet->use_theme_colors)
    {
        color_type = gnc_table_get_gtkrc_bg_color (table, virt_loc,
                     NULL);
        bg_color = get_gtkrc_color(header->sheet, color_type);
    }
    else
    {
        argb = gnc_table_get_bg_color (table, virt_loc, NULL);
        bg_color = gnucash_color_argb_to_gdk (argb);
    }

    h = style->dimensions->height;
    h *= header->num_phys_rows;
    h /= header->style->nrows;

    gdk_gc_set_foreground (header->gc, bg_color);

    gdk_draw_rectangle (drawable, header->gc, TRUE, 0, 0,
                        style->dimensions->width, h);

    gdk_gc_set_line_attributes (header->gc, 1, GDK_LINE_SOLID, GDK_CAP_NOT_LAST, GDK_JOIN_MITER);
    gdk_gc_set_foreground (header->gc, &gn_black);

    gdk_draw_rectangle (drawable, header->gc, FALSE, -x, -y,
                        style->dimensions->width, h);

    gdk_draw_line (drawable, header->gc, 0, h + 1,
                   style->dimensions->width, h + 1);

    gdk_gc_set_line_attributes (header->gc, 1, GDK_LINE_SOLID, GDK_CAP_NOT_LAST, GDK_JOIN_MITER);
    gdk_gc_set_background (header->gc, &gn_white);
    gdk_gc_set_foreground (header->gc, &gn_black);
    /*font = gnucash_register_font;*/

    vcell = gnc_table_get_virtual_cell
            (table, table->current_cursor_loc.vcell_loc);
    cb = vcell ? vcell->cellblock : NULL;

    ypaint = -y;
    h = 0;

    for (i = 0; i < style->nrows; i++)
    {
        xpaint = -x;
        virt_loc.phys_row_offset = i;

        /* TODO: This routine is duplicated in several places.
           Can we abstract at least the cell drawing routine?
           That way we'll be sure everything is drawn
           consistently, and cut down on maintenance issues. */

        for (j = 0; j < style->ncols; j++)
        {
            /*                        gint x_offset, y_offset;*/
            GdkRectangle rect;
            BasicCell *cell;

            virt_loc.phys_col_offset = j;

            cd = gnucash_style_get_cell_dimensions (style, i, j);

            if (header->in_resize && (j == header->resize_col))
                w = header->resize_col_width;
            else
                w = cd->pixel_width;

            cell = gnc_cellblock_get_cell (cb, i, j);
            if (!cell || !cell->cell_name)
            {
                xpaint += w;
                continue;
            }

            h = cd->pixel_height;

            gdk_draw_rectangle (drawable, header->gc, FALSE,
                                xpaint, ypaint, w, h);

            virt_loc.vcell_loc =
                table->current_cursor_loc.vcell_loc;
            text = gnc_table_get_label (table, virt_loc);
            if (!text)
                text = "";

            layout = gtk_widget_create_pango_layout (GTK_WIDGET (header->sheet), text);

            /*y_offset = ((h / 2) +
                                    (((font->ascent + font->descent) / 2) -
                                     font->descent));
                        y_offset++;*/

            switch (gnc_table_get_align (table, virt_loc))
            {
            default:
            case CELL_ALIGN_LEFT:
                pango_layout_set_alignment (layout, PANGO_ALIGN_LEFT);
                break;

            case CELL_ALIGN_RIGHT:
                pango_layout_set_alignment (layout, PANGO_ALIGN_RIGHT);
                break;

            case CELL_ALIGN_CENTER:
                pango_layout_set_alignment (layout, PANGO_ALIGN_CENTER);
                break;
            }

            rect.x = xpaint + CELL_HPADDING;
            rect.y = ypaint + 1;
            rect.width = MAX (0, w - (2 * CELL_HPADDING));
            rect.height = h - 2;

            gdk_gc_set_clip_rectangle (header->gc, &rect);

            gdk_draw_layout (drawable,
                             header->gc,
                             xpaint + CELL_HPADDING,
                             ypaint + 1,
                             layout);

            g_object_unref (layout);

            gdk_gc_set_clip_rectangle (header->gc, NULL);

            xpaint += w;
        }

        ypaint += h;
    }
}
			void GuiSolidLabelElementRenderer::OnElementStateChanged()
			{
				FontProperties font = element->GetFont();
				Color color = element->GetColor();
				int layoutWidth, layoutHeight;
				
				AString family = wtoa(font.fontFamily);
				pango_font_description_set_family(pangoFontDesc, family.Buffer());
				pango_font_description_set_absolute_size(pangoFontDesc, font.size * PANGO_SCALE);

				if(font.italic) pango_font_description_set_style(pangoFontDesc, PANGO_STYLE_ITALIC);
				else pango_font_description_set_style(pangoFontDesc, PANGO_STYLE_NORMAL);

				if(attrList)
				{
					pango_attr_list_unref(attrList);
				}

				attrList = pango_attr_list_new();
				
				pango_attr_list_insert(attrList, pango_attr_underline_new(
							font.underline ? PANGO_UNDERLINE_SINGLE : PANGO_UNDERLINE_NONE)
					);

				pango_attr_list_insert(attrList, pango_attr_strikethrough_new (
							font.strikeline ? TRUE : FALSE
							)
						);

				pango_attr_list_insert(attrList, pango_attr_weight_new (
							font.bold ? PANGO_WEIGHT_BOLD : PANGO_WEIGHT_MEDIUM
							)
						);

				if(layout)
				{
					g_object_unref(layout);
					layout = NULL;
				}

				if(cairoContext)
				{
					layout = pango_cairo_create_layout(cairoContext);

					WString wtext = (font.fontFamily == L"Webdings") ? helpers::WebdingsMap(element->GetText()) : element->GetText();
					AString text = wtoa(wtext);

					pango_layout_set_font_description(layout, pangoFontDesc);
					pango_layout_set_attributes(layout, attrList);
					pango_layout_set_text(layout, text.Buffer(), text.Length());
					pango_layout_set_alignment(layout, 
							element->GetHorizontalAlignment() == Alignment::Left ? PANGO_ALIGN_LEFT :
							element->GetHorizontalAlignment() == Alignment::Center ? PANGO_ALIGN_CENTER :
							element->GetHorizontalAlignment() == Alignment::Right ? PANGO_ALIGN_RIGHT :
							PANGO_ALIGN_LEFT
							);


					pango_cairo_update_layout(cairoContext, layout);


					pango_layout_get_pixel_size( layout, &layoutWidth, &layoutHeight);

					minSize.x = layoutWidth;
					minSize.y = layoutHeight;
				}
			}
Beispiel #10
0
static void
gth_empty_list_realize (GtkWidget *widget)
{
	GthEmptyList  *self;
	GdkWindowAttr  attributes;
	int            attributes_mask;

	g_return_if_fail (GTH_IS_EMPTY_LIST (widget));

	GTK_WIDGET_SET_FLAGS (widget, GTK_REALIZED);

	/**/

	attributes.window_type = GDK_WINDOW_CHILD;
	attributes.x           = widget->allocation.x;
	attributes.y           = widget->allocation.y;
	attributes.width       = widget->allocation.width;
	attributes.height      = widget->allocation.height;
	attributes.wclass      = GDK_INPUT_OUTPUT;
	attributes.visual      = gtk_widget_get_visual (widget);
	attributes.colormap    = gtk_widget_get_colormap (widget);
	attributes.event_mask  = GDK_VISIBILITY_NOTIFY_MASK;
	attributes_mask        = (GDK_WA_X
				  | GDK_WA_Y
				  | GDK_WA_VISUAL
				  | GDK_WA_COLORMAP);
	widget->window = gdk_window_new (gtk_widget_get_parent_window (widget),
					 &attributes,
					 attributes_mask);
	gdk_window_set_user_data (widget->window, widget);

	/**/

	self = (GthEmptyList*) widget;

	attributes.x = 0;
	attributes.y = 0;
	attributes.width = widget->allocation.width;
	attributes.height = widget->allocation.height;
	attributes.event_mask = (GDK_EXPOSURE_MASK
				 | GDK_SCROLL_MASK
				 | GDK_POINTER_MOTION_MASK
				 | GDK_ENTER_NOTIFY_MASK
				 | GDK_LEAVE_NOTIFY_MASK
				 | GDK_BUTTON_PRESS_MASK
				 | GDK_BUTTON_RELEASE_MASK
				 | gtk_widget_get_events (widget));

	self->priv->bin_window = gdk_window_new (widget->window,
						 &attributes,
						 attributes_mask);
	gdk_window_set_user_data (self->priv->bin_window, widget);

	/* Style */

	widget->style = gtk_style_attach (widget->style, widget->window);
	gdk_window_set_background (widget->window, &widget->style->base[widget->state]);
	gdk_window_set_background (self->priv->bin_window, &widget->style->base[widget->state]);
	
	/* 'No Image' message Layout */

	if (self->priv->layout != NULL)
		g_object_unref (self->priv->layout);

	self->priv->layout = gtk_widget_create_pango_layout (widget, NULL);
	pango_layout_set_wrap (self->priv->layout, PANGO_WRAP_WORD_CHAR);
	pango_layout_set_font_description (self->priv->layout, widget->style->font_desc);
	pango_layout_set_alignment (self->priv->layout, PANGO_ALIGN_CENTER);
}
Beispiel #11
0
/**
 * Sends the given character to the terminal at the given row and column,
 * rendering the character immediately. This bypasses the guac_terminal_display
 * mechanism and is intended for flushing of updates only.
 */
int __guac_terminal_set(guac_terminal_display* display, int row, int col, int codepoint) {

    int width;

    int bytes;
    char utf8[4];

    /* Use foreground color */
    const guac_terminal_color* color =
        &guac_terminal_palette[display->glyph_foreground];

    /* Use background color */
    const guac_terminal_color* background =
        &guac_terminal_palette[display->glyph_background];

    cairo_surface_t* surface;
    cairo_t* cairo;
    int surface_width, surface_height;
   
    PangoLayout* layout;
    int layout_width, layout_height;
    int ideal_layout_width, ideal_layout_height;

    /* Calculate width in columns */
    width = wcwidth(codepoint);
    if (width < 0)
        width = 1;

    /* Do nothing if glyph is empty */
    if (width == 0)
        return 0;

    /* Convert to UTF-8 */
    bytes = guac_terminal_encode_utf8(codepoint, utf8);

    surface_width = width * display->char_width;
    surface_height = display->char_height;

    ideal_layout_width = surface_width * PANGO_SCALE;
    ideal_layout_height = surface_height * PANGO_SCALE;

    /* Prepare surface */
    surface = cairo_image_surface_create(CAIRO_FORMAT_RGB24,
                                         surface_width, surface_height);
    cairo = cairo_create(surface);

    /* Fill background */
    cairo_set_source_rgb(cairo,
            background->red   / 255.0,
            background->green / 255.0,
            background->blue  / 255.0);

    cairo_rectangle(cairo, 0, 0, surface_width, surface_height); 
    cairo_fill(cairo);

    /* Get layout */
    layout = pango_cairo_create_layout(cairo);
    pango_layout_set_font_description(layout, display->font_desc);
    pango_layout_set_text(layout, utf8, bytes);
    pango_layout_set_alignment(layout, PANGO_ALIGN_CENTER);

    pango_layout_get_size(layout, &layout_width, &layout_height);

    /* If layout bigger than available space, scale it back */
    if (layout_width > ideal_layout_width || layout_height > ideal_layout_height) {

        double scale = fmin(ideal_layout_width  / (double) layout_width,
                            ideal_layout_height / (double) layout_height);

        cairo_scale(cairo, scale, scale);

        /* Update layout to reflect scaled surface */
        pango_layout_set_width(layout, ideal_layout_width / scale);
        pango_layout_set_height(layout, ideal_layout_height / scale);
        pango_cairo_update_layout(cairo, layout);

    }

    /* Draw */
    cairo_set_source_rgb(cairo,
            color->red   / 255.0,
            color->green / 255.0,
            color->blue  / 255.0);

    cairo_move_to(cairo, 0.0, 0.0);
    pango_cairo_show_layout(cairo, layout);

    /* Draw */
    guac_common_surface_draw(display->display_surface,
        display->char_width * col,
        display->char_height * row,
        surface);

    /* Free all */
    g_object_unref(layout);
    cairo_destroy(cairo);
    cairo_surface_destroy(surface);

    return 0;

}
Beispiel #12
0
static gint
line_numbers_expose (GtkWidget      *widget,
                     GdkEventExpose *event)
{
	GtkTextView *text_view;
	GdkWindow *win;
//	GtkStyle *style;
	PangoLayout *layout;
	PangoAttrList *alist;
	PangoAttribute *attr;
	GArray *numbers;
	GArray *pixels;
	gint y1, y2;
	gint count;
	gint layout_width;
	gint justify_width = 0;
	gint i;
//	gchar *str;
	gchar str [8];  /* we don't expect more than ten million lines */
	GdkGC *gc;
	gint height;
	
	if (line_number_visible){{{{{	// omit calculation
	
	text_view = GTK_TEXT_VIEW (widget);
	
	/* See if this expose is on the line numbers window */
/*	left_win = gtk_text_view_get_window (text_view,
	                                     GTK_TEXT_WINDOW_LEFT);
	right_win = gtk_text_view_get_window (text_view,
	                                      GTK_TEXT_WINDOW_RIGHT);
	
	if (event->window == left_win)
	{
		type = GTK_TEXT_WINDOW_LEFT;
		target = event->window;
	}
	else if (event->window == right_win)
	{
		type = GTK_TEXT_WINDOW_RIGHT;
		target = right_win;
	}
	else
		return FALSE;
*/	
	win = gtk_text_view_get_window (text_view,
	                                GTK_TEXT_WINDOW_LEFT);
	if (event->window != win)
		return FALSE;
	
//	style = gtk_style_copy (widget->style);
//	style = gtk_style_copy (gtk_widget_get_default_style());
	
	y1 = event->area.y;
	y2 = y1 + event->area.height;
	
	gtk_text_view_window_to_buffer_coords (text_view,
	                                       GTK_TEXT_WINDOW_LEFT,
	                                       0,
	                                       y1,
	                                       NULL,
	                                       &y1);
	
	gtk_text_view_window_to_buffer_coords (text_view,
	                                       GTK_TEXT_WINDOW_LEFT,
	                                       0,
	                                       y2,
	                                       NULL,
	                                       &y2);
	
	numbers = g_array_new (FALSE, FALSE, sizeof (gint));
	pixels = g_array_new (FALSE, FALSE, sizeof (gint));
	
	get_lines (text_view,
	           y1,
	           y2,
	           pixels,
	           numbers,
	           &count);
	
	/* a zero-lined document should display a "1"; we don't need to worry about
	scrolling effects of the text widget in this special case */
	
	if (count == 0)
	{
		gint y = 0;
		gint n = 0;
		count = 1;
		g_array_append_val (pixels, y);
		g_array_append_val (numbers, n);
	}
	
DV({g_print("Painting line numbers %d - %d\n",
			g_array_index(numbers, gint, 0),
			g_array_index(numbers, gint, count - 1));	});
	
	layout = gtk_widget_create_pango_layout (widget, "");
	
//	str = g_strdup_printf ("%d", gtk_text_buffer_get_line_count(text_view->buffer));
	g_snprintf (str, sizeof (str),
			"%d", MAX (99, gtk_text_buffer_get_line_count(text_view->buffer)));
	pango_layout_set_text (layout, str, -1);
//	g_free (str);
	
	pango_layout_get_pixel_size (layout, &layout_width, NULL);
	
	min_number_window_width = calculate_min_number_window_width(widget);
	if (layout_width > min_number_window_width)
		gtk_text_view_set_border_window_size (text_view,
			GTK_TEXT_WINDOW_LEFT, layout_width + margin + submargin);
	else {
//		if ((gtk_text_view_get_border_window_size (text_view, GTK_TEXT_WINDOW_LEFT) - 5) > layout_width) {
			gtk_text_view_set_border_window_size (text_view,
				GTK_TEXT_WINDOW_LEFT, min_number_window_width + margin + submargin);
//		}
		justify_width = min_number_window_width - layout_width;
	}
	
	pango_layout_set_width (layout, layout_width);
	pango_layout_set_alignment (layout, PANGO_ALIGN_RIGHT);
	
	alist = pango_attr_list_new();
	attr = pango_attr_foreground_new(
		widget->style->text_aa->red,
		widget->style->text_aa->green,
		widget->style->text_aa->blue);
	attr->start_index = 0;
	attr->end_index = G_MAXUINT;
	pango_attr_list_insert(alist, attr);
	pango_layout_set_attributes(layout, alist);
	pango_attr_list_unref(alist);
	
	/* Draw fully internationalized numbers! */
	
	i = 0;
	while (i < count)
	{
		gint pos;
		
		gtk_text_view_buffer_to_window_coords (text_view,
		                                       GTK_TEXT_WINDOW_LEFT,
		                                       0,
		                                       g_array_index (pixels, gint, i),
		                                       NULL,
		                                       &pos);
		
//		str = g_strdup_printf ("%d", g_array_index (numbers, gint, i) + 1);
		g_snprintf (str, sizeof (str),
				"%d", g_array_index (numbers, gint, i) + 1);
		
		pango_layout_set_text (layout, str, -1);
		
		gtk_paint_layout (widget->style,
		                  win,
		                  GTK_WIDGET_STATE (widget),
		                  FALSE,
		                  NULL,
		                  widget,
		                  NULL,
#if GTK_CHECK_VERSION(2, 6, 0)  // Is this solution???
		                  layout_width + justify_width + margin / 2 + 1,
#else
		                  layout_width + justify_width + margin / 2,
#endif
		                  pos,
		                  layout);
//		g_free (str);
		
		++i;
	}
	
	g_array_free (pixels, TRUE);
	g_array_free (numbers, TRUE);
	
	g_object_unref (G_OBJECT (layout));
//	g_object_ref (G_OBJECT (style));
	
	/* don't stop emission, need to draw children */
	
	}}}}}
Beispiel #13
0
void cairox_paint_pango_text(cairo_t *cr, CairoxTextParameters *p, PangoLayout *layout, const char *buffer)
{
    int x, y, w, h;

    if (strlen(buffer) == 0) {
        return;
    }

    cairo_save(cr);
    cairo_translate(cr, p->x, p->y); 
    cairo_rotate(cr, -p->angle * M_PI / 180.0);

    pango_layout_set_text(layout, buffer, strlen(buffer));

    if (p->x_align == PANGOX_XALIGN_CENTER) {
        pango_layout_set_alignment(layout, PANGO_ALIGN_CENTER);
        if ((w = pango_layout_get_width(layout)) <= 0) {
            pango_layout_get_size(layout, &w, &h);
        }
        x = - w/((double) PANGO_SCALE*2.0);
    }
    else if (p->x_align == PANGOX_XALIGN_RIGHT) {
        pango_layout_set_alignment(layout, PANGO_ALIGN_RIGHT);
        if ((w = pango_layout_get_width(layout)) <= 0) {
            pango_layout_get_size(layout, &w, &h);
        }
        x = - w/((double) PANGO_SCALE);
    }
    else {
        pango_layout_set_alignment(layout, PANGO_ALIGN_LEFT);
        x = 0;
    }

    if (p->y_align == PANGOX_YALIGN_BOTTOM) {
        pango_layout_get_size(layout, &w, &h);
        y = - h/((double) PANGO_SCALE);
    }
    else if (p->y_align == PANGOX_YALIGN_CENTER) {
        pango_layout_get_size(layout, &w, &h);
        y = - h/((double) PANGO_SCALE*2.0);
    }
    else {
        y = 0;
    }

#if FALSE
    double x0, y0;

    /* Calculate the background rectangle coordinates: */
    pango_layout_get_size(layout, &w, &h);
    if (p->x_align == PANGOX_XALIGN_LEFT) {
        x0 = -1.0;
        y0 = y - 1.0;
    }
    else if (p->x_align == PANGOX_XALIGN_RIGHT) {
        x0 = -(w / (double) PANGO_SCALE)-1;
        y0 = y - 1.0;
    }
    else {
        x0 = -(w / (PANGO_SCALE*2.0))-1;
        y0 = y - 1.0;
    }

    cairo_set_source_rgba(cr, 1.0, 1.0, 1.0, 0.5);
    cairo_rectangle(cr, x0, y0, (w / (double) PANGO_SCALE)+2, (h / (double) PANGO_SCALE)+2);
    cairo_fill(cr);
#endif

    cairo_set_source_rgb(cr, 1.0, 1.0, 1.0);
    cairo_move_to(cr, x-1, y-1);
    pango_cairo_show_layout(cr, layout);
    cairo_move_to(cr, x, y-1);
    pango_cairo_show_layout(cr, layout);
    cairo_move_to(cr, x+1, y-1);
    pango_cairo_show_layout(cr, layout);

    cairo_move_to(cr, x-1, y);
    pango_cairo_show_layout(cr, layout);
    cairo_move_to(cr, x+1, y);
    pango_cairo_show_layout(cr, layout);

    cairo_move_to(cr, x-1, y+1);
    pango_cairo_show_layout(cr, layout);
    cairo_move_to(cr, x, y+1);
    pango_cairo_show_layout(cr, layout);
    cairo_move_to(cr, x+1, y+1);
    pango_cairo_show_layout(cr, layout);

    cairo_set_source_rgba(cr, p->foreground.r, p->foreground.g, p->foreground.b, 1.0);
    cairo_move_to(cr, x, y);
    pango_cairo_show_layout(cr, layout);
    cairo_stroke(cr);
    cairo_restore(cr);
}
Beispiel #14
0
static void
draw_text_line(DiaRenderer *self,
	       TextLine *text_line,
	       Point *pos, Alignment alignment, Color *color)
{
  DiaPsFt2Renderer *renderer = DIA_PS_FT2_RENDERER(self);
  PangoLayout *layout;
  int line, linecount;
  double xpos = pos->x, ypos = pos->y;
  char *text = text_line_get_string(text_line);
  /* TODO: we could probably pass the alignment down to the PS file? */
  xpos -= text_line_get_alignment_adjustment (text_line, alignment);

/* Using the global PangoContext does not allow to have renderer specific 
 * different ones. Or it implies the push/pop _context mess. Anyway just 
 * get rid of warnings for now. But the local code may be resurreted 
 * sooner or later...                                               --hb
 */
#define USE_GLOBAL_CONTEXT
#ifndef USE_GLOBAL_CONTEXT
  PangoAttrList* list;
  PangoAttribute* attr;
  guint length;
#endif

  if ((!text)||(text == (const char *)(1))) return;

  lazy_setcolor(DIA_PS_RENDERER(renderer),color);

#define ANNOYING_SCALE_FACTOR 5.9

  /* Make sure the letters aren't too wide. */
#ifdef USE_GLOBAL_CONTEXT
  layout = dia_font_build_layout(text, text_line_get_font(text_line),
				 text_line_get_height(text_line)*ANNOYING_SCALE_FACTOR);
#else
  /* approximately what would be required but w/o dia_font_get_context() */
  dia_font_set_height(text_line_get_font(text_line),
		      text_line_get_height(text_line));
  layout = pango_layout_new(dia_font_get_context());

  length = text ? strlen(text) : 0;
  pango_layout_set_text(layout,text,length);
        
  list = pango_attr_list_new();

  attr = pango_attr_font_desc_new(dia_font_get_description(text_line_get_font(text_line)));
  attr->start_index = 0;
  attr->end_index = length;
  pango_attr_list_insert(list,attr);
    
  pango_layout_set_attributes(layout,list);
  pango_attr_list_unref(list);

  pango_layout_set_indent(layout,0);
  pango_layout_set_justify(layout,FALSE);
#endif

  pango_layout_set_alignment(layout, PANGO_ALIGN_LEFT);
    
  linecount = pango_layout_get_line_count(layout);
  for (line = 0; line < linecount; line++) {
    PangoLayoutLine *layoutline = pango_layout_get_line(layout, line);

    /* Not sure scale is the right one here.  */
    text_line_adjust_layout_line(text_line, layoutline, ANNOYING_SCALE_FACTOR);

    postscript_draw_contour(DIA_PS_RENDERER(renderer),
			    DPI, /* dpi_x */
			    layoutline, xpos, ypos);
    ypos += 10;/* Some line height thing??? */
  }
}
Beispiel #15
0
static void draw_page(GtkPrintOperation *operation, GtkPrintContext *context,
					  gint page_nr, gpointer user_data)
{
	DocInfo *dinfo = user_data;
	GeanyEditor *editor;
	cairo_t *cr;
	gdouble width, height;
	gdouble x = 0.0, y = 0.0;
	/*gint layout_h;*/
	gint count;
	GString *str;

	if (dinfo == NULL || page_nr >= dinfo->n_pages)
		return;

	editor = dinfo->doc->editor;

	if (dinfo->n_pages > 0)
	{
		gdouble fraction = (page_nr + 1) / (gdouble) dinfo->n_pages;
		gchar *text = g_strdup_printf(_("Page %d of %d"), page_nr, dinfo->n_pages);
		gtk_progress_bar_set_fraction(GTK_PROGRESS_BAR(main_widgets.progressbar), fraction);
		gtk_progress_bar_set_text(GTK_PROGRESS_BAR(main_widgets.progressbar), text);
		g_free(text);
	}

#ifdef GEANY_PRINT_DEBUG
	geany_debug("draw_page = %d, pages = %d, (real) lines_per_page = %d",
		page_nr, dinfo->n_pages, dinfo->lines_per_page);
#endif

	str = g_string_sized_new(256);
	cr = gtk_print_context_get_cairo_context(context);
	width = gtk_print_context_get_width(context);
	height = gtk_print_context_get_height(context);

	cairo_set_source_rgb(cr, 0, 0, 0);
#ifdef GEANY_PRINT_DEBUG
	cairo_set_line_width(cr, 0.2);
	cairo_rectangle(cr, 0, 0, width, height);
	cairo_stroke(cr);
#endif
	cairo_move_to(cr, 0, 0);

	pango_layout_set_width(dinfo->layout, width * PANGO_SCALE);
	pango_layout_set_alignment(dinfo->layout, PANGO_ALIGN_LEFT);
	pango_layout_set_ellipsize(dinfo->layout, FALSE);
	pango_layout_set_justify(dinfo->layout, FALSE);

	if (printing_prefs.print_page_header)
		add_page_header(dinfo, cr, width, page_nr);

	count = 0;	/* the actual line counter for the current page, might be different from
				 * dinfo->cur_line due to possible line breaks */
	while (count < dinfo->lines_per_page)
	{
		gchar c = 'a';
		gint style = -1;
		PangoAttrList *layout_attr;
		PangoAttribute *attr;
		gint colours[3] = { 0 };
		gboolean add_linenumber = TRUE;
		gboolean at_eol;

		while (count < dinfo->lines_per_page && c != '\0')
		{
			at_eol = FALSE;

			g_string_erase(str, 0, str->len); /* clear the string */

			/* line numbers */
			if (printing_prefs.print_line_numbers && add_linenumber)
			{
				/* if we had a wrapped line on the last page which needs to be continued, don't
				 * add a line number */
				if (dinfo->long_line)
				{
					add_linenumber = FALSE;
				}
				else
				{
					gchar *line_number = NULL;
					gint cur_line_number_margin = get_line_numbers_arity(dinfo->cur_line + 1);
					gchar *fill = g_strnfill(
						dinfo->max_line_number_margin - cur_line_number_margin - 1, ' ');

					line_number = g_strdup_printf("%s%d ", fill, dinfo->cur_line + 1);
					g_string_append(str, line_number);
					dinfo->cur_line++; /* increase document line */
					add_linenumber = FALSE;
					style = STYLE_LINENUMBER;
					c = 'a'; /* dummy value */
					g_free(fill);
					g_free(line_number);
				}
			}
			/* data */
			else
			{
				style = sci_get_style_at(dinfo->doc->editor->sci, dinfo->cur_pos);
				c = sci_get_char_at(dinfo->doc->editor->sci, dinfo->cur_pos);
				if (c == '\0' || style == -1)
				{	/* if c gets 0, we are probably out of document boundaries,
					 * so stop to break out of outer loop */
					count = dinfo->lines_per_page;
					break;
				}
				dinfo->cur_pos++;

				/* convert tabs to spaces which seems to be better than using Pango tabs */
				if (c == '\t')
				{
					gint tab_width = sci_get_tab_width(editor->sci);
					gchar *s = g_strnfill(tab_width, ' ');
					g_string_append(str, s);
					g_free(s);
				}
				/* don't add line breaks, they are handled manually below */
				else if (c == '\r' || c == '\n')
				{
					gchar c_next = sci_get_char_at(dinfo->doc->editor->sci, dinfo->cur_pos);
					at_eol = TRUE;
					if (c == '\r' && c_next == '\n')
						dinfo->cur_pos++; /* skip LF part of CR/LF */
				}
				else
				{
					g_string_append_c(str, c); /* finally add the character */

					/* handle UTF-8: since we add char by char (better: byte by byte), we need to
					 * keep UTF-8 characters together(e.g. two bytes for one character)
					 * the input is always UTF-8 and c is signed, so all non-Ascii
					 * characters are less than 0 and consist of all bytes less than 0.
					 * style doesn't change since it is only one character with multiple bytes. */
					while (c < 0)
					{
						c = sci_get_char_at(dinfo->doc->editor->sci, dinfo->cur_pos);
						if (c < 0)
						{	/* only add the byte when it is part of the UTF-8 character
							 * otherwise we could add e.g. a '\n' and it won't be visible in the
							 * printed document */
							g_string_append_c(str, c);
							dinfo->cur_pos++;
						}
					}
				}
			}

			if (! at_eol)
			{
				/* set text */
				pango_layout_set_text(dinfo->layout, str->str, -1);
				/* attributes */
				layout_attr = pango_attr_list_new();
				/* foreground colour */
				get_rgb_values(dinfo->styles[style][FORE], &colours[0], &colours[1], &colours[2]);
				attr = pango_attr_foreground_new(colours[0], colours[1], colours[2]);
				ADD_ATTR(layout_attr, attr);
				/* background colour */
				get_rgb_values(dinfo->styles[style][BACK], &colours[0], &colours[1], &colours[2]);
				attr = pango_attr_background_new(colours[0], colours[1], colours[2]);
				ADD_ATTR(layout_attr, attr);
				/* bold text */
				if (dinfo->styles[style][BOLD])
				{
					attr = pango_attr_weight_new(PANGO_WEIGHT_BOLD);
					ADD_ATTR(layout_attr, attr);
				}
				/* italic text */
				if (dinfo->styles[style][ITALIC])
				{
					attr = pango_attr_style_new(PANGO_STYLE_ITALIC);
					ADD_ATTR(layout_attr, attr);
				}
				pango_layout_set_attributes(dinfo->layout, layout_attr);
				pango_layout_context_changed(dinfo->layout);
				pango_attr_list_unref(layout_attr);
			}

			cairo_get_current_point(cr, &x, &y);


			/* normal line break at eol character in document */
			if (at_eol)
			{
				/*pango_layout_get_size(dinfo->layout, NULL, &layout_h);*/
				/*cairo_move_to(cr, 0, y + (gdouble)layout_h / PANGO_SCALE);*/
				cairo_move_to(cr, 0, y + dinfo->line_height);

				count++;
				/* we added a new document line so request a new line number */
				add_linenumber = TRUE;
			}
			else
			{
				gint x_offset = 0;
				/* maybe we need to force a line break because of too long line */
				if (x >= (width - dinfo->font_width))
				{
					/* don't start the line at horizontal origin because we need to skip the
					 * line number margin */
					if (printing_prefs.print_line_numbers)
					{
						x_offset = (dinfo->max_line_number_margin + 1) * dinfo->font_width;
					}

					/*pango_layout_get_size(dinfo->layout, NULL, &layout_h);*/
					/*cairo_move_to(cr, x_offset, y + (gdouble)layout_h / PANGO_SCALE);*/
					/* this is faster but not exactly the same as above */
					cairo_move_to(cr, x_offset, y + dinfo->line_height);
					cairo_get_current_point(cr, &x, &y);
					count++;
				}
				if (count < dinfo->lines_per_page)
				{
					/* str->len is counted in bytes not characters, so use g_utf8_strlen() */
					x_offset = (g_utf8_strlen(str->str, -1) * dinfo->font_width);

					if (dinfo->long_line && count == 0)
					{
						x_offset = (dinfo->max_line_number_margin + 1) * dinfo->font_width;
						dinfo->long_line = FALSE;
					}

					pango_cairo_show_layout(cr, dinfo->layout);
					cairo_move_to(cr, x + x_offset, y);
				}
				else
				/* we are on a wrapped line but we are out of lines on this page, so continue
				 * the current line on the next page and remember to continue in current line */
					dinfo->long_line = TRUE;
			}
		}
	}

	if (printing_prefs.print_line_numbers)
	{	/* print a thin line between the line number margin and the data */
		gint y_start = 0;

		if (printing_prefs.print_page_header)
			y_start = (dinfo->line_height * 3) - 2;	/* "- 2": to connect the line number line to
													 * the page header frame */

		cairo_set_line_width(cr, 0.3);
		cairo_move_to(cr, (dinfo->max_line_number_margin * dinfo->font_width) + 1, y_start);
		cairo_line_to(cr, (dinfo->max_line_number_margin * dinfo->font_width) + 1,
			y + dinfo->line_height); /* y is last added line, we reuse it */
		cairo_stroke(cr);
	}

	if (printing_prefs.print_page_numbers)
	{
		gchar *line = g_strdup_printf("<small>- %d -</small>", page_nr + 1);
		pango_layout_set_markup(dinfo->layout, line, -1);
		pango_layout_set_alignment(dinfo->layout, PANGO_ALIGN_CENTER);
		cairo_move_to(cr, 0, height - dinfo->line_height);
		pango_cairo_show_layout(cr, dinfo->layout);
		g_free(line);

#ifdef GEANY_PRINT_DEBUG
		cairo_set_line_width(cr, 0.3);
		cairo_move_to(cr, 0, height - (1.25 * dinfo->line_height));
		cairo_line_to(cr, width - 1, height - (1.25 * dinfo->line_height));
		cairo_stroke(cr);
#endif
	}
	g_string_free(str, TRUE);
}
Beispiel #16
0
static void
_cairo_render_text (CairoRenderer *renderer,
                    PinPointPoint *point)
{
  PangoLayout          *layout;
  PangoFontDescription *desc;
  PangoRectangle        logical_rect = { 0, };
  ClutterColor          text_color,
                        shading_color;

  float text_x,    text_y,    text_width,    text_height,   text_scale;
  float shading_x, shading_y, shading_width, shading_height;
  if (point == NULL)
    return;

  layout = pango_cairo_create_layout (renderer->ctx);
  desc = pango_font_description_from_string (point->font);
  pango_layout_set_font_description (layout, desc);
  if (point->use_markup)
    pango_layout_set_markup (layout, point->text, -1);
  else
    pango_layout_set_text (layout, point->text, -1);
  pango_layout_set_alignment (layout, point->text_align);

  pango_layout_get_extents (layout, NULL, &logical_rect);
  text_width = (logical_rect.x + logical_rect.width) / 1024;
  text_height = (logical_rect.y + logical_rect.height) / 1024;
  if (text_width < 1)
    goto out;

  pp_get_text_position_scale (point,
                              renderer->width, renderer->height,
                              text_width, text_height,
                              &text_x, &text_y,
                              &text_scale);

  pp_get_shading_position_size (renderer->height, renderer->width, /* XXX: is this right order?? */
                                text_x, text_y,
                                text_width, text_height,
                                text_scale,
                                &shading_x, &shading_y,
                                &shading_width, &shading_height);

  clutter_color_from_string (&text_color, point->text_color);
  clutter_color_from_string (&shading_color, point->shading_color);

  cairo_set_source_rgba (renderer->ctx,
                         shading_color.red / 255.f,
                         shading_color.green / 255.f,
                         shading_color.blue / 255.f,
                         shading_color.alpha / 255.f * point->shading_opacity);
  cairo_rectangle (renderer->ctx,
                   shading_x, shading_y, shading_width, shading_height);
  cairo_fill (renderer->ctx);

  cairo_save (renderer->ctx);
  cairo_translate (renderer->ctx, text_x, text_y);
  cairo_scale (renderer->ctx, text_scale, text_scale);
  cairo_set_source_rgba (renderer->ctx,
                         text_color.red / 255.f,
                         text_color.green / 255.f,
                         text_color.blue / 255.f,
                         text_color.alpha / 255.f);
  pango_cairo_show_layout (renderer->ctx, layout);
  cairo_restore (renderer->ctx);

out:
  pango_font_description_free (desc);
  g_object_unref (layout);
}
Beispiel #17
0
/*
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%                                                                             %
%                                                                             %
%                                                                             %
%   R e a d P A N G O I m a g e                                               %
%                                                                             %
%                                                                             %
%                                                                             %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
%  ReadPANGOImage() reads an image in the Pango Markup Language Format.
%
%  The format of the ReadPANGOImage method is:
%
%      Image *ReadPANGOImage(const ImageInfo *image_info,
%        ExceptionInfo *exception)
%
%  A description of each parameter follows:
%
%    o image_info: the image info.
%
%    o exception: return any errors or warnings in this structure.
%
*/
static Image *ReadPANGOImage(const ImageInfo *image_info,
  ExceptionInfo *exception)
{
  cairo_font_options_t
    *font_options;

  cairo_surface_t
    *surface;

  char
    *caption,
    *property;

  cairo_t
    *cairo_image;

  const char
    *option;

  DrawInfo
    *draw_info;

  Image
    *image;

  MagickBooleanType
    status;

  PangoAlignment
    align;

  PangoContext
    *context;

  PangoFontMap
    *fontmap;

  PangoGravity
    gravity;

  PangoLayout
    *layout;

  PangoRectangle
    extent;

  PixelInfo
    fill_color;

  RectangleInfo
    page;

  register unsigned char
    *p;

  size_t
    stride;

  ssize_t
    y;

  unsigned char
    *pixels;

  /*
    Initialize Image structure.
  */
  assert(image_info != (const ImageInfo *) NULL);
  assert(image_info->signature == MagickSignature);
  if (image_info->debug != MagickFalse)
    (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
      image_info->filename);
  assert(exception != (ExceptionInfo *) NULL);
  assert(exception->signature == MagickSignature);
  image=AcquireImage(image_info,exception);
  (void) ResetImagePage(image,"0x0+0+0");
  /*
    Format caption.
  */
  option=GetImageArtifact(image,"filename");
  if (option == (const char *) NULL)
    property=InterpretImageProperties(image_info,image,image_info->filename,
      exception);
  else
    if (LocaleNCompare(option,"pango:",6) == 0)
      property=InterpretImageProperties(image_info,image,option+6,exception);
    else
      property=InterpretImageProperties(image_info,image,option,exception);
  (void) SetImageProperty(image,"caption",property,exception);
  property=DestroyString(property);
  caption=ConstantString(GetImageProperty(image,"caption",exception));
  /*
    Get context.
  */
  fontmap=pango_cairo_font_map_new();
  pango_cairo_font_map_set_resolution(PANGO_CAIRO_FONT_MAP(fontmap),
    image->resolution.x == 0.0 ? 90.0 : image->resolution.x);
  font_options=cairo_font_options_create();
  option=GetImageArtifact(image,"pango:hinting");
  if (option != (const char *) NULL)
    {
      if (LocaleCompare(option,"none") != 0)
        cairo_font_options_set_hint_style(font_options,CAIRO_HINT_STYLE_NONE);
      if (LocaleCompare(option,"full") != 0)
        cairo_font_options_set_hint_style(font_options,CAIRO_HINT_STYLE_FULL);
    }
  context=pango_font_map_create_context(fontmap);
  pango_cairo_context_set_font_options(context,font_options);
  cairo_font_options_destroy(font_options);
  option=GetImageArtifact(image,"pango:language");
  if (option != (const char *) NULL)
    pango_context_set_language(context,pango_language_from_string(option));
  draw_info=CloneDrawInfo(image_info,(DrawInfo *) NULL);
  pango_context_set_base_dir(context,draw_info->direction ==
    RightToLeftDirection ? PANGO_DIRECTION_RTL : PANGO_DIRECTION_LTR);
  switch (draw_info->gravity)
  {
    case NorthGravity:
    {
      gravity=PANGO_GRAVITY_NORTH;
      break;
    }
    case NorthWestGravity:
    case WestGravity:
    case SouthWestGravity:
    {
      gravity=PANGO_GRAVITY_WEST;
      break;
    }
    case NorthEastGravity:
    case EastGravity:
    case SouthEastGravity:
    {
      gravity=PANGO_GRAVITY_EAST;
      break;
    }
    case SouthGravity:
    {
      gravity=PANGO_GRAVITY_SOUTH;
      break;
    }
    default:
    {
      gravity=PANGO_GRAVITY_AUTO;
      break;
    }
  }
  pango_context_set_base_gravity(context,gravity);
  option=GetImageArtifact(image,"pango:gravity-hint");
  if (option != (const char *) NULL)
    {
      if (LocaleCompare(option,"line") == 0)
        pango_context_set_gravity_hint(context,PANGO_GRAVITY_HINT_LINE);
      if (LocaleCompare(option,"natural") == 0)
        pango_context_set_gravity_hint(context,PANGO_GRAVITY_HINT_NATURAL);
      if (LocaleCompare(option,"strong") == 0)
        pango_context_set_gravity_hint(context,PANGO_GRAVITY_HINT_STRONG);
    }
  /*
    Configure layout.
  */
  layout=pango_layout_new(context);
  option=GetImageArtifact(image,"pango:auto-dir");
  if (option != (const char *) NULL)
    pango_layout_set_auto_dir(layout,1);
  option=GetImageArtifact(image,"pango:ellipsize");
  if (option != (const char *) NULL)
    {
      if (LocaleCompare(option,"end") == 0)
        pango_layout_set_ellipsize(layout,PANGO_ELLIPSIZE_END);
      if (LocaleCompare(option,"middle") == 0)
        pango_layout_set_ellipsize(layout,PANGO_ELLIPSIZE_MIDDLE);
      if (LocaleCompare(option,"none") == 0)
        pango_layout_set_ellipsize(layout,PANGO_ELLIPSIZE_NONE);
      if (LocaleCompare(option,"start") == 0)
        pango_layout_set_ellipsize(layout,PANGO_ELLIPSIZE_START);
    }
  option=GetImageArtifact(image,"pango:justify");
  if (IfMagickTrue(IsStringTrue(option)))
    pango_layout_set_justify(layout,1);
  option=GetImageArtifact(image,"pango:single-paragraph");
  if (IfMagickTrue(IsStringTrue(option)))
    pango_layout_set_single_paragraph_mode(layout,1);
  option=GetImageArtifact(image,"pango:wrap");
  if (option != (const char *) NULL)
    {
      if (LocaleCompare(option,"char") == 0)
        pango_layout_set_wrap(layout,PANGO_WRAP_CHAR);
      if (LocaleCompare(option,"word") == 0)
        pango_layout_set_wrap(layout,PANGO_WRAP_WORD);
      if (LocaleCompare(option,"word-char") == 0)
        pango_layout_set_wrap(layout,PANGO_WRAP_WORD_CHAR);
    }
  option=GetImageArtifact(image,"pango:indent");
  if (option != (const char *) NULL)
    pango_layout_set_indent(layout,(int) ((StringToLong(option)*
      (image->resolution.x == 0.0 ? 90.0 : image->resolution.x)*PANGO_SCALE+36)/
      90.0+0.5));
  switch (draw_info->align)
  {
    case CenterAlign: align=PANGO_ALIGN_CENTER; break;
    case RightAlign: align=PANGO_ALIGN_RIGHT; break;
    case LeftAlign: align=PANGO_ALIGN_LEFT; break;
    default:
    {
      if (draw_info->gravity == CenterGravity)
        {
          align=PANGO_ALIGN_CENTER;
          break;
        }
      align=PANGO_ALIGN_LEFT;
      break;
    }
  }
  if ((align != PANGO_ALIGN_CENTER) &&
      (draw_info->direction == RightToLeftDirection))
    align=(PangoAlignment) (PANGO_ALIGN_LEFT+PANGO_ALIGN_RIGHT-align);
  pango_layout_set_alignment(layout,align);
  if (draw_info->font != (char *) NULL)
    {
      PangoFontDescription
        *description;

      /*
        Set font.
      */
      description=pango_font_description_from_string(draw_info->font);
      pango_font_description_set_size(description,(int) (PANGO_SCALE*
        draw_info->pointsize+0.5));
      pango_layout_set_font_description(layout,description);
      pango_font_description_free(description);
    }
  option=GetImageArtifact(image,"pango:markup");
  if ((option != (const char *) NULL) && (IsStringTrue(option) == MagickFalse))
    pango_layout_set_text(layout,caption,-1);
  else
    {
      GError
        *error;

      error=(GError *) NULL;
      if (pango_parse_markup(caption,-1,0,NULL,NULL,NULL,&error) == 0)
        (void) ThrowMagickException(exception,GetMagickModule(),CoderError,
          error->message,"`%s'",image_info->filename);
      pango_layout_set_markup(layout,caption,-1);
    }
  pango_layout_context_changed(layout);
  page.x=0;
  page.y=0;
  if (image_info->page != (char *) NULL)
    (void) ParseAbsoluteGeometry(image_info->page,&page);
  if (image->columns == 0)
    {
      pango_layout_get_extents(layout,NULL,&extent);
      image->columns=(extent.x+extent.width+PANGO_SCALE/2)/PANGO_SCALE+2*page.x;
    }
  else
    {
      image->columns-=2*page.x;
      pango_layout_set_width(layout,(int) ((PANGO_SCALE*image->columns*
        (image->resolution.x == 0.0 ? 90.0 : image->resolution.x)+45.0)/90.0+
        0.5));
    }
  if (image->rows == 0)
    {
      pango_layout_get_extents(layout,NULL,&extent);
      image->rows=(extent.y+extent.height+PANGO_SCALE/2)/PANGO_SCALE+2*page.y;
    }
  else
    {
      image->rows-=2*page.y;
      pango_layout_set_height(layout,(int) ((PANGO_SCALE*image->rows*
        (image->resolution.y == 0.0 ? 90.0 : image->resolution.y)+45.0)/90.0+
        0.5));
    }
  /*
    Render markup.
  */
  stride=(size_t) cairo_format_stride_for_width(CAIRO_FORMAT_ARGB32,
    image->columns);
  pixels=(unsigned char *) AcquireQuantumMemory(image->rows,stride*
    sizeof(*pixels));
  if (pixels == (unsigned char *) NULL)
    {
      draw_info=DestroyDrawInfo(draw_info);
      caption=DestroyString(caption);
      ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
    }
  surface=cairo_image_surface_create_for_data(pixels,CAIRO_FORMAT_ARGB32,
    image->columns,image->rows,stride);
  cairo_image=cairo_create(surface);
  cairo_set_operator(cairo_image,CAIRO_OPERATOR_CLEAR);
  cairo_paint(cairo_image);
  cairo_set_operator(cairo_image,CAIRO_OPERATOR_OVER);
  cairo_translate(cairo_image,page.x,page.y);
  pango_cairo_show_layout(cairo_image,layout);
  cairo_destroy(cairo_image);
  cairo_surface_destroy(surface);
  g_object_unref(layout);
  g_object_unref(fontmap);
  /*
    Convert surface to image.
  */
  (void) SetImageBackgroundColor(image,exception);
  p=pixels;
  GetPixelInfo(image,&fill_color);
  for (y=0; y < (ssize_t) image->rows; y++)
  {
    register Quantum
      *q;

    register ssize_t
      x;

    q=GetAuthenticPixels(image,0,y,image->columns,1,exception);
    if (q == (Quantum *) NULL)
      break;
    for (x=0; x < (ssize_t) image->columns; x++)
    {
      double
        gamma;

      fill_color.blue=(double) ScaleCharToQuantum(*p++);
      fill_color.green=(double) ScaleCharToQuantum(*p++);
      fill_color.red=(double) ScaleCharToQuantum(*p++);
      fill_color.alpha=(double) ScaleCharToQuantum(*p++);
      /*
        Disassociate alpha.
      */
      gamma=1.0-QuantumScale*fill_color.alpha;
      gamma=PerceptibleReciprocal(gamma);
      fill_color.blue*=gamma;
      fill_color.green*=gamma;
      fill_color.red*=gamma;
      CompositePixelOver(image,&fill_color,fill_color.alpha,q,(double)
        GetPixelAlpha(image,q),q);
      q+=GetPixelChannels(image);
    }
    if (SyncAuthenticPixels(image,exception) == MagickFalse)
      break;
    if (image->previous == (Image *) NULL)
      {
        status=SetImageProgress(image,LoadImageTag,(MagickOffsetType) y,
        image->rows);
        if (status == MagickFalse)
          break;
      }
  }
  /*
    Relinquish resources.
  */
  pixels=(unsigned char *) RelinquishMagickMemory(pixels);
  draw_info=DestroyDrawInfo(draw_info);
  caption=DestroyString(caption);
  return(GetFirstImageInList(image));
}
Beispiel #18
0
void iupdrvDrawText(IdrawCanvas* dc, const char* text, int len, int x, int y, int w, int h, long color, const char* font, int flags, double text_orientation)
{
  PangoLayout* fontlayout = (PangoLayout*)iupgtkGetPangoLayout(font);
  PangoAlignment alignment = PANGO_ALIGN_LEFT;
  GdkColor c;
  PangoContext* fontcontext = NULL;
  int layout_w = w, layout_h = h;
  int layout_center = flags & IUP_DRAW_LAYOUTCENTER;

  if (text_orientation && layout_center)
    iupDrawGetTextInnerBounds(w, h, text_orientation, &layout_w, &layout_h);

  iupgdkColorSet(&c, color);
  gdk_gc_set_rgb_fg_color(dc->pixmap_gc, &c);

  text = iupgtkStrConvertToSystemLen(text, &len);
  pango_layout_set_text(fontlayout, text, len);

  if (flags & IUP_DRAW_RIGHT)
    alignment = PANGO_ALIGN_RIGHT;
  else if (flags & IUP_DRAW_CENTER)
    alignment = PANGO_ALIGN_CENTER;

  if (flags & IUP_DRAW_WRAP)
  {
    pango_layout_set_width(fontlayout, iupGTK_PIXELS2PANGOUNITS(layout_w));
#ifdef PANGO_VERSION_CHECK
#if PANGO_VERSION_CHECK(1,2,0)  
    pango_layout_set_height(fontlayout, iupGTK_PIXELS2PANGOUNITS(layout_h));
#endif
#endif
  }
  else if (flags & IUP_DRAW_ELLIPSIS)
  {
    pango_layout_set_width(fontlayout, iupGTK_PIXELS2PANGOUNITS(layout_w));
#ifdef PANGO_VERSION_CHECK
#if PANGO_VERSION_CHECK(1,2,0)  
    pango_layout_set_height(fontlayout, iupGTK_PIXELS2PANGOUNITS(layout_h));
#endif
#endif
    pango_layout_set_ellipsize(fontlayout, PANGO_ELLIPSIZE_END);
  }

  pango_layout_set_alignment(fontlayout, alignment);

  if (flags & IUP_DRAW_CLIP)
  {
    GdkRectangle rect;
    rect.x = x;
    rect.y = y;
    rect.width = w;
    rect.height = h;
    gdk_gc_set_clip_rectangle(dc->pixmap_gc, &rect);
  }

  if (text_orientation)
  {
    PangoRectangle rect;
    PangoMatrix fontmatrix = PANGO_MATRIX_INIT;
    fontcontext = pango_layout_get_context(fontlayout);

    pango_matrix_rotate(&fontmatrix, text_orientation);

    pango_context_set_matrix(fontcontext, &fontmatrix);
    pango_layout_context_changed(fontlayout);

    pango_layout_get_pixel_extents(fontlayout, NULL, &rect);
#ifdef PANGO_VERSION_CHECK
#if PANGO_VERSION_CHECK(1,16,0)
    pango_matrix_transform_pixel_rectangle(&fontmatrix, &rect);
#endif
#endif

    /* Adjust the position considering the Pango rectangle transformed */
    if (layout_center)
    {
      x += (w - rect.width) / 2;
      y += (h - rect.height) / 2;
    }
    else
    {
      x += (int)rect.x;
      y += (int)rect.y;
    }
  }

  gdk_draw_layout(dc->pixmap, dc->pixmap_gc, x, y, fontlayout);

  /* restore settings */
  if ((flags & IUP_DRAW_WRAP) || (flags & IUP_DRAW_ELLIPSIS))
  {
    pango_layout_set_width(fontlayout, -1);
#ifdef PANGO_VERSION_CHECK
#if PANGO_VERSION_CHECK(1,2,0)  
    pango_layout_set_height(fontlayout, -1);
#endif
#endif
  }
  if (flags & IUP_DRAW_ELLIPSIS)
    pango_layout_set_ellipsize(fontlayout, PANGO_ELLIPSIZE_NONE);
  if (flags & IUP_DRAW_CLIP)
    gdk_gc_set_clip_region(dc->pixmap_gc, NULL);
  if (text_orientation)
    pango_context_set_matrix(fontcontext, NULL);
}
PangoLayout*
gdip_pango_setup_layout (GpGraphics *graphics, GDIPCONST WCHAR *stringUnicode, int length, GDIPCONST GpFont *font,
	GDIPCONST RectF *rc, RectF *box, GDIPCONST GpStringFormat *format, int **charsRemoved)
{
	GpStringFormat *fmt;
	PangoLayout *layout;
	PangoContext *context;
	PangoRectangle logical;   /* logical size of text (used for alignment) */
	PangoRectangle ink;       /* ink size of text (to pixel boundaries) */
	PangoAttrList *list = NULL;
	GString *ftext;
	PangoTabArray *tabs;
	PangoLayoutIter *iter;
	int i;
	int FrameWidth;     /* rc->Width (or rc->Height if vertical) */
	int FrameHeight;    /* rc->Height (or rc->Width if vertical) */
	int FrameX;         /* rc->X (or rc->Y if vertical) */
	int FrameY;         /* rc->Y (or rc->X if vertical) */
	int y0;             /* y0,y1,clipNN used for checking line positions vs. clip rectangle */
	int y1;
	double clipx1;
	double clipx2;
	double clipy1;
	double clipy2;
	int trimSpace;      /* whether or not to trim the space */

	gchar *text = ucs2_to_utf8 (stringUnicode, length);
	if (!text)
		return NULL;
	length = strlen(text);

	if (charsRemoved) {
		(*charsRemoved) = GdipAlloc (sizeof (int) * length);
		if (!*charsRemoved) {
			GdipFree (text);
		return NULL;
		}
		memset (*charsRemoved, 0, sizeof (int) * length);
	}

	/* TODO - Digit substitution */

// g_warning ("layout >%s< (%d) [x %g, y %g, w %g, h %g] [font %s, %g points]", text, length, rc->X, rc->Y, rc->Width, FrameHeight, font->face, font->emSize);

	/* a NULL format is valid, it means get the generic default values (and free them later) */
	if (!format) {
		GpStatus status = GdipStringFormatGetGenericDefault ((GpStringFormat **)&fmt);
		if (status != Ok) {
			GdipFree (text);
			return NULL;
		}
	} else {
		fmt = (GpStringFormat *)format;
	}

	layout = pango_cairo_create_layout (graphics->ct);

	/* context is owned by Pango (i.e. not referenced counted) do not free */
	context = pango_layout_get_context (layout);

	pango_layout_set_font_description (layout, gdip_get_pango_font_description ((GpFont*) font));

	if (fmt->formatFlags & StringFormatFlagsDirectionVertical) {
		FrameWidth = MAKE_SAFE_FOR_PANGO (SAFE_FLOAT_TO_UINT32 (rc->Height));
		FrameHeight = MAKE_SAFE_FOR_PANGO (SAFE_FLOAT_TO_UINT32 (rc->Width));
		FrameX = SAFE_FLOAT_TO_UINT32 (rc->Y);
		FrameY = SAFE_FLOAT_TO_UINT32 (rc->X);
	} else {
		FrameWidth = MAKE_SAFE_FOR_PANGO (SAFE_FLOAT_TO_UINT32 (rc->Width));
		FrameHeight = MAKE_SAFE_FOR_PANGO (SAFE_FLOAT_TO_UINT32 (rc->Height));
		FrameX = SAFE_FLOAT_TO_UINT32 (rc->X);
		FrameY = SAFE_FLOAT_TO_UINT32 (rc->Y);
	}
	//g_warning("FW: %d\tFH: %d", FrameWidth, FrameHeight);

	if ((FrameWidth <= 0) || (fmt->formatFlags & StringFormatFlagsNoWrap)) {
		pango_layout_set_width (layout, -1);
		//g_warning ("Setting width: %d", -1);
	} else {
		pango_layout_set_width (layout, FrameWidth * PANGO_SCALE);
		//g_warning ("Setting width: %d", FrameWidth * PANGO_SCALE);
	}

	if ((rc->Width != 0) && (rc->Height != 0) && ((fmt->formatFlags & StringFormatFlagsNoClip) == 0)) {
// g_warning ("\tclip [%g %g %g %g]", rc->X, rc->Y, rc->Width, rc->Height);
		/* We do not call cairo_reset_clip because we want to take previous clipping into account */
		/* Use rc instead of frame variables because this is pre-transform */
		gdip_cairo_rectangle (graphics, rc->X, rc->Y, rc->Width, rc->Height, TRUE);
		cairo_clip (graphics->ct);
	}

		/* with GDI+ the API not the renderer makes the direction decision */
		pango_layout_set_auto_dir (layout, FALSE);
	if (!(fmt->formatFlags & StringFormatFlagsDirectionRightToLeft) != !(fmt->formatFlags & StringFormatFlagsDirectionVertical)) {
		pango_context_set_base_dir (context, PANGO_DIRECTION_WEAK_RTL);
		pango_layout_context_changed (layout);

		/* horizontal alignment */
		switch (fmt->alignment) {
		case StringAlignmentNear:
			pango_layout_set_alignment (layout, PANGO_ALIGN_RIGHT);
			break;
		case StringAlignmentCenter:
			pango_layout_set_alignment (layout, PANGO_ALIGN_CENTER);
			break;
		case StringAlignmentFar:
			pango_layout_set_alignment (layout, PANGO_ALIGN_LEFT);
			break;
		}
	} else {
		/* pango default base dir is WEAK_LTR, which is what we want */

		/* horizontal alignment */
		switch (fmt->alignment) {
		case StringAlignmentNear:
			pango_layout_set_alignment (layout, PANGO_ALIGN_LEFT);
			break;
		case StringAlignmentCenter:
			pango_layout_set_alignment (layout, PANGO_ALIGN_CENTER);
			break;
		case StringAlignmentFar:
			pango_layout_set_alignment (layout, PANGO_ALIGN_RIGHT);
			break;
		}
	}

#ifdef PANGO_VERSION_CHECK
#if PANGO_VERSION_CHECK(1,16,0)
	if (fmt->formatFlags & StringFormatFlagsDirectionVertical) {
		if (fmt->formatFlags & StringFormatFlagsDirectionRightToLeft) {
			cairo_rotate (graphics->ct, M_PI/2.0);
			cairo_translate (graphics->ct, 0, -FrameHeight);
			pango_cairo_update_context (graphics->ct, context);
		} else {
			cairo_rotate (graphics->ct, 3.0*M_PI/2.0);
			cairo_translate (graphics->ct, -FrameWidth, 0);
			pango_cairo_update_context (graphics->ct, context);
		}
		/* only since Pango 1.16 */
		pango_context_set_base_gravity (context, PANGO_GRAVITY_AUTO);
		pango_context_set_gravity_hint (context, PANGO_GRAVITY_HINT_LINE);
		pango_layout_context_changed (layout);
	}
#endif
#endif

	/* TODO - StringFormatFlagsDisplayFormatControl
		scan and replace them ??? */

	/* Trimming options seem to apply only to the end of the string - gdi+ will still wrap
	 * with preference to word first, then character.  Unfortunately, pango doesn't have
	 * any way to differentiate wrapping behavior from trimming behavior that I could find */
	pango_layout_set_wrap (layout, PANGO_WRAP_WORD_CHAR);
	switch (fmt->trimming) {
	case StringTrimmingNone:
		pango_layout_set_ellipsize (layout, PANGO_ELLIPSIZE_NONE);
		break;
	case StringTrimmingCharacter:
		pango_layout_set_ellipsize (layout, PANGO_ELLIPSIZE_NONE);
		break;
	case StringTrimmingWord:
		pango_layout_set_ellipsize (layout, PANGO_ELLIPSIZE_NONE);
		break;
	case StringTrimmingEllipsisCharacter:
		pango_layout_set_ellipsize (layout, PANGO_ELLIPSIZE_END);
		if (!(fmt->formatFlags & StringFormatFlagsNoWrap))
			pango_layout_set_height (layout, FrameHeight == 0 ? G_MAXINT32 : FrameHeight * PANGO_SCALE);
		break;
	case StringTrimmingEllipsisWord:
		pango_layout_set_ellipsize (layout, PANGO_ELLIPSIZE_END);
		if (!(fmt->formatFlags & StringFormatFlagsNoWrap))
			pango_layout_set_height (layout, FrameHeight == 0 ? G_MAXINT32 : FrameHeight * PANGO_SCALE);
		break;
	case StringTrimmingEllipsisPath:
		pango_layout_set_ellipsize (layout, PANGO_ELLIPSIZE_MIDDLE);
		if (!(fmt->formatFlags & StringFormatFlagsNoWrap))
			pango_layout_set_height (layout, FrameHeight == 0 ? G_MAXINT32 : FrameHeight * PANGO_SCALE);
		break;
	}

	/* some stuff can only be done by manipulating the attributes (but we can avoid this most of the time) */
	if ((fmt->formatFlags & StringFormatFlagsNoFontFallback) || (font->style & (FontStyleUnderline | FontStyleStrikeout))) {

		list = gdip_get_layout_attributes (layout);

		/* StringFormatFlagsNoFontFallback */
		if (fmt->formatFlags & StringFormatFlagsNoFontFallback) {
			PangoAttribute *attr = pango_attr_fallback_new (FALSE);
			attr->start_index = 0;
			attr->end_index = length;
			pango_attr_list_insert (list, attr);
		}

		if (font->style & FontStyleUnderline) {
			PangoAttribute *attr = pango_attr_underline_new (PANGO_UNDERLINE_SINGLE);
			attr->start_index = 0;
			attr->end_index = length;
			pango_attr_list_insert (list, attr);
		}

		if (font->style & FontStyleStrikeout) {
			PangoAttribute *attr = pango_attr_strikethrough_new (TRUE);
			attr->start_index = 0;
			attr->end_index = length;
			pango_attr_list_insert (list, attr);
		}
	}

	if (fmt->numtabStops > 0) {
		float tabPosition;
		tabs = pango_tab_array_new (fmt->numtabStops, FALSE);
		tabPosition = fmt->firstTabOffset;
		for (i = 0; i < fmt->numtabStops; i++) {
			tabPosition += fmt->tabStops[i];
			pango_tab_array_set_tab (tabs, i, PANGO_TAB_LEFT, (gint)min (tabPosition, PANGO_MAX) * PANGO_SCALE);
		}
		pango_layout_set_tabs (layout, tabs);
		pango_tab_array_free (tabs);
	}

	//g_warning ("length before ws removal: %d", length);
	trimSpace = (fmt->formatFlags & StringFormatFlagsMeasureTrailingSpaces) == 0;
	switch (fmt->hotkeyPrefix) {
	case HotkeyPrefixHide:
		/* we need to remove any accelerator from the string */
		ftext = gdip_process_string (text, length, 1, trimSpace, NULL, charsRemoved);
		break;
	case HotkeyPrefixShow:
		/* optimization: is seems that we never see the hotkey when using an underline font */
		if (font->style & FontStyleUnderline) {
			/* so don't bother drawing it (and simply add the '&' character) */
			ftext = gdip_process_string (text, length, 1, trimSpace, NULL, charsRemoved);
		} else {
			/* find accelerator and add attribute to the next character (unless it's the prefix too) */
			if (!list)
				list = gdip_get_layout_attributes (layout);
			ftext = gdip_process_string (text, length, 1, trimSpace, list, charsRemoved);
		}
		break;
	default:
		ftext = gdip_process_string (text, length, 0, trimSpace, NULL, charsRemoved);
		break;
	}
	length = ftext->len;
	//g_warning ("length after ws removal: %d", length);

	if (list) {
		pango_layout_set_attributes (layout, list);
		pango_attr_list_unref (list);
	}

// g_warning("\tftext>%s< (%d)", ftext->str, -1);
	pango_layout_set_text (layout, ftext->str, ftext->len);
	GdipFree (text);
	g_string_free(ftext, TRUE);

	/* Trim the text after the last line for ease of counting lines/characters */
	/* Also prevents drawing whole lines outside the boundaries if NoClip was specified */
	/* In case of pre-existing clipping, use smaller of clip rectangle or our specified height */
	if (FrameHeight > 0) {
		cairo_clip_extents (graphics->ct, &clipx1, &clipy1, &clipx2, &clipy2);
		if (clipy2 > 0 && !(fmt->formatFlags & StringFormatFlagsNoClip))
			clipy2 = min (clipy2, FrameHeight + FrameY);
		else
			clipy2 = FrameHeight + FrameY;
		iter = pango_layout_get_iter (layout);
		do {
			if (iter == NULL)
				break;
			pango_layout_iter_get_line_yrange (iter, &y0, &y1);
			//g_warning("yrange: %d  %d  clipy2: %f", y0 / PANGO_SCALE, y1 / PANGO_SCALE, clipy2);
			/* StringFormatFlagsLineLimit */
			if (((fmt->formatFlags & StringFormatFlagsLineLimit) && y1 / PANGO_SCALE > clipy2) || (y0 / PANGO_SCALE > clipy2)) {
				PangoLayoutLine *line = pango_layout_iter_get_line_readonly (iter);
				pango_layout_set_text (layout, pango_layout_get_text (layout), line->start_index);
				break;
			}
		} while (pango_layout_iter_next_line (iter));
		pango_layout_iter_free (iter);
	}

	pango_layout_get_pixel_extents (layout, &ink, &logical);
// g_warning ("\tlogical\t[x %d, y %d, w %d, h %d][x %d, y %d, w %d, h %d]", logical.x, logical.y, logical.width, logical.height, ink.x, ink.y, ink.width, ink.height);

	if ((fmt->formatFlags & StringFormatFlagsNoFitBlackBox) == 0) {
		/* By default don't allow overhang - ink space may be larger than logical space */
		if (fmt->formatFlags & StringFormatFlagsDirectionVertical) {
			box->X = min (ink.y, logical.y);
			box->Y = min (ink.x, logical.x);
			box->Height = max (ink.width, logical.width);
			box->Width = max (ink.height, logical.height);
		} else {
			box->X = min (ink.x, logical.x);
			box->Y = min (ink.y, logical.y);
			box->Height = max (ink.height, logical.height);
			box->Width = max (ink.width, logical.width);
		}
	} else {
		/* Allow overhang */
		if (fmt->formatFlags & StringFormatFlagsDirectionVertical) {
			box->X = logical.y;
			box->Y = logical.x;
			box->Height = logical.width;
			box->Width = logical.height;
		} else {
			box->X = logical.x;
			box->Y = logical.y;
	box->Height = logical.height;
			box->Width = logical.width;
		}
	}
// g_warning ("\tbox\t[x %g, y %g, w %g, h %g]", box->X, box->Y, box->Width, box->Height);

	/* vertical alignment*/
	if (fmt->formatFlags & StringFormatFlagsDirectionVertical) {
		switch (fmt->lineAlignment) {
		case StringAlignmentNear:
			break;
		case StringAlignmentCenter:
			box->X += (rc->Width - box->Width) / 2;
			break;
		case StringAlignmentFar:
			box->X += (rc->Width - box->Width);
			break;
		}
	} else {
	switch (fmt->lineAlignment) {
	case StringAlignmentNear:
		break;
	case StringAlignmentCenter:
			box->Y += (rc->Height - box->Height) / 2;
		break;
	case StringAlignmentFar:
			box->Y += (rc->Height - box->Height);
		break;
	}
	}
// g_warning ("va-box\t[x %g, y %g, w %g, h %g]", box->X, box->Y, box->Width, box->Height);

	pango_cairo_update_layout (graphics->ct, layout);

	return layout;
}
Beispiel #20
0
static VALUE
rg_set_alignment(VALUE self, VALUE align)
{
    pango_layout_set_alignment(_SELF(self), RVAL2GENUM(align, PANGO_TYPE_ALIGNMENT));
    return self;
}
Beispiel #21
0
static PangoLayout *
rsvg_text_create_layout (RsvgDrawingCtx * ctx,
                         RsvgState * state, const char *text, PangoContext * context)
{
    PangoFontDescription *font_desc;
    PangoLayout *layout;
    PangoAttrList *attr_list;
    PangoAttribute *attribute;

    if (state->lang)
        pango_context_set_language (context, pango_language_from_string (state->lang));

    if (state->unicode_bidi == UNICODE_BIDI_OVERRIDE || state->unicode_bidi == UNICODE_BIDI_EMBED)
        pango_context_set_base_dir (context, state->text_dir);

    font_desc = pango_font_description_copy (pango_context_get_font_description (context));

    if (state->font_family)
        pango_font_description_set_family_static (font_desc, state->font_family);

    pango_font_description_set_style (font_desc, state->font_style);
    pango_font_description_set_variant (font_desc, state->font_variant);
    pango_font_description_set_weight (font_desc, state->font_weight);
    pango_font_description_set_stretch (font_desc, state->font_stretch);
    pango_font_description_set_size (font_desc,
                                     _rsvg_css_normalize_font_size (state, ctx) *
                                     PANGO_SCALE / ctx->dpi_y * 72);

    layout = pango_layout_new (context);
    pango_layout_set_font_description (layout, font_desc);
    pango_font_description_free (font_desc);

    attr_list = pango_attr_list_new ();
    attribute = pango_attr_letter_spacing_new (_rsvg_css_normalize_length (&state->letter_spacing,
                                                                           ctx, 'h') * PANGO_SCALE);
    attribute->start_index = 0;
    attribute->end_index = G_MAXINT;
    pango_attr_list_insert (attr_list, attribute); 

    if (state->has_font_decor && text) {
        if (state->font_decor & TEXT_UNDERLINE) {
            attribute = pango_attr_underline_new (PANGO_UNDERLINE_SINGLE);
            attribute->start_index = 0;
            attribute->end_index = -1;
            pango_attr_list_insert (attr_list, attribute);
        }
	if (state->font_decor & TEXT_STRIKE) {
            attribute = pango_attr_strikethrough_new (TRUE);
            attribute->start_index = 0;
            attribute->end_index = -1;
            pango_attr_list_insert (attr_list, attribute);
	}
    }

    pango_layout_set_attributes (layout, attr_list);
    pango_attr_list_unref (attr_list);

    if (text)
        pango_layout_set_text (layout, text, -1);
    else
        pango_layout_set_text (layout, NULL, 0);

    pango_layout_set_alignment (layout, (state->text_dir == PANGO_DIRECTION_LTR ||
                                         state->text_dir == PANGO_DIRECTION_TTB_LTR) ?
                                PANGO_ALIGN_LEFT : PANGO_ALIGN_RIGHT);

    return layout;
}
  /* Do the Pango text rendering.  If called when pixmap is bg_text_layer,
  |  it is a background draw.  But if called from push_decal_pixmaps() it is
  |  considered a push operation because it is being done whenever any panel
  |  decals or krells are modified.  In this case, Pango does the pixel pushing
  |  instead of gkrellm as was done in pre 2.2.0.
  */
static void
panel_draw_decal_text_list(GdkPixmap *pixmap, GkrellmDecal *d)
	{
	PangoLayout			*layout;
	GdkRectangle		rect;
	GList				*list;
	GkrellmText			*tx;
	GkrellmTextstyle	*ts;
	gchar				*s;
	gint				x, y;

	layout = gtk_widget_create_pango_layout(gkrellm_get_top_window(), NULL);
	rect.x = d->x;
	rect.y = d->y;
	rect.width = d->w;
	rect.height = d->h;
	gdk_gc_set_clip_rectangle(_GK.text_GC, &rect);
	for (list = d->text_list; list; list = list->next)
		{
		tx = (GkrellmText *) list->data;
		if (!*tx->text)
			continue;
		ts = &tx->text_style;

		pango_layout_set_font_description(layout, ts->font);
		x = tx->x_off;
		y = tx->y_off;
		if (d->flags & DF_SCROLL_TEXT_DIVERTED)
			{
			if (d->flags & DF_SCROLL_TEXT_CENTER)
				pango_layout_set_alignment(layout, PANGO_ALIGN_CENTER);
			if (d->flags & DF_SCROLL_TEXT_H_LOOP)
				{
				x %= d->scroll_width;
				if (x > 0)
					x -= d->scroll_width;
				s = g_strconcat(tx->text, tx->text, NULL);
				if (d->flags & DF_TEXT_USE_MARKUP)
					pango_layout_set_markup(layout, s, strlen(s));
				else
					pango_layout_set_text(layout, s, strlen(s));
				g_free(s);
				}
			else if (d->flags & DF_SCROLL_TEXT_V_LOOP)
				{
				y %= d->scroll_height + d->y_ink;
				if (y > 0)
					y -= d->scroll_height + d->y_ink;
				s = g_strconcat(tx->text, "\n", tx->text, NULL);
				if (d->flags & DF_TEXT_USE_MARKUP)
					pango_layout_set_markup(layout, s, strlen(s));
				else
					pango_layout_set_text(layout, s, strlen(s));
				g_free(s);
				}
			else
				{
				if (d->flags & DF_TEXT_USE_MARKUP)
					pango_layout_set_markup(layout, tx->text,strlen(tx->text));
				else
					pango_layout_set_text(layout, tx->text, strlen(tx->text));
				}
			}
		else
			{
			if (d->flags & DF_TEXT_USE_MARKUP)
				pango_layout_set_markup(layout, tx->text, strlen(tx->text));
			else
				pango_layout_set_text(layout, tx->text, strlen(tx->text));
			}
		x += d->x;
		y += d->y;

		if (ts->effect)
			{
			gdk_gc_set_foreground(_GK.text_GC, &ts->shadow_color);
			gdk_draw_layout_with_colors(pixmap, _GK.text_GC,
						x + 1, y + 1, layout,
						&ts->shadow_color, NULL);
			}
		gdk_gc_set_foreground(_GK.text_GC, &ts->color);
		gdk_draw_layout(pixmap, _GK.text_GC, x, y, layout);
		}
	gdk_gc_set_clip_rectangle(_GK.text_GC, NULL);
	g_object_unref(layout);
	}
Beispiel #23
0
static void
draw_info_header (GtkPrintContext *context,
                  cairo_t         *cr,
                  PrintData       *data)
{
  PangoLayout          *layout;
  PangoFontDescription *desc;
  gdouble               text_height;
  gdouble               text_width;
  gdouble               fname_text_width;
  gint                  layout_height;
  gint                  layout_width;
  gchar                 date_buffer[100];
  GDate                *date;
  const gchar          *name_str;
  GimpParasite         *parasite;
  const gchar          *end_ptr;
  gchar                *filename;
  gdouble               cr_width;

  cairo_save (cr);

  cr_width  = gtk_print_context_get_width (context);
  cairo_rectangle (cr, 0, 0, cr_width, HEADER_HEIGHT);
  cairo_set_source_rgb (cr, 0.8, 0.8, 0.8);
  cairo_fill_preserve (cr);

  cairo_set_source_rgb (cr, 0, 0, 0);
  cairo_set_line_width (cr, 1);
  cairo_stroke (cr);

  layout = gtk_print_context_create_pango_layout (context);

  desc = pango_font_description_from_string ("sans 14");
  pango_layout_set_font_description (layout, desc);
  pango_font_description_free (desc);

  pango_layout_set_width (layout, -1);
  pango_layout_set_alignment (layout, PANGO_ALIGN_CENTER);

  /* image name */
  pango_layout_set_text (layout, gimp_image_get_name (data->image_id), -1);

  pango_layout_get_size (layout, &layout_width, &layout_height);
  text_height = (gdouble) layout_height / PANGO_SCALE;

  cairo_move_to (cr, 0.02 * cr_width,  (HEADER_HEIGHT - text_height) / 5);
  pango_cairo_show_layout (cr, layout);

  /* user name */
  name_str = g_get_real_name ();
  if (name_str && g_utf8_validate (name_str, -1, &end_ptr))
    {
      pango_layout_set_text (layout, name_str, -1);

      pango_layout_get_size (layout, &layout_width, &layout_height);
      text_height = (gdouble) layout_height / PANGO_SCALE;
      text_width = (gdouble) layout_width / PANGO_SCALE;

      cairo_move_to (cr, 0.5 * cr_width - 0.5 * text_width,
                     (HEADER_HEIGHT - text_height) / 5);
      pango_cairo_show_layout (cr, layout);
    }

  /* date */
  date = g_date_new ();
  g_date_set_time_t (date, time (NULL));
  g_date_strftime (date_buffer, 100, "%x", date);
  g_date_free (date);
  pango_layout_set_text (layout, date_buffer, -1);

  pango_layout_get_size (layout, &layout_width, &layout_height);
  text_height = (gdouble) layout_height / PANGO_SCALE;
  text_width = (gdouble) layout_width / PANGO_SCALE;

  cairo_move_to (cr,
                 0.98 * cr_width - text_width,
                 (HEADER_HEIGHT - text_height) / 5);
  pango_cairo_show_layout (cr, layout);

  /* file name if any */
  filename = gimp_image_get_filename (data->image_id);

  if (filename)
    {
      pango_layout_set_text (layout,
                             gimp_filename_to_utf8 (filename), -1);
      g_free (filename);

      pango_layout_get_size (layout, &layout_width, &layout_height);
      text_height = (gdouble) layout_height / PANGO_SCALE;
      fname_text_width = (gdouble) layout_width / PANGO_SCALE;

      cairo_move_to (cr,
                     0.02 * cr_width,  4 * (HEADER_HEIGHT - text_height) / 5);
      pango_cairo_show_layout (cr, layout);
    }
  else
    {
      fname_text_width = 0;
    }

  /* image comment if it is short */
  parasite = gimp_image_parasite_find (data->image_id, "gimp-comment");

  if (parasite)
    {
      pango_layout_set_text (layout, gimp_parasite_data (parasite), -1);

      pango_layout_get_size (layout, &layout_width, &layout_height);
      text_height = (gdouble) layout_height / PANGO_SCALE;
      text_width = (gdouble) layout_width / PANGO_SCALE;

      if (fname_text_width + text_width < 0.8 * cr_width &&
          text_height < 0.5 * HEADER_HEIGHT)
        {
          cairo_move_to (cr, 0.98 * cr_width - text_width,
                         4 * (HEADER_HEIGHT - text_height) / 5);
          pango_cairo_show_layout (cr, layout);
        }

      gimp_parasite_free (parasite);
    }

  g_object_unref (layout);

  cairo_restore (cr);
}
static void
gnc_header_draw_offscreen (GncHeader *header)
{
    SheetBlockStyle *style = header->style;
    Table *table = header->sheet->table;
    VirtualLocation virt_loc;
    VirtualCell *vcell;
    guint32 color_type;
    GtkStyleContext *stylectxt = gtk_widget_get_style_context (GTK_WIDGET(header));
    GdkRGBA color;
    int row_offset;
    CellBlock *cb;
    int i;
    cairo_t *cr;

    virt_loc.vcell_loc.virt_row = 0;
    virt_loc.vcell_loc.virt_col = 0;
    virt_loc.phys_row_offset = 0;
    virt_loc.phys_col_offset = 0;

    gtk_style_context_save (stylectxt);

    // Get the background color type and apply the css class
    color_type = gnc_table_get_bg_color (table, virt_loc, NULL);
    gnucash_get_style_classes (header->sheet, stylectxt, color_type);

    if (header->surface)
        cairo_surface_destroy (header->surface);
    header->surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32,
                                                header->width,
                                                header->height);

    cr = cairo_create (header->surface);

    // Fill background color of header
    gtk_render_background (stylectxt, cr, 0, 0, header->width, header->height);

    gdk_rgba_parse (&color, "black");
    cairo_set_source_rgb (cr, color.red, color.green, color.blue);
    cairo_rectangle (cr, 0.5, 0.5, header->width - 1.0, header->height - 1.0);
    cairo_set_line_width (cr, 1.0);
    cairo_stroke (cr);

    // Draw bottom horizontal line, makes bottom line thicker
    cairo_move_to (cr, 0.5, header->height - 1.5);
    cairo_line_to (cr, header->width - 1.0, header->height - 1.5);
    cairo_set_line_cap (cr, CAIRO_LINE_CAP_SQUARE);
    cairo_set_line_width (cr, 1.0);
    cairo_stroke (cr);

    /*font = gnucash_register_font;*/

    vcell = gnc_table_get_virtual_cell
            (table, table->current_cursor_loc.vcell_loc);
    cb = vcell ? vcell->cellblock : NULL;
    row_offset = 0;

    for (i = 0; i < style->nrows; i++)
    {
        int col_offset = 0;
        int h = 0, j;
        virt_loc.phys_row_offset = i;

        /* TODO: This routine is duplicated in several places.
           Can we abstract at least the cell drawing routine?
           That way we'll be sure everything is drawn
           consistently, and cut down on maintenance issues. */

        for (j = 0; j < style->ncols; j++)
        {
            CellDimensions *cd;
            double text_x, text_y, text_w, text_h;
            BasicCell *cell;
            const char *text;
            int w;
            PangoLayout *layout;

            virt_loc.phys_col_offset = j;

            cd = gnucash_style_get_cell_dimensions (style, i, j);
            h = cd->pixel_height;
            if (header->in_resize && (j == header->resize_col))
                w = header->resize_col_width;
            else
                w = cd->pixel_width;

            cell = gnc_cellblock_get_cell (cb, i, j);
            if (!cell || !cell->cell_name)
            {
                col_offset += w;
                continue;
            }

            cairo_rectangle (cr, col_offset - 0.5, row_offset + 0.5, w, h);
            cairo_set_line_width (cr, 1.0);
            cairo_stroke (cr);

            virt_loc.vcell_loc =
                table->current_cursor_loc.vcell_loc;
            text = gnc_table_get_label (table, virt_loc);
            if (!text)
                text = "";

            layout = gtk_widget_create_pango_layout (GTK_WIDGET (header->sheet), text);
            switch (gnc_table_get_align (table, virt_loc))
            {
            default:
            case CELL_ALIGN_LEFT:
                pango_layout_set_alignment (layout, PANGO_ALIGN_LEFT);
                break;

            case CELL_ALIGN_RIGHT:
                pango_layout_set_alignment (layout, PANGO_ALIGN_RIGHT);
                break;

            case CELL_ALIGN_CENTER:
                pango_layout_set_alignment (layout, PANGO_ALIGN_CENTER);
                break;
            }

            text_x = col_offset + CELL_HPADDING;
            text_y = row_offset + 1;
            text_w = MAX (0, w - (2 * CELL_HPADDING));
            text_h = h - 2;
            cairo_save (cr);
            cairo_rectangle (cr, text_x, text_y, text_w, text_h);
            cairo_clip (cr);

            gtk_render_layout (stylectxt, cr, text_x, text_y, layout);

            cairo_restore (cr);
            g_object_unref (layout);

            col_offset += w;
        }
        row_offset += h;
    }
    gtk_style_context_restore (stylectxt);

    cairo_destroy (cr);
}
static void
draw(GtkWidget *widget, cairo_t *cr, gpointer data)
{
    CalibArea *calib_area = (CalibArea*)data;
    int i;
    double x;
    double y;
    PangoLayout *layout;
    PangoRectangle logical_rect;
    GtkStyleContext *context;
    char *markup;

    resize_display(calib_area);

    context = gtk_widget_get_style_context (widget);

    /* Black background and reset the operator */
    cairo_set_operator (cr, CAIRO_OPERATOR_CLEAR);
    cairo_paint (cr);
    cairo_set_operator (cr, CAIRO_OPERATOR_OVER);

    /* If calibration is successful, just draw the tick */
    if (calib_area->icon_success) {
        draw_success_icon (calib_area, cr);
        return;
    }

    /* Print the help lines */
    layout = pango_layout_new (gtk_widget_get_pango_context (widget));
    pango_layout_set_alignment (layout, PANGO_ALIGN_CENTER);
    markup = g_strdup_printf ("<span foreground=\"white\"><big><b>%s</b></big>\n<big>%s</big></span>",
			      _(HELP_TEXT_TITLE),
			      _(HELP_TEXT_MAIN));
    pango_layout_set_markup (layout, markup, -1);
    g_free (markup);

    pango_layout_get_pixel_extents (layout, NULL, &logical_rect);

    x = (calib_area->display_width - logical_rect.width) / 2 + logical_rect.x;
    y = (calib_area->display_height - logical_rect.height) / 2  - logical_rect.height - 40 + logical_rect.y;

    gtk_render_layout (context, cr,
		       x + logical_rect.x,
		       y + logical_rect.y,
		       layout);
    g_object_unref (layout);

    /* Draw the points */
    cairo_set_source_rgb(cr, 1.0, 1.0, 1.0);

    i = calib_area->calibrator.num_clicks;

    cairo_set_line_width(cr, 1);
    cairo_move_to(cr, calib_area->X[i] - CROSS_LINES, calib_area->Y[i] - 0.5);
    cairo_rel_line_to(cr, CROSS_LINES*2, 0);
    cairo_move_to(cr, calib_area->X[i] - 0.5, calib_area->Y[i] - CROSS_LINES);
    cairo_rel_line_to(cr, 0, CROSS_LINES*2);
    cairo_stroke(cr);

    cairo_set_line_width(cr, 2);
    cairo_arc(cr, calib_area->X[i] - 0.5, calib_area->Y[i] - 0.5, CROSS_CIRCLE, 0.0, 2.0 * M_PI);
    cairo_stroke(cr);

    cairo_set_line_width(cr, 5);
    cairo_arc(cr, calib_area->X[i] - 0.5, calib_area->Y[i] - 0.5, CROSS_CIRCLE2, 0.0, 2.0 * M_PI);
    cairo_stroke(cr);

    /* Draw the clock background */
    cairo_arc(cr, calib_area->display_width/2, calib_area->display_height/2, CLOCK_RADIUS/2, 0.0, 2.0 * M_PI);
    cairo_set_source_rgb(cr, 0.5, 0.5, 0.5);
    cairo_fill_preserve(cr);
    cairo_stroke(cr);

    cairo_set_line_width(cr, CLOCK_LINE_WIDTH);
    cairo_arc(cr, calib_area->display_width/2, calib_area->display_height/2, (CLOCK_RADIUS - CLOCK_LINE_WIDTH - CLOCK_LINE_PADDING)/2,
         3/2.0*M_PI, (3/2.0*M_PI) + ((double)calib_area->time_elapsed/(double)MAX_TIME) * 2*M_PI);
    cairo_set_source_rgb(cr, 1.0, 1.0, 1.0);
    cairo_stroke(cr);

    /* Draw the message (if any) */
    if (calib_area->message != NULL)
    {
        cairo_set_source_rgb(cr, 1.0, 1.0, 1.0);

        /* Frame the message */
        layout = pango_layout_new (gtk_widget_get_pango_context (widget));
        pango_layout_set_alignment (layout, PANGO_ALIGN_CENTER);
        markup = g_strdup_printf ("<span foreground=\"white\"><big>%s</big></span>",
				  _(calib_area->message));
        pango_layout_set_markup (layout, markup, -1);
        g_free (markup);
        pango_layout_get_pixel_extents (layout, NULL, &logical_rect);

        x = (calib_area->display_width - logical_rect.width) / 2 + logical_rect.x;
        y = (calib_area->display_height - logical_rect.height + CLOCK_RADIUS) / 2 + 60 + logical_rect.y;
        cairo_set_line_width(cr, 2);
        cairo_rectangle(cr, x - 10 - 0.5 , y - 10 - 0.5,
                logical_rect.width + 20 + 1, logical_rect.height + 20 + 1);
        cairo_stroke (cr);

        /* Print the message */
	gtk_render_layout (context, cr,
			   x + logical_rect.x,
			   y + logical_rect.y,
			   layout);
	g_object_unref (layout);
    }
}
Beispiel #26
0
static void
marlin_text_renderer_get_size (GtkCellRenderer      *cell,
                               GtkWidget            *widget,
                               const GdkRectangle   *cell_area,
                               gint                 *x_offset,
                               gint                 *y_offset,
                               gint                 *width,
                               gint                 *height)
{
    MarlinTextRenderer *text_renderer = MARLIN_TEXT_RENDERER (cell);
    gint text_length;
    gint text_width;
    gint text_height;
    gint xpad, ypad;

    /* setup the new widget */
    marlin_text_renderer_set_widget (text_renderer, widget);

    gfloat xalign, yalign;
    gtk_cell_renderer_get_alignment (cell, &xalign, &yalign);

    /* we can guess the dimensions if we don't wrap */
    if (text_renderer->wrap_width < 0)
    {
        /* determine the text_length in characters */
        text_length = g_utf8_strlen (text_renderer->text, -1);

        /* the approximation is usually 1-2 chars wrong, so wth */
        text_length += 2;

        /* calculate the appromixate text width/height */
        text_width = text_renderer->char_width * text_length;
        text_height = text_renderer->char_height;
    }
    else
    {
        /* calculate the real text dimension */
        pango_layout_set_ellipsize (text_renderer->layout, PANGO_ELLIPSIZE_END);
        pango_layout_set_height (text_renderer->layout, -3);
        pango_layout_set_width (text_renderer->layout, text_renderer->wrap_width * PANGO_SCALE);
        pango_layout_set_wrap (text_renderer->layout, text_renderer->wrap_mode);
        pango_layout_set_text (text_renderer->layout, text_renderer->text, -1);
        if (xalign == 0.5f)
            pango_layout_set_alignment (text_renderer->layout, PANGO_ALIGN_CENTER);

        pango_layout_get_pixel_size (text_renderer->layout, &text_width, &text_height);
    }

    /* if we have to follow the state manually, we'll need
     * to reserve some space to render the indicator to.
     */
    if (text_renderer->follow_state)
    {
        text_width += 2 * text_renderer->focus_width;
        text_height += 2 * text_renderer->focus_width;
    }

    gtk_cell_renderer_get_padding (cell, &xpad, &ypad);
    /* update width/height */
    if (G_LIKELY (width != NULL))
        *width = text_width + 2 * xpad;
    if (G_LIKELY (height != NULL))
        *height = text_height + 2 * ypad;

    /* update the x/y offsets */
    if (G_LIKELY (cell_area != NULL))
    {
        /*gfloat xalign, yalign;
        gtk_cell_renderer_get_alignment (cell, &xalign, &yalign);*/
        if (G_LIKELY (x_offset != NULL))
        {
            *x_offset = ((gtk_widget_get_direction (widget) == GTK_TEXT_DIR_RTL) ?
                         (1.0 - xalign) : xalign) *
                        (cell_area->width - text_width - (2 * xpad));
            *x_offset = MAX (*x_offset, 0);
        }

        if (G_LIKELY (y_offset != NULL))
        {
            *y_offset = yalign * (cell_area->height - text_height - (2 * ypad));
            *y_offset = MAX (*y_offset, 0);
        }
    }
}
Beispiel #27
0
static GLboolean
glgdGraphNodeDrawLabel(glgdGraph *graph, glgdNode *node)
{
    int                     i;
    GLint                   width;
    GLuint                  texture;
    GLfloat                 s0, s1, t0, t1;
    GLfloat                 a;
    guint32                 alpha, rgb, *t;
    guint8                  *row, *row_end;
    PangoContext            *pangoContext;
    PangoFontDescription    *fontDesc;
    PangoLayout             *layout;
    PangoRectangle          extents;
    FT_Bitmap               bitmap;
    glgdVec2                center, pnt[2];
    glgdStroke              *stroke;
    glgdTexture             *tex;
    
    if (graph && graph->pangoFT2Context)
    {
        stroke = &graph->stroke;
        tex = &graph->textTexture;
        if (tex->width <= 0 || tex->height <= 0)
        {
            glgdTrace(1, "Invalid texture dimension (%d,%d)\n", tex->width,
                tex->height);
                
            return GL_FALSE;
        }

        /* Pango font description */
        width = 10 * _PANGO_SCALE;
        pangoContext = gtk_widget_get_pango_context(graph->gtkWindow);
        fontDesc = pango_context_get_font_description(pangoContext);
        pango_font_description_set_size(fontDesc, PANGO_SCALE * width);
        pango_font_description_set_weight(fontDesc, PANGO_WEIGHT_NORMAL);
        pango_context_set_font_description(graph->pangoFT2Context, fontDesc);
        
        /* Text layout */
        width = (int)graph->dim[0] * _PANGO_SCALE;
        layout = graph->layout;
        pango_layout_set_width(layout, PANGO_SCALE * width);
        pango_layout_set_alignment(layout, PANGO_ALIGN_CENTER);
        pango_layout_set_text(layout, node->label, -1);
        pango_layout_get_extents(layout, NULL, &extents);
        if (extents.width == 0 || extents.height == 0)
        {
            glgdTrace(1, "Invalid extents (%d,%d)\n", extents.width,
                extents.height);
                
            return GL_FALSE;
        }

        /* Bitmap creation */
        bitmap.rows = PANGO_PIXELS(extents.height);
        bitmap.width = PANGO_PIXELS(extents.width);
        if (bitmap.width > tex->width || bitmap.rows > tex->height)
        {
            return GL_FALSE;
        }

        bitmap.pitch = bitmap.width;
        bitmap.buffer = GLGD_MALLOC(bitmap.rows * bitmap.width);
        bitmap.num_grays = 256;
        bitmap.pixel_mode = ft_pixel_mode_grays;

        memset(bitmap.buffer, 0, bitmap.rows * bitmap.width);
        pango_ft2_render_layout(&bitmap, layout, PANGO_PIXELS(-extents.x), 0);

#if !defined(GL_VERSION_1_2) && G_BYTE_ORDER == G_LITTLE_ENDIAN
        rgb =((guint32)(stroke->col[0] * 255.0))         |
            (((guint32)(stroke->col[1] * 255.0)) << 8)   |
            (((guint32)(stroke->col[2] * 255.0)) << 16);
#else
        rgb =(((guint32)(stroke->col[0] * 255.0)) << 24)    |
            (((guint32)(stroke->col[1] * 255.0)) << 16) |
            (((guint32)(stroke->col[2] * 255.0)) << 8);
#endif

        /* Bitmap transfer to <glgdTexture> */
        a = stroke->col[3];
        alpha = (guint32)(255.0 * a);
        row = bitmap.buffer + bitmap.rows * bitmap.width;
        row_end = bitmap.buffer;
        t = (guint32 *)tex->texels;
        if (graph->flags & GLGDGRAPH_FLAG_PANGOBOLD)
        {
            do
            {
                row -= bitmap.width;
                for (i=0; i<bitmap.width; i++)
                {
#if !defined(GL_VERSION_1_2) && G_BYTE_ORDER == G_LITTLE_ENDIAN
                    if (row[i] > 0)
                        *t++ = rgb | (alpha << 24);
                    else
                        *t++ = rgb;
#else
                    if (row[i] > 0)
                        *t++ = rgb | alpha;
                    else
                        *t++ = rgb;
#endif
                }
            }
            while (row != row_end);
        }
        else
        {
            do
            {
                row -= bitmap.width;
                for (i=0; i<bitmap.width; i++)
                {
#if !defined(GL_VERSION_1_2) && G_BYTE_ORDER == G_LITTLE_ENDIAN
                    *t++ = rgb | ((guint32)(a * row[i]) << 24);
#else
                    *t++ = rgb | (guint32)(a * row[i]);
#endif
                }
            }
            while (row != row_end);
        }

        glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
        glBindTexture(GL_TEXTURE_2D, tex->name);
#if !defined(GL_VERSION_1_2)
        glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, bitmap.width, bitmap.rows,
            GL_RGBA, GL_UNSIGNED_BYTE, tex->texels);
#else
        glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, bitmap.width, bitmap.rows,
            GL_RGBA, GL_UNSIGNED_INT_8_8_8_8, tex->texels);
#endif

        /* <glgdTexture> render */
        s0 = 0.0;
        s1 = (GLdouble)bitmap.width / (GLdouble)tex->width;
        t0 = 0.0;
        t1 = (GLdouble)bitmap.rows / (GLdouble)tex->height;

        center[0] = node->pos[0] + GLGD_HALF(graph->dim[0]);
        center[1] = node->pos[1] + GLGD_HALF(graph->dim[1]);
        pnt[0][0] = center[0] - GLGD_HALF(bitmap.width / _PANGO_SCALE);
        pnt[0][1] = center[1] - GLGD_HALF(bitmap.rows / _PANGO_SCALE);
        pnt[1][0] = center[0] + GLGD_HALF(bitmap.width / _PANGO_SCALE);
        pnt[1][1] = center[1] + GLGD_HALF(bitmap.rows / _PANGO_SCALE);
        GLGD_FREE(bitmap.buffer);

        glColor3d(stroke->col[0], stroke->col[1], stroke->col[2]);
        glEnable(GL_TEXTURE_2D);
        glEnable(GL_BLEND);
        glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
        glBindTexture(GL_TEXTURE_2D, tex->name);
        glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
        glBegin(GL_QUADS);
            glTexCoord2f(s0, t0);
            glVertex3f(pnt[0][0], pnt[0][1], 0.0);
            
            glTexCoord2f(s0, t1);
            glVertex3f(pnt[0][0], pnt[1][1], 0.0);
            
            glTexCoord2f(s1, t1);
            glVertex3f(pnt[1][0], pnt[1][1], 0.0);
            
            glTexCoord2f(s1, t0);
            glVertex3f(pnt[1][0], pnt[0][1], 0.0);
        glEnd();
        glDisable(GL_BLEND);
        glDisable(GL_TEXTURE_2D);

        return GL_TRUE;
    }
    
    return GL_FALSE;
}
Beispiel #28
0
static Image *ReadCAPTIONImage(const ImageInfo *image_info,
  ExceptionInfo *exception)
{
  char
    *caption,
    *property;

  const char
    *option;

  DrawInfo
    *draw_info;

  FT_Bitmap
    *canvas;

  Image
    *image;

  PangoAlignment
    align;

  PangoContext
    *context;

  PangoFontDescription
    *description;

  PangoFontMap
    *fontmap;

  PangoGravity
    gravity;

  PangoLayout
    *layout;

  PangoRectangle
    extent;

  PixelPacket
    fill_color;

  RectangleInfo
    page;

  register PixelPacket
    *q;

  register unsigned char
    *p;

  ssize_t
    y;

  /*
    Initialize Image structure.
  */
  assert(image_info != (const ImageInfo *) NULL);
  assert(image_info->signature == MagickSignature);
  if (image_info->debug != MagickFalse)
    (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
      image_info->filename);
  assert(exception != (ExceptionInfo *) NULL);
  assert(exception->signature == MagickSignature);
  image=AcquireImage(image_info);
  (void) ResetImagePage(image,"0x0+0+0");
  /*
    Get context.
  */
  fontmap=(PangoFontMap *) pango_ft2_font_map_new();
  pango_ft2_font_map_set_resolution((PangoFT2FontMap *) fontmap,
    image->x_resolution,image->y_resolution);
  option=GetImageOption(image_info,"caption:hinting");
  pango_ft2_font_map_set_default_substitute((PangoFT2FontMap *) fontmap,
    PangoSubstitute,(char *) option,NULL);
  context=pango_font_map_create_context(fontmap);
  option=GetImageOption(image_info,"caption:language");
  if (option != (const char *) NULL)
    pango_context_set_language(context,pango_language_from_string(option));
  draw_info=CloneDrawInfo(image_info,(DrawInfo *) NULL);
  pango_context_set_base_dir(context,draw_info->direction ==
    RightToLeftDirection ? PANGO_DIRECTION_RTL : PANGO_DIRECTION_LTR);
  switch (draw_info->gravity)
  {
    case NorthGravity: gravity=PANGO_GRAVITY_NORTH; break;
    case WestGravity: gravity=PANGO_GRAVITY_WEST; break;
    case EastGravity: gravity=PANGO_GRAVITY_EAST; break;
    case SouthGravity: gravity=PANGO_GRAVITY_SOUTH; break;
    default: gravity=PANGO_GRAVITY_AUTO; break;
  }
  pango_context_set_base_gravity(context,gravity);
  option=GetImageOption(image_info,"caption:gravity-hint");
  if (option != (const char *) NULL)
    {
      if (LocaleCompare(option,"line") == 0)
        pango_context_set_gravity_hint(context,PANGO_GRAVITY_HINT_LINE);
      if (LocaleCompare(option,"natural") == 0)
        pango_context_set_gravity_hint(context,PANGO_GRAVITY_HINT_NATURAL);
      if (LocaleCompare(option,"strong") == 0)
        pango_context_set_gravity_hint(context,PANGO_GRAVITY_HINT_STRONG);
    }
  /*
    Configure layout.
  */
  layout=pango_layout_new(context);
  option=GetImageOption(image_info,"caption:auto-dir");
  if (option != (const char *) NULL)
    pango_layout_set_auto_dir(layout,1);
  option=GetImageOption(image_info,"caption:ellipsize");
  if (option != (const char *) NULL)
    {
      if (LocaleCompare(option,"end") == 0)
        pango_layout_set_ellipsize(layout,PANGO_ELLIPSIZE_END);
      if (LocaleCompare(option,"middle") == 0)
        pango_layout_set_ellipsize(layout,PANGO_ELLIPSIZE_MIDDLE);
      if (LocaleCompare(option,"none") == 0)
        pango_layout_set_ellipsize(layout,PANGO_ELLIPSIZE_NONE);
      if (LocaleCompare(option,"start") == 0)
        pango_layout_set_ellipsize(layout,PANGO_ELLIPSIZE_START);
    }
  option=GetImageOption(image_info,"caption:justify");
  if ((option != (const char *) NULL) && (IsMagickTrue(option) != MagickFalse))
    pango_layout_set_justify(layout,1);
  option=GetImageOption(image_info,"caption:single-paragraph");
  if ((option != (const char *) NULL) && (IsMagickTrue(option) != MagickFalse))
    pango_layout_set_single_paragraph_mode(layout,1);
  option=GetImageOption(image_info,"caption:wrap");
  if (option != (const char *) NULL)
    {
      if (LocaleCompare(option,"char") == 0)
        pango_layout_set_wrap(layout,PANGO_WRAP_CHAR);
      if (LocaleCompare(option,"word") == 0)
        pango_layout_set_wrap(layout,PANGO_WRAP_WORD);
      if (LocaleCompare(option,"word-char") == 0)
        pango_layout_set_wrap(layout,PANGO_WRAP_WORD_CHAR);
    }
  option=GetImageOption(image_info,"caption:indent");
  if (option != (const char *) NULL)
    pango_layout_set_indent(layout,(StringToLong(option)*image->x_resolution*
      PANGO_SCALE+36)/72);
  switch (draw_info->align)
  {
    case CenterAlign: align=PANGO_ALIGN_CENTER; break;
    case RightAlign: align=PANGO_ALIGN_RIGHT; break;
    case LeftAlign:
    default: align=PANGO_ALIGN_LEFT; break;
  }
  if ((align != PANGO_ALIGN_CENTER) &&
      (draw_info->direction == RightToLeftDirection))
    align=(PangoAlignment) (PANGO_ALIGN_LEFT+PANGO_ALIGN_RIGHT-align);
  pango_layout_set_alignment(layout,align);
  description=pango_font_description_from_string(draw_info->font ==
    (char *) NULL ? "helvetica" : draw_info->font);
  pango_font_description_set_size(description,PANGO_SCALE*draw_info->pointsize);
  pango_layout_set_font_description(layout,description);
  pango_font_description_free(description);
  property=InterpretImageProperties(image_info,image,image_info->filename);
  (void) SetImageProperty(image,"caption",property);
  property=DestroyString(property);
  caption=ConstantString(GetImageProperty(image,"caption"));
  /*
    Render caption.
  */
  option=GetImageOption(image_info,"caption:markup");
  if ((option != (const char *) NULL) && (IsMagickTrue(option) != MagickFalse))
    pango_layout_set_markup(layout,caption,-1);
  else
    pango_layout_set_text(layout,caption,-1);
  pango_layout_context_changed(layout);
  page.x=0;
  page.y=0;
  if (image_info->page != (char *) NULL)
    (void) ParseAbsoluteGeometry(image_info->page,&page);
  if (image->columns == 0)
    {
      pango_layout_get_pixel_extents(layout,NULL,&extent);
      image->columns=extent.x+extent.width;
    }
  else
    {
      image->columns-=2*page.x;
      pango_layout_set_width(layout,(PANGO_SCALE*image->columns*
        image->x_resolution+36.0)/72.0);
    }
  if (image->rows == 0)
    {
      pango_layout_get_pixel_extents(layout,NULL,&extent);
      image->rows=extent.y+extent.height;
    }
  else
    {
      image->rows-=2*page.y;
      pango_layout_set_height(layout,(PANGO_SCALE*image->rows*
        image->y_resolution+36.0)/72.0);
    }
  /*
    Create canvas.
  */
  canvas=(FT_Bitmap *) AcquireMagickMemory(sizeof(*canvas));
  if (canvas == (FT_Bitmap *) NULL)
    {
      draw_info=DestroyDrawInfo(draw_info);
      ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
    }
  canvas->width=image->columns;
  canvas->pitch=(canvas->width+3) & ~3;
  canvas->rows=image->rows;
  canvas->buffer=(unsigned char *) AcquireQuantumMemory(canvas->pitch,
    canvas->rows*sizeof(*canvas->buffer));
  if (canvas->buffer == (unsigned char *) NULL)
    {
      draw_info=DestroyDrawInfo(draw_info);
      canvas=(FT_Bitmap *) RelinquishMagickMemory(canvas);
      ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
    }
  canvas->num_grays=256;
  canvas->pixel_mode=ft_pixel_mode_grays;
  ResetMagickMemory(canvas->buffer,0x00,canvas->pitch*canvas->rows);
  pango_ft2_render_layout(canvas,layout,0,0);
  /*
    Convert caption to image.
  */
  image->columns+=2*page.x;
  image->rows+=2*page.y;
  if (SetImageBackgroundColor(image) == MagickFalse)
    {
      draw_info=DestroyDrawInfo(draw_info);
      canvas->buffer=(unsigned char *) RelinquishMagickMemory(canvas->buffer);
      canvas=(FT_Bitmap *) RelinquishMagickMemory(canvas);
      caption=DestroyString(caption);
      image=DestroyImageList(image);
      return((Image *) NULL);
    }
  p=canvas->buffer;
  for (y=page.y; y < (ssize_t) (image->rows-page.y); y++)
  {
    register ssize_t
      x;

    q=GetAuthenticPixels(image,0,y,image->columns,1,exception);
    if (q == (PixelPacket *) NULL)
      break;
    q+=page.x;
    for (x=page.x; x < (ssize_t) (image->columns-page.x); x++)
    {
      MagickRealType
        fill_opacity;

      (void) GetFillColor(draw_info,x,y,&fill_color);
      fill_opacity=QuantumRange-(*p)/canvas->num_grays*(QuantumRange-
        fill_color.opacity);
      if (draw_info->text_antialias == MagickFalse)
        fill_opacity=fill_opacity >= 0.5 ? 1.0 : 0.0;
      MagickCompositeOver(&fill_color,fill_opacity,q,q->opacity,q);
      p++;
      q++;
    }
    for ( ; x < (ssize_t) ((canvas->width+3) & ~3); x++)
      p++;
  }
  /*
    Relinquish resources.
  */
  draw_info=DestroyDrawInfo(draw_info);
  canvas->buffer=(unsigned char *) RelinquishMagickMemory(canvas->buffer);
  canvas=(FT_Bitmap *) RelinquishMagickMemory(canvas);
  caption=DestroyString(caption);
  return(GetFirstImageInList(image));
}
Beispiel #29
0
int main(int argc, char *argv[])
{
	gdImagePtr im;
	char *text;
	FILE *fp;

	int w,h;
	int margin_x, margin_y;
	gdPangoContext *context;
	gdPangoColors default_colors;
	PangoContext *pangocontext;
	PangoMatrix rotated_matrix = PANGO_MATRIX_INIT;
	PangoLayout *layout;

	gdPangoInit();

	default_colors.fg = gdTrueColorAlpha(0, 255, 255, 0);
	default_colors.bg = gdTrueColorAlpha(255, 255, 255, 0);
	default_colors.alpha = 0;
/*
	text = readFile("russian.txt");
	text = readFile("arabic.txt");
	text = readFile("hebrew.txt");
	text = readFile("german.txt");
 	text = readFile("english.txt");
	text = readFile("japanese.txt");
*/

	text = readFile("english.txt");

	context = gdPangoCreateContext();

	gdPangoSetDpi(context, 96, 96);
	gdPangoSetMinimumSize(context, 800, 200);

	gdPangoSetDefaultColor(context, &default_colors);
	gdPangoSetMarkup(context, text, -1);
	free(text);

	pangocontext = gdPangoGetPangoContext(context);
	layout = gdPangoGetPangoLayout(context);
	pango_context_set_base_dir(pangocontext, PANGO_DIRECTION_LTR);


	w = gdPangoGetLayoutWidth(context);
	h = gdPangoGetLayoutHeight(context);
   margin_x  = 0;
   margin_y  = 0;
   im = gdImageCreateTrueColor(800, 800);
	gdPangoRenderTo(context, im, margin_x, margin_y);

	fp = fopen("c.png", "wb");
	gdImagePng(im, fp);
	fclose(fp);

	gdImageDestroy(im);

	context->angle = -30;

	if (context->angle != 0.0) {
		pango_matrix_rotate (&rotated_matrix, context->angle);
		pango_context_set_matrix(pangocontext, &rotated_matrix);
		pango_layout_set_alignment(layout, PANGO_ALIGN_RIGHT);
		pango_layout_context_changed (layout);
		context->matrix = &rotated_matrix;
	}

	/* Render to a new image, sized for a rotated text */
	im = gdPangoCreateSurfaceDraw(context);
	fp = fopen("d.png", "wb");
	gdImagePng(im, fp);
	fclose(fp);
	gdPangoFreeContext(context);
	gdImageDestroy(im);
	return 0;
}
Beispiel #30
0
static void
marlin_text_renderer_render (GtkCellRenderer    *cell,
                             cairo_t            *cr,
                             GtkWidget          *widget,
                             const GdkRectangle *background_area,
                             const GdkRectangle *cell_area,
                             GtkCellRendererState flags)
{
    MarlinTextRenderer *text_renderer = MARLIN_TEXT_RENDERER (cell);
    GtkStyleContext *context;
    GtkStateFlags state;
    gint x0, x1, y0, y1;
    gint text_width;
    gint text_height;
    gint x_offset;
    gint y_offset;
    gint xpad, ypad;
    gfloat xalign, yalign;
    gboolean selected;

    /* setup the new widget */
    marlin_text_renderer_set_widget (text_renderer, widget);

    state = gtk_widget_get_state_flags (widget);
    if ((flags & GTK_CELL_RENDERER_SELECTED) == GTK_CELL_RENDERER_SELECTED)
    {
        state |= GTK_STATE_FLAG_SELECTED;
    }
    else if ((flags & GTK_CELL_RENDERER_PRELIT) == GTK_CELL_RENDERER_PRELIT
             && gtk_widget_get_state (widget) == GTK_STATE_PRELIGHT)
    {
        state = GTK_STATE_PRELIGHT;
    }
    else
    {
        state = gtk_widget_get_sensitive (widget) ? GTK_STATE_FLAG_NORMAL : GTK_STATE_INSENSITIVE;
    }

    /* render small/normal text depending on the zoom_level */
    if (text_renderer->zoom_level < MARLIN_ZOOM_LEVEL_NORMAL)
    {
        if (text_renderer->follow_prelit && (flags & GTK_CELL_RENDERER_PRELIT) != 0)
            pango_layout_set_attributes (text_renderer->layout, eel_pango_attr_list_small_underline_single ());
        else
            pango_layout_set_attributes (text_renderer->layout, eel_pango_attr_list_small ());
    } else {
        if (text_renderer->follow_prelit && (flags & GTK_CELL_RENDERER_PRELIT) != 0)
            pango_layout_set_attributes (text_renderer->layout, eel_pango_attr_list_underline_single ());
        else
            pango_layout_set_attributes (text_renderer->layout, NULL);
    }

    /* setup the wrapping */
    if (text_renderer->wrap_width < 0)
    {
        pango_layout_set_width (text_renderer->layout, -1);
        pango_layout_set_wrap (text_renderer->layout, PANGO_WRAP_CHAR);
    }
    else
    {
        pango_layout_set_width (text_renderer->layout, text_renderer->wrap_width * PANGO_SCALE);
        pango_layout_set_wrap (text_renderer->layout, text_renderer->wrap_mode);
    }

    /* ellipsize to max lines except for selected or prelit items */
    pango_layout_set_ellipsize (text_renderer->layout, PANGO_ELLIPSIZE_END);
    pango_layout_set_height (text_renderer->layout, -3);
    if ((flags & GTK_CELL_RENDERER_SELECTED) == GTK_CELL_RENDERER_SELECTED ||
            (flags & GTK_CELL_RENDERER_PRELIT) == GTK_CELL_RENDERER_PRELIT) {
        pango_layout_set_ellipsize (text_renderer->layout, PANGO_ELLIPSIZE_NONE);
    }

    gtk_cell_renderer_get_alignment (cell, &xalign, &yalign);
    if (xalign == 0.5f)
        pango_layout_set_alignment (text_renderer->layout, PANGO_ALIGN_CENTER);

    pango_layout_set_text (text_renderer->layout, text_renderer->text, -1);

    /* calculate the real text dimension */
    pango_layout_get_pixel_size (text_renderer->layout, &text_width, &text_height);


    /* take into account the state indicator (required for calculation) */
    if (text_renderer->follow_state)
    {
        text_width += 2 * text_renderer->focus_width;
        text_height += 2 * text_renderer->focus_width;
    }

    gtk_cell_renderer_get_padding (cell, &xpad, &ypad);

    /* calculate the real x-offset */
    x_offset = ((gtk_widget_get_direction (widget) == GTK_TEXT_DIR_RTL) ? (1.0 - xalign) : xalign)
               * (cell_area->width - text_width - (2 * xpad));
    x_offset = MAX (x_offset, 0);

    /* calculate the real y-offset */
    y_offset = yalign * (cell_area->height - text_height - (2 * ypad));
    y_offset = MAX (y_offset, 0);

    context = gtk_widget_get_style_context (gtk_widget_get_parent (widget));
    gtk_style_context_save (context);
    gtk_style_context_set_state (context, state);

    selected = ((flags & GTK_CELL_RENDERER_SELECTED) == GTK_CELL_RENDERER_SELECTED && text_renderer->follow_state);

    /* render the state indicator */
    if (selected || text_renderer->background != NULL)
    {
        /* calculate the text bounding box (including the focus padding/width) */
        x0 = cell_area->x + x_offset;
        y0 = cell_area->y + y_offset;
        x1 = x0 + text_width;
        y1 = y0 + text_height;

        cairo_move_to (cr, x0 + 5, y0);
        cairo_line_to (cr, x1 - 5, y0);
        cairo_curve_to (cr, x1 - 5, y0, x1, y0, x1, y0 + 5);
        cairo_line_to (cr, x1, y1 - 5);
        cairo_curve_to (cr, x1, y1 - 5, x1, y1, x1 - 5, y1);
        cairo_line_to (cr, x0 + 5, y1);
        cairo_curve_to (cr, x0 + 5, y1, x0, y1, x0, y1 - 5);
        cairo_line_to (cr, x0, y0 + 5);
        cairo_curve_to (cr, x0, y0 + 5, x0, y0, x0 + 5, y0);

        GdkRGBA color;

        if(text_renderer->background != NULL && !selected)
        {
            if(!gdk_rgba_parse(&color, text_renderer->background))
            {
                g_critical("Can't parse this color value: %s", text_renderer->background);
                gtk_style_context_get_background_color (context, state, &color);
            }

        }
        else
        {
            gtk_style_context_get_background_color (context, state, &color);
        }
        gdk_cairo_set_source_rgba (cr, &color);
        cairo_fill (cr);
    }

    /* draw the focus indicator */
    if (text_renderer->follow_state && (flags & GTK_CELL_RENDERER_FOCUSED) != 0)
    {
        gtk_render_focus (context, cr, cell_area->x + x_offset, cell_area->y + y_offset, text_width, text_height);
    }

    /* get proper sizing for the layout drawing */
    if (text_renderer->follow_state)
    {
        text_width -= 2 * text_renderer->focus_width;
        text_height -= 2 * text_renderer->focus_width;
        x_offset += text_renderer->focus_width;
        y_offset += text_renderer->focus_width;
    }

    /* draw the text */
    if (xalign == 0.5f)
        x_offset = (cell_area->width - text_renderer->wrap_width)/2;

    gtk_render_layout (context, cr,
                       cell_area->x + x_offset + xpad,
                       cell_area->y + y_offset + ypad,
                       text_renderer->layout);

    gtk_style_context_restore (context);
}