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

📄 pangoxft-render.c

📁 GTK+-2.0源码之pango-1.15.6.tar.gz
💻 C
📖 第 1 页 / 共 2 页
字号:
/* Pango * pangoxft-render.c: Rendering routines for the Xft library * * Copyright (C) 2004 Red Hat Software * * 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 <math.h>#include "pangoxft-render.h"#include "pangoxft-private.h"enum {  PROP_0,  PROP_DISPLAY,  PROP_SCREEN};struct _PangoXftRendererPrivate{  PangoColor default_color;  guint16 alpha;  Picture src_picture;  Picture dest_picture;  XRenderPictFormat *mask_format;  GArray *trapezoids;  PangoRenderPart trapezoid_part;  GArray *glyphs;  PangoFont *glyph_font;};static void pango_xft_renderer_finalize     (GObject      *object);static void pango_xft_renderer_set_property (GObject      *object,					     guint         prop_id,					     const GValue *value,					     GParamSpec   *pspec);static void pango_xft_renderer_real_composite_trapezoids (PangoXftRenderer *xftrenderer,							  PangoRenderPart   part,							  XTrapezoid       *trapezoids,							  int               n_trapezoids);static void pango_xft_renderer_real_composite_glyphs     (PangoXftRenderer *xftrenderer,							  XftFont          *xft_font,							  XftGlyphSpec     *glyphs,							  int               n_glyphs);static void pango_xft_renderer_draw_glyphs    (PangoRenderer    *renderer,					       PangoFont        *font,					       PangoGlyphString *glyphs,					       int               x,					       int               y);static void pango_xft_renderer_draw_trapezoid (PangoRenderer    *renderer,					       PangoRenderPart   part,					       double            y1,					       double            x11,					       double            x21,					       double            y2,					       double            x12,					       double            x22);static void pango_xft_renderer_part_changed   (PangoRenderer    *renderer,					       PangoRenderPart   part);static void pango_xft_renderer_end            (PangoRenderer    *renderer);static void flush_trapezoids (PangoXftRenderer *xftrenderer);static void flush_glyphs (PangoXftRenderer *xftrenderer);G_DEFINE_TYPE (PangoXftRenderer, pango_xft_renderer, PANGO_TYPE_RENDERER)static voidpango_xft_renderer_init (PangoXftRenderer *xftrenderer){  xftrenderer->priv = G_TYPE_INSTANCE_GET_PRIVATE (xftrenderer,						   PANGO_TYPE_XFT_RENDERER,						   PangoXftRendererPrivate);  xftrenderer->priv->alpha = 0xffff;}static voidpango_xft_renderer_class_init (PangoXftRendererClass *klass){  GObjectClass *object_class = G_OBJECT_CLASS (klass);  PangoRendererClass *renderer_class = PANGO_RENDERER_CLASS (klass);  klass->composite_glyphs = pango_xft_renderer_real_composite_glyphs;  klass->composite_trapezoids = pango_xft_renderer_real_composite_trapezoids;  renderer_class->draw_glyphs = pango_xft_renderer_draw_glyphs;  renderer_class->draw_trapezoid = pango_xft_renderer_draw_trapezoid;  renderer_class->part_changed = pango_xft_renderer_part_changed;  renderer_class->end = pango_xft_renderer_end;  object_class->finalize = pango_xft_renderer_finalize;  object_class->set_property = pango_xft_renderer_set_property;  g_object_class_install_property (object_class, PROP_DISPLAY,				   g_param_spec_pointer ("display",							 "Display",							 "The display being rendered to",							 G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY));  g_object_class_install_property (object_class, PROP_SCREEN,				   g_param_spec_int ("screen",						     "Screen",						     "The screen being rendered to",						     0, G_MAXINT, 0,						     G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY));  g_type_class_add_private (object_class, sizeof (PangoXftRendererPrivate));}static voidpango_xft_renderer_finalize (GObject *object){  PangoXftRenderer *renderer = PANGO_XFT_RENDERER (object);  if (renderer->priv->glyphs)    g_array_free (renderer->priv->glyphs, TRUE);  if (renderer->priv->trapezoids)    g_array_free (renderer->priv->trapezoids, TRUE);  G_OBJECT_CLASS (pango_xft_renderer_parent_class)->finalize (object);}static voidpango_xft_renderer_set_property (GObject      *object,				 guint         prop_id,				 const GValue *value,				 GParamSpec   *pspec){  PangoXftRenderer *xftrenderer = PANGO_XFT_RENDERER (object);  switch (prop_id)    {    case PROP_DISPLAY:      xftrenderer->display = g_value_get_pointer (value);      /* We possibly should use ARGB format when subpixel-AA is turned       * on for the fontmap; we could discover that using the technique       * for FC_DPI in pango_fc_face_list_sizes.       */      xftrenderer->priv->mask_format = XRenderFindStandardFormat (xftrenderer->display,								  PictStandardA8);      break;    case PROP_SCREEN:      xftrenderer->screen = g_value_get_int (value);      break;    default:      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);      break;    }}static voidpango_xft_renderer_set_pictures (PangoXftRenderer *renderer,				 Picture           src_picture,				 Picture           dest_picture){  renderer->priv->src_picture = src_picture;  renderer->priv->dest_picture = dest_picture;}static voidflush_glyphs (PangoXftRenderer *xftrenderer){  XftFont *xft_font;  if (!xftrenderer->priv->glyphs ||      xftrenderer->priv->glyphs->len == 0)    return;  xft_font = pango_xft_font_get_font (xftrenderer->priv->glyph_font);  PANGO_XFT_RENDERER_GET_CLASS (xftrenderer)->composite_glyphs (xftrenderer,								xft_font,								(XftGlyphSpec *)xftrenderer->priv->glyphs->data,								xftrenderer->priv->glyphs->len);  g_array_set_size (xftrenderer->priv->glyphs, 0);  g_object_unref (xftrenderer->priv->glyph_font);  xftrenderer->priv->glyph_font = NULL;}#define MAX_GLYPHS	1024static voiddraw_glyph (PangoRenderer *renderer,	    PangoFont     *font,	    FT_UInt        glyph,	    int            x,	    int            y){  PangoXftRenderer *xftrenderer = PANGO_XFT_RENDERER (renderer);  XftGlyphSpec gs;  int pixel_x, pixel_y;  if (renderer->matrix)    {      pixel_x = floor (0.5 + (x * renderer->matrix->xx + y * renderer->matrix->xy) / PANGO_SCALE + renderer->matrix->x0);      pixel_y = floor (0.5 + (x * renderer->matrix->yx + y * renderer->matrix->yy) / PANGO_SCALE + renderer->matrix->y0);    }  else    {      pixel_x = PANGO_PIXELS (x);      pixel_y = PANGO_PIXELS (y);    }  /* Clip glyphs into the X coordinate range; we really   * want to clip glyphs with an ink rect outside the   * [0,32767] x [0,32767] rectangle but looking up   * the ink rect here would be a noticeable speed hit.   * This is close enough.   */  if (pixel_x < -32768 || pixel_x > 32767 ||      pixel_y < -32768 || pixel_y > 32767)    return;  flush_trapezoids (xftrenderer);  if (!xftrenderer->priv->glyphs)    xftrenderer->priv->glyphs = g_array_new (FALSE, FALSE,					     sizeof (XftGlyphSpec));  if (xftrenderer->priv->glyph_font != font ||      xftrenderer->priv->glyphs->len == MAX_GLYPHS)    {      flush_glyphs (xftrenderer);      xftrenderer->priv->glyph_font = g_object_ref (font);    }  gs.x = pixel_x;  gs.y = pixel_y;  gs.glyph = glyph;  g_array_append_val (xftrenderer->priv->glyphs, gs);}static gbooleanpoint_in_bounds (PangoRenderer *renderer,		 gint           x,		 gint           y){  gdouble pixel_x = (x * renderer->matrix->xx + y * renderer->matrix->xy) / PANGO_SCALE + renderer->matrix->x0;  gdouble pixel_y = (x * renderer->matrix->yx + y * renderer->matrix->yy) / PANGO_SCALE + renderer->matrix->y0;  return (pixel_x >= -32768. && pixel_x < 32768. &&	  pixel_y >= -32768. && pixel_y < 32768.);}static gbooleanbox_in_bounds (PangoRenderer *renderer,	       gint           x,	       gint           y,	       gint           width,	       gint           height){  if (!renderer->matrix)    {#define COORD_MIN (PANGO_SCALE * -16384 - PANGO_SCALE / 2)#define COORD_MAX (PANGO_SCALE * 32767 + PANGO_SCALE / 2 - 1)      return (x >= COORD_MIN && x + width <= COORD_MAX &&	      y >= COORD_MIN && y + width <= COORD_MAX);#undef COORD_MIN#undef COORD_MAX    }  else    {      return (point_in_bounds (renderer, x, y) &&	      point_in_bounds (renderer, x + width, y) &&	      point_in_bounds (renderer, x + width, y + height) &&	      point_in_bounds (renderer, x, y + height));    }}static voiddraw_box (PangoRenderer *renderer,	  gint           line_width,	  gint           x,	  gint           y,	  gint           width,	  gint           height){  pango_renderer_draw_rectangle (renderer, PANGO_RENDER_PART_FOREGROUND,				 x, y, width, line_width);  pango_renderer_draw_rectangle (renderer, PANGO_RENDER_PART_FOREGROUND,				 x, y + line_width, line_width, height - line_width * 2);  pango_renderer_draw_rectangle (renderer, PANGO_RENDER_PART_FOREGROUND,				 x + width - line_width, y + line_width, line_width, height - line_width * 2);  pango_renderer_draw_rectangle (renderer, PANGO_RENDER_PART_FOREGROUND,				 x, y + height - line_width, width, line_width);}static void_pango_xft_renderer_draw_box_glyph (PangoRenderer    *renderer,				    PangoGlyphInfo   *gi,				    int               glyph_x,				    int               glyph_y){  int x = glyph_x + PANGO_SCALE;  int y = glyph_y - PANGO_SCALE * (PANGO_UNKNOWN_GLYPH_HEIGHT - 1);  int width = gi->geometry.width - PANGO_SCALE * 2;  int height = PANGO_SCALE * (PANGO_UNKNOWN_GLYPH_HEIGHT - 2);  if (box_in_bounds (renderer, x, y, width, height))    draw_box (renderer, PANGO_SCALE, x, y, width, height);}static void_pango_xft_renderer_draw_unknown_glyph (PangoRenderer    *renderer,					PangoXftFont     *xfont,					XftFont          *xft_font,					PangoGlyphInfo   *gi,					int               glyph_x,					int               glyph_y){  char buf[7];  int ys[3];  int xs[4];  int row, col;  int cols;  PangoGlyph glyph;  PangoFont *mini_font = _pango_xft_font_get_mini_font (xfont);  XftFont *mini_xft_font = pango_xft_font_get_font (mini_font);  if (!mini_xft_font)    {      _pango_xft_renderer_draw_box_glyph (renderer, gi, glyph_x, glyph_y);      return;    }  glyph = gi->glyph & ~PANGO_GLYPH_UNKNOWN_FLAG;  ys[0] = glyph_y - PANGO_SCALE * xft_font->ascent + PANGO_SCALE * (((xft_font->ascent + xft_font->descent) - (xfont->mini_height * 2 + xfont->mini_pad * 5 + PANGO_SCALE / 2) / PANGO_SCALE) / 2);  ys[1] = ys[0] + 2 * xfont->mini_pad + xfont->mini_height;  ys[2] = ys[1] + xfont->mini_height + xfont->mini_pad;  xs[0] = glyph_x;  xs[1] = xs[0] + 2 * xfont->mini_pad;  xs[2] = xs[1] + xfont->mini_width + xfont->mini_pad;  xs[3] = xs[2] + xfont->mini_width + xfont->mini_pad;  if (glyph > 0xffff)    {      cols = 3;      g_snprintf (buf, sizeof(buf), "%06X", glyph);    }  else    {      cols = 2;      g_snprintf (buf, sizeof(buf), "%04X", glyph);    }  if (box_in_bounds (renderer,		     xs[0], ys[0],		     xfont->mini_width * cols + xfont->mini_pad * (2 * cols + 1),		     xfont->mini_height * 2 + xfont->mini_pad * 5))    {      if (xfont->mini_pad)	draw_box (renderer, xfont->mini_pad,		  xs[0], ys[0],		  xfont->mini_width * cols + xfont->mini_pad * (2 * cols + 1),		  xfont->mini_height * 2 + xfont->mini_pad * 5);      for (row = 0; row < 2; row++)	for (col = 0; col < cols; col++)	  {	    draw_glyph (renderer, mini_font,			XftCharIndex (NULL, mini_xft_font,				      buf[row * cols + col] & 0xff),			xs[col+1],			ys[row+1]);	  }    }}static voidpango_xft_renderer_draw_glyphs (PangoRenderer    *renderer,				PangoFont        *font,				PangoGlyphString *glyphs,				int               x,				int               y){  PangoXftFont *xfont = PANGO_XFT_FONT (font);  PangoFcFont *fcfont = PANGO_FC_FONT (font);  XftFont *xft_font = pango_xft_font_get_font (font);  int i;  int x_off = 0;  if (!fcfont)    {      for (i=0; i<glyphs->num_glyphs; i++)	{	  PangoGlyphInfo *gi = &glyphs->glyphs[i];	  if (gi->glyph != PANGO_GLYPH_EMPTY)	    {	      int glyph_x = x + x_off + gi->geometry.x_offset;	      int glyph_y = y + gi->geometry.y_offset;	      _pango_xft_renderer_draw_box_glyph (renderer, gi, glyph_x, glyph_y);	    }	  x_off += gi->geometry.width;	}      return;    }  if (!fcfont->fontmap)	/* Display closed */    return;  for (i=0; i<glyphs->num_glyphs; i++)    {      PangoGlyphInfo *gi = &glyphs->glyphs[i];      if (gi->glyph != PANGO_GLYPH_EMPTY)	{	  int glyph_x = x + x_off + gi->geometry.x_offset;	  int glyph_y = y + gi->geometry.y_offset;	  if (gi->glyph & PANGO_GLYPH_UNKNOWN_FLAG)	    {	      _pango_xft_renderer_draw_unknown_glyph (renderer,						      xfont,						      xft_font,						      gi,						      glyph_x,						      glyph_y);	    }	  else	    {	      draw_glyph (renderer, font, gi->glyph, glyph_x, glyph_y);	    }

⌨️ 快捷键说明

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