X-Git-Url: https://code.delx.au/gnu-emacs/blobdiff_plain/f46305c86cd247b2396e73ce8bb064f69373834d..829733104db073f8abd67765eae162e7360281fa:/src/w32font.c diff --git a/src/w32font.c b/src/w32font.c index 105daa0636..018e657256 100644 --- a/src/w32font.c +++ b/src/w32font.c @@ -1,12 +1,12 @@ /* Font backend for the Microsoft Windows API. - Copyright (C) 2007-2013 Free Software Foundation, Inc. + Copyright (C) 2007-2016 Free Software Foundation, Inc. This file is part of GNU Emacs. GNU Emacs is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. +the Free Software Foundation, either version 3 of the License, or (at +your option) any later version. GNU Emacs is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of @@ -26,13 +26,11 @@ along with GNU Emacs. If not, see . */ #include "lisp.h" #include "w32term.h" #include "frame.h" -#include "dispextern.h" -#include "character.h" -#include "charset.h" -#include "coding.h" -#include "fontset.h" -#include "font.h" +#include "coding.h" /* for ENCODE_SYSTEM, DECODE_SYSTEM */ #include "w32font.h" +#ifdef WINDOWSNT +#include "w32.h" +#endif /* Cleartype available on Windows XP, cleartype_natural from XP SP1. The latter does not try to fit cleartype smoothed fonts into the @@ -54,52 +52,7 @@ along with GNU Emacs. If not, see . */ #define JOHAB_CHARSET 130 #endif -Lisp_Object Qgdi; -Lisp_Object Quniscribe; -static Lisp_Object QCformat; -static Lisp_Object Qmonospace, Qsansserif, Qmono, Qsans, Qsans_serif; -static Lisp_Object Qserif, Qscript, Qdecorative; -static Lisp_Object Qraster, Qoutline, Qunknown; - -/* antialiasing */ -static Lisp_Object Qstandard, Qsubpixel, Qnatural; - -/* languages */ -static Lisp_Object Qzh; - -/* scripts */ -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 Qtibetan, Qmyanmar, Qgeorgian, Qhangul, Qethiopic; -static Lisp_Object Qcherokee, Qcanadian_aboriginal, Qogham, Qrunic; -static Lisp_Object Qkhmer, Qmongolian, Qbraille, Qhan; -static Lisp_Object Qideographic_description, Qcjk_misc, Qkana, Qbopomofo; -static Lisp_Object Qkanbun, Qyi, Qbyzantine_musical_symbol; -static Lisp_Object Qmusical_symbol, Qmathematical, Qcham, Qphonetic; -/* Not defined in characters.el, but referenced in fontset.el. */ -static Lisp_Object Qbalinese, Qbuginese, Qbuhid, Qcuneiform, Qcypriot; -static Lisp_Object Qdeseret, Qglagolitic, Qgothic, Qhanunoo, Qkharoshthi; -static Lisp_Object Qlimbu, Qlinear_b, Qold_italic, Qold_persian, Qosmanya; -static Lisp_Object Qphags_pa, Qphoenician, Qshavian, Qsyloti_nagri; -static Lisp_Object Qtagalog, Qtagbanwa, Qtai_le, Qtifinagh, Qugaritic; - -/* W32 charsets: for use in Vw32_charset_info_alist. */ -static Lisp_Object Qw32_charset_ansi, Qw32_charset_default; -static Lisp_Object Qw32_charset_symbol, Qw32_charset_shiftjis; -static Lisp_Object Qw32_charset_hangeul, Qw32_charset_gb2312; -static Lisp_Object Qw32_charset_chinesebig5, Qw32_charset_oem; -static Lisp_Object Qw32_charset_easteurope, Qw32_charset_turkish; -static Lisp_Object Qw32_charset_baltic, Qw32_charset_russian; -static Lisp_Object Qw32_charset_arabic, Qw32_charset_greek; -static Lisp_Object Qw32_charset_hebrew, Qw32_charset_vietnamese; -static Lisp_Object Qw32_charset_thai, Qw32_charset_johab, Qw32_charset_mac; - -/* Font spacing symbols - defined in font.c. */ -extern Lisp_Object Qc, Qp, Qm; - -static void fill_in_logfont (FRAME_PTR, LOGFONT *, Lisp_Object); +static void fill_in_logfont (struct frame *, LOGFONT *, Lisp_Object); static BYTE w32_antialias_type (Lisp_Object); static Lisp_Object lispy_antialias_type (BYTE); @@ -112,15 +65,15 @@ static void compute_metrics (HDC, struct w32font_info *, unsigned int, static Lisp_Object w32_registry (LONG, DWORD); /* EnumFontFamiliesEx callbacks. */ -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_font_name_to_list (ENUMLOGFONTEX *, - NEWTEXTMETRICEX *, - DWORD, LPARAM); +static int CALLBACK ALIGN_STACK add_font_entity_to_list (ENUMLOGFONTEX *, + NEWTEXTMETRICEX *, + DWORD, LPARAM); +static int CALLBACK ALIGN_STACK add_one_font_entity_to_list (ENUMLOGFONTEX *, + NEWTEXTMETRICEX *, + DWORD, LPARAM); +static int CALLBACK ALIGN_STACK 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. */ @@ -137,18 +90,20 @@ struct font_callback_data /* The list to add matches to. */ Lisp_Object list; /* Whether to match only opentype fonts. */ - int opentype_only; + bool opentype_only; }; /* Handles the problem that EnumFontFamiliesEx will not return all style variations if the font name is not specified. */ static void list_all_matching_fonts (struct font_callback_data *); -static BOOL g_b_init_is_w9x; +#ifdef WINDOWSNT + 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; +static BOOL g_b_init_get_char_width_32_w; typedef UINT (WINAPI * GetOutlineTextMetricsW_Proc) ( HDC hdc, @@ -165,6 +120,11 @@ typedef DWORD (WINAPI * GetGlyphOutlineW_Proc) ( DWORD cbBuffer, LPVOID lpvBuffer, const MAT2 *lpmat2); +typedef BOOL (WINAPI * GetCharWidth32W_Proc) ( + HDC hdc, + UINT uFirstChar, + UINT uLastChar, + LPINT lpBuffer); /* Several "wide" functions we use to support the font backends are unavailable on Windows 9X, unless UNICOWS.DLL is installed (their @@ -177,45 +137,7 @@ typedef DWORD (WINAPI * GetGlyphOutlineW_Proc) ( 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; + return maybe_load_unicows_dll (); } /* The following 3 functions call the problematic "wide" APIs via @@ -274,6 +196,35 @@ get_glyph_outline_w (HDC hdc, UINT uChar, UINT uFormat, LPGLYPHMETRICS lpgm, lpvBuffer, lpmat2); } +static DWORD WINAPI +get_char_width_32_w (HDC hdc, UINT uFirstChar, UINT uLastChar, LPINT lpBuffer) +{ + static GetCharWidth32W_Proc s_pfn_Get_Char_Width_32W = NULL; + HMODULE hm_unicows = NULL; + if (g_b_init_get_char_width_32_w == 0) + { + g_b_init_get_char_width_32_w = 1; + hm_unicows = w32_load_unicows_or_gdi32 (); + if (hm_unicows) + s_pfn_Get_Char_Width_32W = (GetCharWidth32W_Proc) + GetProcAddress (hm_unicows, "GetCharWidth32W"); + } + eassert (s_pfn_Get_Char_Width_32W != NULL); + return s_pfn_Get_Char_Width_32W (hdc, uFirstChar, uLastChar, lpBuffer); +} + +#else /* Cygwin */ + +/* Cygwin doesn't support Windows 9X, and links against GDI32.DLL, so + it can just call these functions directly. */ +#define get_outline_metrics_w(h,d,o) GetOutlineTextMetricsW(h,d,o) +#define get_text_metrics_w(h,t) GetTextMetricsW(h,t) +#define get_glyph_outline_w(h,uc,f,gm,b,v,m) \ + GetGlyphOutlineW(h,uc,f,gm,b,v,m) +#define get_char_width_32_w(h,fc,lc,b) GetCharWidth32W(h,fc,lc,b) + +#endif /* Cygwin */ + static int memq_no_quit (Lisp_Object elt, Lisp_Object list) { @@ -286,20 +237,20 @@ Lisp_Object intern_font_name (char * string) { Lisp_Object str = DECODE_SYSTEM (build_string (string)); - int len = SCHARS (str); + ptrdiff_t len = SCHARS (str); Lisp_Object obarray = check_obarray (Vobarray); - Lisp_Object tem = oblookup (obarray, SDATA (str), len, len); + Lisp_Object tem = oblookup (obarray, SSDATA (str), len, len); /* This code is similar to intern function from lread.c. */ - return SYMBOLP (tem) ? tem : Fintern (str, obarray); + return SYMBOLP (tem) ? tem : intern_driver (str, obarray, tem); } /* w32 implementation of get_cache for font backend. 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 (FRAME_PTR f) +w32font_get_cache (struct frame *f) { - struct w32_display_info *dpyinfo = FRAME_X_DISPLAY_INFO (f); + struct w32_display_info *dpyinfo = FRAME_DISPLAY_INFO (f); return (dpyinfo->name_list_element); } @@ -309,9 +260,9 @@ w32font_get_cache (FRAME_PTR f) is a vector of font-entities. This is the sole API that allocates font-entities. */ static Lisp_Object -w32font_list (Lisp_Object frame, Lisp_Object font_spec) +w32font_list (struct frame *f, Lisp_Object font_spec) { - Lisp_Object fonts = w32font_list_internal (frame, font_spec, 0); + Lisp_Object fonts = w32font_list_internal (f, font_spec, 0); FONT_ADD_LOG ("w32font-list", font_spec, fonts); return fonts; } @@ -321,9 +272,9 @@ w32font_list (Lisp_Object frame, Lisp_Object font_spec) FRAME. The closeness is determined by the font backend, thus `face-font-selection-order' is ignored here. */ static Lisp_Object -w32font_match (Lisp_Object frame, Lisp_Object font_spec) +w32font_match (struct frame *f, Lisp_Object font_spec) { - Lisp_Object entity = w32font_match_internal (frame, font_spec, 0); + Lisp_Object entity = w32font_match_internal (f, font_spec, 0); FONT_ADD_LOG ("w32font-match", font_spec, entity); return entity; } @@ -332,12 +283,11 @@ w32font_match (Lisp_Object frame, Lisp_Object font_spec) List available families. The value is a list of family names (symbols). */ static Lisp_Object -w32font_list_family (Lisp_Object frame) +w32font_list_family (struct frame *f) { Lisp_Object list = Qnil; LOGFONT font_match_pattern; HDC dc; - FRAME_PTR f = XFRAME (frame); memset (&font_match_pattern, 0, sizeof (font_match_pattern)); font_match_pattern.lfCharSet = DEFAULT_CHARSET; @@ -356,7 +306,7 @@ w32font_list_family (Lisp_Object frame) 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 (FRAME_PTR f, Lisp_Object font_entity, int pixel_size) +w32font_open (struct frame *f, Lisp_Object font_entity, int pixel_size) { Lisp_Object font_object = font_make_object (VECSIZE (struct w32font_info), @@ -377,26 +327,28 @@ w32font_open (FRAME_PTR f, Lisp_Object font_entity, int pixel_size) return font_object; } -/* w32 implementation of close for font_backend. - Close FONT on frame F. */ +/* w32 implementation of close for font_backend. */ void -w32font_close (FRAME_PTR f, struct font *font) +w32font_close (struct font *font) { - int i; struct w32font_info *w32_font = (struct w32font_info *) font; - /* Delete the GDI font object. */ - DeleteObject (w32_font->hfont); - - /* Free all the cached metrics. */ - if (w32_font->cached_metrics) + if (w32_font->hfont) { - for (i = 0; i < w32_font->n_cache_blocks; i++) - { - xfree (w32_font->cached_metrics[i]); - } - xfree (w32_font->cached_metrics); - w32_font->cached_metrics = NULL; + /* Delete the GDI font object. */ + DeleteObject (w32_font->hfont); + w32_font->hfont = NULL; + + /* Free all the cached metrics. */ + if (w32_font->cached_metrics) + { + int i; + + for (i = 0; i < w32_font->n_cache_blocks; i++) + xfree (w32_font->cached_metrics[i]); + xfree (w32_font->cached_metrics); + w32_font->cached_metrics = NULL; + } } } @@ -471,7 +423,7 @@ w32font_encode_char (struct font *font, int c) of METRICS. The glyphs are specified by their glyph codes in CODE (length NGLYPHS). Apparently metrics can be NULL, in this case just return the overall width. */ -int +void w32font_text_extents (struct font *font, unsigned *code, int nglyphs, struct font_metrics *metrics) { @@ -482,87 +434,95 @@ w32font_text_extents (struct font *font, unsigned *code, int total_width = 0; WORD *wcode; SIZE size; + bool first; struct w32font_info *w32_font = (struct w32font_info *) font; - if (metrics) - { - memset (metrics, 0, sizeof (struct font_metrics)); - metrics->ascent = font->ascent; - metrics->descent = font->descent; + memset (metrics, 0, sizeof (struct font_metrics)); - for (i = 0; i < nglyphs; i++) - { - struct w32_metric_cache *char_metric; - int block = *(code + i) / CACHE_BLOCKSIZE; - int pos_in_block = *(code + i) % CACHE_BLOCKSIZE; + for (i = 0, first = true; i < nglyphs; i++) + { + struct w32_metric_cache *char_metric; + int block = *(code + i) / CACHE_BLOCKSIZE; + int pos_in_block = *(code + i) % CACHE_BLOCKSIZE; - if (block >= w32_font->n_cache_blocks) - { - if (!w32_font->cached_metrics) - w32_font->cached_metrics - = xmalloc ((block + 1) - * sizeof (struct w32_metric_cache *)); - else - w32_font->cached_metrics - = xrealloc (w32_font->cached_metrics, - (block + 1) - * 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; - } + if (block >= w32_font->n_cache_blocks) + { + if (!w32_font->cached_metrics) + w32_font->cached_metrics + = xmalloc ((block + 1) + * sizeof (struct w32_metric_cache *)); + else + w32_font->cached_metrics + = xrealloc (w32_font->cached_metrics, + (block + 1) + * 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; + } - if (!w32_font->cached_metrics[block]) - { - w32_font->cached_metrics[block] - = xzalloc (CACHE_BLOCKSIZE * sizeof (struct w32_metric_cache)); - } + if (!w32_font->cached_metrics[block]) + { + w32_font->cached_metrics[block] + = xzalloc (CACHE_BLOCKSIZE * sizeof (struct w32_metric_cache)); + } - char_metric = w32_font->cached_metrics[block] + pos_in_block; + char_metric = w32_font->cached_metrics[block] + pos_in_block; - if (char_metric->status == W32METRIC_NO_ATTEMPT) + if (char_metric->status == W32METRIC_NO_ATTEMPT) + { + if (dc == NULL) { - if (dc == NULL) - { - /* TODO: Frames can come and go, and their fonts - outlive them. So we can't cache the frame in the - font structure. Use selected_frame until the API - is updated to pass in a frame. */ - f = XFRAME (selected_frame); - - dc = get_frame_dc (f); - old_font = SelectObject (dc, w32_font->hfont); - } - compute_metrics (dc, w32_font, *(code + i), char_metric); + /* TODO: Frames can come and go, and their fonts + outlive them. So we can't cache the frame in the + font structure. Use selected_frame until the API + is updated to pass in a frame. */ + f = XFRAME (selected_frame); + + dc = get_frame_dc (f); + old_font = SelectObject (dc, w32_font->hfont); } + compute_metrics (dc, w32_font, *(code + i), char_metric); + } - if (char_metric->status == W32METRIC_SUCCESS) + if (char_metric->status == W32METRIC_SUCCESS) + { + if (first) { - metrics->lbearing = min (metrics->lbearing, - metrics->width + char_metric->lbearing); - metrics->rbearing = max (metrics->rbearing, - metrics->width + char_metric->rbearing); - metrics->width += char_metric->width; + metrics->lbearing = char_metric->lbearing; + metrics->rbearing = char_metric->rbearing; + metrics->width = 0; + metrics->ascent = char_metric->ascent; + metrics->descent = char_metric->descent; + first = false; } - else - /* If we couldn't get metrics for a char, - use alternative method. */ - break; + if (metrics->lbearing > char_metric->lbearing) + metrics->lbearing = char_metric->lbearing; + if (metrics->rbearing < char_metric->rbearing) + metrics->rbearing = char_metric->rbearing; + metrics->width += char_metric->width; + if (metrics->ascent < char_metric->ascent) + metrics->ascent = char_metric->ascent; + if (metrics->descent < char_metric->descent) + metrics->descent = char_metric->descent; } - /* If we got through everything, return. */ - if (i == nglyphs) - { - if (dc != NULL) - { - /* Restore state and release DC. */ - SelectObject (dc, old_font); - release_frame_dc (f, dc); - } - - return metrics->width; - } + else + /* If we couldn't get metrics for a char, + use alternative method. */ + break; + } + /* If we got through everything, return. */ + if (i == nglyphs) + { + if (dc != NULL) + { + /* Restore state and release DC. */ + SelectObject (dc, old_font); + release_frame_dc (f, dc); + } + return; } /* For non-truetype fonts, GetGlyphOutlineW is not supported, so @@ -618,18 +578,15 @@ w32font_text_extents (struct font *font, unsigned *code, } /* Give our best estimate of the metrics, based on what we know. */ - if (metrics) - { - metrics->width = total_width - w32_font->metrics.tmOverhang; - metrics->lbearing = 0; - metrics->rbearing = total_width; - } + metrics->width = total_width - w32_font->metrics.tmOverhang; + metrics->lbearing = 0; + metrics->rbearing = total_width; + metrics->ascent = font->ascent; + metrics->descent = font->descent; /* Restore state and release DC. */ SelectObject (dc, old_font); release_frame_dc (f, dc); - - return total_width; } /* w32 implementation of draw for font backend. @@ -688,12 +645,31 @@ w32font_draw (struct glyph_string *s, int from, int to, HBRUSH brush; RECT rect; struct font *font = s->font; - + int ascent = font->ascent, descent = font->descent; + + /* Font's global ascent and descent values might be + preposterously large for some fonts. We fix here the case + when those fonts are used for display of glyphless + characters, because drawing background with font dimensions + in those cases makes the display illegible. There's only one + more call to the draw method with with_background set to + true, and that's in x_draw_glyph_string_foreground, when + drawing the cursor, where we have no such heuristics + available. FIXME. */ + if (s->first_glyph->type == GLYPHLESS_GLYPH + && (s->first_glyph->u.glyphless.method == GLYPHLESS_DISPLAY_HEX_CODE + || s->first_glyph->u.glyphless.method == GLYPHLESS_DISPLAY_ACRONYM)) + { + ascent = + s->first_glyph->slice.glyphless.lower_yoff + - s->first_glyph->slice.glyphless.upper_yoff; + descent = 0; + } brush = CreateSolidBrush (s->gc->background); rect.left = x; - rect.top = y - font->ascent; + rect.top = y - ascent; rect.right = x + s->width; - rect.bottom = y + font->descent; + rect.bottom = y + descent; FillRect (s->hdc, &rect, brush); DeleteObject (brush); } @@ -732,13 +708,13 @@ w32font_free_entity (Lisp_Object entity); storing some data in FACE->extra. If successful, return 0. Otherwise, return -1. static int -w32font_prepare_face (FRAME_PTR f, struct face *face); +w32font_prepare_face (struct frame *f, struct face *face); */ /* w32 implementation of done_face for font backend. Optional. Done FACE for displaying characters by FACE->font on frame F. static void -w32font_done_face (FRAME_PTR f, struct face *face); */ +w32font_done_face (struct frame *f, struct face *face); */ /* w32 implementation of get_bitmap for font backend. Optional. @@ -755,19 +731,6 @@ w32font_get_bitmap (struct font *font, unsigned code, static void w32font_free_bitmap (struct font *font, struct font_bitmap *bitmap); */ -/* w32 implementation of get_outline for font backend. - Optional. - Return an outline data for glyph-code CODE of FONT. The format - of the outline data depends on the font-driver. -static void * -w32font_get_outline (struct font *font, unsigned code); - */ -/* w32 implementation of free_outline for font backend. - Optional. - Free OUTLINE (that is obtained by the above method). -static void -w32font_free_outline (struct font *font, void *outline); - */ /* w32 implementation of anchor_point for font backend. Optional. Get coordinates of the INDEXth anchor point of the glyph whose @@ -811,15 +774,15 @@ w32font_otf_drive (struct font *font, Lisp_Object features, Additional parameter opentype_only restricts the returned fonts to opentype fonts, which can be used with the Uniscribe backend. */ Lisp_Object -w32font_list_internal (Lisp_Object frame, Lisp_Object font_spec, int opentype_only) +w32font_list_internal (struct frame *f, Lisp_Object font_spec, + bool opentype_only) { struct font_callback_data match_data; HDC dc; - FRAME_PTR f = XFRAME (frame); match_data.orig_font_spec = font_spec; match_data.list = Qnil; - match_data.frame = frame; + XSETFRAME (match_data.frame, f); memset (&match_data.pattern, 0, sizeof (LOGFONT)); fill_in_logfont (f, &match_data.pattern, font_spec); @@ -833,7 +796,8 @@ w32font_list_internal (Lisp_Object frame, Lisp_Object font_spec, int opentype_on && !EQ (spec_charset, Qiso10646_1) && !EQ (spec_charset, Qunicode_bmp) && !EQ (spec_charset, Qunicode_sip) - && !EQ (spec_charset, Qunknown)) + && !EQ (spec_charset, Qunknown) + && !EQ (spec_charset, Qascii_0)) return Qnil; } @@ -864,14 +828,14 @@ w32font_list_internal (Lisp_Object frame, Lisp_Object font_spec, int opentype_on Additional parameter opentype_only restricts the returned fonts to opentype fonts, which can be used with the Uniscribe backend. */ Lisp_Object -w32font_match_internal (Lisp_Object frame, Lisp_Object font_spec, int opentype_only) +w32font_match_internal (struct frame *f, Lisp_Object font_spec, + bool opentype_only) { struct font_callback_data match_data; HDC dc; - FRAME_PTR f = XFRAME (frame); match_data.orig_font_spec = font_spec; - match_data.frame = frame; + XSETFRAME (match_data.frame, f); match_data.list = Qnil; memset (&match_data.pattern, 0, sizeof (LOGFONT)); @@ -892,14 +856,14 @@ w32font_match_internal (Lisp_Object frame, Lisp_Object font_spec, int opentype_o } int -w32font_open_internal (FRAME_PTR f, Lisp_Object font_entity, +w32font_open_internal (struct frame *f, Lisp_Object font_entity, int pixel_size, Lisp_Object font_object) { int len, size; LOGFONT logfont; HDC dc; HFONT hfont, old_font; - Lisp_Object val, extra; + Lisp_Object val; struct w32font_info *w32_font; struct font * font; OUTLINETEXTMETRICW* metrics = NULL; @@ -990,24 +954,8 @@ w32font_open_internal (FRAME_PTR f, Lisp_Object font_entity, font->baseline_offset = 0; font->relative_compose = 0; font->default_ascent = w32_font->metrics.tmAscent; - font->font_encoder = NULL; font->pixel_size = size; font->driver = &w32font_driver; - /* Use format cached during list, as the information we have access to - here is incomplete. */ - extra = AREF (font_entity, FONT_EXTRA_INDEX); - if (CONSP (extra)) - { - val = assq_no_quit (QCformat, extra); - if (CONSP (val)) - font->props[FONT_FORMAT_INDEX] = XCDR (val); - else - font->props[FONT_FORMAT_INDEX] = Qunknown; - } - else - font->props[FONT_FORMAT_INDEX] = Qunknown; - - font->props[FONT_FILE_INDEX] = Qnil; font->encoding_charset = -1; font->repertory_charset = -1; /* TODO: do we really want the minimum width here, which could be negative? */ @@ -1038,7 +986,7 @@ w32font_open_internal (FRAME_PTR f, Lisp_Object font_entity, /* Callback function for EnumFontFamiliesEx. * Adds the name of a font to a Lisp list (passed in as the lParam arg). */ -static int CALLBACK +static int CALLBACK ALIGN_STACK add_font_name_to_list (ENUMLOGFONTEX *logical_font, NEWTEXTMETRICEX *physical_font, DWORD font_type, LPARAM list_object) @@ -1153,11 +1101,11 @@ w32_enumfont_pattern_entity (Lisp_Object frame, truetype so that this information is not any worse than we could have obtained later. */ if (EQ (backend, Quniscribe) && (full_type & NTMFLAGS_OPENTYPE)) - tem = intern ("opentype"); + tem = Qopentype; else if (font_type & TRUETYPE_FONTTYPE) tem = intern ("truetype"); else if (full_type & NTM_PS_OPENTYPE) - tem = intern ("postscript"); + tem = Qpostscript; else if (full_type & NTM_TYPE1) tem = intern ("type1"); else if (font_type & RASTER_FONTTYPE) @@ -1484,7 +1432,7 @@ check_face_name (LOGFONT *font, char *full_name) * 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 +static int CALLBACK ALIGN_STACK add_font_entity_to_list (ENUMLOGFONTEX *logical_font, NEWTEXTMETRICEX *physical_font, DWORD font_type, LPARAM lParam) @@ -1526,12 +1474,12 @@ add_font_entity_to_list (ENUMLOGFONTEX *logical_font, by a foundry, we accept raster fonts if the font name is found anywhere within the full name. */ if ((logical_font->elfLogFont.lfOutPrecision == OUT_STRING_PRECIS - && !strstr (logical_font->elfFullName, + && !strstr ((char *)logical_font->elfFullName, logical_font->elfLogFont.lfFaceName)) /* Check for well known substitutions that mess things up in the presence of Type-1 fonts of the same name. */ || (!check_face_name (&logical_font->elfLogFont, - logical_font->elfFullName))) + (char *)logical_font->elfFullName))) return 1; /* Make a font entity for the font. */ @@ -1603,7 +1551,7 @@ add_font_entity_to_list (ENUMLOGFONTEX *logical_font, /* Callback function for EnumFontFamiliesEx. * Terminates the search once we have a match. */ -static int CALLBACK +static int CALLBACK ALIGN_STACK add_one_font_entity_to_list (ENUMLOGFONTEX *logical_font, NEWTEXTMETRICEX *physical_font, DWORD font_type, LPARAM lParam) @@ -1708,7 +1656,7 @@ registry_to_w32_charset (Lisp_Object charset) else if (EQ (charset, Qiso8859_1)) return ANSI_CHARSET; else if (SYMBOLP (charset)) - return x_to_w32_charset (SDATA (SYMBOL_NAME (charset))); + return x_to_w32_charset (SSDATA (SYMBOL_NAME (charset))); else return DEFAULT_CHARSET; } @@ -1830,7 +1778,7 @@ w32_to_x_charset (int fncharset, char *matching) || !SYMBOLP (XCAR (XCDR (this_entry)))) continue; - x_charset = SDATA (XCAR (this_entry)); + x_charset = SSDATA (XCAR (this_entry)); w32_charset = XCAR (XCDR (this_entry)); codepage = XCDR (XCDR (this_entry)); @@ -1956,15 +1904,15 @@ static Lisp_Object w32_to_fc_weight (int n) { if (n >= FW_EXTRABOLD) return intern ("black"); - if (n >= FW_BOLD) return intern ("bold"); + if (n >= FW_BOLD) return Qbold; if (n >= FW_SEMIBOLD) return intern ("demibold"); if (n >= FW_NORMAL) return intern ("medium"); - return intern ("light"); + return Qlight; } /* Fill in all the available details of LOGFONT from FONT_SPEC. */ static void -fill_in_logfont (FRAME_PTR f, LOGFONT *logfont, Lisp_Object font_spec) +fill_in_logfont (struct frame *f, LOGFONT *logfont, Lisp_Object font_spec) { Lisp_Object tmp, extra; int dpi = FRAME_RES_Y (f); @@ -2035,7 +1983,7 @@ fill_in_logfont (FRAME_PTR f, LOGFONT *logfont, Lisp_Object font_spec) else if (SYMBOLP (tmp)) { strncpy (logfont->lfFaceName, - SDATA (ENCODE_SYSTEM (SYMBOL_NAME (tmp))), LF_FACESIZE); + SSDATA (ENCODE_SYSTEM (SYMBOL_NAME (tmp))), LF_FACESIZE); logfont->lfFaceName[LF_FACESIZE-1] = '\0'; } } @@ -2114,7 +2062,7 @@ static void list_all_matching_fonts (struct font_callback_data *match_data) { HDC dc; - Lisp_Object families = w32font_list_family (match_data->frame); + Lisp_Object families = w32font_list_family (XFRAME (match_data->frame)); struct frame *f = XFRAME (match_data->frame); dc = get_frame_dc (f); @@ -2131,7 +2079,7 @@ list_all_matching_fonts (struct font_callback_data *match_data) if (NILP (family)) continue; else if (SYMBOLP (family)) - name = SDATA (ENCODE_SYSTEM (SYMBOL_NAME (family))); + name = SSDATA (ENCODE_SYSTEM (SYMBOL_NAME (family))); else continue; @@ -2208,9 +2156,18 @@ font_supported_scripts (FONTSIGNATURE * sig) supported = Fcons ((sym), supported) SUBRANGE (0, Qlatin); - /* The following count as latin too, ASCII should be present in these fonts, - so don't need to mark them separately. */ /* 1: Latin-1 supplement, 2: Latin Extended A, 3: Latin Extended B. */ + /* Most fonts that support Latin will have good coverage of the + Extended blocks, so in practice marking them below is not really + needed, or useful: if a font claims support for, say, Latin + Extended-B, but does not contain glyphs for some of the + characters in the range, the user will have to augment her + fontset to display those few characters. But we mark these + subranges here anyway, for the marginal use cases where they + might make a difference. */ + SUBRANGE (1, Qlatin); + SUBRANGE (2, Qlatin); + SUBRANGE (3, Qlatin); SUBRANGE (4, Qphonetic); /* 5: Spacing and tone modifiers, 6: Combining Diacritical Marks. */ SUBRANGE (7, Qgreek); @@ -2218,7 +2175,12 @@ font_supported_scripts (FONTSIGNATURE * sig) SUBRANGE (9, Qcyrillic); SUBRANGE (10, Qarmenian); SUBRANGE (11, Qhebrew); - /* 12: Vai. */ + /* Bit 12 is rather useless if the user has Hebrew fonts installed, + because apparently at some point in the past bit 12 was "Hebrew + Extended", and many Hebrew fonts still have this bit set. The + only workaround is to customize fontsets to use fonts like Ebrima + or Quivira. */ + SUBRANGE (12, Qvai); SUBRANGE (13, Qarabic); SUBRANGE (14, Qnko); SUBRANGE (15, Qdevanagari); @@ -2234,8 +2196,11 @@ font_supported_scripts (FONTSIGNATURE * sig) SUBRANGE (25, Qlao); SUBRANGE (26, Qgeorgian); SUBRANGE (27, Qbalinese); - /* 28: Hangul Jamo. */ - /* 29: Latin Extended, 30: Greek Extended, 31: Punctuation. */ + /* 28: Hangul Jamo -- covered by the default fontset. */ + /* 29: Latin Extended, 30: Greek Extended -- covered above. */ + /* 31: Supplemental Punctuation -- most probably be masked by + Courier New, so fontset customization is needed. */ + SUBRANGE (31, Qsymbol); /* 32-47: Symbols (defined below). */ SUBRANGE (48, Qcjk_misc); /* Match either 49: katakana or 50: hiragana for kana. */ @@ -2250,6 +2215,9 @@ font_supported_scripts (FONTSIGNATURE * sig) SUBRANGE (59, Qhan); /* There are others, but this is the main one. */ SUBRANGE (59, Qideographic_description); /* Windows lumps this in. */ SUBRANGE (59, Qkanbun); /* And this. */ + /* These are covered well either by the default Courier New or by + CJK fonts that are set up specially in the default fontset. So + marking them here wouldn't be useful. */ /* 60: Private use, 61: CJK strokes and compatibility. */ /* 62: Alphabetic Presentation, 63: Arabic Presentation A. */ /* 64: Combining half marks, 65: Vertical and CJK compatibility. */ @@ -2278,31 +2246,54 @@ font_supported_scripts (FONTSIGNATURE * sig) SUBRANGE (87, Qdeseret); SUBRANGE (88, Qbyzantine_musical_symbol); SUBRANGE (88, Qmusical_symbol); /* Windows doesn't distinguish these. */ - SUBRANGE (89, Qmathematical); + SUBRANGE (89, Qmathematical_bold); /* See fontset.el:setup-default-fontset. */ + SUBRANGE (89, Qmathematical_italic); + SUBRANGE (89, Qmathematical_bold_italic); + SUBRANGE (89, Qmathematical_script); + SUBRANGE (89, Qmathematical_bold_script); + SUBRANGE (89, Qmathematical_fraktur); + SUBRANGE (89, Qmathematical_double_struck); + SUBRANGE (89, Qmathematical_bold_fraktur); + SUBRANGE (89, Qmathematical_sans_serif); + SUBRANGE (89, Qmathematical_sans_serif_bold); + SUBRANGE (89, Qmathematical_sans_serif_italic); + SUBRANGE (89, Qmathematical_sans_serif_bold_italic); + SUBRANGE (89, Qmathematical_monospace); /* 90: Private use, 91: Variation selectors, 92: Tags. */ SUBRANGE (93, Qlimbu); SUBRANGE (94, Qtai_le); - /* 95: New Tai Le */ - SUBRANGE (90, Qbuginese); + SUBRANGE (95, Qtai_le); + SUBRANGE (96, Qbuginese); SUBRANGE (97, Qglagolitic); SUBRANGE (98, Qtifinagh); /* 99: Yijing Hexagrams. */ + SUBRANGE (99, Qhan); SUBRANGE (100, Qsyloti_nagri); SUBRANGE (101, Qlinear_b); - /* 102: Ancient Greek Numbers. */ + SUBRANGE (102, Qancient_greek_number); SUBRANGE (103, Qugaritic); SUBRANGE (104, Qold_persian); SUBRANGE (105, Qshavian); SUBRANGE (106, Qosmanya); SUBRANGE (107, Qcypriot); SUBRANGE (108, Qkharoshthi); - /* 109: Tai Xuan Jing. */ + SUBRANGE (109, Qtai_xuan_jing_symbol); SUBRANGE (110, Qcuneiform); - /* 111: Counting Rods, 112: Sundanese, 113: Lepcha, 114: Ol Chiki. */ - /* 115: Saurashtra, 116: Kayah Li, 117: Rejang. */ + SUBRANGE (111, Qcounting_rod_numeral); + SUBRANGE (112, Qsundanese); + SUBRANGE (113, Qlepcha); + SUBRANGE (114, Qol_chiki); + SUBRANGE (115, Qsaurashtra); + SUBRANGE (116, Qkayah_li); + SUBRANGE (117, Qrejang); SUBRANGE (118, Qcham); - /* 119: Ancient symbols, 120: Phaistos Disc. */ - /* 121: Carian, Lycian, Lydian, 122: Dominoes, Mahjong tiles. */ + SUBRANGE (119, Qancient_symbol); + SUBRANGE (120, Qphaistos_disc); + SUBRANGE (121, Qlycian); + SUBRANGE (121, Qcarian); + SUBRANGE (121, Qlydian); + SUBRANGE (122, Qdomino_tile); + SUBRANGE (122, Qmahjong_tile); /* 123-127: Reserved. */ /* There isn't really a main symbol range, so include symbol if any @@ -2438,6 +2429,7 @@ compute_metrics (HDC dc, struct w32font_info *w32_font, unsigned int code, GLYPHMETRICS gm; MAT2 transform; unsigned int options = GGO_METRICS; + INT width; if (w32_font->glyph_idx) options |= GGO_GLYPH_INDEX; @@ -2452,6 +2444,17 @@ compute_metrics (HDC dc, struct w32font_info *w32_font, unsigned int code, metrics->lbearing = gm.gmptGlyphOrigin.x; metrics->rbearing = gm.gmptGlyphOrigin.x + gm.gmBlackBoxX; metrics->width = gm.gmCellIncX; + metrics->ascent = gm.gmptGlyphOrigin.y; + metrics->descent = gm.gmBlackBoxY - gm.gmptGlyphOrigin.y; + metrics->status = W32METRIC_SUCCESS; + } + else if (get_char_width_32_w (dc, code, code, &width) != 0) + { + metrics->lbearing = 0; + metrics->rbearing = width; + metrics->width = width; + metrics->ascent = w32_font->font.ascent; + metrics->descent = w32_font->font.descent; metrics->status = W32METRIC_SUCCESS; } else @@ -2467,7 +2470,7 @@ If EXCLUDE-PROPORTIONAL is non-nil, exclude proportional fonts in the font selection dialog. */) (Lisp_Object frame, Lisp_Object exclude_proportional) { - FRAME_PTR f = decode_window_system_frame (frame); + struct frame *f = decode_window_system_frame (frame); CHOOSEFONT cf; LOGFONT lf; TEXTMETRIC tm; @@ -2533,8 +2536,8 @@ w32font_filter_properties (Lisp_Object font, Lisp_Object alist) struct font_driver w32font_driver = { - 0, /* Qgdi */ - 0, /* case insensitive */ + LISP_INITIALLY_ZERO, /* Qgdi */ + false, /* case insensitive */ w32font_get_cache, w32font_list, w32font_match, @@ -2550,8 +2553,6 @@ struct font_driver w32font_driver = w32font_draw, NULL, /* get_bitmap */ NULL, /* free_bitmap */ - NULL, /* get_outline */ - NULL, /* free_outline */ NULL, /* anchor_point */ NULL, /* otf_capability */ NULL, /* otf_drive */ @@ -2605,6 +2606,7 @@ syms_of_w32font (void) DEFSYM (Qcyrillic, "cyrillic"); DEFSYM (Qarmenian, "armenian"); DEFSYM (Qhebrew, "hebrew"); + DEFSYM (Qvai, "vai"); DEFSYM (Qarabic, "arabic"); DEFSYM (Qsyriac, "syriac"); DEFSYM (Qnko, "nko"); @@ -2642,7 +2644,19 @@ syms_of_w32font (void) DEFSYM (Qyi, "yi"); DEFSYM (Qbyzantine_musical_symbol, "byzantine-musical-symbol"); DEFSYM (Qmusical_symbol, "musical-symbol"); - DEFSYM (Qmathematical, "mathematical"); + DEFSYM (Qmathematical_bold, "mathematical-bold"); + DEFSYM (Qmathematical_italic, "mathematical-italic"); + DEFSYM (Qmathematical_bold_italic, "mathematical-bold-italic"); + DEFSYM (Qmathematical_script, "mathematical-script"); + DEFSYM (Qmathematical_bold_script, "mathematical-bold-script"); + DEFSYM (Qmathematical_fraktur, "mathematical-fraktur"); + DEFSYM (Qmathematical_double_struck, "mathematical-double-struck"); + DEFSYM (Qmathematical_bold_fraktur, "mathematical-bold-fraktur"); + DEFSYM (Qmathematical_sans_serif, "mathematical-sans-serif"); + DEFSYM (Qmathematical_sans_serif_bold, "mathematical-sans-serif-bold"); + DEFSYM (Qmathematical_sans_serif_italic, "mathematical-sans-serif-italic"); + DEFSYM (Qmathematical_sans_serif_bold_italic, "mathematical-sans-serif-bold-italic"); + DEFSYM (Qmathematical_monospace, "mathematical-monospace"); DEFSYM (Qcham, "cham"); DEFSYM (Qphonetic, "phonetic"); DEFSYM (Qbalinese, "balinese"); @@ -2669,6 +2683,22 @@ syms_of_w32font (void) DEFSYM (Qtai_le, "tai_le"); DEFSYM (Qtifinagh, "tifinagh"); DEFSYM (Qugaritic, "ugaritic"); + DEFSYM (Qlycian, "lycian"); + DEFSYM (Qcarian, "carian"); + DEFSYM (Qlydian, "lydian"); + DEFSYM (Qdomino_tile, "domino-tile"); + DEFSYM (Qmahjong_tile, "mahjong-tile"); + DEFSYM (Qtai_xuan_jing_symbol, "tai-xuan-jing-symbol"); + DEFSYM (Qcounting_rod_numeral, "counting-rod-numeral"); + DEFSYM (Qancient_symbol, "ancient-symbol"); + DEFSYM (Qphaistos_disc, "phaistos-disc"); + DEFSYM (Qancient_greek_number, "ancient-greek-number"); + DEFSYM (Qsundanese, "sundanese"); + DEFSYM (Qlepcha, "lepcha"); + DEFSYM (Qol_chiki, "ol-chiki"); + DEFSYM (Qsaurashtra, "saurashtra"); + DEFSYM (Qkayah_li, "kayah-li"); + DEFSYM (Qrejang, "rejang"); /* W32 font encodings. */ DEFVAR_LISP ("w32-charset-info-alist", @@ -2724,8 +2754,10 @@ versions of Windows) characters. */); void globals_of_w32font (void) { - g_b_init_is_w9x = 0; +#ifdef WINDOWSNT g_b_init_get_outline_metrics_w = 0; g_b_init_get_text_metrics_w = 0; g_b_init_get_glyph_outline_w = 0; + g_b_init_get_char_width_32_w = 0; +#endif }