X-Git-Url: https://code.delx.au/gnu-emacs/blobdiff_plain/af025ae850c8f30431cf79876c4452d9f1679250..785adfcc8dee02ac544f80e4f7f8d3d5b2965981:/src/w32font.c diff --git a/src/w32font.c b/src/w32font.c index fb83ec16a5..ab77267990 100644 --- a/src/w32font.c +++ b/src/w32font.c @@ -1,5 +1,5 @@ /* Font backend for the Microsoft Windows API. - Copyright (C) 2007-2013 Free Software Foundation, Inc. + Copyright (C) 2007-2015 Free Software Foundation, Inc. This file is part of GNU Emacs. @@ -33,6 +33,9 @@ along with GNU Emacs. If not, see . */ #include "fontset.h" #include "font.h" #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,51 +57,6 @@ 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 (struct frame *, LOGFONT *, Lisp_Object); static BYTE w32_antialias_type (Lisp_Object); @@ -112,15 +70,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. */ @@ -144,7 +102,8 @@ struct font_callback_data 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; @@ -183,45 +142,7 @@ typedef BOOL (WINAPI * GetCharWidth32W_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 @@ -280,8 +201,8 @@ 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 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; @@ -297,6 +218,18 @@ static DWORD WINAPI get_char_width_32_w (HDC hdc, UINT uFirstChar, 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) { @@ -309,11 +242,11 @@ 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); /* 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. @@ -495,7 +428,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) { @@ -509,84 +442,80 @@ w32font_text_extents (struct font *font, unsigned *code, 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)); + metrics->ascent = font->ascent; + metrics->descent = font->descent; - 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; 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 (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); - } - - if (char_metric->status == W32METRIC_SUCCESS) + if (char_metric->status == W32METRIC_NO_ATTEMPT) + { + if (dc == NULL) { - 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; + /* 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); } - else - /* If we couldn't get metrics for a char, - use alternative method. */ - break; + compute_metrics (dc, w32_font, *(code + i), char_metric); } - /* 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; - } + if (char_metric->status == W32METRIC_SUCCESS) + { + 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; + } + 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 @@ -642,18 +571,13 @@ 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; /* Restore state and release DC. */ SelectObject (dc, old_font); release_frame_dc (f, dc); - - return total_width; } /* w32 implementation of draw for font backend. @@ -779,19 +703,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 @@ -921,7 +832,7 @@ w32font_open_internal (struct frame *f, Lisp_Object font_entity, 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; @@ -1014,21 +925,6 @@ w32font_open_internal (struct frame *f, Lisp_Object font_entity, font->default_ascent = w32_font->metrics.tmAscent; 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? */ @@ -1059,7 +955,7 @@ w32font_open_internal (struct frame *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) @@ -1505,7 +1401,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) @@ -1624,7 +1520,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) @@ -2579,8 +2475,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 */ @@ -2753,9 +2647,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 }