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

📄 pangoft2-render.c

📁 GTK+-2.0源码之pango-1.15.6.tar.gz
💻 C
📖 第 1 页 / 共 2 页
字号:
/* Pango * pangoft2-render.c: Rendering routines to FT_Bitmap objects * * Copyright (C) 2004 Red Hat Software * Copyright (C) 2000 Tor Lillqvist * * 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 "pangoft2-private.h"/* for compatibility with older freetype versions */#ifndef FT_LOAD_TARGET_MONO#define FT_LOAD_TARGET_MONO  FT_LOAD_MONOCHROME#endiftypedef struct _PangoFT2RendererClass PangoFT2RendererClass;#define PANGO_FT2_RENDERER_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass), PANGO_TYPE_FT2_RENDERER, PangoFT2RendererClass))#define PANGO_IS_FT2_RENDERER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), PANGO_TYPE_FT2_RENDERER))#define PANGO_FT2_RENDERER_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS ((obj), PANGO_TYPE_FT2_RENDERER, PangoFT2RendererClass))struct _PangoFT2Renderer{  PangoRenderer parent_instance;  FT_Bitmap *bitmap;};struct _PangoFT2RendererClass{  PangoRendererClass parent_class;};static void pango_ft2_renderer_draw_glyph     (PangoRenderer    *renderer,					       PangoFont        *font,					       PangoGlyph        glyph,					       double            x,					       double            y);static void pango_ft2_renderer_draw_trapezoid (PangoRenderer    *renderer,					       PangoRenderPart   part,					       double            y1,					       double            x11,					       double            x21,					       double            y2,					       double            x12,					       double            x22);G_DEFINE_TYPE (PangoFT2Renderer, pango_ft2_renderer, PANGO_TYPE_RENDERER)static voidpango_ft2_renderer_init (PangoFT2Renderer *renderer){}static voidpango_ft2_renderer_class_init (PangoFT2RendererClass *klass){  PangoRendererClass *renderer_class = PANGO_RENDERER_CLASS (klass);  renderer_class->draw_glyph = pango_ft2_renderer_draw_glyph;  renderer_class->draw_trapezoid = pango_ft2_renderer_draw_trapezoid;}static voidpango_ft2_renderer_set_bitmap (PangoFT2Renderer *renderer,			      FT_Bitmap         *bitmap){  renderer->bitmap = bitmap;}typedef struct{  FT_Bitmap bitmap;  int bitmap_left;  int bitmap_top;} PangoFT2RenderedGlyph;static voidpango_ft2_free_rendered_glyph (PangoFT2RenderedGlyph *rendered){  g_free (rendered->bitmap.buffer);  g_slice_free (PangoFT2RenderedGlyph, rendered);}static PangoFT2RenderedGlyph *pango_ft2_font_render_box_glyph (int width,				 int height,				 int top){  PangoFT2RenderedGlyph *box;  int i, j, offset1, offset2, line_width;  line_width = MAX ((height + 43) / 44, 1);  if (width < 1 || height < 1)    line_width = 0;  box = g_slice_new (PangoFT2RenderedGlyph);  box->bitmap_left = 0;  box->bitmap_top = top;  box->bitmap.pixel_mode = ft_pixel_mode_grays;  box->bitmap.width = width;  box->bitmap.rows = height;  box->bitmap.pitch = height;  box->bitmap.buffer = g_malloc0 (box->bitmap.rows * box->bitmap.pitch);  /* draw the box */  for (j = 0; j < line_width; j++)    {      offset1 = box->bitmap.pitch * (MIN (1 + j, height - 1));      offset2 = box->bitmap.pitch * (MAX (box->bitmap.rows - 2 - j, 0));      for (i = 1;	   i < box->bitmap.width - 1;	   i++)	{	  box->bitmap.buffer[offset1 + i] = 0xff;	  box->bitmap.buffer[offset2 + i] = 0xff;	}    }  for (j = 0; j < line_width; j++)    {      offset1 = MIN (1 + j, width - 1);      offset2 = MAX (box->bitmap.width - 2 - j, 0);      for (i = box->bitmap.pitch;	   i < (box->bitmap.rows - 1) * box->bitmap.pitch;	   i += box->bitmap.pitch)	{	  box->bitmap.buffer[offset1 + i] = 0xff;	  box->bitmap.buffer[offset2 + i] = 0xff;	}    }  return box;}static PangoFT2RenderedGlyph *pango_ft2_font_render_glyph (PangoFont *font,			     int glyph_index){  FT_Face face;  if (glyph_index & PANGO_GLYPH_UNKNOWN_FLAG)    {      PangoFT2RenderedGlyph *box;      PangoFontMetrics *metrics;      if (!font)	goto generic_box;      metrics = pango_font_get_metrics (font, NULL);      if (!metrics)	goto generic_box;      box = pango_ft2_font_render_box_glyph (PANGO_PIXELS (metrics->approximate_char_width),					     PANGO_PIXELS (metrics->ascent + metrics->descent),					     PANGO_PIXELS (metrics->ascent));      pango_font_metrics_unref (metrics);      return box;    }  face = pango_ft2_font_get_face (font);  if (face)    {      PangoFT2RenderedGlyph *rendered;      PangoFT2Font *ft2font = (PangoFT2Font *) font;      rendered = g_slice_new (PangoFT2RenderedGlyph);      /* Draw glyph */      FT_Load_Glyph (face, glyph_index, ft2font->load_flags);      FT_Render_Glyph (face->glyph,		       (ft2font->load_flags & FT_LOAD_TARGET_MONO ?			ft_render_mode_mono : ft_render_mode_normal));      rendered->bitmap = face->glyph->bitmap;      rendered->bitmap.buffer = g_memdup (face->glyph->bitmap.buffer,					  face->glyph->bitmap.rows * face->glyph->bitmap.pitch);      rendered->bitmap_left = face->glyph->bitmap_left;      rendered->bitmap_top = face->glyph->bitmap_top;      return rendered;    }  else    {generic_box:      return  pango_ft2_font_render_box_glyph (PANGO_UNKNOWN_GLYPH_WIDTH,					       PANGO_UNKNOWN_GLYPH_HEIGHT,					       PANGO_UNKNOWN_GLYPH_HEIGHT);    }}static voidpango_ft2_renderer_draw_glyph (PangoRenderer *renderer,			       PangoFont     *font,			       PangoGlyph     glyph,			       double         x,			       double         y){  FT_Bitmap *bitmap = PANGO_FT2_RENDERER (renderer)->bitmap;  PangoFT2RenderedGlyph *rendered_glyph;  gboolean add_glyph_to_cache;  guchar *src, *dest;  int x_start, x_limit;  int y_start, y_limit;  int ixoff = floor (x + 0.5);  int iyoff = floor (y + 0.5);  int ix, iy;  if (glyph & PANGO_GLYPH_UNKNOWN_FLAG)    {      glyph = pango_ft2_get_unknown_glyph (font);      if (glyph == PANGO_GLYPH_EMPTY)	{	  /* No unknown glyph found for the font, draw a box */	  /* Since we only draw an empty box for FT2 renderer,	   * we unify the rendered bitmaps in the cache.	   */	  glyph = PANGO_GLYPH_UNKNOWN_FLAG;	}    }  rendered_glyph = _pango_ft2_font_get_cache_glyph_data (font, glyph);  add_glyph_to_cache = FALSE;  if (rendered_glyph == NULL)    {      rendered_glyph = pango_ft2_font_render_glyph (font, glyph);      add_glyph_to_cache = TRUE;    }  x_start = MAX (0, - (ixoff + rendered_glyph->bitmap_left));  x_limit = MIN (rendered_glyph->bitmap.width,		 bitmap->width - (ixoff + rendered_glyph->bitmap_left));  y_start = MAX (0,  - (iyoff - rendered_glyph->bitmap_top));  y_limit = MIN (rendered_glyph->bitmap.rows,		 bitmap->rows - (iyoff - rendered_glyph->bitmap_top));  src = rendered_glyph->bitmap.buffer +    y_start * rendered_glyph->bitmap.pitch;  dest = bitmap->buffer +    (y_start + iyoff - rendered_glyph->bitmap_top) * bitmap->pitch +    x_start + ixoff + rendered_glyph->bitmap_left;  switch (rendered_glyph->bitmap.pixel_mode)    {    case ft_pixel_mode_grays:      src += x_start;      for (iy = y_start; iy < y_limit; iy++)	{	  guchar *s = src;	  guchar *d = dest;	  for (ix = x_start; ix < x_limit; ix++)	    {	      switch (*s)		{		case 0:		  break;		case 0xff:		  *d = 0xff;		default:		  *d = MIN ((gushort) *d + (gushort) *s, 0xff);		  break;		}	      s++;	      d++;	    }	  dest += bitmap->pitch;	  src  += rendered_glyph->bitmap.pitch;	}      break;    case ft_pixel_mode_mono:      src += x_start / 8;      for (iy = y_start; iy < y_limit; iy++)	{	  guchar *s = src;	  guchar *d = dest;	  for (ix = x_start; ix < x_limit; ix++)	    {	      if ((*s) & (1 << (7 - (ix % 8))))		*d |= 0xff;	      if ((ix % 8) == 7)		s++;	      d++;	    }	  dest += bitmap->pitch;	  src  += rendered_glyph->bitmap.pitch;	}      break;    default:      g_warning ("pango_ft2_render: "		 "Unrecognized glyph bitmap pixel mode %d\n",		 rendered_glyph->bitmap.pixel_mode);      break;    }  if (add_glyph_to_cache)    {      _pango_ft2_font_set_glyph_cache_destroy (font,					       (GDestroyNotify) pango_ft2_free_rendered_glyph);      _pango_ft2_font_set_cache_glyph_data (font,					    glyph, rendered_glyph);    }}typedef struct {  double y;  double x1;  double x2;} Position;static voiddraw_simple_trap (PangoRenderer *renderer,		  Position      *t,		  Position      *b){  FT_Bitmap *bitmap = PANGO_FT2_RENDERER (renderer)->bitmap;  int iy = floor (t->y);  int x1, x2, x;  double dy = b->y - t->y;  guchar *dest;  if (iy < 0 || iy >= bitmap->rows)    return;

⌨️ 快捷键说明

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