[win32] Use pango_win32_font_description_from_logfontw() to get
the system font, instead of the code duplication.
This commit is contained in:
		 Martin Schlemmer
					Martin Schlemmer
				
			
				
					committed by
					
						 Fridrich Štrba
						Fridrich Štrba
					
				
			
			
				
	
			
			
			 Fridrich Štrba
						Fridrich Štrba
					
				
			
						parent
						
							04e241fd85
						
					
				
				
					commit
					8476d22dea
				
			| @ -30,6 +30,9 @@ | ||||
|  *  http://msdn.microsoft.com/library/default.asp?url=/library/en-us/gdi/pantdraw_4b3g.asp | ||||
|  */ | ||||
|  | ||||
| /* Include first, else we get redefinition warnings about STRICT */ | ||||
| #include "pango/pangowin32.h" | ||||
|  | ||||
| #include "msw_style.h" | ||||
| #include "xp_theme.h" | ||||
|  | ||||
| @ -172,24 +175,22 @@ static struct | ||||
| }; | ||||
|  | ||||
| static gboolean | ||||
| get_system_font (XpThemeClass klazz, XpThemeFont type, LOGFONT *out_lf) | ||||
| get_system_font (XpThemeClass klazz, XpThemeFont type, LOGFONTW *out_lf) | ||||
| { | ||||
| #if 0 | ||||
|   /* TODO: this causes crashes later because the font name is in UCS2, and | ||||
|      the pango fns don't deal with that gracefully */ | ||||
|   if (xp_theme_get_system_font (klazz, type, out_lf)) | ||||
|     { | ||||
|       return TRUE; | ||||
|     } | ||||
|   else | ||||
| #endif | ||||
|     { | ||||
|       NONCLIENTMETRICS ncm; | ||||
|       /* Use wide char versions here, as the theming functions only support | ||||
|        * wide chars versions of the structures. */ | ||||
|       NONCLIENTMETRICSW ncm; | ||||
|  | ||||
|       ncm.cbSize = sizeof (NONCLIENTMETRICS); | ||||
|       ncm.cbSize = sizeof (NONCLIENTMETRICSW); | ||||
|  | ||||
|       if (SystemParametersInfo (SPI_GETNONCLIENTMETRICS, | ||||
| 				sizeof (NONCLIENTMETRICS), &ncm, 0)) | ||||
|       if (SystemParametersInfoW (SPI_GETNONCLIENTMETRICS, | ||||
| 				sizeof (NONCLIENTMETRICSW), &ncm, 0)) | ||||
| 	{ | ||||
| 	  if (type == XP_THEME_FONT_CAPTION) | ||||
| 	    *out_lf = ncm.lfCaptionFont; | ||||
| @ -207,312 +208,56 @@ get_system_font (XpThemeClass klazz, XpThemeFont type, LOGFONT *out_lf) | ||||
|   return FALSE; | ||||
| } | ||||
|  | ||||
| /***************************** BEGIN STOLEN FROM PANGO *****************************/ | ||||
|  | ||||
| /* | ||||
| 	This code is stolen from Pango 1.4. It attempts to address the following problems: | ||||
|  | ||||
| 	http://bugzilla.gnome.org/show_bug.cgi?id=135098 | ||||
| 	http://sourceforge.net/tracker/index.php?func=detail&aid=895762&group_id=76416&atid=547655 | ||||
|  | ||||
| 	As Owen suggested in bug 135098, once Pango 1.6 is released, we need to get rid of this code. | ||||
| */ | ||||
|  | ||||
| #define PING(printlist) | ||||
|  | ||||
| /* TrueType defines: */ | ||||
|  | ||||
| #define MAKE_TT_TABLE_NAME(c1, c2, c3, c4) \ | ||||
|    (((guint32)c4) << 24 | ((guint32)c3) << 16 | ((guint32)c2) << 8 | ((guint32)c1)) | ||||
|  | ||||
| #define CMAP (MAKE_TT_TABLE_NAME('c','m','a','p')) | ||||
| #define CMAP_HEADER_SIZE 4 | ||||
|  | ||||
| #define NAME (MAKE_TT_TABLE_NAME('n','a','m','e')) | ||||
| #define NAME_HEADER_SIZE 6 | ||||
|  | ||||
| #define ENCODING_TABLE_SIZE 8 | ||||
|  | ||||
| #define APPLE_UNICODE_PLATFORM_ID 0 | ||||
| #define MACINTOSH_PLATFORM_ID 1 | ||||
| #define ISO_PLATFORM_ID 2 | ||||
| #define MICROSOFT_PLATFORM_ID 3 | ||||
|  | ||||
| #define SYMBOL_ENCODING_ID 0 | ||||
| #define UNICODE_ENCODING_ID 1 | ||||
| #define UCS4_ENCODING_ID 10 | ||||
|  | ||||
| struct name_header | ||||
| { | ||||
|   guint16 format_selector; | ||||
|   guint16 num_records; | ||||
|   guint16 string_storage_offset; | ||||
| }; | ||||
|  | ||||
| struct name_record | ||||
| { | ||||
|   guint16 platform_id; | ||||
|   guint16 encoding_id; | ||||
|   guint16 language_id; | ||||
|   guint16 name_id; | ||||
|   guint16 string_length; | ||||
|   guint16 string_offset; | ||||
| }; | ||||
|  | ||||
| static gboolean | ||||
| pango_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; | ||||
| } | ||||
|  | ||||
| static gboolean | ||||
| pango_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 gchar * | ||||
| get_family_name (LOGFONT *lfp, HDC pango_win32_hdc) | ||||
| { | ||||
|   HFONT hfont; | ||||
|   HFONT oldhfont; | ||||
|  | ||||
|   struct name_header header; | ||||
|   struct name_record record; | ||||
|  | ||||
|   gint unicode_ix = -1, mac_ix = -1, microsoft_ix = -1; | ||||
|   gint name_ix; | ||||
|   gchar *codeset; | ||||
|  | ||||
|   gchar *string = NULL; | ||||
|   gchar *name; | ||||
|  | ||||
|   size_t i, l, nbytes; | ||||
|  | ||||
|   /* If lfFaceName is ASCII, assume it is the common (English) name for the | ||||
|      font. Is this valid? Do some TrueType fonts have different names in | ||||
|      French, German, etc, and does the system return these if the locale is | ||||
|      set to use French, German, etc? */ | ||||
|   l = strlen (lfp->lfFaceName); | ||||
|   for (i = 0; i < l; i++) | ||||
|     { | ||||
|       if (lfp->lfFaceName[i] < ' ' || lfp->lfFaceName[i] > '~') | ||||
| 	{ | ||||
| 	  break; | ||||
| 	} | ||||
|     } | ||||
|  | ||||
|   if (i == l) | ||||
|     return g_strdup (lfp->lfFaceName); | ||||
|  | ||||
|   if ((hfont = CreateFontIndirect (lfp)) == NULL) | ||||
|     goto fail0; | ||||
|  | ||||
|   if ((oldhfont = (HFONT) SelectObject (pango_win32_hdc, hfont)) == NULL) | ||||
|     goto fail1; | ||||
|  | ||||
|   if (!pango_win32_get_name_header (pango_win32_hdc, &header)) | ||||
|     goto fail2; | ||||
|  | ||||
|   PING (("%d name records", header.num_records)); | ||||
|  | ||||
|   for (i = 0; i < header.num_records; i++) | ||||
|     { | ||||
|       if (!pango_win32_get_name_record (pango_win32_hdc, i, &record)) | ||||
| 	goto fail2; | ||||
|  | ||||
|       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 == APPLE_UNICODE_PLATFORM_ID || | ||||
| 	  record.platform_id == ISO_PLATFORM_ID) | ||||
| 	{ | ||||
| 	  unicode_ix = i; | ||||
| 	} | ||||
|       else if (record.platform_id == MACINTOSH_PLATFORM_ID && record.encoding_id == 0 &&	/* Roman | ||||
| 												 */ | ||||
| 	       record.language_id == 0)	/* English */ | ||||
| 	{ | ||||
| 	  mac_ix = i; | ||||
| 	} | ||||
|       else if (record.platform_id == MICROSOFT_PLATFORM_ID) | ||||
| 	{ | ||||
| 	  if ((microsoft_ix == -1 || | ||||
| 	       PRIMARYLANGID (record.language_id) == LANG_ENGLISH) && | ||||
| 	      (record.encoding_id == SYMBOL_ENCODING_ID || | ||||
| 	       record.encoding_id == UNICODE_ENCODING_ID || | ||||
| 	       record.encoding_id == UCS4_ENCODING_ID)) | ||||
| 	    { | ||||
| 	      microsoft_ix = i; | ||||
| 	    } | ||||
| 	} | ||||
|     } | ||||
|  | ||||
|   if (microsoft_ix >= 0) | ||||
|     name_ix = microsoft_ix; | ||||
|   else if (mac_ix >= 0) | ||||
|     name_ix = mac_ix; | ||||
|   else if (unicode_ix >= 0) | ||||
|     name_ix = unicode_ix; | ||||
|   else | ||||
|     goto fail2; | ||||
|  | ||||
|   if (!pango_win32_get_name_record (pango_win32_hdc, name_ix, &record)) | ||||
|     goto fail2; | ||||
|  | ||||
|   string = g_malloc (record.string_length + 1); | ||||
|   if (GetFontData (pango_win32_hdc, NAME, | ||||
| 		   header.string_storage_offset + record.string_offset, | ||||
| 		   string, record.string_length) != record.string_length) | ||||
|     goto fail2; | ||||
|  | ||||
|   string[record.string_length] = '\0'; | ||||
|  | ||||
|   if (name_ix == microsoft_ix) | ||||
|     { | ||||
|       if (record.encoding_id == SYMBOL_ENCODING_ID || | ||||
| 	  record.encoding_id == UNICODE_ENCODING_ID) | ||||
| 	{ | ||||
| 	  codeset = "UTF-16BE"; | ||||
| 	} | ||||
|       else | ||||
| 	{ | ||||
| 	  codeset = "UCS-4BE"; | ||||
| 	} | ||||
|     } | ||||
|   else if (name_ix == mac_ix) | ||||
|     { | ||||
|       codeset = "MacRoman"; | ||||
|     } | ||||
|   else				/* name_ix == unicode_ix */ | ||||
|     { | ||||
|       codeset = "UCS-4BE"; | ||||
|     } | ||||
|  | ||||
|  | ||||
|   name = g_convert (string, record.string_length, "UTF-8", codeset, NULL, | ||||
| 		    &nbytes, NULL); | ||||
|   if (name == NULL) | ||||
|     goto fail2; | ||||
|  | ||||
|   g_free (string); | ||||
|  | ||||
|   PING (("%s", name)); | ||||
|  | ||||
|   SelectObject (pango_win32_hdc, oldhfont); | ||||
|   DeleteObject (hfont); | ||||
|  | ||||
|   return name; | ||||
|  | ||||
| fail2: | ||||
|   g_free (string); | ||||
|   SelectObject (pango_win32_hdc, oldhfont); | ||||
|  | ||||
| fail1: | ||||
|   DeleteObject (hfont); | ||||
|  | ||||
| fail0: | ||||
|   return g_locale_to_utf8 (lfp->lfFaceName, -1, NULL, NULL, NULL); | ||||
| } | ||||
|  | ||||
| /***************************** END STOLEN FROM PANGO *****************************/ | ||||
|  | ||||
| static char * | ||||
| sys_font_to_pango_font (XpThemeClass klazz, XpThemeFont type, char *buf, | ||||
| 			size_t bufsiz) | ||||
| { | ||||
|   HDC hDC; | ||||
|   HWND hwnd; | ||||
|   LOGFONT lf; | ||||
|   int pt_size; | ||||
|   const char *weight; | ||||
|   const char *style; | ||||
|   char *font; | ||||
|   LOGFONTW lf; | ||||
|  | ||||
|   if (get_system_font (klazz, type, &lf)) | ||||
|     { | ||||
|       switch (lf.lfWeight) | ||||
| 	{ | ||||
| 	case FW_THIN: | ||||
| 	case FW_EXTRALIGHT: | ||||
| 	  weight = "Ultra-Light"; | ||||
| 	  break; | ||||
|       PangoFontDescription *desc = NULL; | ||||
|       int pt_size; | ||||
|       const char *font; | ||||
|  | ||||
| 	case FW_LIGHT: | ||||
| 	  weight = "Light"; | ||||
| 	  break; | ||||
|  | ||||
| 	case FW_BOLD: | ||||
| 	  weight = "Bold"; | ||||
| 	  break; | ||||
|  | ||||
| 	case FW_SEMIBOLD: | ||||
| 	  weight = "Semi-Bold"; | ||||
| 	  break; | ||||
|  | ||||
| 	case FW_ULTRABOLD: | ||||
| 	  weight = "Ultra-Bold"; | ||||
| 	  break; | ||||
|  | ||||
| 	case FW_HEAVY: | ||||
| 	  weight = "Heavy"; | ||||
| 	  break; | ||||
|  | ||||
| 	default: | ||||
| 	  weight = ""; | ||||
| 	  break; | ||||
| 	} | ||||
|  | ||||
|       if (lf.lfItalic) | ||||
| 	style = "Italic"; | ||||
|       else | ||||
| 	style = ""; | ||||
|  | ||||
|       hwnd = GetDesktopWindow (); | ||||
|       hDC = GetDC (hwnd); | ||||
|       if (hDC) | ||||
| 	{ | ||||
| 	  pt_size = -MulDiv (lf.lfHeight, 72, | ||||
| 			     GetDeviceCaps (hDC, LOGPIXELSY)); | ||||
| 	} | ||||
|       else | ||||
| 	{ | ||||
| 	  pt_size = 10; | ||||
| 	} | ||||
|  | ||||
|       font = get_family_name (&lf, hDC); | ||||
|  | ||||
|       if (hDC) | ||||
| 	ReleaseDC (hwnd, hDC); | ||||
|  | ||||
|       if (!(font && *font)) | ||||
|       desc = pango_win32_font_description_from_logfontw (&lf); | ||||
|       if (!desc) | ||||
| 	return NULL; | ||||
|  | ||||
|       g_snprintf (buf, bufsiz, "%s %s %s %d", font, style, weight, pt_size); | ||||
|       g_free (font); | ||||
|       font = pango_font_description_to_string (desc); | ||||
|       pt_size = pango_font_description_get_size (desc); | ||||
|  | ||||
|       if (!(font && *font)) | ||||
| 	{ | ||||
| 	  pango_font_description_free (desc); | ||||
| 	  return NULL; | ||||
| 	} | ||||
|  | ||||
|       if (pt_size == 0) | ||||
| 	{ | ||||
| 	  HDC hDC; | ||||
| 	  HWND hwnd; | ||||
|  | ||||
| 	  hwnd = GetDesktopWindow (); | ||||
| 	  hDC = GetDC (hwnd); | ||||
|  | ||||
| 	  if (hDC) | ||||
| 	    pt_size = -MulDiv (lf.lfHeight, 72, GetDeviceCaps (hDC, LOGPIXELSY)); | ||||
| 	  else | ||||
| 	    pt_size = 10; | ||||
|  | ||||
| 	  if (hDC) | ||||
| 	    ReleaseDC (hwnd, hDC); | ||||
|  | ||||
| 	  g_snprintf (buf, bufsiz, "%s %d", font, pt_size); | ||||
| 	} | ||||
|       else | ||||
| 	{ | ||||
| 	  g_snprintf (buf, bufsiz, "%s", font); | ||||
| 	} | ||||
|  | ||||
|       if (desc) | ||||
| 	pango_font_description_free (desc); | ||||
|  | ||||
|       return buf; | ||||
|     } | ||||
|  | ||||
		Reference in New Issue
	
	Block a user