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

📄 pangowin32.c

📁 GTK+-2.0源码之pango-1.15.6.tar.gz
💻 C
📖 第 1 页 / 共 3 页
字号:
  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)    return NULL;  res = GetFontData (hdc, CMAP, offset + 4, &length, 4);  if (res != 4)    return NULL;  length = GUINT32_FROM_BE (length);  table = g_malloc (length);  res = GetFontData (hdc, CMAP, offset, table, length);  if (res != length)    {      g_free (table);      return NULL;    }  table->format = GUINT16_FROM_BE (table->format);  table->length = GUINT32_FROM_BE (table->length);  table->language = GUINT32_FROM_BE (table->language);  table->count = GUINT32_FROM_BE (table->count);  if (table->format != 12 ||      (table->length % 4) != 0 ||      table->length > length ||      table->length < 16 + table->count * 12)    {      g_free (table);      return NULL;    }  tbl_end = (guint32 *) ((char *) table + length);  tbl = table->groups;  while (tbl < tbl_end)    {      *tbl = GUINT32_FROM_BE (*tbl);      tbl++;    }  return table;}static gpointerfont_get_cmap (PangoFont *font){  PangoWin32Font *win32font = (PangoWin32Font *)font;  gpointer cmap;  if (win32font->win32face->cmap)    return win32font->win32face->cmap;  pango_win32_font_select_font (font, pango_win32_hdc);  /* Prefer the format 12 cmap */  if ((cmap = get_format_12_cmap (pango_win32_hdc)) != NULL)    {      win32font->win32face->cmap_format = 12;      win32font->win32face->cmap = cmap;    }  else if ((cmap = get_format_4_cmap (pango_win32_hdc)) != NULL)    {      win32font->win32face->cmap_format = 4;      win32font->win32face->cmap = cmap;    }  pango_win32_font_done_font (font);  return cmap;}/** * pango_win32_font_get_glyph_index: * @font: a #PangoFont. * @wc: a Unicode character. * * Obtains the index of the glyph for @wc in @font, or 0, if not * covered. * * Return value: the glyph index for @wc. **/gintpango_win32_font_get_glyph_index (PangoFont *font,				  gunichar   wc){  PangoWin32Font *win32font = (PangoWin32Font *)font;  gpointer cmap;  guint16 glyph;  /* Do GetFontData magic on font->hfont here. */  cmap = font_get_cmap (font);  if (cmap == NULL)    return 0;  if (win32font->win32face->cmap_format == 4)    {      struct format_4_cmap *cmap4 = cmap;      guint16 *id_range_offset;      guint16 *id_delta;      guint16 *start_count;      guint16 segment;      guint16 id;      guint16 ch = wc;      if (wc > 0xFFFF)	return 0;      if (!find_segment (cmap4, ch, &segment))	return 0;      id_range_offset = get_id_range_offset (cmap4);      id_delta = get_id_delta (cmap4);      start_count = get_start_count (cmap4);      if (id_range_offset[segment] == 0)	glyph = (id_delta[segment] + ch) % 65536;      else	{	  id = *(id_range_offset[segment]/2 +		 (ch - start_count[segment]) +		 &id_range_offset[segment]);	  if (id)	    glyph = (id_delta[segment] + id) %65536;	  else	    glyph = 0;	}    }  else if (win32font->win32face->cmap_format == 12)    {      struct format_12_cmap *cmap12 = cmap;      guint32 i;      glyph = 0;      for (i = 0; i < cmap12->count; i++)	{	  if (cmap12->groups[i*3+0] <= wc && wc <= cmap12->groups[i*3+1])	    {	      glyph = cmap12->groups[i*3+2] + (wc - cmap12->groups[i*3+0]);	      break;	    }	}    }  else    g_assert_not_reached ();  return glyph;}gbooleanpango_win32_get_name_header (HDC                 hdc,			     struct name_header *header){  if (GetFontData (hdc, NAME, 0, header, sizeof (*header)) != sizeof (*header))    return FALSE;  header->num_records = GUINT16_FROM_BE (header->num_records);  header->string_storage_offset = GUINT16_FROM_BE (header->string_storage_offset);  return TRUE;}gbooleanpango_win32_get_name_record (HDC                 hdc,			     gint                i,			     struct name_record *record){  if (GetFontData (hdc, NAME, 6 + i * sizeof (*record),		   record, sizeof (*record)) != sizeof (*record))    return FALSE;  record->platform_id = GUINT16_FROM_BE (record->platform_id);  record->encoding_id = GUINT16_FROM_BE (record->encoding_id);  record->language_id = GUINT16_FROM_BE (record->language_id);  record->name_id = GUINT16_FROM_BE (record->name_id);  record->string_length = GUINT16_FROM_BE (record->string_length);  record->string_offset = GUINT16_FROM_BE (record->string_offset);  return TRUE;}static gbooleanfont_has_name_in (PangoFont                       *font,		  PangoWin32CoverageLanguageClass  cjkv){  HFONT hfont, oldhfont;  struct name_header header;  struct name_record record;  gint i;  gboolean retval = FALSE;  if (cjkv == PANGO_WIN32_COVERAGE_UNSPEC)    return TRUE;  hfont = pango_win32_get_hfont (font);  oldhfont = SelectObject (pango_win32_hdc, hfont);  if (!pango_win32_get_name_header (pango_win32_hdc, &header))    {      SelectObject (pango_win32_hdc, oldhfont);      return FALSE;    }  for (i = 0; i < header.num_records; i++)    {      if (!pango_win32_get_name_record (pango_win32_hdc, i, &record))	{	  SelectObject (pango_win32_hdc, oldhfont);	  return FALSE;	}      if ((record.name_id != 1 && record.name_id != 16) || record.string_length <= 0)	continue;      PING(("platform:%d encoding:%d language:%04x name_id:%d",	    record.platform_id, record.encoding_id, record.language_id, record.name_id));      if (record.platform_id == MICROSOFT_PLATFORM_ID)	if ((cjkv == PANGO_WIN32_COVERAGE_ZH_TW &&	     record.language_id == MAKELANGID (LANG_CHINESE, SUBLANG_CHINESE_TRADITIONAL))	    ||	    (cjkv == PANGO_WIN32_COVERAGE_ZH_CN &&	     record.language_id == MAKELANGID (LANG_CHINESE, SUBLANG_CHINESE_SIMPLIFIED))	    ||	    (cjkv == PANGO_WIN32_COVERAGE_JA &&	     PRIMARYLANGID (record.language_id) == LANG_JAPANESE)	    ||	    (cjkv == PANGO_WIN32_COVERAGE_KO &&	     PRIMARYLANGID (record.language_id) == LANG_KOREAN)	    ||	    (cjkv == PANGO_WIN32_COVERAGE_VI &&	     PRIMARYLANGID (record.language_id) == LANG_VIETNAMESE))	  {	    PING (("yep:%d:%04x", cjkv, record.language_id));	    retval = TRUE;	    break;	  }    }  SelectObject (pango_win32_hdc, oldhfont);  return retval;}static voidpango_win32_font_calc_coverage (PangoFont     *font,				PangoCoverage *coverage,				PangoLanguage *lang){  PangoWin32Font *win32font = (PangoWin32Font *)font;  gpointer cmap;  guint32 ch;  guint32 i;  PangoWin32CoverageLanguageClass cjkv;  gboolean hide_unihan = FALSE;  PING(("font:%s lang:%s",	pango_font_description_to_string (pango_font_describe (font)),	pango_language_to_string (lang)));  cjkv = pango_win32_coverage_language_classify (lang);  if (cjkv != PANGO_WIN32_COVERAGE_UNSPEC && !font_has_name_in (font, cjkv))    {      PING(("hiding UniHan chars"));      hide_unihan = TRUE;    }  /* Do GetFontData magic on font->hfont here. */  cmap = font_get_cmap (font);  if (cmap == NULL)    {      PING(("no table"));      return;    }  PING (("coverage:"));  if (win32font->win32face->cmap_format == 4)    {      struct format_4_cmap *cmap4 = cmap;      guint16 *id_range_offset;      guint16 *start_count;      guint16 *end_count;      guint16 seg_count;      guint16 id;      seg_count = cmap4->seg_count_x_2/2;      end_count = get_end_count (cmap4);      start_count = get_start_count (cmap4);      id_range_offset = get_id_range_offset (cmap4);      for (i = 0; i < seg_count; i++)	{	  if (id_range_offset[i] == 0)	    {#ifdef PANGO_WIN32_DEBUGGING	      if (pango_win32_debug)		{		  if (end_count[i] == start_count[i])		    g_print ("%04x ", start_count[i]);		  else		    g_print ("%04x:%04x ", start_count[i], end_count[i]);		}#endif	      for (ch = start_count[i]; ch <= end_count[i]; ch++)		if (hide_unihan && CH_IS_UNIHAN_BMP (ch))		  pango_coverage_set (coverage, ch, PANGO_COVERAGE_APPROXIMATE);		else		  pango_coverage_set (coverage, ch, PANGO_COVERAGE_EXACT);	    }	  else	    {#ifdef PANGO_WIN32_DEBUGGING	      guint32 ch0 = G_MAXUINT;#endif	      for (ch = start_count[i]; ch <= end_count[i]; ch++)		{		  if (ch == 0xFFFF)		    break;		  id = *(id_range_offset[i]/2 +			 (ch - start_count[i]) +			 &id_range_offset[i]);		  if (id)		    {#ifdef PANGO_WIN32_DEBUGGING		      if (ch0 == G_MAXUINT)			ch0 = ch;#endif		      if (hide_unihan && CH_IS_UNIHAN_BMP (ch))			pango_coverage_set (coverage, ch, PANGO_COVERAGE_APPROXIMATE);		      else			pango_coverage_set (coverage, ch, PANGO_COVERAGE_EXACT);		    }#ifdef PANGO_WIN32_DEBUGGING		  else if (ch0 < G_MAXUINT)		    {		      if (pango_win32_debug)			{			  if (ch > ch0 + 2)			    g_print ("%04x:%04x ", ch0, ch - 1);			  else			    g_print ("%04x ", ch0);			}		      ch0 = G_MAXUINT;		    }#endif		}#ifdef PANGO_WIN32_DEBUGGING	      if (ch0 < G_MAXUINT)		{		  if (pango_win32_debug)		    {		      if (ch > ch0 + 2)			g_print ("%04x:%04x ", ch0, ch - 1);		      else			g_print ("%04x ", ch0);		    }		}#endif	    }	}    }  else if (win32font->win32face->cmap_format == 12)    {      struct format_12_cmap *cmap12 = cmap;      for (i = 0; i < cmap12->count; i++)	{#ifdef PANGO_WIN32_DEBUGGING	  if (pango_win32_debug)	    {	      if (cmap12->groups[i*3+0] == cmap12->groups[i*3+1])		g_print ("%04x ", cmap12->groups[i*3+0]);	      else		g_print ("%04x:%04x ", cmap12->groups[i*3+0], cmap12->groups[i*3+1]);	    }#endif	  for (ch = cmap12->groups[i*3+0]; ch <= cmap12->groups[i*3+1]; ch++)	    {	      if (hide_unihan && CH_IS_UNIHAN (ch))		pango_coverage_set (coverage, ch, PANGO_COVERAGE_APPROXIMATE);	      else		pango_coverage_set (coverage, ch, PANGO_COVERAGE_EXACT);	    }	}    }  else    g_assert_not_reached ();#ifdef PANGO_WIN32_DEBUGGING  if (pango_win32_debug)    g_print ("\n");#endif}

⌨️ 快捷键说明

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