#include "device.h"
#include "insdel.h"
-#ifdef __CYGWIN32__
+#if (defined(__CYGWIN32__) || defined(__MINGW32__)) && \
+ CYGWIN_VERSION_DLL_MAJOR < 21
#define stricmp strcasecmp
+#define FONTENUMPROC FONTENUMEXPROC
+#define ntmTm ntmentm
#endif
typedef struct colormap_t
{
- char *name;
- COLORREF colorref;
+ CONST char *name;
+ CONST COLORREF colorref;
} colormap_t;
/* Colors from X11R6 "XConsortium: rgb.txt,v 10.41 94/02/20 18:39:36 rws Exp" */
{"LightGreen" , PALETTERGB (144, 238, 144) }
};
+
+typedef struct fontmap_t
+{
+ CONST char *name;
+ CONST int value;
+} fontmap_t;
+
+/* Default weight first, preferred names listed before synonyms */
+static CONST fontmap_t fontweight_map[] =
+{
+ {"Regular" , FW_REGULAR}, /* The standard font weight */
+ {"Thin" , FW_THIN},
+ {"Extra Light" , FW_EXTRALIGHT},
+ {"Ultra Light" , FW_ULTRALIGHT},
+ {"Light" , FW_LIGHT},
+ {"Normal" , FW_NORMAL},
+ {"Medium" , FW_MEDIUM},
+ {"Semi Bold" , FW_SEMIBOLD},
+ {"Demi Bold" , FW_DEMIBOLD},
+ {"Bold" , FW_BOLD}, /* The standard bold font weight */
+ {"Extra Bold" , FW_EXTRABOLD},
+ {"Ultra Bold" , FW_ULTRABOLD},
+ {"Heavy" , FW_HEAVY},
+ {"Black" , FW_BLACK}
+};
+
+/* Default charset first, no synonyms allowed because these names are
+ * matched against the names reported by win32 by match_font() */
+static CONST fontmap_t charset_map[] =
+{
+ {"Western" , ANSI_CHARSET},
+ {"Symbol" , SYMBOL_CHARSET},
+ {"Shift JIS" , SHIFTJIS_CHARSET}, /* #### Name to be verified */
+ {"GB2312" , GB2312_CHARSET}, /* #### Name to be verified */
+ {"Hanguel" , HANGEUL_CHARSET},
+ {"Chinese Big 5" , CHINESEBIG5_CHARSET}, /* #### Name to be verified */
+#if (WINVER >= 0x0400)
+ {"Johab" , JOHAB_CHARSET}, /* #### Name to be verified */
+ {"Hebrew" , HEBREW_CHARSET}, /* #### Name to be verified */
+ {"Arabic" , ARABIC_CHARSET}, /* #### Name to be verified */
+ {"Greek" , GREEK_CHARSET},
+ {"Turkish" , TURKISH_CHARSET},
+ {"Vietnamese" , VIETNAMESE_CHARSET}, /* #### Name to be verified */
+ {"Thai" , THAI_CHARSET}, /* #### Name to be verified */
+ {"Central European" , EASTEUROPE_CHARSET},
+ {"Cyrillic" , RUSSIAN_CHARSET},
+ {"Mac" , MAC_CHARSET},
+ {"Baltic" , BALTIC_CHARSET},
+#endif
+ {"OEM/DOS" , OEM_CHARSET}
+};
+
\f
/************************************************************************/
/* helpers */
return 1;
}
+
+
+
+\f
+/************************************************************************/
+/* exports */
+/************************************************************************/
+
+struct font_enum_t
+{
+ HDC hdc;
+ Lisp_Object list;
+};
+
+static int CALLBACK
+font_enum_callback_2 (ENUMLOGFONTEX *lpelfe, NEWTEXTMETRICEX *lpntme,
+ int FontType, struct font_enum_t *font_enum)
+{
+ char fontname[MSW_FONTSIZE];
+ Lisp_Object fontname_lispstr;
+ int i;
+
+ /*
+ * The enumerated font weights are not to be trusted because:
+ * a) lpelfe->elfStyle is only filled in for TrueType fonts.
+ * b) Not all Bold and Italic styles of all fonts (inluding some Vector,
+ * Truetype and Raster fonts) are enumerated.
+ * I guess that fonts for which Bold and Italic styles are generated
+ * 'on-the-fly' are not enumerated. It would be overly restrictive to
+ * disallow Bold And Italic weights for these fonts, so we just leave
+ * weights unspecified. This means that we have to weed out duplicates of
+ * those fonts that do get enumerated with different weights.
+ */
+ if (FontType == 0 /*vector*/ || FontType == TRUETYPE_FONTTYPE)
+ /* Scalable, so leave pointsize blank */
+ sprintf (fontname, "%s::::", lpelfe->elfLogFont.lfFaceName);
+ else
+ /* Formula for pointsize->height from LOGFONT docs in Platform SDK */
+ sprintf (fontname, "%s::%d::", lpelfe->elfLogFont.lfFaceName,
+ MulDiv (lpntme->ntmTm.tmHeight - lpntme->ntmTm.tmInternalLeading,
+ 72, GetDeviceCaps (font_enum->hdc, LOGPIXELSY)));
+
+ /*
+ * The enumerated font character set strings are not to be trusted because
+ * lpelfe->elfScript is returned in the host language and not in English.
+ * We can't know a priori the translations of "Western", "Central European"
+ * etc into the host language, so we must use English. The same argument
+ * applies to the font weight string when matching fonts.
+ */
+ for (i=0; i<countof (charset_map); i++)
+ if (lpelfe->elfLogFont.lfCharSet == charset_map[i].value)
+ {
+ strcat (fontname, charset_map[i].name);
+ break;
+ }
+ if (i==countof (charset_map))
+ strcpy (fontname, charset_map[0].name);
+
+ /* Add the font name to the list if not already there */
+ fontname_lispstr = build_string (fontname);
+ if (NILP (memq_no_quit (fontname_lispstr, font_enum->list)))
+ font_enum->list = Fcons (fontname_lispstr, font_enum->list);
+
+ return 1;
+}
+
+static int CALLBACK
+font_enum_callback_1 (ENUMLOGFONTEX *lpelfe, NEWTEXTMETRICEX *lpntme,
+ int FontType, struct font_enum_t *font_enum)
+{
+ /* This function gets called once per facename per character set.
+ * We call a second callback to enumerate the fonts in each facename */
+ return EnumFontFamiliesEx (font_enum->hdc, &lpelfe->elfLogFont,
+ (FONTENUMPROC) font_enum_callback_2,
+ (LPARAM) font_enum, 0);
+}
+
+/*
+ * Enumerate the available on the HDC fonts and return a list of string
+ * font names.
+ */
+Lisp_Object
+mswindows_enumerate_fonts (HDC hdc)
+{
+ /* This cannot CG */
+ LOGFONT logfont;
+ struct font_enum_t font_enum;
+
+ assert (hdc!=NULL);
+ logfont.lfCharSet = DEFAULT_CHARSET;
+ logfont.lfFaceName[0] = '\0';
+ logfont.lfPitchAndFamily = DEFAULT_PITCH;
+ font_enum.hdc = hdc;
+ font_enum.list = Qnil;
+ EnumFontFamiliesEx (hdc, &logfont, (FONTENUMPROC) font_enum_callback_1,
+ (LPARAM) (&font_enum), 0);
+ return font_enum.list;
+}
+
+static void
+mswindows_create_font_variant (Lisp_Font_Instance* f,
+ int under, int strike)
+{
+ /* Cannot GC */
+
+ LOGFONT lf;
+ HFONT hfont;
+
+ assert (FONT_INSTANCE_MSWINDOWS_HFONT_VARIANT (f, under, strike) == NULL);
+
+ if (GetObject (FONT_INSTANCE_MSWINDOWS_HFONT_VARIANT (f, 0, 0),
+ sizeof (lf), (void*) &lf) == 0)
+ {
+ hfont = MSWINDOWS_BAD_HFONT;
+ }
+ else
+ {
+ lf.lfUnderline = under;
+ lf.lfStrikeOut = strike;
+
+ hfont = CreateFontIndirect (&lf);
+ if (hfont == NULL)
+ hfont = MSWINDOWS_BAD_HFONT;
+ }
+
+ FONT_INSTANCE_MSWINDOWS_HFONT_VARIANT (f, under, strike) = hfont;
+}
+
+HFONT
+mswindows_get_hfont (Lisp_Font_Instance* f,
+ int under, int strike)
+{
+ /* Cannot GC */
+ HFONT hfont;
+
+ if (FONT_INSTANCE_MSWINDOWS_HFONT_VARIANT (f, under, strike) == NULL)
+ mswindows_create_font_variant (f, under, strike);
+
+ assert (FONT_INSTANCE_MSWINDOWS_HFONT_VARIANT (f, under, strike) != NULL);
+
+ hfont = FONT_INSTANCE_MSWINDOWS_HFONT_VARIANT (f, under, strike);
+
+ /* If strikeout/underline variant of the font could not be
+ created, then use the base version of the font */
+ if (hfont == MSWINDOWS_BAD_HFONT)
+ hfont = FONT_INSTANCE_MSWINDOWS_HFONT_VARIANT (f, 0, 0);
+
+ assert (hfont != NULL && hfont != MSWINDOWS_BAD_HFONT);
+
+ return hfont;
+}
\f
/************************************************************************/
/* methods */
/************************************************************************/
static int
-mswindows_initialize_color_instance (struct Lisp_Color_Instance *c, Lisp_Object name,
+mswindows_initialize_color_instance (Lisp_Color_Instance *c, Lisp_Object name,
Lisp_Object device, Error_behavior errb)
{
CONST char *extname;
COLORREF color;
- GET_C_STRING_CTEXT_DATA_ALLOCA (name, extname);
+ TO_EXTERNAL_FORMAT (LISP_STRING, name,
+ C_STRING_ALLOCA, extname,
+ Qctext);
color = mswindows_string_to_color(extname);
if (color != -1)
{
COLOR_INSTANCE_MSWINDOWS_COLOR (c) = color;
return 1;
}
- maybe_signal_simple_error ("unrecognized color", name, Qcolor, errb);
+ maybe_signal_simple_error ("Unrecognized color", name, Qcolor, errb);
return(0);
}
#if 0
static void
-mswindows_mark_color_instance (struct Lisp_Color_Instance *c,
- void (*markobj) (Lisp_Object))
+mswindows_mark_color_instance (Lisp_Color_Instance *c)
{
}
#endif
static void
-mswindows_print_color_instance (struct Lisp_Color_Instance *c,
- Lisp_Object printcharfun,
- int escapeflag)
+mswindows_print_color_instance (Lisp_Color_Instance *c,
+ Lisp_Object printcharfun,
+ int escapeflag)
{
char buf[32];
COLORREF color = COLOR_INSTANCE_MSWINDOWS_COLOR (c);
}
static void
-mswindows_finalize_color_instance (struct Lisp_Color_Instance *c)
+mswindows_finalize_color_instance (Lisp_Color_Instance *c)
{
if (c->data)
{
}
static int
-mswindows_color_instance_equal (struct Lisp_Color_Instance *c1,
- struct Lisp_Color_Instance *c2,
- int depth)
+mswindows_color_instance_equal (Lisp_Color_Instance *c1,
+ Lisp_Color_Instance *c2,
+ int depth)
{
return (COLOR_INSTANCE_MSWINDOWS_COLOR(c1) == COLOR_INSTANCE_MSWINDOWS_COLOR(c2));
}
static unsigned long
-mswindows_color_instance_hash (struct Lisp_Color_Instance *c, int depth)
+mswindows_color_instance_hash (Lisp_Color_Instance *c, int depth)
{
- return (unsigned long)(COLOR_INSTANCE_MSWINDOWS_COLOR(c));
+ return (unsigned long) COLOR_INSTANCE_MSWINDOWS_COLOR(c);
}
static Lisp_Object
-mswindows_color_instance_rgb_components (struct Lisp_Color_Instance *c)
+mswindows_color_instance_rgb_components (Lisp_Color_Instance *c)
{
COLORREF color = COLOR_INSTANCE_MSWINDOWS_COLOR (c);
return list3 (make_int (GetRValue (color) * 257),
{
CONST char *extname;
- GET_C_STRING_CTEXT_DATA_ALLOCA (color, extname);
+ TO_EXTERNAL_FORMAT (LISP_STRING, color,
+ C_STRING_ALLOCA, extname,
+ Qctext);
return (mswindows_string_to_color(extname)!=-1);
}
\f
static void
-mswindows_finalize_font_instance (struct Lisp_Font_Instance *f)
-{
- if (f->data)
- {
- DeleteObject(f->data);
- f->data=0;
- }
-}
+mswindows_finalize_font_instance (Lisp_Font_Instance *f);
+/*
+ * This is a work horse for both mswindows_initialize_font_instanc and
+ * msprinter_initialize_font_instance.
+ */
static int
-mswindows_initialize_font_instance (struct Lisp_Font_Instance *f, Lisp_Object name,
- Lisp_Object device, Error_behavior errb)
+initialize_font_instance (Lisp_Font_Instance *f, Lisp_Object name,
+ Lisp_Object device_font_list, HDC hdc,
+ Error_behavior errb)
{
CONST char *extname;
LOGFONT logfont;
- int fields;
+ int fields, i;
int pt;
char fontname[LF_FACESIZE], weight[LF_FACESIZE], *style, points[8];
char effects[LF_FACESIZE], charset[LF_FACESIZE];
char *c;
-
- GET_C_STRING_CTEXT_DATA_ALLOCA (f->name, extname);
+ HFONT hfont, holdfont;
+ TEXTMETRIC metrics;
+
+ extname = XSTRING_DATA (name);
/*
* mswindows fonts look like:
/* This function is implemented in a fairly ad-hoc manner.
* The general idea is to validate and canonicalize each of the above fields
* at the same time as we build up the win32 LOGFONT structure. This enables
- * us to use math_font() on a canonicalized font string to check the
+ * us to use match_font() on a canonicalized font string to check the
* availability of the requested font */
- if (fields<0)
+ if (fields < 0)
{
- maybe_signal_simple_error ("Invalid font", f->name, Qfont, errb);
+ maybe_signal_simple_error ("Invalid font", name, Qfont, errb);
return (0);
}
}
else
{
- maybe_signal_simple_error ("Must specify a font name", f->name, Qfont, errb);
+ maybe_signal_simple_error ("Must specify a font name", name, Qfont, errb);
return (0);
}
/* weight */
if (fields < 2)
- strcpy (weight, "Regular");
+ strcpy (weight, fontweight_map[0].name);
/* Maybe split weight into weight and style */
if ((c=strchr(weight, ' ')))
else
style = NULL;
-#define FROB(wgt) \
- if (stricmp (weight, #wgt) == 0) \
- logfont.lfWeight = FW_##wgt
-
- FROB (REGULAR);
- else FROB (THIN);
- else FROB (EXTRALIGHT);
- else FROB (ULTRALIGHT);
- else FROB (LIGHT);
- else FROB (NORMAL);
- else FROB (MEDIUM);
- else FROB (SEMIBOLD);
- else FROB (DEMIBOLD);
- else FROB (BOLD);
- else FROB (EXTRABOLD);
- else FROB (ULTRABOLD);
- else FROB (HEAVY);
- else FROB (BLACK);
- else if (!style)
- {
- logfont.lfWeight = FW_REGULAR;
- style = weight; /* May have specified style without weight */
- }
- else
+ for (i=0; i<countof (fontweight_map); i++)
+ if (!stricmp (weight, fontweight_map[i].name))
+ {
+ logfont.lfWeight = fontweight_map[i].value;
+ break;
+ }
+ if (i == countof (fontweight_map)) /* No matching weight */
{
- maybe_signal_simple_error ("Invalid font weight", f->name, Qfont, errb);
- return (0);
+ if (!style)
+ {
+ logfont.lfWeight = FW_REGULAR;
+ style = weight; /* May have specified style without weight */
+ }
+ else
+ {
+ maybe_signal_simple_error ("Invalid font weight", name, Qfont, errb);
+ return (0);
+ }
}
-#undef FROB
-
if (style)
{
/* #### what about oblique? */
logfont.lfItalic = TRUE;
else
{
- maybe_signal_simple_error ("Invalid font weight or style", f->name, Qfont, errb);
+ maybe_signal_simple_error ("Invalid font weight or style", name, Qfont, errb);
return (0);
}
pt = 10; /* #### Should we reject strings that don't specify a size? */
else if ((pt=atoi(points)) == 0)
{
- maybe_signal_simple_error ("Invalid font pointsize", f->name, Qfont, errb);
+ maybe_signal_simple_error ("Invalid font pointsize", name, Qfont, errb);
return (0);
}
/* Formula for pointsize->height from LOGFONT docs in MSVC5 Platform SDK */
- logfont.lfHeight = -MulDiv(pt, DEVICE_MSWINDOWS_LOGPIXELSY(XDEVICE (device)), 72);
+ logfont.lfHeight = -MulDiv(pt, GetDeviceCaps (hdc, LOGPIXELSY), 72);
logfont.lfWidth = 0;
/* Effects */
logfont.lfStrikeOut = TRUE;
else
{
- maybe_signal_simple_error ("Invalid font effect", f->name,
- Qfont, errb);
+ maybe_signal_simple_error ("Invalid font effect", name, Qfont, errb);
return (0);
}
logfont.lfStrikeOut = TRUE;
else
{
- maybe_signal_simple_error ("Invalid font effect", f->name,
+ maybe_signal_simple_error ("Invalid font effect", name,
Qfont, errb);
return (0);
}
else
effects[0] = '\0';
-#define FROB(cs) \
- else if (stricmp (charset, #cs) == 0) \
- logfont.lfCharSet = cs##_CHARSET
-
- /* Charset aliases. Hangeul = Hangul is defined in windows.h.
- We do not use the name "russian", only "cyrillic", as it is
- the common name of this charset, used in other languages
- than Russian. */
-#define CYRILLIC_CHARSET RUSSIAN_CHARSET
-#define CENTRALEUROPEAN_CHARSET EASTEUROPE_CHARSET
-#define CENTRALEUROPEAN_CHARSET EASTEUROPE_CHARSET
-
+ /* Charset */
/* charset can be specified even if earlier fields havn't been */
- if ((fields < 5) && (c=strchr (extname, ':')) && (c=strchr (c+1, ':')) &&
- (c=strchr (c+1, ':')) && (c=strchr (c+1, ':')))
+ if (fields < 5)
{
- strncpy (charset, c+1, LF_FACESIZE);
- charset[LF_FACESIZE-1] = '\0';
- }
- else
- charset[0] = '\0';
-
- if (charset[0] == '\0' || (stricmp (charset, "ansi") == 0) ||
- (stricmp (charset, "western") == 0))
- {
- logfont.lfCharSet = ANSI_CHARSET;
- strcpy (charset, "western");
- }
- FROB (SYMBOL);
- FROB (SHIFTJIS);
- FROB (GB2312);
- FROB (HANGEUL);
- FROB (CHINESEBIG5);
- FROB (JOHAB);
- FROB (HEBREW);
- FROB (ARABIC);
- FROB (GREEK);
- FROB (TURKISH);
- FROB (THAI);
- FROB (EASTEUROPE);
- FROB (CENTRALEUROPEAN);
- FROB (CYRILLIC);
- FROB (MAC);
- FROB (BALTIC);
- else if (stricmp (charset, "oem/dos") == 0)
- logfont.lfCharSet = OEM_CHARSET;
- else
- {
- maybe_signal_simple_error ("Invalid charset", f->name, Qfont, errb);
- return 0;
+ if ((c=strchr (extname, ':')) && (c=strchr (c+1, ':')) &&
+ (c=strchr (c+1, ':')) && (c=strchr (c+1, ':')))
+ {
+ strncpy (charset, c+1, LF_FACESIZE);
+ charset[LF_FACESIZE-1] = '\0';
+ }
+ else
+ strcpy (charset, charset_map[0].name);
}
-#undef FROB
-
- /* Windows will silently substitute a default font if the fontname
- * specifies a non-existent font. So we check the font against the device's
- * list of font patterns to make sure that at least one of them matches */
- {
- struct mswindows_font_enum *fontlist;
- char truename[MSW_FONTSIZE];
- int done = 0;
-
- sprintf (truename, "%s:%s:%d:%s:%s", fontname, weight, pt, effects, charset);
- fontlist = DEVICE_MSWINDOWS_FONTLIST (XDEVICE (device));
- while (fontlist && !done)
- {
- done = match_font (fontlist->fontname, truename, NULL);
- fontlist = fontlist->next;
- }
- if (!done)
+ for (i=0; i<countof (charset_map); i++)
+ if (!stricmp (charset, charset_map[i].name))
{
- maybe_signal_simple_error ("No matching font", f->name, Qfont, errb);
- return 0;
+ logfont.lfCharSet = charset_map[i].value;
+ break;
}
- }
+
+ if (i == countof (charset_map)) /* No matching charset */
+ {
+ maybe_signal_simple_error ("Invalid charset", name, Qfont, errb);
+ return 0;
+ }
/* Misc crud */
logfont.lfEscapement = logfont.lfOrientation = 0;
logfont.lfClipPrecision = CLIP_STROKE_PRECIS;
logfont.lfQuality = PROOF_QUALITY;
#endif
- /* Default to monospaced if the specified fontname doesn't exist.
- * The match_font calls above should mean that this can't happen. */
+ /* Default to monospaced if the specified fontname doesn't exist. */
logfont.lfPitchAndFamily = FF_MODERN;
- if ((f->data = CreateFontIndirect(&logfont)) == NULL)
+ /* Windows will silently substitute a default font if the fontname
+ specifies a non-existent font. So we check the font against the
+ device's list of font patterns to make sure that at least one of
+ them matches.
+
+ Personally, I do not like the idea - it is better to come out with
+ some font than completely without one. The diversity of printer
+ fonts is much greater than that of screen font. We can tread on
+ that. -- kkm. */
+
+ if (!NILP (device_font_list))
+ {
+ Lisp_Object fonttail;
+ char truename[MSW_FONTSIZE];
+
+ sprintf (truename, "%s:%s:%d:%s:%s", fontname, weight, pt, effects, charset);
+ LIST_LOOP (fonttail, device_font_list)
+ {
+ if (match_font (XSTRING_DATA (XCAR (fonttail)), truename, NULL))
+ break;
+ }
+ if (NILP (fonttail))
+ {
+ maybe_signal_simple_error ("No matching font", name, Qfont, errb);
+ return 0;
+ }
+ }
+
+ if ((hfont = CreateFontIndirect(&logfont)) == NULL)
{
- maybe_signal_simple_error ("Couldn't create font", f->name, Qfont, errb);
+ maybe_signal_simple_error ("Couldn't create font", name, Qfont, errb);
return 0;
}
- {
- HDC hdc;
- HFONT holdfont;
- TEXTMETRIC metrics;
+ f->data = xnew_and_zero (struct mswindows_font_instance_data);
+ FONT_INSTANCE_MSWINDOWS_HFONT_VARIANT (f,0,0) = hfont;
+
+ holdfont = SelectObject(hdc, hfont);
+ if (!holdfont)
+ {
+ mswindows_finalize_font_instance (f);
+ maybe_signal_simple_error ("Couldn't map font", name, Qfont, errb);
+ return 0;
+ }
- hdc = CreateCompatibleDC (NULL);
- if (hdc)
- {
- holdfont = SelectObject(hdc, f->data);
- if (holdfont)
- {
- GetTextMetrics (hdc, &metrics);
- SelectObject(hdc, holdfont);
- DeleteDC (hdc);
- f->width = (unsigned short) metrics.tmAveCharWidth;
- f->height = (unsigned short) metrics.tmHeight;
- f->ascent = (unsigned short) metrics.tmAscent;
- f->descent = (unsigned short) metrics.tmDescent;
- f->proportional_p = (metrics.tmPitchAndFamily & TMPF_FIXED_PITCH);
- return 1;
- }
- DeleteDC (hdc);
- }
- mswindows_finalize_font_instance (f);
- maybe_signal_simple_error ("Couldn't map font", f->name, Qfont, errb);
- }
- return 0;
+ GetTextMetrics (hdc, &metrics);
+ SelectObject(hdc, holdfont);
+
+ f->width = (unsigned short) metrics.tmAveCharWidth;
+ f->height = (unsigned short) metrics.tmHeight;
+ /* Font variant metrics hack. The problem is that in Windows
+ some underlined fonts have the descent of one pixel more
+ than their non-underlined counterparts. Font variants
+ though are assumed to have identical metrics. Lowering
+ the font's baseline one pixel down cures the problem, and
+ is visually undetectable. - kkm */
+ f->ascent = (unsigned short) metrics.tmAscent - 1;
+ f->descent = (unsigned short) metrics.tmDescent + 1;
+ f->proportional_p = (metrics.tmPitchAndFamily & TMPF_FIXED_PITCH);
+
+ return 1;
+}
+
+static int
+mswindows_initialize_font_instance (Lisp_Font_Instance *f, Lisp_Object name,
+ Lisp_Object device, Error_behavior errb)
+{
+ HDC hdc = CreateCompatibleDC (NULL);
+ Lisp_Object font_list = DEVICE_MSWINDOWS_FONTLIST (XDEVICE (device));
+ int res = initialize_font_instance (f, name, font_list, hdc, errb);
+ DeleteDC (hdc);
+ return res;
+}
+
+static int
+msprinter_initialize_font_instance (Lisp_Font_Instance *f, Lisp_Object name,
+ Lisp_Object device, Error_behavior errb)
+{
+ HDC hdc = DEVICE_MSPRINTER_HDC (XDEVICE (device));
+ Lisp_Object font_list = DEVICE_MSPRINTER_FONTLIST (XDEVICE (device));
+ return initialize_font_instance (f, name, font_list, hdc, errb);
+}
+
+static void
+mswindows_finalize_font_instance (Lisp_Font_Instance *f)
+{
+ int i;
+
+ if (f->data)
+ {
+ for (i = 0; i < MSWINDOWS_NUM_FONT_VARIANTS; i++)
+ {
+ if (FONT_INSTANCE_MSWINDOWS_HFONT_I (f, i) != NULL
+ && FONT_INSTANCE_MSWINDOWS_HFONT_I (f, i) != MSWINDOWS_BAD_HFONT)
+ DeleteObject (FONT_INSTANCE_MSWINDOWS_HFONT_I (f, i));
+ }
+
+ xfree (f->data);
+ f->data = 0;
+ }
}
#if 0
static void
-mswindows_mark_font_instance (struct Lisp_Font_Instance *f,
- void (*markobj) (Lisp_Object))
+mswindows_mark_font_instance (Lisp_Font_Instance *f)
{
}
#endif
static void
-mswindows_print_font_instance (struct Lisp_Font_Instance *f,
- Lisp_Object printcharfun,
- int escapeflag)
+mswindows_print_font_instance (Lisp_Font_Instance *f,
+ Lisp_Object printcharfun,
+ int escapeflag)
{
+ char buf[10];
+ sprintf (buf, " 0x%lx",
+ (unsigned long)FONT_INSTANCE_MSWINDOWS_HFONT_VARIANT (f,0,0));
+ write_c_string (buf, printcharfun);
}
static Lisp_Object
mswindows_list_fonts (Lisp_Object pattern, Lisp_Object device)
{
- Lisp_Object result = Qnil;
- struct mswindows_font_enum *fontlist;
- char fontname[MSW_FONTSIZE], *extpattern;
+ Lisp_Object fonttail, result = Qnil;
+ char *extpattern;
- GET_C_STRING_CTEXT_DATA_ALLOCA (pattern, extpattern);
- fontlist = DEVICE_MSWINDOWS_FONTLIST (XDEVICE (device));
- while (fontlist)
+ TO_EXTERNAL_FORMAT (LISP_STRING, pattern,
+ C_STRING_ALLOCA, extpattern,
+ Qctext);
+
+ LIST_LOOP (fonttail, DEVICE_MSWINDOWS_FONTLIST (XDEVICE (device)))
{
- if (match_font (fontlist->fontname, extpattern, fontname))
- result = Fcons (build_string (fontname), result);
- fontlist = fontlist->next;
+ if (match_font (XSTRING_DATA (XCAR (fonttail)), extpattern, NULL))
+ result = Fcons (XCAR (fonttail), result);
}
return Fnreverse (result);
}
+/* Fill in missing parts of a font spec. This is primarily intended as a
+ * helper function for the functions below.
+ * mswindows fonts look like:
+ * fontname[:[weight][ style][:pointsize[:effects]]][:charset]
+ * A minimal mswindows font spec looks like:
+ * Courier New
+ * A maximal mswindows font spec looks like:
+ * Courier New:Bold Italic:10:underline strikeout:Western
+ * Missing parts of the font spec should be filled in with these values:
+ * Courier New:Regular:10::Western */
+static Lisp_Object
+mswindows_font_instance_truename (Lisp_Font_Instance *f, Error_behavior errb)
+{
+ int nsep=0;
+ char *name = (char *) XSTRING_DATA (f->name);
+ char* ptr = name;
+ char* extname = alloca (strlen (name) + 19);
+ strcpy (extname, name);
+
+ while ((ptr = strchr (ptr, ':')) != 0)
+ {
+ ptr++;
+ nsep++;
+ }
+
+ switch (nsep)
+ {
+ case 0:
+ strcat (extname, ":Regular:10::Western");
+ break;
+ case 1:
+ strcat (extname, ":10::Western");
+ break;
+ case 2:
+ strcat (extname, "::Western");
+ break;
+ case 3:
+ strcat (extname, ":Western");
+ break;
+ default:;
+ }
+
+ return build_ext_string (extname, Qnative);
+}
+
#ifdef MULE
static int
/* CONSOLE_HAS_METHOD (mswindows, mark_font_instance); */
CONSOLE_HAS_METHOD (mswindows, print_font_instance);
CONSOLE_HAS_METHOD (mswindows, finalize_font_instance);
-/* CONSOLE_HAS_METHOD (mswindows, font_instance_truename); */
+ CONSOLE_HAS_METHOD (mswindows, font_instance_truename);
CONSOLE_HAS_METHOD (mswindows, list_fonts);
#ifdef MULE
CONSOLE_HAS_METHOD (mswindows, font_spec_matches_charset);
CONSOLE_HAS_METHOD (mswindows, find_charset_font);
#endif
+
+ /* Printer methods - delegate most to windows methods,
+ since graphical objects behave the same way. */
+
+ CONSOLE_INHERITS_METHOD (msprinter, mswindows, initialize_color_instance);
+/* CONSOLE_INHERITS_METHOD (msprinter, mswindows, mark_color_instance); */
+ CONSOLE_INHERITS_METHOD (msprinter, mswindows, print_color_instance);
+ CONSOLE_INHERITS_METHOD (msprinter, mswindows, finalize_color_instance);
+ CONSOLE_INHERITS_METHOD (msprinter, mswindows, color_instance_equal);
+ CONSOLE_INHERITS_METHOD (msprinter, mswindows, color_instance_hash);
+ CONSOLE_INHERITS_METHOD (msprinter, mswindows, color_instance_rgb_components);
+ CONSOLE_INHERITS_METHOD (msprinter, mswindows, valid_color_name_p);
+
+ CONSOLE_HAS_METHOD (msprinter, initialize_font_instance);
+/* CONSOLE_INHERITS_METHOD (msprinter, mswindows, mark_font_instance); */
+ CONSOLE_INHERITS_METHOD (msprinter, mswindows, print_font_instance);
+ CONSOLE_INHERITS_METHOD (msprinter, mswindows, finalize_font_instance);
+ CONSOLE_INHERITS_METHOD (msprinter, mswindows, font_instance_truename);
+ CONSOLE_INHERITS_METHOD (msprinter, mswindows, list_fonts);
+#ifdef MULE
+ CONSOLE_INHERITS_METHOD (msprinter, mswindows, font_spec_matches_charset);
+ CONSOLE_INHERITS_METHOD (msprinter, mswindows, find_charset_font);
+#endif
}
void