⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 pango-renderer.c

📁 Pango is a library for layout and rendering of text, with an emphasis on internationalization. Pang
💻 C
📖 第 1 页 / 共 3 页
字号:
 **/voidpango_renderer_draw_layout_line (PangoRenderer    *renderer,				 PangoLayoutLine  *line,				 int               x,				 int               y){  int x_off = 0;  int glyph_string_width;  LineState state;  GSList *l;  gboolean got_overall = FALSE;  PangoRectangle overall_rect;  g_return_if_fail (PANGO_IS_RENDERER_FAST (renderer));  /* We only change the matrix if the renderer isn't already   * active.   */  if (!renderer->active_count)    {      PangoContext *context = pango_layout_get_context (line->layout);      pango_renderer_set_matrix (renderer,				 pango_context_get_matrix (context));    }  pango_renderer_activate (renderer);  renderer->priv->line = line;  renderer->priv->line_state = &state;  state.underline = PANGO_UNDERLINE_NONE;  state.strikethrough = FALSE;  for (l = line->runs; l; l = l->next)    {      PangoFontMetrics *metrics;      gint rise;      PangoLayoutRun *run = l->data;      PangoAttrShape *shape_attr;      PangoRectangle ink_rect, *ink = NULL;      PangoRectangle logical_rect, *logical = NULL;      if (run->item->analysis.flags & PANGO_ANALYSIS_FLAG_CENTERED_BASELINE)	logical = &logical_rect;      pango_renderer_prepare_run (renderer, run);      get_item_properties (run->item, &rise, &shape_attr);      if (shape_attr)	{	  ink = &ink_rect;	  logical = &logical_rect;          _pango_shape_get_extents (run->glyphs->num_glyphs,				    &shape_attr->ink_rect,				    &shape_attr->logical_rect,				    ink,				    logical);	  glyph_string_width = logical->width;	}      else	{	  if (renderer->underline != PANGO_UNDERLINE_NONE ||	      renderer->strikethrough)	    {	      ink = &ink_rect;	      logical = &logical_rect;	    }	  if (G_UNLIKELY (ink || logical))	    pango_glyph_string_extents (run->glyphs, run->item->analysis.font,					ink, logical);	  if (logical)	    glyph_string_width = logical_rect.width;	  else	    glyph_string_width = pango_glyph_string_get_width (run->glyphs);	}      state.logical_rect_end = x + x_off + glyph_string_width;      if (run->item->analysis.flags & PANGO_ANALYSIS_FLAG_CENTERED_BASELINE)	{	  gboolean is_hinted = ((logical_rect.y | logical_rect.height) & (PANGO_SCALE - 1)) == 0;	  int adjustment = logical_rect.y + logical_rect.height / 2;	  if (is_hinted)	    adjustment = PANGO_UNITS_ROUND (adjustment);	  rise += adjustment;	}      if (renderer->priv->color_set[PANGO_RENDER_PART_BACKGROUND])	{	  if (!got_overall)	    {	      pango_layout_line_get_extents (line, NULL, &overall_rect);	      got_overall = TRUE;	    }	  pango_renderer_draw_rectangle (renderer,					 PANGO_RENDER_PART_BACKGROUND,					 x + x_off,					 y + overall_rect.y,					 glyph_string_width,					 overall_rect.height);	}      if (shape_attr)	{	  draw_shaped_glyphs (renderer, run->glyphs, shape_attr, x + x_off, y - rise);	}      else	{	  pango_renderer_draw_glyphs (renderer,				      run->item->analysis.font, run->glyphs,				      x + x_off, y - rise);	}      if (renderer->underline != PANGO_UNDERLINE_NONE ||	  renderer->strikethrough)	{	  metrics = pango_font_get_metrics (run->item->analysis.font,					    run->item->analysis.language);	  if (renderer->underline != PANGO_UNDERLINE_NONE)	    add_underline (renderer, &state,metrics,			   x + x_off, y - rise,			   ink, logical);	  if (renderer->strikethrough)	    add_strikethrough (renderer, &state, metrics,			       x + x_off, y - rise,			       ink, logical);	  pango_font_metrics_unref (metrics);	}      if (renderer->underline == PANGO_UNDERLINE_NONE &&	  state.underline != PANGO_UNDERLINE_NONE)	draw_underline (renderer, &state);      if (!renderer->strikethrough && state.strikethrough)	draw_strikethrough (renderer, &state);      x_off += glyph_string_width;    }  /* Finish off any remaining underlines   */  draw_underline (renderer, &state);  draw_strikethrough (renderer, &state);  renderer->priv->line_state = NULL;  renderer->priv->line = NULL;  pango_renderer_deactivate (renderer);}/** * pango_renderer_draw_glyphs: * @renderer: a #PangoRenderer * @font: a #PangoFont * @glyphs: a #PangoGlyphString * @x: X position of left edge of baseline, in user space coordinates *   in Pango units. * @y: Y position of left edge of baseline, in user space coordinates *    in Pango units. * * Draws the glyphs in @glyphs with the specified #PangoRenderer. * * Since: 1.8 **/voidpango_renderer_draw_glyphs (PangoRenderer    *renderer,			    PangoFont        *font,			    PangoGlyphString *glyphs,			    int               x,			    int               y){  g_return_if_fail (PANGO_IS_RENDERER_FAST (renderer));  pango_renderer_activate (renderer);  PANGO_RENDERER_GET_CLASS (renderer)->draw_glyphs (renderer, font, glyphs, x, y);  pango_renderer_deactivate (renderer);}static voidpango_renderer_default_draw_glyphs (PangoRenderer    *renderer,				    PangoFont        *font,				    PangoGlyphString *glyphs,				    int               x,				    int               y){  int i;  int x_position = 0;  for (i = 0; i < glyphs->num_glyphs; i++)    {      PangoGlyphInfo *gi = &glyphs->glyphs[i];      Point p;      to_device (renderer->matrix,		 x + x_position + gi->geometry.x_offset,		 y +              gi->geometry.y_offset,		 &p);      pango_renderer_draw_glyph (renderer, font, gi->glyph, p.x, p.y);      x_position += gi->geometry.width;    }}/** * pango_renderer_draw_rectangle: * @renderer: a #PangoRenderer * @part: type of object this rectangle is part of * @x: X position at which to draw rectangle, in user space coordinates in Pango units * @y: Y position at which to draw rectangle, in user space coordinates in Pango units * @width: width of rectangle in Pango units in user space coordinates * @height: height of rectangle in Pango units in user space coordinates * * Draws an axis-aligned rectangle in user space coordinates with the * specified #PangoRenderer. * * This should be called while @renderer is already active.  Use * pango_renderer_activate() to activate a renderer. * * Since: 1.8 **/voidpango_renderer_draw_rectangle (PangoRenderer   *renderer,			       PangoRenderPart  part,			       int              x,			       int              y,			       int              width,			       int              height){  g_return_if_fail (PANGO_IS_RENDERER_FAST (renderer));  g_return_if_fail (IS_VALID_PART (part));  g_return_if_fail (renderer->active_count > 0);  PANGO_RENDERER_GET_CLASS (renderer)->draw_rectangle (renderer, part, x, y, width, height);}static intcompare_points (const void *a,		const void *b){  const Point *pa = a;  const Point *pb = b;  if (pa->y < pb->y)    return -1;  else if (pa->y > pb->y)    return 1;  else if (pa->x < pb->x)    return -1;  else if (pa->x > pb->x)    return 1;  else    return 0;}static voiddraw_rectangle (PangoRenderer   *renderer,		PangoMatrix     *matrix,		PangoRenderPart  part,		int              x,		int              y,		int              width,		int              height){  Point points[4];  /* Convert the points to device coordinates, and sort   * in ascending Y order. (Ordering by X for ties)   */  to_device (matrix, x, y, &points[0]);  to_device (matrix, x + width, y, &points[1]);  to_device (matrix, x, y + height, &points[2]);  to_device (matrix, x + width, y + height, &points[3]);  qsort (points, 4, sizeof (Point), compare_points);  /* There are essentially three cases. (There is a fourth   * case where trapezoid B is degenerate and we just have   * two triangles, but we don't need to handle it separately.)   *   *     1            2             3   *   *     ______       /\           /\   *    /     /      /A \         /A \   *   /  B  /      /____\       /____\   *  /_____/      /  B  /       \  B  \   *              /_____/         \_____\   *              \ C  /           \ C  /   *               \  /             \  /   *                \/               \/   */  if (points[0].y == points[1].y)    {     /* Case 1 (pure shear) */      pango_renderer_draw_trapezoid (renderer, part,                                      /* B */				     points[0].y, points[0].x, points[1].x,				     points[2].y, points[2].x, points[3].x);    }  else if (points[1].x < points[2].x)    {      /* Case 2 */      double tmp_width = ((points[2].x - points[0].x) * (points[1].y - points[0].y)) / (points[2].y - points[0].y);      double base_width = tmp_width + points[0].x - points[1].x;      pango_renderer_draw_trapezoid (renderer, part,                                      /* A */				     points[0].y, points[0].x, points[0].x,				     points[1].y, points[1].x, points[1].x + base_width);      pango_renderer_draw_trapezoid (renderer, part,                                      /* B */				     points[1].y, points[1].x, points[1].x + base_width,				     points[2].y, points[2].x - base_width, points[2].x);      pango_renderer_draw_trapezoid (renderer, part,                                      /* C */				     points[2].y, points[2].x - base_width, points[2].x,				     points[3].y, points[3].x, points[3].x);    }  else    {      /* case 3 */      double tmp_width = ((points[0].x - points[2].x) * (points[1].y - points[0].y)) / (points[2].y - points[0].y);      double base_width = tmp_width + points[1].x - points[0].x;      pango_renderer_draw_trapezoid (renderer, part,                                     /* A */				     points[0].y, points[0].x, points[0].x,				     points[1].y,  points[1].x - base_width, points[1].x);      pango_renderer_draw_trapezoid (renderer, part,                                     /* B */				     points[1].y, points[1].x - base_width, points[1].x,				     points[2].y, points[2].x, points[2].x + base_width);      pango_renderer_draw_trapezoid (renderer, part,                                     /* C */				     points[2].y, points[2].x, points[2].x + base_width,				     points[3].y, points[3].x, points[3].x);    }}static voidpango_renderer_default_draw_rectangle (PangoRenderer  *renderer,				       PangoRenderPart part,				       int             x,				       int             y,				       int             width,				       int             height){  draw_rectangle (renderer, renderer->matrix, part, x, y, width, height);}/** * pango_renderer_draw_error_underline: * @renderer: a #PangoRenderer * @x: X coordinate of underline, in Pango units in user coordinate system * @y: Y coordinate of underline, in Pango units in user coordinate system * @width: width of underline, in Pango units in user coordinate system * @height: height of underline, in Pango units in user coordinate system * * Draw a squiggly line that approximately covers the given rectangle * in the style of an underline used to indicate a spelling error. * (The width of the underline is rounded to an integer number * of up/down segments and the resulting rectangle is centered * in the original rectangle) * * This should be called while @renderer is already active.  Use * pango_renderer_activate() to activate a renderer. * * Since: 1.8 **/voidpango_renderer_draw_error_underline (PangoRenderer *renderer,				     int            x,				     int            y,				     int            width,				     int            height){  g_return_if_fail (PANGO_IS_RENDERER_FAST (renderer));  g_return_if_fail (renderer->active_count > 0);  PANGO_RENDERER_GET_CLASS (renderer)->draw_error_underline (renderer, x, y, width, height);}/* We are drawing an error underline that looks like one of: * *  /\      /\      /\        /\      /\               - * /  \    /  \    /  \      /  \    /  \              | * \   \  /\   \  /   /      \   \  /\   \             | *  \   \/B \   \/ C /        \   \/B \   \            | height = HEIGHT_SQUARES * square *   \ A \  /\ A \  /          \ A \  /\ A \           | *    \   \/  \   \/            \   \/  \   \          | *     \  /    \  /              \  /    \  /          | *      \/      \/                \/      \/           - *      |---| *    unit_width = (HEIGHT_SQUARES - 1) * square * * To do this conveniently, we work in a coordinate system where A,B,C * are axis aligned rectangles. (If fonts were square, the diagrams * would be clearer) * *             (0,0) *              /\      /\ *             /  \    /  \ *            /\  /\  /\  / *           /  \/  \/  \/ *          /    \  /\  / *      Y axis    \/  \/ *                 \  /\ *                  \/  \ *                       \ X axis * * Note that the long side in this coordinate system is HEIGHT_SQUARES + 1 * units long * * The diagrams above are shown with HEIGHT_SQUARES an integer, but * that is actually incidental; the value 2.5 below seems better than * either HEIGHT_SQUARES=3 (a little long and skinny) or * HEIGHT_SQUARES=2 (a bit short and stubby) */#define HEIGHT_SQUARES 2.5static voidget_total_matrix (PangoMatrix       *total,		  const PangoMatrix *global,		  int                x,		  int                y,		  int                square){  PangoMatrix local;  gdouble scale = 0.5 * square;  /* The local matrix translates from the axis aligned coordinate system   * to the original user space coordinate system.   */  local.xx = scale;  local.xy = - scale;  local.yx = scale;  local.yy = scale;  local.x0 = 0;  local.y0 = 0;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -