/* Font backend for the Microsoft W32 API.
- Copyright (C) 2007, 2008, 2009, 2010 Free Software Foundation, Inc.
+ Copyright (C) 2007-2012 Free Software Foundation, Inc.
This file is part of GNU Emacs.
#define JOHAB_CHARSET 130
#endif
-extern struct font_driver w32font_driver;
-
Lisp_Object Qgdi;
Lisp_Object Quniscribe;
static Lisp_Object QCformat;
static Lisp_Object Qraster, Qoutline, Qunknown;
/* antialiasing */
-extern Lisp_Object QCantialias, QCotf, QClang; /* defined in font.c */
extern Lisp_Object Qnone; /* reuse from w32fns.c */
static Lisp_Object Qstandard, Qsubpixel, Qnatural;
static Lisp_Object Qzh;
/* scripts */
-static Lisp_Object Qlatin, Qgreek, Qcoptic, Qcyrillic, Qarmenian, Qhebrew;
+static Lisp_Object Qgreek, Qcoptic, Qcyrillic, Qarmenian, Qhebrew;
static Lisp_Object Qarabic, Qsyriac, Qnko, Qthaana, Qdevanagari, Qbengali;
static Lisp_Object Qgurmukhi, Qgujarati, Qoriya, Qtamil, Qtelugu;
static Lisp_Object Qkannada, Qmalayalam, Qsinhala, Qthai, Qlao;
static Lisp_Object Qw32_charset_hebrew, Qw32_charset_vietnamese;
static Lisp_Object Qw32_charset_thai, Qw32_charset_johab, Qw32_charset_mac;
-/* Associative list linking character set strings to Windows codepages. */
-static Lisp_Object Vw32_charset_info_alist;
-
/* Font spacing symbols - defined in font.c. */
extern Lisp_Object Qc, Qp, Qm;
-static void fill_in_logfont P_ ((FRAME_PTR, LOGFONT *, Lisp_Object));
+static void fill_in_logfont (FRAME_PTR, LOGFONT *, Lisp_Object);
-static BYTE w32_antialias_type P_ ((Lisp_Object));
-static Lisp_Object lispy_antialias_type P_ ((BYTE));
+static BYTE w32_antialias_type (Lisp_Object);
+static Lisp_Object lispy_antialias_type (BYTE);
-static Lisp_Object font_supported_scripts P_ ((FONTSIGNATURE *));
-static int w32font_full_name P_ ((LOGFONT *, Lisp_Object, int, char *, int));
-static void compute_metrics P_ ((HDC, struct w32font_info *, unsigned int,
- struct w32_metric_cache *));
+static Lisp_Object font_supported_scripts (FONTSIGNATURE *);
+static int w32font_full_name (LOGFONT *, Lisp_Object, int, char *, int);
+static void compute_metrics (HDC, struct w32font_info *, unsigned int,
+ struct w32_metric_cache *);
-static Lisp_Object w32_registry P_ ((LONG, DWORD));
+static Lisp_Object w32_registry (LONG, DWORD);
/* EnumFontFamiliesEx callbacks. */
-static int CALLBACK add_font_entity_to_list P_ ((ENUMLOGFONTEX *,
+static int CALLBACK add_font_entity_to_list (ENUMLOGFONTEX *,
+ NEWTEXTMETRICEX *,
+ DWORD, LPARAM);
+static int CALLBACK add_one_font_entity_to_list (ENUMLOGFONTEX *,
NEWTEXTMETRICEX *,
- DWORD, LPARAM));
-static int CALLBACK add_one_font_entity_to_list P_ ((ENUMLOGFONTEX *,
- NEWTEXTMETRICEX *,
- DWORD, LPARAM));
-static int CALLBACK add_font_name_to_list P_ ((ENUMLOGFONTEX *,
- NEWTEXTMETRICEX *,
- DWORD, LPARAM));
+ DWORD, LPARAM);
+static int CALLBACK add_font_name_to_list (ENUMLOGFONTEX *,
+ NEWTEXTMETRICEX *,
+ DWORD, LPARAM);
/* struct passed in as LPARAM arg to EnumFontFamiliesEx, for keeping track
of what we really want. */
/* Handles the problem that EnumFontFamiliesEx will not return all
style variations if the font name is not specified. */
-static void list_all_matching_fonts P_ ((struct font_callback_data *));
+static void list_all_matching_fonts (struct font_callback_data *);
+
+static BOOL g_b_init_is_w9x;
+static BOOL g_b_init_get_outline_metrics_w;
+static BOOL g_b_init_get_text_metrics_w;
+static BOOL g_b_init_get_glyph_outline_w;
+static BOOL g_b_init_get_glyph_outline_w;
+
+typedef UINT (WINAPI * GetOutlineTextMetricsW_Proc) (
+ HDC hdc,
+ UINT cbData,
+ LPOUTLINETEXTMETRICW lpotmw);
+typedef BOOL (WINAPI * GetTextMetricsW_Proc) (
+ HDC hdc,
+ LPTEXTMETRICW lptmw);
+typedef DWORD (WINAPI * GetGlyphOutlineW_Proc) (
+ HDC hdc,
+ UINT uChar,
+ UINT uFormat,
+ LPGLYPHMETRICS lpgm,
+ DWORD cbBuffer,
+ LPVOID lpvBuffer,
+ const MAT2 *lpmat2);
+
+/* Several "wide" functions we use to support the font backends are
+ unavailable on Windows 9X, unless UNICOWS.DLL is installed (their
+ versions in the default libraries are non-functional stubs). On NT
+ and later systems, these functions are in GDI32.DLL. The following
+ helper function attempts to load UNICOWS.DLL on Windows 9X, and
+ refuses to let Emacs start up if that library is not found. On NT
+ and later versions, it simply loads GDI32.DLL, which should always
+ be available. */
+static HMODULE
+w32_load_unicows_or_gdi32 (void)
+{
+ static BOOL is_9x = 0;
+ OSVERSIONINFO os_ver;
+ HMODULE ret;
+ if (g_b_init_is_w9x == 0)
+ {
+ g_b_init_is_w9x = 1;
+ ZeroMemory (&os_ver, sizeof (OSVERSIONINFO));
+ os_ver.dwOSVersionInfoSize = sizeof (OSVERSIONINFO);
+ if (GetVersionEx (&os_ver))
+ is_9x = (os_ver.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS);
+ }
+ if (is_9x)
+ {
+ ret = LoadLibrary ("Unicows.dll");
+ if (!ret)
+ {
+ int button;
+
+ button = MessageBox (NULL,
+ "Emacs cannot load the UNICOWS.DLL library.\n"
+ "This library is essential for using Emacs\n"
+ "on this system. You need to install it.\n\n"
+ "However, you can still use Emacs by invoking\n"
+ "it with the '-nw' command-line option.\n\n"
+ "Emacs will exit when you click OK.",
+ "Emacs cannot load UNICOWS.DLL",
+ MB_ICONERROR | MB_TASKMODAL
+ | MB_SETFOREGROUND | MB_OK);
+ switch (button)
+ {
+ case IDOK:
+ default:
+ exit (1);
+ }
+ }
+ }
+ else
+ ret = LoadLibrary ("Gdi32.dll");
+ return ret;
+}
+/* The following 3 functions call the problematic "wide" APIs via
+ function pointers, to avoid linking against the non-standard
+ libunicows on W9X. */
+static UINT WINAPI
+get_outline_metrics_w(HDC hdc, UINT cbData, LPOUTLINETEXTMETRICW lpotmw)
+{
+ static GetOutlineTextMetricsW_Proc s_pfn_Get_Outline_Text_MetricsW = NULL;
+ HMODULE hm_unicows = NULL;
+ if (g_b_init_get_outline_metrics_w == 0)
+ {
+ g_b_init_get_outline_metrics_w = 1;
+ hm_unicows = w32_load_unicows_or_gdi32 ();
+ if (hm_unicows)
+ s_pfn_Get_Outline_Text_MetricsW = (GetOutlineTextMetricsW_Proc)
+ GetProcAddress (hm_unicows, "GetOutlineTextMetricsW");
+ }
+ if (s_pfn_Get_Outline_Text_MetricsW == NULL)
+ abort (); /* cannot happen */
+ return s_pfn_Get_Outline_Text_MetricsW (hdc, cbData, lpotmw);
+}
+
+static BOOL WINAPI
+get_text_metrics_w(HDC hdc, LPTEXTMETRICW lptmw)
+{
+ static GetTextMetricsW_Proc s_pfn_Get_Text_MetricsW = NULL;
+ HMODULE hm_unicows = NULL;
+ if (g_b_init_get_text_metrics_w == 0)
+ {
+ g_b_init_get_text_metrics_w = 1;
+ hm_unicows = w32_load_unicows_or_gdi32 ();
+ if (hm_unicows)
+ s_pfn_Get_Text_MetricsW = (GetTextMetricsW_Proc)
+ GetProcAddress (hm_unicows, "GetTextMetricsW");
+ }
+ if (s_pfn_Get_Text_MetricsW == NULL)
+ abort (); /* cannot happen */
+ return s_pfn_Get_Text_MetricsW (hdc, lptmw);
+}
+
+static DWORD WINAPI
+get_glyph_outline_w (HDC hdc, UINT uChar, UINT uFormat, LPGLYPHMETRICS lpgm,
+ DWORD cbBuffer, LPVOID lpvBuffer, const MAT2 *lpmat2)
+{
+ static GetGlyphOutlineW_Proc s_pfn_Get_Glyph_OutlineW = NULL;
+ HMODULE hm_unicows = NULL;
+ if (g_b_init_get_glyph_outline_w == 0)
+ {
+ g_b_init_get_glyph_outline_w = 1;
+ hm_unicows = w32_load_unicows_or_gdi32 ();
+ if (hm_unicows)
+ s_pfn_Get_Glyph_OutlineW = (GetGlyphOutlineW_Proc)
+ GetProcAddress (hm_unicows, "GetGlyphOutlineW");
+ }
+ if (s_pfn_Get_Glyph_OutlineW == NULL)
+ abort (); /* cannot happen */
+ return s_pfn_Get_Glyph_OutlineW (hdc, uChar, uFormat, lpgm, cbBuffer,
+ lpvBuffer, lpmat2);
+}
static int
-memq_no_quit (elt, list)
- Lisp_Object elt, list;
+memq_no_quit (Lisp_Object elt, Lisp_Object list)
{
while (CONSP (list) && ! EQ (XCAR (list), elt))
list = XCDR (list);
}
Lisp_Object
-intern_font_name (string)
- char * string;
+intern_font_name (char * string)
{
Lisp_Object obarray, tem, str;
int len;
/* The following code is copied from the function intern (in lread.c). */
obarray = Vobarray;
- if (!VECTORP (obarray) || XVECTOR (obarray)->size == 0)
+ if (!VECTORP (obarray) || ASIZE (obarray) == 0)
obarray = check_obarray (obarray);
tem = oblookup (obarray, SDATA (str), len, len);
if (SYMBOLP (tem))
Return a cache of font-entities on FRAME. The cache must be a
cons whose cdr part is the actual cache area. */
Lisp_Object
-w32font_get_cache (f)
- FRAME_PTR f;
+w32font_get_cache (FRAME_PTR f)
{
struct w32_display_info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
is a vector of font-entities. This is the sole API that
allocates font-entities. */
static Lisp_Object
-w32font_list (frame, font_spec)
- Lisp_Object frame, font_spec;
+w32font_list (Lisp_Object frame, Lisp_Object font_spec)
{
Lisp_Object fonts = w32font_list_internal (frame, font_spec, 0);
FONT_ADD_LOG ("w32font-list", font_spec, fonts);
/* w32 implementation of match for font backend.
Return a font entity most closely matching with FONT_SPEC on
- FRAME. The closeness is detemined by the font backend, thus
+ FRAME. The closeness is determined by the font backend, thus
`face-font-selection-order' is ignored here. */
static Lisp_Object
-w32font_match (frame, font_spec)
- Lisp_Object frame, font_spec;
+w32font_match (Lisp_Object frame, Lisp_Object font_spec)
{
Lisp_Object entity = w32font_match_internal (frame, font_spec, 0);
FONT_ADD_LOG ("w32font-match", font_spec, entity);
List available families. The value is a list of family names
(symbols). */
static Lisp_Object
-w32font_list_family (frame)
- Lisp_Object frame;
+w32font_list_family (Lisp_Object frame)
{
Lisp_Object list = Qnil;
LOGFONT font_match_pattern;
HDC dc;
FRAME_PTR f = XFRAME (frame);
- bzero (&font_match_pattern, sizeof (font_match_pattern));
+ memset (&font_match_pattern, 0, sizeof (font_match_pattern));
font_match_pattern.lfCharSet = DEFAULT_CHARSET;
dc = get_frame_dc (f);
Open a font specified by FONT_ENTITY on frame F.
If the font is scalable, open it with PIXEL_SIZE. */
static Lisp_Object
-w32font_open (f, font_entity, pixel_size)
- FRAME_PTR f;
- Lisp_Object font_entity;
- int pixel_size;
+w32font_open (FRAME_PTR f, Lisp_Object font_entity, int pixel_size)
{
Lisp_Object font_object
= font_make_object (VECSIZE (struct w32font_info),
/* w32 implementation of close for font_backend.
Close FONT on frame F. */
void
-w32font_close (f, font)
- FRAME_PTR f;
- struct font *font;
+w32font_close (FRAME_PTR f, struct font *font)
{
int i;
struct w32font_info *w32_font = (struct w32font_info *) font;
return 1. If not, return 0. If a font must be opened to check
it, return -1. */
int
-w32font_has_char (entity, c)
- Lisp_Object entity;
- int c;
+w32font_has_char (Lisp_Object entity, int c)
{
/* We can't be certain about which characters a font will support until
we open it. Checking the scripts that the font supports turns out
Return a glyph code of FONT for character C (Unicode code point).
If FONT doesn't have such a glyph, return FONT_INVALID_CODE.
- For speed, the gdi backend uses unicode (Emacs calls encode_char
+ For speed, the gdi backend uses Unicode (Emacs calls encode_char
far too often for it to be efficient). But we still need to detect
which characters are not supported by the font.
*/
static unsigned
-w32font_encode_char (font, c)
- struct font *font;
- int c;
+w32font_encode_char (struct font *font, int c)
{
struct w32font_info * w32_font = (struct w32font_info *)font;
CODE (length NGLYPHS). Apparently metrics can be NULL, in this
case just return the overall width. */
int
-w32font_text_extents (font, code, nglyphs, metrics)
- struct font *font;
- unsigned *code;
- int nglyphs;
- struct font_metrics *metrics;
+w32font_text_extents (struct font *font, unsigned *code,
+ int nglyphs, struct font_metrics *metrics)
{
int i;
HFONT old_font = NULL;
if (metrics)
{
- bzero (metrics, sizeof (struct font_metrics));
+ memset (metrics, 0, sizeof (struct font_metrics));
metrics->ascent = font->ascent;
metrics->descent = font->descent;
= xrealloc (w32_font->cached_metrics,
(block + 1)
* sizeof (struct w32_metric_cache *));
- bzero (w32_font->cached_metrics + w32_font->n_cache_blocks,
- ((block + 1 - w32_font->n_cache_blocks)
- * sizeof (struct w32_metric_cache *)));
+ memset (w32_font->cached_metrics + w32_font->n_cache_blocks, 0,
+ ((block + 1 - w32_font->n_cache_blocks)
+ * sizeof (struct w32_metric_cache *)));
w32_font->n_cache_blocks = block + 1;
}
{
w32_font->cached_metrics[block]
= xmalloc (CACHE_BLOCKSIZE * sizeof (struct w32_metric_cache));
- bzero (w32_font->cached_metrics[block],
- CACHE_BLOCKSIZE * sizeof (struct w32_metric_cache));
+ memset (w32_font->cached_metrics[block], 0,
+ CACHE_BLOCKSIZE * sizeof (struct w32_metric_cache));
}
char_metric = w32_font->cached_metrics[block] + pos_in_block;
total_width = size.cx;
}
- /* On 95/98/ME, only some unicode functions are available, so fallback
+ /* On 95/98/ME, only some Unicode functions are available, so fallback
on doing a dummy draw to find the total width. */
if (!total_width)
{
*/
int
-w32font_draw (s, from, to, x, y, with_background)
- struct glyph_string *s;
- int from, to, x, y, with_background;
+w32font_draw (struct glyph_string *s, int from, int to,
+ int x, int y, int with_background)
{
UINT options;
HRGN orig_clip = NULL;
+ int len = to - from;
struct w32font_info *w32font = (struct w32font_info *) s->font;
options = w32font->glyph_idx;
if (s->padding_p)
{
- int len = to - from, i;
+ int i;
for (i = 0; i < len; i++)
ExtTextOutW (s->hdc, x + i, y, options, NULL,
s->char2b + from + i, 1, NULL);
}
else
- ExtTextOutW (s->hdc, x, y, options, NULL, s->char2b + from, to - from, NULL);
+ ExtTextOutW (s->hdc, x, y, options, NULL, s->char2b + from, len, NULL);
/* Restore clip region. */
if (s->num_clips > 0)
if (orig_clip)
DeleteObject (orig_clip);
+
+ return len;
}
/* w32 implementation of free_entity for font backend.
Optional.
Get coordinates of the INDEXth anchor point of the glyph whose
code is CODE. Store the coordinates in *X and *Y. Return 0 if
- the operations was successfull. Otherwise return -1.
+ the operations was successful. Otherwise return -1.
static int
w32font_anchor_point (struct font *font, unsigned code,
int index, int *x, int *y);
Additional parameter opentype_only restricts the returned fonts to
opentype fonts, which can be used with the Uniscribe backend. */
Lisp_Object
-w32font_list_internal (frame, font_spec, opentype_only)
- Lisp_Object frame, font_spec;
- int opentype_only;
+w32font_list_internal (Lisp_Object frame, Lisp_Object font_spec, int opentype_only)
{
struct font_callback_data match_data;
HDC dc;
match_data.list = Qnil;
match_data.frame = frame;
- bzero (&match_data.pattern, sizeof (LOGFONT));
+ memset (&match_data.pattern, 0, sizeof (LOGFONT));
fill_in_logfont (f, &match_data.pattern, font_spec);
/* If the charset is unrecognized, then we won't find a font, so don't
Additional parameter opentype_only restricts the returned fonts to
opentype fonts, which can be used with the Uniscribe backend. */
Lisp_Object
-w32font_match_internal (frame, font_spec, opentype_only)
- Lisp_Object frame, font_spec;
- int opentype_only;
+w32font_match_internal (Lisp_Object frame, Lisp_Object font_spec, int opentype_only)
{
struct font_callback_data match_data;
HDC dc;
match_data.frame = frame;
match_data.list = Qnil;
- bzero (&match_data.pattern, sizeof (LOGFONT));
+ memset (&match_data.pattern, 0, sizeof (LOGFONT));
fill_in_logfont (f, &match_data.pattern, font_spec);
match_data.opentype_only = opentype_only;
}
int
-w32font_open_internal (f, font_entity, pixel_size, font_object)
- FRAME_PTR f;
- Lisp_Object font_entity;
- int pixel_size;
- Lisp_Object font_object;
+w32font_open_internal (FRAME_PTR f, Lisp_Object font_entity,
+ int pixel_size, Lisp_Object font_object)
{
- int len, size, i;
+ int len, size;
LOGFONT logfont;
HDC dc;
HFONT hfont, old_font;
if (!font)
return 0;
- bzero (&logfont, sizeof (logfont));
+ memset (&logfont, 0, sizeof (logfont));
fill_in_logfont (f, &logfont, font_entity);
/* Prefer truetype fonts, to avoid known problems with type1 fonts, and
old_font = SelectObject (dc, hfont);
/* Try getting the outline metrics (only works for truetype fonts). */
- len = GetOutlineTextMetricsW (dc, 0, NULL);
+ len = get_outline_metrics_w (dc, 0, NULL);
if (len)
{
metrics = (OUTLINETEXTMETRICW *) alloca (len);
- if (GetOutlineTextMetricsW (dc, len, metrics))
- bcopy (&metrics->otmTextMetrics, &w32_font->metrics,
- sizeof (TEXTMETRICW));
+ if (get_outline_metrics_w (dc, len, metrics))
+ memcpy (&w32_font->metrics, &metrics->otmTextMetrics,
+ sizeof (TEXTMETRICW));
else
metrics = NULL;
}
if (!metrics)
- GetTextMetricsW (dc, &w32_font->metrics);
+ get_text_metrics_w (dc, &w32_font->metrics);
w32_font->cached_metrics = NULL;
w32_font->n_cache_blocks = 0;
/* Callback function for EnumFontFamiliesEx.
* Adds the name of a font to a Lisp list (passed in as the lParam arg). */
static int CALLBACK
-add_font_name_to_list (logical_font, physical_font, font_type, list_object)
- ENUMLOGFONTEX *logical_font;
- NEWTEXTMETRICEX *physical_font;
- DWORD font_type;
- LPARAM list_object;
+add_font_name_to_list (ENUMLOGFONTEX *logical_font,
+ NEWTEXTMETRICEX *physical_font,
+ DWORD font_type, LPARAM list_object)
{
Lisp_Object* list = (Lisp_Object *) list_object;
Lisp_Object family;
return 1;
}
-static int w32_decode_weight P_ ((int));
-static int w32_encode_weight P_ ((int));
+static int w32_decode_weight (int);
+static int w32_encode_weight (int);
/* Convert an enumerated Windows font to an Emacs font entity. */
static Lisp_Object
-w32_enumfont_pattern_entity (frame, logical_font, physical_font,
- font_type, requested_font, backend)
- Lisp_Object frame;
- ENUMLOGFONTEX *logical_font;
- NEWTEXTMETRICEX *physical_font;
- DWORD font_type;
- LOGFONT *requested_font;
- Lisp_Object backend;
+w32_enumfont_pattern_entity (Lisp_Object frame,
+ ENUMLOGFONTEX *logical_font,
+ NEWTEXTMETRICEX *physical_font,
+ DWORD font_type,
+ LOGFONT *requested_font,
+ Lisp_Object backend)
{
Lisp_Object entity, tem;
LOGFONT *lf = (LOGFONT*) logical_font;
else
ASET (entity, FONT_SIZE_INDEX, make_number (0));
- /* Cache unicode codepoints covered by this font, as there is no other way
+ /* Cache Unicode codepoints covered by this font, as there is no other way
of getting this information easily. */
if (font_type & TRUETYPE_FONTTYPE)
{
/* Convert generic families to the family portion of lfPitchAndFamily. */
-BYTE
+static BYTE
w32_generic_family (Lisp_Object name)
{
/* Generic families. */
}
static int
-logfonts_match (font, pattern)
- LOGFONT *font, *pattern;
+logfonts_match (LOGFONT *font, LOGFONT *pattern)
{
/* Only check height for raster fonts. */
if (pattern->lfHeight && font->lfOutPrecision == OUT_STRING_PRECIS
#define CSB_CHINESE ((1 << 18) | (1 << 20))
static int
-font_matches_spec (type, font, spec, backend, logfont)
- DWORD type;
- NEWTEXTMETRICEX *font;
- Lisp_Object spec;
- Lisp_Object backend;
- LOGFONT *logfont;
+font_matches_spec (DWORD type, NEWTEXTMETRICEX *font,
+ Lisp_Object spec, Lisp_Object backend,
+ LOGFONT *logfont)
{
Lisp_Object extra, val;
{
/* Only truetype fonts will have information about what
scripts they support. This probably means the user
- will have to force Emacs to use raster, postscript
- or atm fonts for non-ASCII text. */
+ will have to force Emacs to use raster, PostScript
+ or ATM fonts for non-ASCII text. */
if (type & TRUETYPE_FONTTYPE)
{
Lisp_Object support
= font_supported_scripts (&font->ntmFontSig);
if (! memq_no_quit (val, support))
return 0;
+
+ /* Avoid using non-Japanese fonts for Japanese, even
+ if they claim they are capable, due to known
+ breakage in Vista and Windows 7 fonts
+ (bug#6029). */
+ if (EQ (val, Qkana)
+ && (font->ntmTm.tmCharSet != SHIFTJIS_CHARSET
+ || !(font->ntmFontSig.fsCsb[0] & CSB_JAPANESE)))
+ return 0;
}
else
{
}
static int
-w32font_coverage_ok (coverage, charset)
- FONTSIGNATURE * coverage;
- BYTE charset;
+w32font_coverage_ok (FONTSIGNATURE * coverage, BYTE charset)
{
DWORD subrange1 = coverage->fsUsb[1];
static int
-check_face_name (font, full_name)
- LOGFONT *font;
- char *full_name;
+check_face_name (LOGFONT *font, char *full_name)
{
char full_iname[LF_FULLFACESIZE+1];
/* Helvetica is mapped to Arial in Windows, but if a Type-1 Helvetica is
installed, we run into problems with the Uniscribe backend which tries
to avoid non-truetype fonts, and ends up mixing the Type-1 Helvetica
- with Arial's characteristics, since that attempt to use Truetype works
+ with Arial's characteristics, since that attempt to use TrueType works
some places, but not others. */
if (!xstrcasecmp (font->lfFaceName, "helvetica"))
{
/* Callback function for EnumFontFamiliesEx.
- * Checks if a font matches everything we are trying to check agaist,
+ * Checks if a font matches everything we are trying to check against,
* and if so, adds it to a list. Both the data we are checking against
* and the list to which the fonts are added are passed in via the
* lparam argument, in the form of a font_callback_data struct. */
static int CALLBACK
-add_font_entity_to_list (logical_font, physical_font, font_type, lParam)
- ENUMLOGFONTEX *logical_font;
- NEWTEXTMETRICEX *physical_font;
- DWORD font_type;
- LPARAM lParam;
+add_font_entity_to_list (ENUMLOGFONTEX *logical_font,
+ NEWTEXTMETRICEX *physical_font,
+ DWORD font_type, LPARAM lParam)
{
struct font_callback_data *match_data
= (struct font_callback_data *) lParam;
/* Skip non matching fonts. */
/* For uniscribe backend, consider only truetype or opentype fonts
- that have some unicode coverage. */
+ that have some Unicode coverage. */
if (match_data->opentype_only
- && ((!physical_font->ntmTm.ntmFlags & NTMFLAGS_OPENTYPE
+ && ((!(physical_font->ntmTm.ntmFlags & NTMFLAGS_OPENTYPE)
&& !(font_type & TRUETYPE_FONTTYPE))
|| !is_unicode))
return 1;
Lisp_Object spec_charset = AREF (match_data->orig_font_spec,
FONT_REGISTRY_INDEX);
- /* iso10646-1 fonts must contain unicode mapping tables. */
+ /* iso10646-1 fonts must contain Unicode mapping tables. */
if (EQ (spec_charset, Qiso10646_1))
{
if (!is_unicode)
&& !(physical_font->ntmFontSig.fsUsb[0] & 0x007F001F))
return 1;
}
- /* unicode-sip fonts must contain characters in unicode plane 2.
+ /* unicode-sip fonts must contain characters in Unicode plane 2.
so look for bit 57 (surrogates) in the Unicode subranges, plus
the bits for CJK ranges that include those characters. */
else if (EQ (spec_charset, Qunicode_sip))
{
- if (!physical_font->ntmFontSig.fsUsb[1] & 0x02000000
- || !physical_font->ntmFontSig.fsUsb[1] & 0x28000000)
+ if (!(physical_font->ntmFontSig.fsUsb[1] & 0x02000000)
+ || !(physical_font->ntmFontSig.fsUsb[1] & 0x28000000))
return 1;
}
/* If registry was specified, ensure it is reported as the same. */
if (!NILP (spec_charset))
- ASET (entity, FONT_REGISTRY_INDEX, spec_charset);
-
+ {
+ /* Avoid using non-Japanese fonts for Japanese, even if they
+ claim they are capable, due to known breakage in Vista
+ and Windows 7 fonts (bug#6029). */
+ if (logical_font->elfLogFont.lfCharSet == SHIFTJIS_CHARSET
+ && !(physical_font->ntmFontSig.fsCsb[0] & CSB_JAPANESE))
+ return 1;
+ else
+ ASET (entity, FONT_REGISTRY_INDEX, spec_charset);
+ }
/* Otherwise if using the uniscribe backend, report ANSI and DEFAULT
- fonts as unicode and skip other charsets. */
+ fonts as Unicode and skip other charsets. */
else if (match_data->opentype_only)
{
if (logical_font->elfLogFont.lfCharSet == ANSI_CHARSET
/* Callback function for EnumFontFamiliesEx.
* Terminates the search once we have a match. */
static int CALLBACK
-add_one_font_entity_to_list (logical_font, physical_font, font_type, lParam)
- ENUMLOGFONTEX *logical_font;
- NEWTEXTMETRICEX *physical_font;
- DWORD font_type;
- LPARAM lParam;
+add_one_font_entity_to_list (ENUMLOGFONTEX *logical_font,
+ NEWTEXTMETRICEX *physical_font,
+ DWORD font_type, LPARAM lParam)
{
struct font_callback_data *match_data
= (struct font_callback_data *) lParam;
/* Old function to convert from x to w32 charset, from w32fns.c. */
static LONG
-x_to_w32_charset (lpcs)
- char * lpcs;
+x_to_w32_charset (char * lpcs)
{
Lisp_Object this_entry, w32_charset;
char *charset;
if (strncmp (lpcs, "*-#", 3) == 0)
return atoi (lpcs + 3);
- /* All Windows fonts qualify as unicode. */
+ /* All Windows fonts qualify as Unicode. */
if (!strncmp (lpcs, "iso10646", 8))
return DEFAULT_CHARSET;
/* Convert a Lisp font registry (symbol) to a windows charset. */
static LONG
-registry_to_w32_charset (charset)
- Lisp_Object charset;
+registry_to_w32_charset (Lisp_Object charset)
{
if (EQ (charset, Qiso10646_1) || EQ (charset, Qunicode_bmp)
|| EQ (charset, Qunicode_sip))
/* Old function to convert from w32 to x charset, from w32fns.c. */
static char *
-w32_to_x_charset (fncharset, matching)
- int fncharset;
- char *matching;
+w32_to_x_charset (int fncharset, char *matching)
{
static char buf[32];
Lisp_Object charset_type;
}
static Lisp_Object
-w32_registry (w32_charset, font_type)
- LONG w32_charset;
- DWORD font_type;
+w32_registry (LONG w32_charset, DWORD font_type)
{
char *charset;
- /* If charset is defaulted, charset is unicode or unknown, depending on
+ /* If charset is defaulted, charset is Unicode or unknown, depending on
font type. */
if (w32_charset == DEFAULT_CHARSET)
return font_type == TRUETYPE_FONTTYPE ? Qiso10646_1 : Qunknown;
}
static int
-w32_decode_weight (fnweight)
- int fnweight;
+w32_decode_weight (int fnweight)
{
if (fnweight >= FW_HEAVY) return 210;
if (fnweight >= FW_EXTRABOLD) return 205;
}
static int
-w32_encode_weight (n)
- int n;
+w32_encode_weight (int n)
{
if (n >= 210) return FW_HEAVY;
if (n >= 205) return FW_EXTRABOLD;
/* Convert a Windows font weight into one of the weights supported
by fontconfig (see font.c:font_parse_fcname). */
static Lisp_Object
-w32_to_fc_weight (n)
- int n;
+w32_to_fc_weight (int n)
{
if (n >= FW_EXTRABOLD) return intern ("black");
if (n >= FW_BOLD) return intern ("bold");
/* Fill in all the available details of LOGFONT from FONT_SPEC. */
static void
-fill_in_logfont (f, logfont, font_spec)
- FRAME_PTR f;
- LOGFONT *logfont;
- Lisp_Object font_spec;
+fill_in_logfont (FRAME_PTR f, LOGFONT *logfont, Lisp_Object font_spec)
{
Lisp_Object tmp, extra;
int dpi = FRAME_W32_DISPLAY_INFO (f)->resy;
/* Font families are interned, but allow for strings also in case of
user input. */
else if (SYMBOLP (tmp))
- strncpy (logfont->lfFaceName,
- SDATA (ENCODE_SYSTEM (SYMBOL_NAME (tmp))), LF_FACESIZE);
+ {
+ strncpy (logfont->lfFaceName,
+ SDATA (ENCODE_SYSTEM (SYMBOL_NAME (tmp))), LF_FACESIZE);
+ logfont->lfFaceName[LF_FACESIZE-1] = '\0';
+ }
}
tmp = AREF (font_spec, FONT_ADSTYLE_INDEX);
int spacing = XINT (tmp);
if (spacing < FONT_SPACING_MONO)
logfont->lfPitchAndFamily
- = logfont->lfPitchAndFamily & 0xF0 | VARIABLE_PITCH;
+ = (logfont->lfPitchAndFamily & 0xF0) | VARIABLE_PITCH;
else
logfont->lfPitchAndFamily
- = logfont->lfPitchAndFamily & 0xF0 | FIXED_PITCH;
+ = (logfont->lfPitchAndFamily & 0xF0) | FIXED_PITCH;
}
/* Process EXTRA info. */
{
Lisp_Object key, val;
key = XCAR (tmp), val = XCDR (tmp);
- /* Only use QCscript if charset is not provided, or is unicode
+ /* Only use QCscript if charset is not provided, or is Unicode
and a single script is specified. This is rather crude,
and is only used to narrow down the fonts returned where
there is a definite match. Some scripts, such as latin, han,
}
static void
-list_all_matching_fonts (match_data)
- struct font_callback_data *match_data;
+list_all_matching_fonts (struct font_callback_data *match_data)
{
HDC dc;
Lisp_Object families = w32font_list_family (match_data->frame);
}
static Lisp_Object
-lispy_antialias_type (type)
- BYTE type;
+lispy_antialias_type (BYTE type)
{
Lisp_Object lispy;
/* Convert antialiasing symbols to lfQuality */
static BYTE
-w32_antialias_type (type)
- Lisp_Object type;
+w32_antialias_type (Lisp_Object type)
{
if (EQ (type, Qnone))
return NONANTIALIASED_QUALITY;
so don't need to mark them separately. */
/* 1: Latin-1 supplement, 2: Latin Extended A, 3: Latin Extended B. */
SUBRANGE (4, Qphonetic);
- /* 5: Spacing and tone modifiers, 6: Combining Diacriticals. */
+ /* 5: Spacing and tone modifiers, 6: Combining Diacritical Marks. */
SUBRANGE (7, Qgreek);
SUBRANGE (8, Qcoptic);
SUBRANGE (9, Qcyrillic);
/* 115: Saurashtra, 116: Kayah Li, 117: Rejang. */
SUBRANGE (118, Qcham);
/* 119: Ancient symbols, 120: Phaistos Disc. */
- /* 121: Carian, Lycian, Lydian, 122: Dominos, Mah Jong tiles. */
+ /* 121: Carian, Lycian, Lydian, 122: Dominoes, Mahjong tiles. */
/* 123-127: Reserved. */
/* There isn't really a main symbol range, so include symbol if any
The full name is in fcname format, with weight, slant and antialiasing
specified if they are not "normal". */
static int
-w32font_full_name (font, font_obj, pixel_size, name, nbytes)
- LOGFONT * font;
- Lisp_Object font_obj;
- int pixel_size;
- char *name;
- int nbytes;
+w32font_full_name (LOGFONT * font, Lisp_Object font_obj,
+ int pixel_size, char *name, int nbytes)
{
int len, height, outline;
char *p;
the function returns -1, otherwise it returns the number of bytes
written to FCNAME. */
static int
-logfont_to_fcname (font, pointsize, fcname, size)
- LOGFONT* font;
- int pointsize;
- char *fcname;
- int size;
+logfont_to_fcname (LOGFONT* font, int pointsize, char *fcname, int size)
{
int len, height;
char *p = fcname;
}
static void
-compute_metrics (dc, w32_font, code, metrics)
- HDC dc;
- struct w32font_info *w32_font;
- unsigned int code;
- struct w32_metric_cache *metrics;
+compute_metrics (HDC dc, struct w32font_info *w32_font, unsigned int code,
+ struct w32_metric_cache *metrics)
{
GLYPHMETRICS gm;
MAT2 transform;
if (w32_font->glyph_idx)
options |= GGO_GLYPH_INDEX;
- bzero (&transform, sizeof (transform));
+ memset (&transform, 0, sizeof (transform));
transform.eM11.value = 1;
transform.eM22.value = 1;
- if (GetGlyphOutlineW (dc, code, options, &gm, 0, NULL, &transform)
+ if (get_glyph_outline_w (dc, code, options, &gm, 0, NULL, &transform)
!= GDI_ERROR)
{
metrics->lbearing = gm.gmptGlyphOrigin.x;
If FRAME is omitted or nil, it defaults to the selected frame.
If EXCLUDE-PROPORTIONAL is non-nil, exclude proportional fonts
in the font selection dialog. */)
- (frame, exclude_proportional)
- Lisp_Object frame, exclude_proportional;
+ (Lisp_Object frame, Lisp_Object exclude_proportional)
{
FRAME_PTR f = check_x_frame (frame);
CHOOSEFONT cf;
HANDLE oldobj;
char buf[100];
- bzero (&cf, sizeof (cf));
- bzero (&lf, sizeof (lf));
+ memset (&cf, 0, sizeof (cf));
+ memset (&lf, 0, sizeof (lf));
cf.lStructSize = sizeof (cf);
cf.hwndOwner = FRAME_W32_WINDOW (f);
return DECODE_SYSTEM (build_string (buf));
}
-static const char *w32font_booleans [] = {
+static const char *const w32font_booleans [] = {
NULL,
};
-static const char *w32font_non_booleans [] = {
+static const char *const w32font_non_booleans [] = {
":script",
":antialias",
":style",
};
static void
-w32font_filter_properties (font, alist)
- Lisp_Object font;
- Lisp_Object alist;
+w32font_filter_properties (Lisp_Object font, Lisp_Object alist)
{
font_filter_properties (font, alist, w32font_booleans, w32font_non_booleans);
}
NULL, /* check */
NULL, /* get_variation_glyphs */
w32font_filter_properties,
+ NULL, /* cached_font_ok */
};
/* Initialize state that does not change between invocations. This is only
called when Emacs is dumped. */
void
-syms_of_w32font ()
+syms_of_w32font (void)
{
DEFSYM (Qgdi, "gdi");
DEFSYM (Quniscribe, "uniscribe");
/* W32 font encodings. */
DEFVAR_LISP ("w32-charset-info-alist",
- &Vw32_charset_info_alist,
+ Vw32_charset_info_alist,
doc: /* Alist linking Emacs character sets to Windows fonts and codepages.
Each entry should be of the form:
register_font_driver (&w32font_driver, NULL);
}
-/* arch-tag: 65b8a3cd-46aa-4c0d-a1f3-99e75b9c07ee
- (do not change this comment) */
+void
+globals_of_w32font (void)
+{
+ g_b_init_is_w9x = 0;
+ g_b_init_get_outline_metrics_w = 0;
+ g_b_init_get_text_metrics_w = 0;
+ g_b_init_get_glyph_outline_w = 0;
+}