mirror of
git://git.sv.gnu.org/emacs.git
synced 2026-04-27 08:43:40 -07:00
(Quniscribe, QCformat): New symbols.
(syms_of_w32font): Define them. (w32font_has_char): Indicate uncertainty. (w32font_encode_char): Encode as glyph point. Make static. (recompute_cached_metrics): New function. (w32font_open_internal): Use it. Set font to use glyph points initially. Set format based on type of font. (w32font_text_extents, w32font_draw): Optionally use glyph points. (w32_enumfont_pattern_entity): Accept backend arg. Set type based on it. Set format based on information available here. (add_font_entity_to_list): Identify backend based on opentype_only.
This commit is contained in:
parent
500591f86b
commit
34fd2d28e9
2 changed files with 188 additions and 48 deletions
|
|
@ -1,3 +1,22 @@
|
|||
2008-03-03 Jason Rumney <jasonr@gnu.org>
|
||||
|
||||
* w32font.h (NTM_PS_OPENTYPE, NTM_TT_OPENTYPE, NTM_TYPE1): Define
|
||||
if system headers don't.
|
||||
(struct w32font_info): Enlarge ascii_metrics. Add glyph_idx.
|
||||
(w32font_encode_char): Don't declare here.
|
||||
|
||||
* w32font.c (Quniscribe, QCformat): New symbols.
|
||||
(syms_of_w32font): Define them.
|
||||
(w32font_has_char): Indicate uncertainty.
|
||||
(w32font_encode_char): Encode as glyph point. Make static.
|
||||
(recompute_cached_metrics): New function.
|
||||
(w32font_open_internal): Use it. Set font to use glyph points
|
||||
initially. Set format based on type of font.
|
||||
(w32font_text_extents, w32font_draw): Optionally use glyph points.
|
||||
(w32_enumfont_pattern_entity): Accept backend arg. Set type based
|
||||
on it. Set format based on information available here.
|
||||
(add_font_entity_to_list): Identify backend based on opentype_only.
|
||||
|
||||
2008-03-02 Andreas Schwab <schwab@suse.de>
|
||||
|
||||
* ftfont.c (ftfont_pattern_entity): Fix aliasing violations.
|
||||
|
|
|
|||
217
src/w32font.c
217
src/w32font.c
|
|
@ -45,6 +45,8 @@ Boston, MA 02110-1301, USA. */
|
|||
extern struct font_driver w32font_driver;
|
||||
|
||||
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;
|
||||
|
|
@ -78,9 +80,7 @@ static Lisp_Object lispy_antialias_type P_ ((BYTE type));
|
|||
static Lisp_Object font_supported_scripts P_ ((FONTSIGNATURE * sig));
|
||||
static int w32font_full_name P_ ((LOGFONT * font, Lisp_Object font_obj,
|
||||
int pixel_size, char *name, int nbytes));
|
||||
|
||||
/* From old font code in w32fns.c */
|
||||
char * w32_to_x_charset P_ ((int charset, char * matching));
|
||||
static void recompute_cached_metrics P_ ((HDC dc, struct font * font));
|
||||
|
||||
static Lisp_Object w32_registry P_ ((LONG w32_charset));
|
||||
|
||||
|
|
@ -117,12 +117,9 @@ struct font_callback_data
|
|||
style variations if the font name is not specified. */
|
||||
static void list_all_matching_fonts P_ ((struct font_callback_data *match));
|
||||
|
||||
/* From old font code in w32fns.c */
|
||||
char * w32_to_x_charset P_ ((int charset, char * matching));
|
||||
|
||||
/* MingW headers only define this when _WIN32_WINNT >= 0x0500, but we
|
||||
target older versions. */
|
||||
#ifndef GGI_MARK_NONEXISTING_GLYPHS
|
||||
#define GGI_MARK_NONEXISTING_GLYPHS 1
|
||||
#endif
|
||||
|
||||
static int
|
||||
memq_no_quit (elt, list)
|
||||
|
|
@ -263,20 +260,74 @@ w32font_has_char (entity, c)
|
|||
|
||||
script = CHAR_TABLE_REF (Vchar_script_table, c);
|
||||
|
||||
return (memq_no_quit (script, supported_scripts)) ? 1 : 0;
|
||||
return (memq_no_quit (script, supported_scripts)) ? -1 : 0;
|
||||
}
|
||||
|
||||
/* w32 implementation of encode_char for font backend.
|
||||
Return a glyph code of FONT for characer C (Unicode code point).
|
||||
If FONT doesn't have such a glyph, return FONT_INVALID_CODE. */
|
||||
unsigned
|
||||
static unsigned
|
||||
w32font_encode_char (font, c)
|
||||
struct font *font;
|
||||
int c;
|
||||
{
|
||||
/* Avoid unneccesary conversion - all the Win32 APIs will take a unicode
|
||||
character. */
|
||||
return c;
|
||||
struct frame *f;
|
||||
HDC dc;
|
||||
HFONT old_font;
|
||||
DWORD retval;
|
||||
GCP_RESULTSW result;
|
||||
wchar_t in[2];
|
||||
wchar_t out[2];
|
||||
int len;
|
||||
struct w32font_info *w32_font = (struct w32font_info *) font;
|
||||
|
||||
/* If glyph indexing is not working for this font, just return the
|
||||
unicode code-point. */
|
||||
if (!w32_font->glyph_idx)
|
||||
return c;
|
||||
|
||||
if (c > 0xFFFF)
|
||||
{
|
||||
/* TODO: Encode as surrogate pair and lookup the glyph. */
|
||||
return FONT_INVALID_CODE;
|
||||
}
|
||||
else
|
||||
{
|
||||
in[0] = (wchar_t) c;
|
||||
len = 1;
|
||||
}
|
||||
|
||||
bzero (&result, sizeof (result));
|
||||
result.lStructSize = sizeof (result);
|
||||
result.lpGlyphs = out;
|
||||
result.nGlyphs = 2;
|
||||
|
||||
f = XFRAME (selected_frame);
|
||||
|
||||
dc = get_frame_dc (f);
|
||||
old_font = SelectObject (dc, ((W32FontStruct *) (font->font.font))->hfont);
|
||||
|
||||
retval = GetCharacterPlacementW (dc, in, len, 0, &result, 0);
|
||||
|
||||
SelectObject (dc, old_font);
|
||||
release_frame_dc (f, dc);
|
||||
|
||||
if (retval)
|
||||
{
|
||||
if (result.nGlyphs != 1 || !result.lpGlyphs[0])
|
||||
return FONT_INVALID_CODE;
|
||||
return result.lpGlyphs[0];
|
||||
}
|
||||
else
|
||||
{
|
||||
int i;
|
||||
/* Mark this font as not supporting glyph indices. This can happen
|
||||
on Windows9x, and maybe with non-Truetype fonts on NT etc. */
|
||||
w32_font->glyph_idx = 0;
|
||||
recompute_cached_metrics (dc, font);
|
||||
|
||||
return c;
|
||||
}
|
||||
}
|
||||
|
||||
/* w32 implementation of text_extents for font backend.
|
||||
|
|
@ -308,6 +359,7 @@ w32font_text_extents (font, code, nglyphs, metrics)
|
|||
{
|
||||
GLYPHMETRICS gm;
|
||||
MAT2 transform;
|
||||
struct w32font_info *w32_font = (struct w32font_info *) font;
|
||||
|
||||
/* Set transform to the identity matrix. */
|
||||
bzero (&transform, sizeof (transform));
|
||||
|
|
@ -320,11 +372,11 @@ w32font_text_extents (font, code, nglyphs, metrics)
|
|||
|
||||
for (i = 0; i < nglyphs; i++)
|
||||
{
|
||||
if (*(code + i) < 128 && *(code + i) > 32)
|
||||
if (*(code + i) < 128)
|
||||
{
|
||||
/* Use cached metrics for ASCII. */
|
||||
struct font_metrics *char_metric
|
||||
= &((struct w32font_info *)font)->ascii_metrics[*(code+i)-32];
|
||||
= &w32_font->ascii_metrics[*(code+i)];
|
||||
|
||||
/* If we couldn't get metrics when caching, use fallback. */
|
||||
if (char_metric->width == 0)
|
||||
|
|
@ -346,8 +398,11 @@ w32font_text_extents (font, code, nglyphs, metrics)
|
|||
old_font = SelectObject (dc, ((W32FontStruct *)
|
||||
(font->font.font))->hfont);
|
||||
}
|
||||
if (GetGlyphOutlineW (dc, *(code + i), GGO_METRICS, &gm, 0,
|
||||
NULL, &transform) != GDI_ERROR)
|
||||
if (GetGlyphOutlineW (dc, *(code + i),
|
||||
GGO_METRICS
|
||||
| w32_font->glyph_idx
|
||||
? GGO_GLYPH_INDEX : 0,
|
||||
&gm, 0, NULL, &transform) != GDI_ERROR)
|
||||
{
|
||||
int new_val = metrics->width + gm.gmBlackBoxX
|
||||
+ gm.gmptGlyphOrigin.x;
|
||||
|
|
@ -362,6 +417,20 @@ w32font_text_extents (font, code, nglyphs, metrics)
|
|||
}
|
||||
else
|
||||
{
|
||||
if (w32_font->glyph_idx)
|
||||
{
|
||||
/* Disable glyph indexing for this font, as we can't
|
||||
handle the metrics. Abort this run, our recovery
|
||||
strategies rely on having unicode code points here.
|
||||
This will cause a glitch in display, but in practice,
|
||||
any problems should be caught when initialising the
|
||||
metrics cache. */
|
||||
w32_font->glyph_idx = 0;
|
||||
recompute_cached_metrics (dc, font);
|
||||
SelectObject (dc, old_font);
|
||||
release_frame_dc (f, dc);
|
||||
return 0;
|
||||
}
|
||||
/* Rely on an estimate based on the overall font metrics. */
|
||||
break;
|
||||
}
|
||||
|
|
@ -449,8 +518,11 @@ w32font_draw (s, from, to, x, y, with_background)
|
|||
struct glyph_string *s;
|
||||
int from, to, x, y, with_background;
|
||||
{
|
||||
UINT options = 0;
|
||||
UINT options;
|
||||
HRGN orig_clip;
|
||||
struct w32font_info *w32font = (struct w32font_info *) s->face->font_info;
|
||||
|
||||
options = w32font->glyph_idx;
|
||||
|
||||
/* Save clip region for later restoration. */
|
||||
GetClipRgn(s->hdc, orig_clip);
|
||||
|
|
@ -709,34 +781,12 @@ w32font_open_internal (f, font_entity, pixel_size, w32_font)
|
|||
GetTextMetrics (dc, &w32_font->metrics);
|
||||
|
||||
/* Cache ASCII metrics. */
|
||||
{
|
||||
GLYPHMETRICS gm;
|
||||
MAT2 transform;
|
||||
int i;
|
||||
|
||||
bzero (&transform, sizeof (transform));
|
||||
transform.eM11.value = 1;
|
||||
transform.eM22.value = 1;
|
||||
|
||||
for (i = 0; i < 96; i++)
|
||||
{
|
||||
struct font_metrics* char_metric = &w32_font->ascii_metrics[i];
|
||||
|
||||
if (GetGlyphOutlineW (dc, i + 32, GGO_METRICS, &gm, 0,
|
||||
NULL, &transform) != GDI_ERROR)
|
||||
{
|
||||
char_metric->lbearing = -gm.gmptGlyphOrigin.x;
|
||||
char_metric->rbearing = gm.gmBlackBoxX + gm.gmptGlyphOrigin.x;
|
||||
char_metric->width = gm.gmCellIncX;
|
||||
char_metric->ascent = -gm.gmptGlyphOrigin.y;
|
||||
char_metric->descent = gm.gmBlackBoxY + gm.gmptGlyphOrigin.y;
|
||||
}
|
||||
else
|
||||
char_metric->width = 0;
|
||||
}
|
||||
}
|
||||
recompute_cached_metrics (dc, font);
|
||||
SelectObject (dc, old_font);
|
||||
release_frame_dc (f, dc);
|
||||
|
||||
w32_font->glyph_idx = ETO_GLYPH_INDEX;
|
||||
|
||||
/* W32FontStruct - we should get rid of this, and use the w32font_info
|
||||
struct for any W32 specific fields. font->font.font can then be hfont. */
|
||||
font->font.font = xmalloc (sizeof (W32FontStruct));
|
||||
|
|
@ -790,7 +840,20 @@ w32font_open_internal (f, font_entity, pixel_size, w32_font)
|
|||
font->entity = font_entity;
|
||||
font->pixel_size = size;
|
||||
font->driver = &w32font_driver;
|
||||
font->format = Qgdi;
|
||||
/* 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->format = XCDR (val);
|
||||
else
|
||||
font->format = Qunknown;
|
||||
}
|
||||
else
|
||||
font->format = Qunknown;
|
||||
|
||||
font->file_name = NULL;
|
||||
font->encoding_charset = -1;
|
||||
font->repertory_charset = -1;
|
||||
|
|
@ -859,20 +922,22 @@ add_font_name_to_list (logical_font, physical_font, font_type, list_object)
|
|||
/* 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)
|
||||
font_type, requested_font, backend)
|
||||
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;
|
||||
BYTE generic_type;
|
||||
BYTE full_type = physical_font->ntmTm.ntmFlags;
|
||||
|
||||
entity = Fmake_vector (make_number (FONT_ENTITY_MAX), Qnil);
|
||||
|
||||
ASET (entity, FONT_TYPE_INDEX, Qgdi);
|
||||
ASET (entity, FONT_TYPE_INDEX, backend);
|
||||
ASET (entity, FONT_FRAME_INDEX, frame);
|
||||
ASET (entity, FONT_REGISTRY_INDEX, w32_registry (lf->lfCharSet));
|
||||
ASET (entity, FONT_OBJLIST_INDEX, Qnil);
|
||||
|
|
@ -939,6 +1004,24 @@ w32_enumfont_pattern_entity (frame, logical_font, physical_font,
|
|||
font_supported_scripts (&physical_font->ntmFontSig));
|
||||
}
|
||||
|
||||
/* This information is not fully available when opening fonts, so
|
||||
save it here. Only Windows 2000 and later return information
|
||||
about opentype and type1 fonts, so need a fallback for detecting
|
||||
truetype so that this information is not any worse than we could
|
||||
have obtained later. */
|
||||
if (full_type & NTM_TT_OPENTYPE || font_type & TRUETYPE_FONTTYPE)
|
||||
tem = intern ("truetype");
|
||||
else if (full_type & NTM_TYPE1)
|
||||
tem = intern ("type1");
|
||||
else if (full_type & NTM_PS_OPENTYPE)
|
||||
tem = intern ("postscript");
|
||||
else if (font_type & RASTER_FONTTYPE)
|
||||
tem = intern ("w32bitmap");
|
||||
else
|
||||
tem = intern ("w32vector");
|
||||
|
||||
font_put_extra (entity, QCformat, tem);
|
||||
|
||||
return entity;
|
||||
}
|
||||
|
||||
|
|
@ -1166,7 +1249,9 @@ add_font_entity_to_list (logical_font, physical_font, font_type, lParam)
|
|||
Lisp_Object entity
|
||||
= w32_enumfont_pattern_entity (match_data->frame, logical_font,
|
||||
physical_font, font_type,
|
||||
&match_data->pattern);
|
||||
&match_data->pattern,
|
||||
match_data->opentype_only
|
||||
? Quniscribe : Qgdi);
|
||||
if (!NILP (entity))
|
||||
match_data->list = Fcons (entity, match_data->list);
|
||||
}
|
||||
|
|
@ -1615,6 +1700,40 @@ w32font_full_name (font, font_obj, pixel_size, name, nbytes)
|
|||
return (p - name);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
recompute_cached_metrics (dc, font)
|
||||
HDC dc;
|
||||
struct font *font;
|
||||
{
|
||||
GLYPHMETRICS gm;
|
||||
MAT2 transform;
|
||||
int i;
|
||||
struct w32font_info *w32_font;
|
||||
|
||||
bzero (&transform, sizeof (transform));
|
||||
transform.eM11.value = 1;
|
||||
transform.eM22.value = 1;
|
||||
|
||||
for (i = 0; i < 128; i++)
|
||||
{
|
||||
struct font_metrics* char_metric = &w32_font->ascii_metrics[i];
|
||||
|
||||
if (GetGlyphOutlineW (dc, i + 32, GGO_METRICS
|
||||
| w32_font->glyph_idx ? GGO_GLYPH_INDEX : 0,
|
||||
&gm, 0, NULL, &transform) != GDI_ERROR)
|
||||
{
|
||||
char_metric->lbearing = -gm.gmptGlyphOrigin.x;
|
||||
char_metric->rbearing = gm.gmBlackBoxX + gm.gmptGlyphOrigin.x;
|
||||
char_metric->width = gm.gmCellIncX;
|
||||
char_metric->ascent = -gm.gmptGlyphOrigin.y;
|
||||
char_metric->descent = gm.gmBlackBoxY + gm.gmptGlyphOrigin.y;
|
||||
}
|
||||
else
|
||||
char_metric->width = 0;
|
||||
}
|
||||
}
|
||||
|
||||
struct font_driver w32font_driver =
|
||||
{
|
||||
0, /* Qgdi */
|
||||
|
|
@ -1650,6 +1769,8 @@ void
|
|||
syms_of_w32font ()
|
||||
{
|
||||
DEFSYM (Qgdi, "gdi");
|
||||
DEFSYM (Quniscribe, "uniscribe");
|
||||
DEFSYM (QCformat, ":format");
|
||||
|
||||
/* Generic font families. */
|
||||
DEFSYM (Qmonospace, "monospace");
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue