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

📄 pangowin32.c

📁 Pango is a library for layout and rendering of text, with an emphasis on internationalization. Pang
💻 C
📖 第 1 页 / 共 4 页
字号:
  if (!coverage)    {      coverage = pango_coverage_new ();      pango_win32_font_calc_coverage (font, coverage, lang);      pango_win32_font_entry_set_coverage (win32font->win32face, coverage, lang);    }  return coverage;}static PangoEngineShape *pango_win32_font_find_shaper (PangoFont     *font,			      PangoLanguage *lang,			      guint32        ch){  PangoMap *shape_map = NULL;  PangoScript script;  shape_map = pango_win32_get_shaper_map (lang);  script = pango_script_for_unichar (ch);  return (PangoEngineShape *)pango_map_get_engine (shape_map, script);}/* Utility functions *//** * pango_win32_get_unknown_glyph: * @font: a #PangoFont * @wc: the Unicode character for which a glyph is needed. * * Returns the index of a glyph suitable for drawing @wc as an * unknown character. * * Use PANGO_GET_UNKNOWN_GLYPH() instead. * * Return value: a glyph index into @font **/PangoGlyphpango_win32_get_unknown_glyph (PangoFont *font,			       gunichar   wc){  return PANGO_GET_UNKNOWN_GLYPH (wc);}/** * pango_win32_render_layout_line: * @hdc:       DC to use for uncolored drawing * @line:      a #PangoLayoutLine * @x:         the x position of start of string (in pixels) * @y:         the y position of baseline (in pixels) * * Render a #PangoLayoutLine onto a device context. For underlining to * work property the text alignment of the DC should have TA_BASELINE * and TA_LEFT. */voidpango_win32_render_layout_line (HDC              hdc,				PangoLayoutLine *line,				int              x,				int              y){  GSList *tmp_list = line->runs;  PangoRectangle overall_rect;  PangoRectangle logical_rect;  PangoRectangle ink_rect;  int x_off = 0;  pango_layout_line_get_extents (line,NULL, &overall_rect);  while (tmp_list)    {      HBRUSH oldfg = NULL;      HBRUSH brush = NULL;      POINT points[2];      PangoUnderline uline = PANGO_UNDERLINE_NONE;      PangoLayoutRun *run = tmp_list->data;      PangoAttrColor fg_color, bg_color;      gboolean fg_set, bg_set;      tmp_list = tmp_list->next;      pango_win32_get_item_properties (run->item, &uline, &fg_color, &fg_set, &bg_color, &bg_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 (bg_set)	{	  HBRUSH oldbrush;	  brush = CreateSolidBrush (RGB ((bg_color.color.red + 128) >> 8,					 (bg_color.color.green + 128) >> 8,					 (bg_color.color.blue + 128) >> 8));	  oldbrush = SelectObject (hdc, brush);	  Rectangle (hdc, x + PANGO_PIXELS (x_off + logical_rect.x),			  y + PANGO_PIXELS (overall_rect.y),			  PANGO_PIXELS (logical_rect.width),			  PANGO_PIXELS (overall_rect.height));	  SelectObject (hdc, oldbrush);	  DeleteObject (brush);	}      if (fg_set)	{	  brush = CreateSolidBrush (RGB ((fg_color.color.red + 128) >> 8,					 (fg_color.color.green + 128) >> 8,					 (fg_color.color.blue + 128) >> 8));	  oldfg = SelectObject (hdc, brush);	}      pango_win32_render (hdc, run->item->analysis.font, run->glyphs,			  x + PANGO_PIXELS (x_off), y);      switch (uline)	{	case PANGO_UNDERLINE_NONE:	  break;	case PANGO_UNDERLINE_DOUBLE:	  points[0].x = x + PANGO_PIXELS (x_off + ink_rect.x) - 1;	  points[0].y = points[1].y = y + 4;	  points[1].x = x + PANGO_PIXELS (x_off + ink_rect.x + ink_rect.width);	  Polyline (hdc, points, 2);	  points[0].y = points[1].y = y + 2;	  Polyline (hdc, points, 2);	  break;	case PANGO_UNDERLINE_SINGLE:	  points[0].x = x + PANGO_PIXELS (x_off + ink_rect.x) - 1;	  points[0].y = points[1].y = y + 2;	  points[1].x = x + PANGO_PIXELS (x_off + ink_rect.x + ink_rect.width);	  Polyline (hdc, points, 2);	  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)	    {	      points[0].x = point_x;	      points[1].x = MAX (point_x + 1, end_x);	      if (counter)		points[0].y = points[1].y = y + 2;	      else		points[0].y = points[1].y = y + 3;	      Polyline (hdc, points, 2);	      counter = (counter + 1) % 2;	    }	  }	  break;	case PANGO_UNDERLINE_LOW:	  points[0].x = x + PANGO_PIXELS (x_off + ink_rect.x) - 1;	  points[0].y = points[1].y = y + PANGO_PIXELS (ink_rect.y + ink_rect.height) + 2;	  points[1].x = x + PANGO_PIXELS (x_off + ink_rect.x + ink_rect.width);	  Polyline (hdc, points, 2);	  break;	}      if (fg_set)	{	  SelectObject (hdc, oldfg);	  DeleteObject (brush);	}      x_off += logical_rect.width;    }}/** * pango_win32_render_layout: * @hdc:       HDC to use for uncolored drawing * @layout:    a #PangoLayout * @x:         the X position of the left of the layout (in pixels) * @y:         the Y position of the top of the layout (in pixels) * * Render a #PangoLayoutLine onto an X drawable */voidpango_win32_render_layout (HDC          hdc,			   PangoLayout *layout,			   int          x,			   int          y){  PangoLayoutIter *iter;  g_return_if_fail (hdc != NULL);  g_return_if_fail (PANGO_IS_LAYOUT (layout));  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_win32_render_layout_line (hdc,				      line,				      x + PANGO_PIXELS (logical_rect.x),				      y + PANGO_PIXELS (baseline));    }  while (pango_layout_iter_next_line (iter));  pango_layout_iter_free (iter);}/* This utility function is duplicated here and in pango-layout.c; should it be * public? Trouble is - what is the appropriate set of properties? */static voidpango_win32_get_item_properties (PangoItem      *item,				 PangoUnderline *uline,				 PangoAttrColor *fg_color,				 gboolean       *fg_set,				 PangoAttrColor *bg_color,				 gboolean       *bg_set){  GSList *tmp_list = item->analysis.extra_attrs;  if (fg_set)    *fg_set = FALSE;  if (bg_set)    *bg_set = FALSE;  while (tmp_list)    {      PangoAttribute *attr = tmp_list->data;      switch (attr->klass->type)	{	case PANGO_ATTR_UNDERLINE:	  if (uline)	    *uline = ((PangoAttrInt *)attr)->value;	  break;	case PANGO_ATTR_FOREGROUND:	  if (fg_color)	    *fg_color = *((PangoAttrColor *)attr);	  if (fg_set)	    *fg_set = TRUE;	  break;	case PANGO_ATTR_BACKGROUND:	  if (bg_color)	    *bg_color = *((PangoAttrColor *)attr);	  if (bg_set)	    *bg_set = TRUE;	  break;	default:	  break;	}      tmp_list = tmp_list->next;    }}static guintget_cmap_offset (HDC     hdc,		 guint16 encoding_id){  guint16 n_tables;  struct cmap_encoding_subtable *table;  gint32 res;  int i;  guint32 offset;  /* Get The number of encoding tables, at offset 2 */  res = GetFontData (hdc, CMAP, 2, &n_tables, 2);  if (res != 2)    return 0;  n_tables = GUINT16_FROM_BE (n_tables);  table = g_malloc (ENCODING_TABLE_SIZE*n_tables);  res = GetFontData (hdc, CMAP, CMAP_HEADER_SIZE, table, ENCODING_TABLE_SIZE*n_tables);  if (res != ENCODING_TABLE_SIZE*n_tables)    return 0;  for (i = 0; i < n_tables; i++)    {      if (table[i].platform_id == GUINT16_TO_BE (MICROSOFT_PLATFORM_ID) &&	  table[i].encoding_id == GUINT16_TO_BE (encoding_id))	{	  offset = GUINT32_FROM_BE (table[i].offset);	  g_free (table);	  return offset;	}    }  g_free (table);  return 0;}static gpointerget_format_4_cmap (HDC hdc){  guint32 offset;  guint32 res;  guint16 length;  guint16 *tbl, *tbl_end;  struct format_4_cmap *table;  /* FIXME: Could look here at the CRC for the font in the DC	    and return a cached copy if the same */  offset = get_cmap_offset (hdc, UNICODE_ENCODING_ID);  if (offset == 0)    return NULL;  res = GetFontData (hdc, CMAP, offset + 2, &length, 2);  if (res != 2)    return NULL;  length = GUINT16_FROM_BE (length);  table = g_malloc (length);  res = GetFontData (hdc, CMAP, offset, table, length);  if (res != length ||      GUINT16_FROM_BE (table->format) != 4 ||      (GUINT16_FROM_BE (table->length) % 2) != 0)    {      g_free (table);      return NULL;    }  table->format = GUINT16_FROM_BE (table->format);  table->length = GUINT16_FROM_BE (table->length);  table->language = GUINT16_FROM_BE (table->language);  table->seg_count_x_2 = GUINT16_FROM_BE (table->seg_count_x_2);  table->search_range = GUINT16_FROM_BE (table->search_range);  table->entry_selector = GUINT16_FROM_BE (table->entry_selector);  table->range_shift = GUINT16_FROM_BE (table->range_shift);  tbl_end = (guint16 *)((char *)table + length);  tbl = &table->reserved;  while (tbl < tbl_end)    {      *tbl = GUINT16_FROM_BE (*tbl);      tbl++;    }  return table;}static guint16 *get_id_range_offset (struct format_4_cmap *table){  gint32 seg_count = table->seg_count_x_2/2;  return &table->arrays[seg_count*3];}static guint16 *get_id_delta (struct format_4_cmap *table){  gint32 seg_count = table->seg_count_x_2/2;  return &table->arrays[seg_count*2];}static guint16 *get_start_count (struct format_4_cmap *table){  gint32 seg_count = table->seg_count_x_2/2;  return &table->arrays[seg_count*1];}static guint16 *get_end_count (struct format_4_cmap *table){  gint32 seg_count = table->seg_count_x_2/2;  /* Apparently the reseved spot is not reserved for     the end_count array!? */  return (&table->arrays[seg_count*0])-1;}static gbooleanfind_segment (struct format_4_cmap *table,	      guint16               wc,	      guint16              *segment){  guint16 start, end, i;  guint16 seg_count = table->seg_count_x_2/2;  guint16 *end_count = get_end_count (table);  guint16 *start_count = get_start_count (table);  static guint last = 0; /* Cache of one */  if (last < seg_count &&      wc >= start_count[last] &&      wc <= end_count[last])    {      *segment = last;      return TRUE;    }  /* Binary search for the segment */  start = 0; /* inclusive */  end = seg_count; /* not inclusive */  while (start < end)    {      /* Look at middle pos */      i = (start + end)/2;      if (i == start)	{	  /* We made no progress. Look if this is the one. */	  if (wc >= start_count[i] &&	      wc <= end_count[i])	    {	      *segment = i;	      last = i;	      return TRUE;	    }	  else	    return FALSE;	}      else if (wc < start_count[i])	{	  end = i;	}      else if (wc > end_count[i])	{	  start = i;	}      else	{	  /* Found it! */	  *segment = i;	  last = i;	  return TRUE;	}    }  return FALSE;}static gpointerget_format_12_cmap (HDC hdc){  guint32 offset;  guint32 res;  guint32 length;  guint32 *tbl, *tbl_end;  struct format_12_cmap *table;  offset = get_cmap_offset (hdc, UCS4_ENCODING_ID);  if (offset == 0)

⌨️ 快捷键说明

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