1 /* GDK - The GIMP Drawing Kit
2 * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Library General Public
6 * License as published by the Free Software Foundation; either
7 * version 2 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Library General Public License for more details.
14 * You should have received a copy of the GNU Library General Public
15 * License along with this library; if not, write to the
16 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17 * Boston, MA 02111-1307, USA.
21 * Modified by the GTK+ Team and others 1997-1999. See the AUTHORS
22 * file for a list of people on the GTK+ Team. See the ChangeLog
23 * files for a list of changes. These files are distributed with
24 * GTK+ at ftp://ftp.gtk.org/pub/gtk/.
33 #include "gdkprivate.h"
36 gdk_font_load (const gchar *font_name)
39 GdkFontPrivate *private;
42 TEXTMETRIC textmetric;
44 DWORD fdwItalic, fdwUnderline, fdwStrikeOut, fdwCharSet,
45 fdwOutputPrecision, fdwClipPrecision, fdwQuality, fdwPitchAndFamily;
48 int numfields, n1, n2, tries;
49 char foundry[32], family[100], weight[32], slant[32], set_width[32],
50 spacing[32], registry[32], encoding[32];
51 char pixel_size[10], point_size[10], res_x[10], res_y[10], avg_width[10];
54 int nHeight, nWidth, nEscapement, nOrientation, fnWeight;
57 g_return_val_if_fail (font_name != NULL, NULL);
59 private = g_new (GdkFontPrivate, 1);
60 font = (GdkFont*) private;
62 numfields = sscanf (font_name,
63 "-%30[^-]-%100[^-]-%30[^-]-%30[^-]-%30[^-]-%n",
72 /* Probably a plain Windows font name */
77 fnWeight = FW_DONTCARE;
81 fdwCharSet = ANSI_CHARSET;
82 fdwOutputPrecision = OUT_TT_PRECIS;
83 fdwClipPrecision = CLIP_DEFAULT_PRECIS;
84 fdwQuality = PROOF_QUALITY;
85 fdwPitchAndFamily = DEFAULT_PITCH;
88 else if (numfields != 5)
90 g_warning ("gdk_font_load: font name %s illegal", font_name);
96 /* It must be a XLFD name */
98 /* Check for hex escapes in the font family,
99 * put in there by gtkfontsel.
104 if (*p == '%' && isxdigit (p[1]) && isxdigit (p[2]))
106 sscanf (p+1, "%2x", &c);
113 /* Skip add_style which often is empty in the requested font name */
114 while (font_name[n1] && font_name[n1] != '-')
118 numfields += sscanf (font_name + n1,
119 "-%8[^-]-%8[^-]-%8[^-]-%8[^-]-%30[^-]-%8[^-]-%30[^-]-%30[^-]%n",
130 if (numfields != 14 || font_name[n1 + n2] != '\0')
132 g_warning ("gdk_font_load: font name %s illegal", font_name);
137 logpixelsy = GetDeviceCaps (gdk_DC, LOGPIXELSY);
139 if (strcmp (pixel_size, "*") == 0)
140 if (strcmp (point_size, "*") == 0)
143 nHeight = (int) (((double) atoi (point_size))/720.*logpixelsy);
145 nHeight = atoi (pixel_size);
151 if (g_strcasecmp (weight, "thin") == 0)
153 else if (g_strcasecmp (weight, "extralight") == 0)
154 fnWeight = FW_EXTRALIGHT;
156 else if (g_strcasecmp (weight, "ultralight") == 0)
157 fnWeight = FW_ULTRALIGHT;
159 else if (g_strcasecmp (weight, "light") == 0)
161 else if (g_strcasecmp (weight, "normal") == 0)
162 fnWeight = FW_NORMAL;
163 else if (g_strcasecmp (weight, "regular") == 0)
164 fnWeight = FW_REGULAR;
165 else if (g_strcasecmp (weight, "medium") == 0)
166 fnWeight = FW_MEDIUM;
167 else if (g_strcasecmp (weight, "semibold") == 0)
168 fnWeight = FW_SEMIBOLD;
170 else if (g_strcasecmp (weight, "demibold") == 0)
171 fnWeight = FW_DEMIBOLD;
173 else if (g_strcasecmp (weight, "bold") == 0)
175 else if (g_strcasecmp (weight, "extrabold") == 0)
176 fnWeight = FW_EXTRABOLD;
178 else if (g_strcasecmp (weight, "ultrabold") == 0)
179 fnWeight = FW_ULTRABOLD;
181 else if (g_strcasecmp (weight, "heavy") == 0)
184 else if (g_strcasecmp (weight, "black") == 0)
188 fnWeight = FW_DONTCARE;
190 if (g_strcasecmp (slant, "italic") == 0
191 || g_strcasecmp (slant, "oblique") == 0
192 || g_strcasecmp (slant, "i") == 0
193 || g_strcasecmp (slant, "o") == 0)
197 fdwUnderline = FALSE;
198 fdwStrikeOut = FALSE;
199 if (g_strcasecmp (registry, "iso8859") == 0)
200 if (strcmp (encoding, "1") == 0)
201 fdwCharSet = ANSI_CHARSET;
203 fdwCharSet = ANSI_CHARSET; /* XXX ??? */
204 else if (g_strcasecmp (registry, "windows") == 0)
205 if (g_strcasecmp (encoding, "symbol") == 0)
206 fdwCharSet = SYMBOL_CHARSET;
207 else if (g_strcasecmp (encoding, "shiftjis") == 0)
208 fdwCharSet = SHIFTJIS_CHARSET;
209 else if (g_strcasecmp (encoding, "gb2312") == 0)
210 fdwCharSet = GB2312_CHARSET;
211 else if (g_strcasecmp (encoding, "hangeul") == 0)
212 fdwCharSet = HANGEUL_CHARSET;
213 else if (g_strcasecmp (encoding, "chinesebig5") == 0)
214 fdwCharSet = CHINESEBIG5_CHARSET;
216 else if (g_strcasecmp (encoding, "johab") == 0)
217 fdwCharSet = JOHAB_CHARSET;
219 else if (g_strcasecmp (encoding, "hebrew") == 0)
220 fdwCharSet = HEBREW_CHARSET;
221 else if (g_strcasecmp (encoding, "arabic") == 0)
222 fdwCharSet = ARABIC_CHARSET;
223 else if (g_strcasecmp (encoding, "greek") == 0)
224 fdwCharSet = GREEK_CHARSET;
225 else if (g_strcasecmp (encoding, "turkish") == 0)
226 fdwCharSet = TURKISH_CHARSET;
227 else if (g_strcasecmp (encoding, "easteurope") == 0)
228 fdwCharSet = EASTEUROPE_CHARSET;
229 else if (g_strcasecmp (encoding, "russian") == 0)
230 fdwCharSet = RUSSIAN_CHARSET;
231 else if (g_strcasecmp (encoding, "mac") == 0)
232 fdwCharSet = MAC_CHARSET;
233 else if (g_strcasecmp (encoding, "baltic") == 0)
234 fdwCharSet = BALTIC_CHARSET;
236 fdwCharSet = ANSI_CHARSET; /* XXX ??? */
238 fdwCharSet = ANSI_CHARSET; /* XXX ??? */
239 fdwOutputPrecision = OUT_TT_PRECIS;
240 fdwClipPrecision = CLIP_DEFAULT_PRECIS;
241 fdwQuality = PROOF_QUALITY;
242 if (g_strcasecmp (spacing, "m") == 0)
243 fdwPitchAndFamily = FIXED_PITCH;
244 else if (g_strcasecmp (spacing, "p") == 0)
245 fdwPitchAndFamily = VARIABLE_PITCH;
247 fdwPitchAndFamily = DEFAULT_PITCH;
251 for (tries = 0; ; tries++)
253 GDK_NOTE (MISC, g_print ("gdk_font_load: trying CreateFont(%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%#.02x,\"%s\")\n",
254 nHeight, nWidth, nEscapement, nOrientation,
255 fnWeight, fdwItalic, fdwUnderline, fdwStrikeOut,
256 fdwCharSet, fdwOutputPrecision, fdwClipPrecision,
257 fdwQuality, fdwPitchAndFamily, lpszFace));
258 if ((private->xfont =
259 CreateFont (nHeight, nWidth, nEscapement, nOrientation,
260 fnWeight, fdwItalic, fdwUnderline, fdwStrikeOut,
261 fdwCharSet, fdwOutputPrecision, fdwClipPrecision,
262 fdwQuality, fdwPitchAndFamily, lpszFace)) != NULL)
265 /* If we fail, try some similar fonts often found on Windows. */
269 if (g_strcasecmp (family, "helvetica") == 0)
271 else if (g_strcasecmp (family, "new century schoolbook") == 0)
272 lpszFace = "century schoolbook";
273 else if (g_strcasecmp (family, "courier") == 0)
274 lpszFace = "courier new";
275 else if (g_strcasecmp (family, "lucida") == 0)
276 lpszFace = "lucida sans unicode";
277 else if (g_strcasecmp (family, "lucidatypewriter") == 0)
278 lpszFace = "lucida console";
279 else if (g_strcasecmp (family, "times") == 0)
280 lpszFace = "times new roman";
284 if (g_strcasecmp (family, "courier") == 0)
287 fdwPitchAndFamily |= FF_MODERN;
289 else if (g_strcasecmp (family, "times new roman") == 0)
292 fdwPitchAndFamily |= FF_ROMAN;
294 else if (g_strcasecmp (family, "helvetica") == 0
295 || g_strcasecmp (family, "lucida") == 0)
298 fdwPitchAndFamily |= FF_SWISS;
303 fdwPitchAndFamily = (fdwPitchAndFamily & 0x0F) | FF_DONTCARE;
313 g_warning ("gdk_font_load: font %s not found", font_name);
318 private->ref_count = 1;
319 font->type = GDK_FONT_FONT;
320 GetObject (private->xfont, sizeof (logfont), &logfont);
321 oldfont = SelectObject (gdk_DC, private->xfont);
322 GetTextMetrics (gdk_DC, &textmetric);
323 SelectObject (gdk_DC, oldfont);
324 font->ascent = textmetric.tmAscent;
325 font->descent = textmetric.tmDescent;
327 GDK_NOTE (MISC, g_print ("gdk_font_load: %s = %#x asc %d desc %d\n",
328 font_name, private->xfont,
329 font->ascent, font->descent));
331 /* This memory is leaked, so shoot me. */
332 f = g_new (HANDLE, 1);
333 *f = (HANDLE) ((guint) private->xfont + HFONT_DITHER);
334 gdk_xid_table_insert (f, font);
340 gdk_fontset_load (gchar *fontset_name)
342 g_warning ("gdk_fontset_load: Not implemented");
347 gdk_font_ref (GdkFont *font)
349 GdkFontPrivate *private;
351 g_return_val_if_fail (font != NULL, NULL);
353 private = (GdkFontPrivate*) font;
354 private->ref_count += 1;
359 gdk_font_unref (GdkFont *font)
361 GdkFontPrivate *private;
363 g_return_if_fail (font != NULL);
365 private = (GdkFontPrivate*) font;
367 private->ref_count -= 1;
368 if (private->ref_count == 0)
373 GDK_NOTE (MISC, g_print ("gdk_font_unref %#x\n", private->xfont));
375 gdk_xid_table_remove ((HANDLE) ((guint) private->xfont + HFONT_DITHER));
376 DeleteObject (private->xfont);
380 g_assert_not_reached ();
387 gdk_font_id (const GdkFont *font)
389 const GdkFontPrivate *font_private;
391 g_return_val_if_fail (font != NULL, 0);
393 font_private = (const GdkFontPrivate*) font;
395 if (font->type == GDK_FONT_FONT)
396 return (gint) font_private->xfont;
398 g_assert_not_reached ();
403 gdk_font_equal (const GdkFont *fonta,
404 const GdkFont *fontb)
406 const GdkFontPrivate *privatea;
407 const GdkFontPrivate *privateb;
409 g_return_val_if_fail (fonta != NULL, FALSE);
410 g_return_val_if_fail (fontb != NULL, FALSE);
412 privatea = (const GdkFontPrivate*) fonta;
413 privateb = (const GdkFontPrivate*) fontb;
415 if (fonta->type == GDK_FONT_FONT && fontb->type == GDK_FONT_FONT)
416 return (privatea->xfont == privateb->xfont);
418 g_assert_not_reached ();
423 gdk_string_width (GdkFont *font,
426 return gdk_text_width (font, string, strlen (string));
430 gdk_text_width (GdkFont *font,
434 GdkFontPrivate *private;
439 g_return_val_if_fail (font != NULL, -1);
440 g_return_val_if_fail (text != NULL, -1);
442 private = (GdkFontPrivate*) font;
447 oldfont = SelectObject (gdk_DC, private->xfont);
448 GetTextExtentPoint32A (gdk_DC, text, text_length, &size);
449 SelectObject (gdk_DC, oldfont);
454 g_assert_not_reached ();
460 gdk_text_width_wc (GdkFont *font,
461 const GdkWChar *text,
464 GdkFontPrivate *private;
470 g_return_val_if_fail (font != NULL, -1);
471 g_return_val_if_fail (text != NULL, -1);
473 private = (GdkFontPrivate*) font;
478 wcstr = g_new (wchar_t, text_length);
479 for (i = 0; i < text_length; i++)
481 oldfont = SelectObject (gdk_DC, private->xfont);
482 GetTextExtentPoint32W (gdk_DC, wcstr, text_length, &size);
484 SelectObject (gdk_DC, oldfont);
495 gdk_char_width (GdkFont *font,
498 return gdk_text_width (font, &character, 1);
502 gdk_char_width_wc (GdkFont *font,
505 return gdk_text_width_wc (font, &character, 1);
509 gdk_string_measure (GdkFont *font,
512 g_return_val_if_fail (font != NULL, -1);
513 g_return_val_if_fail (string != NULL, -1);
515 return gdk_text_measure (font, string, strlen (string));
519 gdk_text_extents (GdkFont *font,
528 GdkFontPrivate *private;
532 g_return_if_fail (font != NULL);
533 g_return_if_fail (text != NULL);
535 private = (GdkFontPrivate*) font;
540 oldfont = SelectObject (gdk_DC, private->xfont);
541 GetTextExtentPoint32A (gdk_DC, text, text_length, &size);
542 SelectObject (gdk_DC, oldfont);
543 /* XXX This is all quite bogus */
551 *ascent = size.cy + 1;
553 *descent = font->descent + 1;
557 g_assert_not_reached ();
562 gdk_text_extents_wc (GdkFont *font,
563 const GdkWChar *text,
571 GdkFontPrivate *private;
577 g_return_if_fail (font != NULL);
578 g_return_if_fail (text != NULL);
580 private = (GdkFontPrivate*) font;
585 wcstr = g_new (wchar_t, text_length);
586 for (i = 0; i < text_length; i++)
588 oldfont = SelectObject (gdk_DC, private->xfont);
589 GetTextExtentPoint32W (gdk_DC, wcstr, text_length, &size);
591 SelectObject (gdk_DC, oldfont);
593 /* XXX This is all quite bogus */
601 *ascent = size.cy + 1;
603 *descent = font->descent + 1;
607 g_assert_not_reached ();
612 gdk_string_extents (GdkFont *font,
620 g_return_if_fail (font != NULL);
621 g_return_if_fail (string != NULL);
623 gdk_text_extents (font, string, strlen (string),
624 lbearing, rbearing, width, ascent, descent);
629 gdk_text_measure (GdkFont *font,
633 GdkFontPrivate *private;
636 g_return_val_if_fail (font != NULL, -1);
637 g_return_val_if_fail (text != NULL, -1);
639 private = (GdkFontPrivate*) font;
644 return gdk_text_width (font, text, text_length); /* ??? */
648 g_assert_not_reached ();
654 gdk_char_measure (GdkFont *font,
657 g_return_val_if_fail (font != NULL, -1);
659 return gdk_text_measure (font, &character, 1);
663 gdk_string_height (GdkFont *font,
666 g_return_val_if_fail (font != NULL, -1);
667 g_return_val_if_fail (string != NULL, -1);
669 return gdk_text_height (font, string, strlen (string));
673 gdk_text_height (GdkFont *font,
677 GdkFontPrivate *private;
682 g_return_val_if_fail (font != NULL, -1);
683 g_return_val_if_fail (text != NULL, -1);
685 private = (GdkFontPrivate*) font;
690 oldfont = SelectObject (gdk_DC, private->xfont);
691 GetTextExtentPoint32 (gdk_DC, text, text_length, &size);
692 SelectObject (gdk_DC, oldfont);
697 g_error ("font->type = %d", font->type);
703 gdk_char_height (GdkFont *font,
706 g_return_val_if_fail (font != NULL, -1);
708 return gdk_text_height (font, &character, 1);