Commit 34fd2d28 authored by Jason Rumney's avatar Jason Rumney

(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.
parent 500591f8
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.
......
......@@ -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");
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment