Exemple #1
0
void 
fo_doc_cairo_do_line_callbacks (cairo_t         *cr,
				PangoLayoutLine *line,
				gint             x, 
				gint             y)
{
  GSList *run_list;
  PangoRectangle overall_rect;
  PangoRectangle logical_rect;
  gint      x_off = 0;

  pango_layout_line_get_extents (line,
				 NULL,
				 &overall_rect);
  
  run_list = line->runs;
  while (run_list)
    {
      PangoLayoutRun *run = run_list->data;
      
      pango_glyph_string_extents (run->glyphs,
				  run->item->analysis.font,
				  NULL,
				  &logical_rect);

      fo_doc_cairo_do_run_callbacks (cr,
				  run,
				  x + x_off,
				  y);

      x_off += logical_rect.width;
      run_list = run_list->next;
    }
}
int GtkPaintContext::stringWidth(const char *str, int len) const {
	if (myContext == 0) {
		return 0;
	}

	if (!g_utf8_validate(str, len, 0)) {
		return 0;
	}

	pango_shape(str, len, &myAnalysis, myString);
	PangoRectangle logicalRectangle;
	pango_glyph_string_extents(myString, myAnalysis.font, 0, &logicalRectangle);
	return (logicalRectangle.width + PANGO_SCALE / 2) / PANGO_SCALE;
}
static VALUE
rglyph_extents(int argc, VALUE *argv, VALUE self)
{
    VALUE font, start_index, end_index;
    PangoRectangle ink_rect;
    PangoRectangle logical_rect;

    rb_scan_args(argc, argv, "12", &font, &start_index, &end_index);

    if (NIL_P(start_index)){
        pango_glyph_string_extents(_SELF(self), 
                                   PANGO_FONT(RVAL2GOBJ(font)),
                                   &ink_rect, &logical_rect);
    } else {
        pango_glyph_string_extents_range(_SELF(self), 
                                         NUM2INT(start_index), NUM2INT(end_index),
                                         PANGO_FONT(RVAL2GOBJ(font)),
                                         &ink_rect, &logical_rect);
    }

    return rb_assoc_new(BOXED2RVAL(&ink_rect, PANGO_TYPE_RECTANGLE),
                        BOXED2RVAL(&logical_rect, PANGO_TYPE_RECTANGLE));
}
Exemple #4
0
static void
pango_draw_line (XftDraw *draw, Window id, GC gc, XftColor *xft_color,
		 PangoLayoutLine *line, int x, int y)
{
    GSList *p;

    for (p = line->runs; p != NULL; p = p->next)
    {
	PangoLayoutRun *run = p->data;
	PangoFont *font = run->item->analysis.font;
	PangoGlyphString *glyphs = run->glyphs;
	PangoRectangle rect;

	pango_glyph_string_extents (glyphs, font, NULL, &rect);
#ifdef HAVE_PANGO_XFT
	if (PANGO_XFT_IS_FONT (font))
	    pango_xft_render (draw, xft_color, font, glyphs, x, y);
#else
	    pango_x_render (dpy, id, gc, font, glyphs, x, y);
#endif

	x += rect.width / PANGO_SCALE;
    }
}
/*!
    Draw a line.

    @param *context [in] Context
    @param *surface [out] Surface to draw on it
    @param *line [in] Innter variable of Pango
    @param x [in] X location of line
    @param y [in] Y location of line
    @param height [in] Height of line
    @param baseline [in] Rise / sink of line (for super/subscript)
*/
static void
drawLine(
    SDLPango_Context *context,
    SDL_Surface *surface,
    PangoLayoutLine *line,
    gint x, 
    gint y, 
    gint height,
    gint baseline)
{
    GSList *tmp_list = line->runs;
    PangoColor fg_color, bg_color;
    PangoRectangle logical_rect;
    PangoRectangle ink_rect;
    int x_off = 0;

    while (tmp_list) {
	SDLPango_Matrix color_matrix = context->color_matrix;
	PangoUnderline uline = PANGO_UNDERLINE_NONE;
	gboolean strike, fg_set, bg_set, shape_set;
	gint rise, risen_y;
	PangoLayoutRun *run = tmp_list->data;
	SDL_Rect d_rect;

	tmp_list = tmp_list->next;

	getItemProperties(run->item,
	    &uline, &strike, &rise,
	    &fg_color, &fg_set, &bg_color, &bg_set,
	    &shape_set, &ink_rect, &logical_rect);

	risen_y = y + baseline - PANGO_PIXELS (rise);

	if(fg_set) {
	    color_matrix.m[0][1] = (Uint8)(fg_color.red >> 8);
	    color_matrix.m[1][1] = (Uint8)(fg_color.green >> 8);
	    color_matrix.m[2][1] = (Uint8)(fg_color.blue >> 8);
	    color_matrix.m[3][1] = 255;
	    if(color_matrix.m[3][0] == 0) {
		color_matrix.m[0][0] = (Uint8)(fg_color.red >> 8);
		color_matrix.m[1][0] = (Uint8)(fg_color.green >> 8);
		color_matrix.m[2][0] = (Uint8)(fg_color.blue >> 8);
	    }
	}

	if (bg_set) {
	    color_matrix.m[0][0] = (Uint8)(bg_color.red >> 8);
	    color_matrix.m[1][0] = (Uint8)(bg_color.green >> 8);
	    color_matrix.m[2][0] = (Uint8)(bg_color.blue >> 8);
	    color_matrix.m[3][0] = 255;
	}

	if(! shape_set) {
	    if (uline == PANGO_UNDERLINE_NONE)
		pango_glyph_string_extents (run->glyphs, run->item->analysis.font,
					    NULL, &logical_rect);
	    else
		pango_glyph_string_extents (run->glyphs, run->item->analysis.font,
					    &ink_rect, &logical_rect);

	    d_rect.w = (Uint16)PANGO_PIXELS(logical_rect.width);
	    d_rect.h = (Uint16)height;
	    d_rect.x = (Uint16)(x + PANGO_PIXELS (x_off));
	    d_rect.y = (Uint16)(risen_y - baseline);

	    if((! context->tmp_ftbitmap) || d_rect.w + d_rect.x > context->tmp_ftbitmap->width
		|| d_rect.h + d_rect.y > context->tmp_ftbitmap->rows)
	    {
		freeFTBitmap(context->tmp_ftbitmap);
		context->tmp_ftbitmap = createFTBitmap(d_rect.w + d_rect.x, d_rect.h + d_rect.y);
	    }

	    drawGlyphString(context, surface, 
		&color_matrix, 
		run->item->analysis.font, run->glyphs, &d_rect, baseline);
	}
        switch (uline) {
	case PANGO_UNDERLINE_NONE:
	    break;
	case PANGO_UNDERLINE_DOUBLE:
	    drawHLine(surface, &color_matrix,
		risen_y + 4,
		x + PANGO_PIXELS (x_off + ink_rect.x),
		x + PANGO_PIXELS (x_off + ink_rect.x + ink_rect.width));
	  /* Fall through */
	case PANGO_UNDERLINE_SINGLE:
	    drawHLine(surface, &color_matrix,
		risen_y + 2,
		x + PANGO_PIXELS (x_off + ink_rect.x),
		x + PANGO_PIXELS (x_off + ink_rect.x + ink_rect.width));
	    break;
	case PANGO_UNDERLINE_ERROR:
	    {
		int point_x;
		int counter = 0;
		int end_x = x + PANGO_PIXELS (x_off + ink_rect.x + ink_rect.width);

		for (point_x = x + PANGO_PIXELS (x_off + ink_rect.x) - 1;
		    point_x <= end_x;
		    point_x += 2)
		{
		    if (counter)
			drawHLine(surface, &color_matrix,
			    risen_y + 2,
			    point_x, MIN (point_x + 1, end_x));
		    else
			drawHLine(surface, &color_matrix,
			    risen_y + 3,
			    point_x, MIN (point_x + 1, end_x));
    		
		    counter = (counter + 1) % 2;
		}
	    }
	    break;
	case PANGO_UNDERLINE_LOW:
	    drawHLine(surface, &color_matrix,
		risen_y + PANGO_PIXELS (ink_rect.y + ink_rect.height),
		x + PANGO_PIXELS (x_off + ink_rect.x),
		x + PANGO_PIXELS (x_off + ink_rect.x + ink_rect.width));
	  break;
	}

        if (strike)
	    drawHLine(surface, &color_matrix,
		risen_y + PANGO_PIXELS (logical_rect.y + logical_rect.height / 2),
		x + PANGO_PIXELS (x_off + logical_rect.x),
		x + PANGO_PIXELS (x_off + logical_rect.x + logical_rect.width));

	x_off += logical_rect.width;
    }
Exemple #6
0
void
x11_draw_layout_line_with_colors( Drawable         drawable,
                                  GC               gc,
                                  int              x,
                                  int              y,
                                  PangoLayoutLine *line,
                                  wxColour        &colour )
{
    PangoRectangle overall_rect;
    PangoRectangle logical_rect;
    PangoRectangle ink_rect;
    PangoContext *context;
    gint x_off = 0;
    gint rise = 0;

    context = pango_layout_get_context (line->layout);

    pango_layout_line_get_extents (line,NULL, &overall_rect);

    GSList *tmp_list = line->runs;
    while (tmp_list)
    {
        PangoUnderline uline = PANGO_UNDERLINE_NONE;
        PangoLayoutRun *run = (PangoLayoutRun *) tmp_list->data;
        PangoColor fg_color, bg_color;
        gboolean strike, fg_set, bg_set, shape_set;
        gint risen_y;

        tmp_list = tmp_list->next;

        x11_pango_get_item_properties (run->item, &uline,
            &strike, &rise,  &fg_color, &fg_set, &bg_color, &bg_set,
            &shape_set, &ink_rect, &logical_rect);

        /* we subtract the rise because X coordinates are upside down */
        risen_y = y - rise / PANGO_SCALE;

        if (!shape_set)
        {
            if (uline == PANGO_UNDERLINE_NONE)
                pango_glyph_string_extents (run->glyphs, run->item->analysis.font, NULL, &logical_rect);
            else
                pango_glyph_string_extents (run->glyphs, run->item->analysis.font, &ink_rect, &logical_rect);
        }

#if 0
        XDrawRectangle( drawable, gc, TRUE,
                  x + (x_off + logical_rect.x) / PANGO_SCALE,
                  risen_y + overall_rect.y / PANGO_SCALE,
                  logical_rect.width / PANGO_SCALE,
                  overall_rect.height / PANGO_SCALE);
#endif

        if (!shape_set)
        {
            int gx = x + x_off / PANGO_SCALE;
            int gy = risen_y;

            x11_draw_glyphs( drawable, gc, run->item->analysis.font, gx, gy, run->glyphs, colour );
        }

        if (uline ==  PANGO_UNDERLINE_SINGLE)
        {
            XDrawLine( wxGlobalDisplay(), drawable, gc,
              x + (x_off + ink_rect.x) / PANGO_SCALE - 1,
                          risen_y + 1,
              x + (x_off + ink_rect.x + ink_rect.width) / PANGO_SCALE,
                         risen_y + 1);
        }

        x_off += logical_rect.width;
    }
}
Exemple #7
0
static void
render_layout_line (GdkDrawable        *drawable,
                    GtkTextRenderState *render_state,
                    PangoLayoutLine    *line,
                    GSList            **shaped_pointer,
                    int                 x,
                    int                 y,
                    gboolean            selected,
                    GList             **widgets)
{
  GSList *tmp_list = line->runs;
  PangoRectangle overall_rect;
  PangoRectangle logical_rect;
  PangoRectangle ink_rect;
  gint x_off = 0;
  GdkGC *fg_gc;
  
  pango_layout_line_get_extents (line, NULL, &overall_rect);

  while (tmp_list)
    {
      PangoLayoutRun *run = tmp_list->data;
      GtkTextAppearance *appearance;
      gint risen_y;
      gint shaped_width_pixels = 0;
      gboolean need_ink = FALSE;
      
      tmp_list = tmp_list->next;

      get_item_properties (run->item, &appearance);

      g_assert (appearance != NULL);
      
      risen_y = y - PANGO_PIXELS (appearance->rise);
      
      if (selected)
        {
	  if (GTK_WIDGET_HAS_FOCUS (render_state->widget))
	    fg_gc = render_state->widget->style->text_gc[GTK_STATE_SELECTED];
	  else
	    fg_gc = render_state->widget->style->text_gc [GTK_STATE_ACTIVE];
        }
      else
        {
          gtk_text_render_state_update (render_state, appearance);
          
          fg_gc = render_state->fg_gc;
        }
      
      if (appearance->underline != PANGO_UNDERLINE_NONE ||
          appearance->strikethrough)
        need_ink = TRUE;
      
      if (appearance->is_text)
        {
          if (need_ink)
            pango_glyph_string_extents (run->glyphs, run->item->analysis.font,
                                        &ink_rect, &logical_rect);
          else
            pango_glyph_string_extents (run->glyphs, run->item->analysis.font,
                                        NULL, &logical_rect);
        }
      else
        {
          if (need_ink)
            get_shape_extents (run, &ink_rect, &logical_rect);
          else
            get_shape_extents (run, NULL, &logical_rect);
        }
      
      if (appearance->draw_bg && !selected)
        gdk_draw_rectangle (drawable, render_state->bg_gc, TRUE,
                            x + PANGO_PIXELS (x_off) + PANGO_PIXELS (logical_rect.x),
                            risen_y + PANGO_PIXELS (logical_rect.y),
                            PANGO_PIXELS (logical_rect.width),
                            PANGO_PIXELS (logical_rect.height));

      if (appearance->is_text)
        gdk_draw_glyphs (drawable, fg_gc,
                         run->item->analysis.font,
                         x + PANGO_PIXELS (x_off),
                         risen_y, run->glyphs);
      else
        {
          GObject *shaped = (*shaped_pointer)->data;

          *shaped_pointer = (*shaped_pointer)->next;

          if (shaped == NULL)
            {
              /* This happens if we have an empty widget anchor. Draw
               * something empty-looking.
               */
              GdkRectangle shape_rect, draw_rect;

              shape_rect.x = x + x_off / PANGO_SCALE;
              shape_rect.y = risen_y - PANGO_PIXELS (logical_rect.height);
              shape_rect.width = PANGO_PIXELS (logical_rect.width);
              shape_rect.height = PANGO_PIXELS (logical_rect.height);

              if (gdk_rectangle_intersect (&shape_rect, &render_state->clip_rect,
                                           &draw_rect))
                {
                  gdk_draw_rectangle (drawable, render_state->fg_gc,
                                      FALSE, shape_rect.x, shape_rect.y,
                                      shape_rect.width, shape_rect.height);

                  gdk_draw_line (drawable, render_state->fg_gc,
                                 shape_rect.x, shape_rect.y,
                                 shape_rect.x + shape_rect.width,
                                 shape_rect.y + shape_rect.height);

                  gdk_draw_line (drawable, render_state->fg_gc,
                                 shape_rect.x + shape_rect.width, shape_rect.y,
                                 shape_rect.x,
                                 shape_rect.y + shape_rect.height);
                }

              shaped_width_pixels = shape_rect.width;
            }
          else if (GDK_IS_PIXBUF (shaped))
            {
              gint width, height;
              GdkRectangle pixbuf_rect, draw_rect;
              GdkPixbuf *pixbuf;

              pixbuf = GDK_PIXBUF (shaped);
              
              width = gdk_pixbuf_get_width (pixbuf);
              height = gdk_pixbuf_get_height (pixbuf);

              pixbuf_rect.x = x + x_off / PANGO_SCALE;
              pixbuf_rect.y = risen_y - height;
              pixbuf_rect.width = width;
              pixbuf_rect.height = height;

              if (gdk_rectangle_intersect (&pixbuf_rect, &render_state->clip_rect,
                                           &draw_rect))
                {
                  gdk_draw_pixbuf (drawable,
				   render_state->fg_gc,
				   pixbuf,
				   draw_rect.x - pixbuf_rect.x,
				   draw_rect.y - pixbuf_rect.y,
				   draw_rect.x, draw_rect.y,
				   draw_rect.width,
				   draw_rect.height,
				   GDK_RGB_DITHER_NORMAL,
				   0, 0);
                }

              shaped_width_pixels = width;
            }
          else if (GTK_IS_WIDGET (shaped))
            {
              GtkWidget *widget;
              
              widget = GTK_WIDGET (shaped);
              
              shaped_width_pixels = widget->allocation.width;

              if (widgets)
                {
                  g_object_ref (widget);
                  *widgets = g_list_prepend (*widgets, widget);
                }
            }
          else
            g_assert_not_reached (); /* not a pixbuf or widget */
        }

      switch (appearance->underline)
        {
        case PANGO_UNDERLINE_NONE:
          break;
        case PANGO_UNDERLINE_DOUBLE:
          g_assert (need_ink);
          gdk_draw_line (drawable, fg_gc,
                         x + (x_off + ink_rect.x) / PANGO_SCALE - 1,
                         risen_y + 3,
                         x + (x_off + ink_rect.x + ink_rect.width) / PANGO_SCALE,
                         risen_y + 3);
          /* Fall through */
        case PANGO_UNDERLINE_SINGLE:
          g_assert (need_ink);
          gdk_draw_line (drawable, fg_gc,
                         x + (x_off + ink_rect.x) / PANGO_SCALE - 1,
                         risen_y + 1,
                         x + (x_off + ink_rect.x + ink_rect.width) / PANGO_SCALE,
                         risen_y + 1);
          break;
        case PANGO_UNDERLINE_LOW:
          g_assert (need_ink);
          gdk_draw_line (drawable, fg_gc,
                         x + (x_off + ink_rect.x) / PANGO_SCALE - 1,
                         risen_y + (ink_rect.y + ink_rect.height) / PANGO_SCALE + 1,
                         x + (x_off + ink_rect.x + ink_rect.width) / PANGO_SCALE,
                         risen_y + (ink_rect.y + ink_rect.height) / PANGO_SCALE + 1);
          break;
        }

      if (appearance->strikethrough)
        {          
          gint strikethrough_y = risen_y + (0.3 * logical_rect.y) / PANGO_SCALE;

          g_assert (need_ink);
          
          gdk_draw_line (drawable, fg_gc,
                         x + (x_off + ink_rect.x) / PANGO_SCALE - 1, strikethrough_y,
                         x + (x_off + ink_rect.x + ink_rect.width) / PANGO_SCALE, strikethrough_y);
        }

      if (appearance->is_text)
        x_off += logical_rect.width;
      else
        x_off += shaped_width_pixels * PANGO_SCALE;
    }
}
static void 
print_pango_layout_line (GnomePrintContext *gpc, PangoLayoutLine *line)
{
	GSList *tmp_list = line->runs;
	PangoRectangle overall_rect;
	PangoRectangle logical_rect;
	PangoRectangle ink_rect;
	gint x_off = 0;
	
	gnome_print_gsave (gpc);

	current_point_to_origin (gpc);

	pango_layout_line_get_extents (line, NULL, &overall_rect);
	
	while (tmp_list) {
		ItemProperties properties;
		PangoLayoutRun *run = tmp_list->data;
		
		tmp_list = tmp_list->next;
		
		get_item_properties (run->item, &properties);

		if (properties.shape_logical_rect) {
			x_off += properties.shape_logical_rect->width;
			continue;
		}

		gnome_print_gsave (gpc);

		translate (gpc, x_off, properties.rise);
		gnome_print_moveto (gpc, 0, 0);

		if (properties.uline == PANGO_UNDERLINE_NONE && !properties.strikethrough)
			pango_glyph_string_extents (run->glyphs, run->item->analysis.font,
						    NULL, &logical_rect);
		else
			pango_glyph_string_extents (run->glyphs, run->item->analysis.font,
						    &ink_rect, &logical_rect);
		
		if (properties.bg_color) {
			gnome_print_gsave (gpc);

			gnome_print_setrgbcolor (gpc,
						 (gdouble) properties.bg_color->red / 0xFFFF,
						 (gdouble) properties.bg_color->green / 0xFFFF,
						 (gdouble) properties.bg_color->blue / 0xFFFF);

			rect_filled (gpc,
				     logical_rect.x,    - overall_rect.y - overall_rect.height,
				     logical_rect.width,  overall_rect.height);

			gnome_print_grestore (gpc);
		}

		if (properties.fg_color) {
			gnome_print_setrgbcolor (gpc,
						 (gdouble) properties.fg_color->red / 0xFFFF,
						 (gdouble) properties.fg_color->green / 0xFFFF,
						 (gdouble) properties.fg_color->blue / 0xFFFF);
		}

		gnome_print_pango_glyph_string (gpc, run->item->analysis.font, run->glyphs);
		
		if (properties.uline != PANGO_UNDERLINE_NONE || properties.strikethrough) {
			PangoFontMetrics *metrics = pango_font_get_metrics (run->item->analysis.font,
									    run->item->analysis.language);
	      
			if (properties.uline != PANGO_UNDERLINE_NONE)
				draw_underline (gpc, metrics,
						properties.uline,
						ink_rect.x,
						ink_rect.width,
						ink_rect.y + ink_rect.height);
			
			if (properties.strikethrough)
				draw_strikethrough (gpc, metrics,
						    ink_rect.x,
						    ink_rect.width);

			pango_font_metrics_unref (metrics);
		}
		
		gnome_print_grestore (gpc);
	
		x_off += logical_rect.width;
	}
	
	gnome_print_grestore (gpc);
}