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

📄 pango-renderer.c

📁 Pango is a library for layout and rendering of text, with an emphasis on internationalization. Pang
💻 C
📖 第 1 页 / 共 3 页
字号:
/* Pango * pango-renderer.h: Base class for rendering * * Copyright (C) 2004 Red Hat, Inc. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.	 See the GNU * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public * License along with this library; if not, write to the * Free Software Foundation, Inc., 59 Temple Place - Suite 330, * Boston, MA 02111-1307, USA. */#include <config.h>#include <stdlib.h>#include "pango-renderer.h"#include "pango-impl-utils.h"#define N_RENDER_PARTS 4#define PANGO_IS_RENDERER_FAST(renderer) (renderer != NULL)#define IS_VALID_PART(part) ((guint)part < N_RENDER_PARTS)typedef struct _LineState LineState;typedef struct _Point Point;struct _Point{  double x, y;};struct _LineState{  PangoUnderline underline;  PangoRectangle underline_rect;  gboolean strikethrough;  PangoRectangle strikethrough_rect;  int logical_rect_end;};struct _PangoRendererPrivate{  PangoColor color[N_RENDER_PARTS];  gboolean color_set[N_RENDER_PARTS];  PangoLayoutLine *line;  LineState *line_state;};static void pango_renderer_finalize                     (GObject          *gobject);static void pango_renderer_default_draw_glyphs          (PangoRenderer    *renderer,							 PangoFont        *font,							 PangoGlyphString *glyphs,							 int               x,							 int               y);static void pango_renderer_default_draw_rectangle       (PangoRenderer    *renderer,							 PangoRenderPart   part,							 int               x,							 int               y,							 int               width,							 int               height);static void pango_renderer_default_draw_error_underline (PangoRenderer    *renderer,							 int               x,							 int               y,							 int               width,							 int               height);static void pango_renderer_default_prepare_run          (PangoRenderer    *renderer,							 PangoLayoutRun   *run);static void pango_renderer_prepare_run (PangoRenderer  *renderer,					PangoLayoutRun *run);static voidto_device (PangoMatrix *matrix,	   double       x,	   double       y,	   Point       *result){  if (matrix)    {      result->x = (x * matrix->xx + y * matrix->xy) / PANGO_SCALE + matrix->x0;      result->y = (x * matrix->yx + y * matrix->yy) / PANGO_SCALE + matrix->y0;    }  else    {      result->x = x / PANGO_SCALE;      result->y = y / PANGO_SCALE;    }}G_DEFINE_ABSTRACT_TYPE (PangoRenderer, pango_renderer, G_TYPE_OBJECT)static voidpango_renderer_class_init (PangoRendererClass *klass){  GObjectClass *gobject_class = G_OBJECT_CLASS (klass);  klass->draw_glyphs = pango_renderer_default_draw_glyphs;  klass->draw_rectangle = pango_renderer_default_draw_rectangle;  klass->draw_error_underline = pango_renderer_default_draw_error_underline;  klass->prepare_run = pango_renderer_default_prepare_run;  gobject_class->finalize = pango_renderer_finalize;  g_type_class_add_private (gobject_class, sizeof (PangoRendererPrivate));}static voidpango_renderer_init (PangoRenderer *renderer){  renderer->priv = G_TYPE_INSTANCE_GET_PRIVATE (renderer,						PANGO_TYPE_RENDERER,						PangoRendererPrivate);  renderer->matrix = NULL;}static voidpango_renderer_finalize (GObject *gobject){  PangoRenderer *renderer = PANGO_RENDERER (gobject);  if (renderer->matrix)    pango_matrix_free (renderer->matrix);}/** * pango_renderer_draw_layout: * @renderer: a #PangoRenderer * @layout: a #PangoLayout * @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 @layout with the specified #PangoRenderer. * * Since: 1.8 **/voidpango_renderer_draw_layout (PangoRenderer    *renderer,			    PangoLayout      *layout,			    int               x,			    int               y){  PangoLayoutIter *iter;  g_return_if_fail (PANGO_IS_RENDERER (renderer));  g_return_if_fail (PANGO_IS_LAYOUT (layout));  /* We only change the matrix if the renderer isn't already   * active.   */  if (!renderer->active_count)    {      PangoContext *context = pango_layout_get_context (layout);      pango_renderer_set_matrix (renderer,				 pango_context_get_matrix (context));    }  pango_renderer_activate (renderer);  iter = pango_layout_get_iter (layout);  do    {      PangoRectangle   logical_rect;      PangoLayoutLine *line;      int              baseline;      line = pango_layout_iter_get_line_readonly (iter);      pango_layout_iter_get_line_extents (iter, NULL, &logical_rect);      baseline = pango_layout_iter_get_baseline (iter);      pango_renderer_draw_layout_line (renderer,				       line,				       x + logical_rect.x,				       y + baseline);    }  while (pango_layout_iter_next_line (iter));  pango_layout_iter_free (iter);  pango_renderer_deactivate (renderer);}static voiddraw_underline (PangoRenderer *renderer,		LineState     *state){  PangoRectangle *rect = &state->underline_rect;  PangoUnderline underline = state->underline;  state->underline = PANGO_UNDERLINE_NONE;  switch (underline)    {    case PANGO_UNDERLINE_NONE:      break;    case PANGO_UNDERLINE_DOUBLE:      pango_renderer_draw_rectangle (renderer,				     PANGO_RENDER_PART_UNDERLINE,				     rect->x,				     rect->y + 2 * rect->height,				     rect->width,				     rect->height);      /* Fall through */    case PANGO_UNDERLINE_SINGLE:    case PANGO_UNDERLINE_LOW:      pango_renderer_draw_rectangle (renderer,				     PANGO_RENDER_PART_UNDERLINE,				     rect->x,				     rect->y,				     rect->width,				     rect->height);      break;    case PANGO_UNDERLINE_ERROR:      pango_renderer_draw_error_underline (renderer,					   rect->x,					   rect->y,					   rect->width,					   3 * rect->height);      break;    }}static voiddraw_strikethrough (PangoRenderer *renderer,		    LineState     *state){  PangoRectangle *rect = &state->strikethrough_rect;  gboolean strikethrough = state->strikethrough;  state->strikethrough = FALSE;  if (strikethrough)    pango_renderer_draw_rectangle (renderer,				   PANGO_RENDER_PART_STRIKETHROUGH,				   rect->x,				   rect->y,				   rect->width,				   rect->height);}static voidhandle_line_state_change (PangoRenderer  *renderer,			  PangoRenderPart part){  LineState *state = renderer->priv->line_state;  if (!state)    return;  if (part == PANGO_RENDER_PART_UNDERLINE &&      state->underline != PANGO_UNDERLINE_NONE)    {      PangoRectangle *rect = &state->underline_rect;      rect->width = state->logical_rect_end - rect->x;      draw_underline (renderer, state);      state->underline = renderer->underline;      rect->x = state->logical_rect_end;      rect->width = 0;    }  if (part == PANGO_RENDER_PART_STRIKETHROUGH &&      state->strikethrough)    {      PangoRectangle *rect = &state->strikethrough_rect;      rect->width = state->logical_rect_end - rect->x;      draw_strikethrough (renderer, state);      state->strikethrough = renderer->strikethrough;      rect->x = state->logical_rect_end;      rect->width = 0;    }}static voidadd_underline (PangoRenderer    *renderer,	       LineState        *state,	       PangoFontMetrics *metrics,	       int               base_x,	       int               base_y,	       PangoRectangle   *ink_rect,	       PangoRectangle   *logical_rect){  PangoRectangle *current_rect = &state->underline_rect;  PangoRectangle new_rect;  int underline_thickness = pango_font_metrics_get_underline_thickness (metrics);  int underline_position = pango_font_metrics_get_underline_position (metrics);  new_rect.x = base_x + logical_rect->x;  new_rect.width = logical_rect->width;  new_rect.height = underline_thickness;  new_rect.y = base_y;  switch (renderer->underline)    {    case PANGO_UNDERLINE_NONE:      g_assert_not_reached ();      break;    case PANGO_UNDERLINE_SINGLE:    case PANGO_UNDERLINE_DOUBLE:    case PANGO_UNDERLINE_ERROR:      new_rect.y -= underline_position;      break;    case PANGO_UNDERLINE_LOW:      new_rect.y += ink_rect->y + ink_rect->height + underline_thickness;      break;    }  if (renderer->underline == state->underline &&      new_rect.y == current_rect->y &&      new_rect.height == current_rect->height)    {      current_rect->width = new_rect.x + new_rect.width - current_rect->x;    }  else    {      draw_underline (renderer, state);      *current_rect = new_rect;      state->underline = renderer->underline;    }}static voidadd_strikethrough (PangoRenderer    *renderer,		   LineState        *state,		   PangoFontMetrics *metrics,		   int               base_x,		   int               base_y,		   PangoRectangle   *ink_rect,		   PangoRectangle   *logical_rect){  PangoRectangle *current_rect = &state->strikethrough_rect;  PangoRectangle new_rect;  int strikethrough_thickness = pango_font_metrics_get_strikethrough_thickness (metrics);  int strikethrough_position = pango_font_metrics_get_strikethrough_position (metrics);  new_rect.x = base_x + logical_rect->x;  new_rect.width = logical_rect->width;  new_rect.y = base_y - strikethrough_position;  new_rect.height = strikethrough_thickness;  if (state->strikethrough &&      new_rect.y == current_rect->y &&      new_rect.height == current_rect->height)    {      current_rect->width = new_rect.x + new_rect.width - current_rect->x;    }  else    {      draw_strikethrough (renderer, state);      *current_rect = new_rect;      state->strikethrough = TRUE;    }}static voidget_item_properties (PangoItem       *item,		     gint            *rise,		     PangoAttrShape **shape_attr){  GSList *l;  if (rise)    *rise = 0;  if (shape_attr)    *shape_attr = NULL;  for (l = item->analysis.extra_attrs; l; l = l->next)    {      PangoAttribute *attr = l->data;      switch (attr->klass->type)	{	case PANGO_ATTR_SHAPE:	  if (shape_attr)	    *shape_attr = (PangoAttrShape *)attr;	  break;	case PANGO_ATTR_RISE:	  if (rise)	    *rise = ((PangoAttrInt *)attr)->value;	  break;	default:	  break;	}    }}static voiddraw_shaped_glyphs (PangoRenderer    *renderer,		    PangoGlyphString *glyphs,		    PangoAttrShape   *attr,		    int               x,		    int               y){  PangoRendererClass *class = PANGO_RENDERER_GET_CLASS (renderer);  int i;  if (!class->draw_shape)    return;  for (i = 0; i < glyphs->num_glyphs; i++)    {      PangoGlyphInfo *gi = &glyphs->glyphs[i];      class->draw_shape (renderer, attr, x, y);      x += gi->geometry.width;    }}/** * pango_renderer_draw_layout_line: * @renderer: a #PangoRenderer * @line: a #PangoLayoutLine * @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 @line with the specified #PangoRenderer. * * Since: 1.8

⌨️ 快捷键说明

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