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

📄 basic-win32.c

📁 Pango is a library for layout and rendering of text, with an emphasis on internationalization. Pang
💻 C
📖 第 1 页 / 共 2 页
字号:
    {      byte_offset[charix] = p - text;      charix++;      p = g_utf8_next_char (p);    }  /* Convert char indexes in the log_clusters array to byte offsets.   */  for (glyphix = 0; glyphix < glyphs->num_glyphs; glyphix++)    {      g_assert (glyphs->log_clusters[glyphix] < n_chars);      glyphs->log_clusters[glyphix] = byte_offset[glyphs->log_clusters[glyphix]];    }  g_free (byte_offset);}static gbooleanitemize_shape_and_place (PangoFont           *font,			 HDC                  hdc,			 wchar_t             *wtext,			 int                  wlen,			 const PangoAnalysis *analysis,			 PangoGlyphString    *glyphs,			 SCRIPT_CACHE        *script_cache){  int i;  int item, nitems, item_step;  int itemlen, glyphix, nglyphs;  SCRIPT_CONTROL control;  SCRIPT_STATE state;  SCRIPT_ITEM items[100];  double scale = pango_win32_font_get_metrics_factor (font);  memset (&control, 0, sizeof (control));  memset (&state, 0, sizeof (state));  control.uDefaultLanguage = make_langid (analysis->language);  state.uBidiLevel = analysis->level;#ifdef BASIC_WIN32_DEBUGGING  if (pango_win32_debug)    g_print (G_STRLOC ": ScriptItemize: uDefaultLanguage:%04x uBidiLevel:%d\n",	     control.uDefaultLanguage, state.uBidiLevel);#endif  if ((*script_itemize) (wtext, wlen, G_N_ELEMENTS (items), &control, NULL,			 items, &nitems))    {#ifdef BASIC_WIN32_DEBUGGING      if (pango_win32_debug)	g_print ("ScriptItemize failed\n");#endif      return FALSE;    }#ifdef BASIC_WIN32_DEBUGGING  if (pango_win32_debug)    g_print ("%d items:\n", nitems);#endif  if (analysis->level % 2)    {      item = nitems - 1;      item_step = -1;    }  else    {      item = 0;      item_step = 1;    }  for (i = 0; i < nitems; i++, item += item_step)    {      WORD iglyphs[1000];      WORD log_clusters[1000];      SCRIPT_VISATTR visattrs[1000];      int advances[1000];      GOFFSET offsets[1000];      ABC abc;      int script = items[item].a.eScript;      int ng;      int char_offset;      memset (advances, 0, sizeof (advances));      memset (offsets, 0, sizeof (offsets));      memset (&abc, 0, sizeof (abc));      /* Note that itemlen is number of wchar_t's i.e. surrogate pairs       * count as two!       */      itemlen = items[item+1].iCharPos - items[item].iCharPos;      char_offset = unichar_index (wtext, items[item].iCharPos);#ifdef BASIC_WIN32_DEBUGGING      if (pango_win32_debug)	g_print ("  Item %d: iCharPos=%d eScript=%d (%s) %s%s%s%s%s%s%s wchar_t %d--%d (%d)\n",		 item, items[item].iCharPos, script,		 lang_name (scripts[script]->langid),		 scripts[script]->fComplex ? "complex" : "simple",		 items[item].a.fRTL ? " fRTL" : "",		 items[item].a.fLayoutRTL ? " fLayoutRTL" : "",		 items[item].a.fLinkBefore ? " fLinkBefore" : "",		 items[item].a.fLinkAfter ? " fLinkAfter" : "",		 items[item].a.fLogicalOrder ? " fLogicalOrder" : "",		 items[item].a.fNoGlyphIndex ? " fNoGlyphIndex" : "",		 items[item].iCharPos, items[item+1].iCharPos-1, itemlen);#endif      items[item].a.fRTL = analysis->level % 2;      if ((*script_shape) (hdc, &script_cache[script],			   wtext + items[item].iCharPos, itemlen,			   G_N_ELEMENTS (iglyphs),			   &items[item].a,			   iglyphs,			   log_clusters,			   visattrs,			   &nglyphs))	{#ifdef BASIC_WIN32_DEBUGGING	  if (pango_win32_debug)	    g_print ("pango-basic-win32: ScriptShape failed\n");#endif	  return FALSE;	}#ifdef BASIC_WIN32_DEBUGGING      dump_glyphs_and_log_clusters (items[item].a.fRTL, itemlen,				    items[item].iCharPos, log_clusters,				    iglyphs, nglyphs);#endif      ng = glyphs->num_glyphs;      pango_glyph_string_set_size (glyphs, ng + nglyphs);      set_up_pango_log_clusters (wtext + items[item].iCharPos,				 items[item].a.fRTL, itemlen, log_clusters,				 nglyphs, glyphs->log_clusters + ng,				 char_offset);      if ((*script_place) (hdc, &script_cache[script], iglyphs, nglyphs,			   visattrs, &items[item].a,			   advances, offsets, &abc))	{#ifdef BASIC_WIN32_DEBUGGING	  if (pango_win32_debug)	    g_print ("pango-basic-win32: ScriptPlace failed\n");#endif	  return FALSE;	}      for (glyphix = 0; glyphix < nglyphs; glyphix++)	{	  if (iglyphs[glyphix] != 0)	    {	      glyphs->glyphs[ng+glyphix].glyph = iglyphs[glyphix];	      glyphs->glyphs[ng+glyphix].geometry.width = floor (0.5 + scale * advances[glyphix]);	      glyphs->glyphs[ng+glyphix].geometry.x_offset = floor (0.5 + scale * offsets[glyphix].du);	      glyphs->glyphs[ng+glyphix].geometry.y_offset = floor (0.5 + scale * offsets[glyphix].dv);	    }	  else	    {	      PangoRectangle logical_rect;	      /* Should pass actual char that was not found to	       * PANGO_GET_UNKNOWN_GLYPH(), but a bit hard to	       * find out that at this point, so cheat and use 0.	       */	      PangoGlyph unk = PANGO_GET_UNKNOWN_GLYPH (0);	      glyphs->glyphs[ng+glyphix].glyph = unk;	      pango_font_get_glyph_extents (font, unk, NULL, &logical_rect);	      glyphs->glyphs[ng+glyphix].geometry.width = logical_rect.width;	      glyphs->glyphs[ng+glyphix].geometry.x_offset = 0;	      glyphs->glyphs[ng+glyphix].geometry.y_offset = 0;	    }	}    }#ifdef BASIC_WIN32_DEBUGGING  if (pango_win32_debug)    {      g_print ("  Pango log_clusters (level:%d), char index:", analysis->level);      for (glyphix = 0; glyphix < glyphs->num_glyphs; glyphix++)	g_print ("%d ", glyphs->log_clusters[glyphix]);      g_print ("\n");    }#endif  return TRUE;}static gbooleanuniscribe_shape (PangoFont           *font,		 const char          *text,		 gint                 length,		 const PangoAnalysis *analysis,		 PangoGlyphString    *glyphs){  wchar_t *wtext;  long wlen;  int i;  gboolean retval = TRUE;  SCRIPT_CACHE script_cache[100];  if (!pango_win32_font_select_font (font, hdc))    return FALSE;  wtext = g_utf8_to_utf16 (text, length, NULL, &wlen, NULL);  if (wtext == NULL)    retval = FALSE;  if (retval)    {      memset (script_cache, 0, sizeof (script_cache));      retval = itemize_shape_and_place (font, hdc, wtext, wlen, analysis, glyphs, script_cache);      for (i = 0; i < G_N_ELEMENTS (script_cache); i++)	if (script_cache[i])	  (*script_free_cache)(&script_cache[i]);    }  if (retval)    {      convert_log_clusters_to_byte_offsets (text, length, glyphs);#ifdef BASIC_WIN32_DEBUGGING      if (pango_win32_debug)	{	  int glyphix;	  g_print ("  Pango log_clusters, byte offsets:");	  for (glyphix = 0; glyphix < glyphs->num_glyphs; glyphix++)	    g_print ("%d ", glyphs->log_clusters[glyphix]);	  g_print ("\n");	}#endif    }  pango_win32_font_done_font (font);  g_free (wtext);  return retval && glyphs->num_glyphs > 0;}static gbooleantext_is_simple (const char *text,		gint        length){  gboolean retval;  wchar_t *wtext;  long wlen;  wtext = (wchar_t *) g_utf8_to_utf16 (text, length, NULL, &wlen, NULL);  if (wtext == NULL)    return TRUE;  retval = ((*script_is_complex) (wtext, wlen, SIC_COMPLEX) == S_FALSE);  g_free (wtext);#ifdef BASIC_WIN32_DEBUGGING  if (pango_win32_debug)    g_print ("text_is_simple: %.*s (%ld wchar_t): %s\n",	     MIN (length, 10), text, wlen, retval ? "YES" : "NO");#endif  return retval;}static voidbasic_engine_shape (PangoEngineShape 	*engine,		    PangoFont        	*font,		    const char       	*text,		    int              	 length,		    const PangoAnalysis *analysis,		    PangoGlyphString    *glyphs){  int n_chars;  int i;  const char *p;  g_return_if_fail (font != NULL);  g_return_if_fail (text != NULL);  g_return_if_fail (length >= 0);  g_return_if_fail (analysis != NULL);  if (have_uniscribe &&      !text_is_simple (text, length) &&      uniscribe_shape (font, text, length, analysis, glyphs))    return;  n_chars = g_utf8_strlen (text, length);  pango_glyph_string_set_size (glyphs, n_chars);  p = text;  for (i = 0; i < n_chars; i++)    {      gunichar wc;      gunichar mirrored_ch;      PangoGlyph index;      wc = g_utf8_get_char (p);      if (analysis->level % 2)	if (pango_get_mirror_char (wc, &mirrored_ch))	  wc = mirrored_ch;      if (wc == 0xa0)	/* non-break-space */	wc = 0x20;      if (pango_is_zero_width (wc))	{	  set_glyph (font, glyphs, i, p - text, PANGO_GLYPH_EMPTY);	}      else	{	  index = find_char (font, wc);	  if (index)	    {	      set_glyph (font, glyphs, i, p - text, index);	      if (g_unichar_type (wc) == G_UNICODE_NON_SPACING_MARK)		{		  if (i > 0)		    {		      PangoRectangle logical_rect, ink_rect;		      glyphs->glyphs[i].geometry.width = MAX (glyphs->glyphs[i-1].geometry.width,							      glyphs->glyphs[i].geometry.width);		      glyphs->glyphs[i-1].geometry.width = 0;		      glyphs->log_clusters[i] = glyphs->log_clusters[i-1];		      /* Some heuristics to try to guess how overstrike glyphs are		       * done and compensate		       */		      /* FIXME: (alex) Is this double call to get_glyph_extents really necessary? */		      pango_font_get_glyph_extents (font, glyphs->glyphs[i].glyph, &ink_rect, &logical_rect);		      if (logical_rect.width == 0 && ink_rect.x == 0)			glyphs->glyphs[i].geometry.x_offset = (glyphs->glyphs[i].geometry.width - ink_rect.width) / 2;		    }		}	    }	  else	    set_glyph (font, glyphs, i, p - text, PANGO_GET_UNKNOWN_GLYPH (wc));	}      p = g_utf8_next_char (p);    }  /* Simple bidi support... may have separate modules later */  if (analysis->level % 2)    {      int start, end;      /* Swap all glyphs */      swap_range (glyphs, 0, n_chars);      /* Now reorder glyphs within each cluster back to LTR */      for (start = 0; start < n_chars;)	{	  end = start;	  while (end < n_chars &&		 glyphs->log_clusters[end] == glyphs->log_clusters[start])	    end++;	  swap_range (glyphs, start, end);	  start = end;	}    }}static voidinit_uniscribe (void){  HMODULE usp10_dll;  have_uniscribe = FALSE;  if ((usp10_dll = LoadLibrary ("usp10.dll")) != NULL)    {      (script_get_properties = (pScriptGetProperties)       GetProcAddress (usp10_dll, "ScriptGetProperties")) &&      (script_itemize = (pScriptItemize)       GetProcAddress (usp10_dll, "ScriptItemize")) &&      (script_shape = (pScriptShape)       GetProcAddress (usp10_dll, "ScriptShape")) &&      (script_place = (pScriptPlace)       GetProcAddress (usp10_dll, "ScriptPlace")) &&      (script_free_cache = (pScriptFreeCache)       GetProcAddress (usp10_dll, "ScriptFreeCache")) &&      (script_is_complex = (pScriptIsComplex)       GetProcAddress (usp10_dll, "ScriptIsComplex")) &&      (have_uniscribe = TRUE);    }  if (have_uniscribe)    {#ifdef BASIC_WIN32_DEBUGGING      (*script_get_properties) (&scripts, &nscripts);#endif      hdc = pango_win32_get_dc ();    }}static voidbasic_engine_win32_class_init (PangoEngineShapeClass *class){  class->script_shape = basic_engine_shape;}PANGO_ENGINE_SHAPE_DEFINE_TYPE (BasicEngineWin32, basic_engine_win32,				basic_engine_win32_class_init, NULL);voidPANGO_MODULE_ENTRY(init) (GTypeModule *module){  init_uniscribe ();  if (pango_win32_get_debug_flag ())    pango_win32_debug = TRUE;  basic_engine_win32_register_type (module);}voidPANGO_MODULE_ENTRY(exit) (void){}voidPANGO_MODULE_ENTRY(list) (PangoEngineInfo **engines,			  int              *n_engines){  init_uniscribe ();  script_engines[0].scripts = basic_scripts;  script_engines[0].n_scripts = G_N_ELEMENTS (basic_scripts);  if (have_uniscribe)    {#if 0      int i;      GArray *ranges = g_array_new (FALSE, FALSE, sizeof (PangoEngineRange));      /* Walk through scripts supported by the Uniscribe implementation on this       * machine, and mark corresponding Unicode ranges.       */      for (i = 0; i < nscripts; i++)	{	}      /* Sort range array */      g_array_sort (ranges, compare_range);      script_engines[0].ranges = ranges;      script_engines[0].n_ranges = ranges->len;#else      script_engines[0].scripts = uniscribe_scripts;      script_engines[0].n_scripts = G_N_ELEMENTS (uniscribe_scripts);#endif    }  *engines = script_engines;  *n_engines = G_N_ELEMENTS (script_engines);}PangoEngine *PANGO_MODULE_ENTRY(create) (const char *id){  if (!strcmp (id, SCRIPT_ENGINE_NAME))    return g_object_new (basic_engine_win32_type, NULL);  else    return NULL;}

⌨️ 快捷键说明

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