/* w32 implementation of text_extents for font backend.
Perform the size computation of glyphs of FONT and fillin members
of METRICS. The glyphs are specified by their glyph codes in
- CODE (length NGLYPHS). Apparently medtrics can be NULL, in this
+ CODE (length NGLYPHS). Apparently metrics can be NULL, in this
case just return the overall width. */
static int
w32font_text_extents (font, code, nglyphs, metrics)
device context to measure against... */
HDC dc = GetDC (NULL);
int total_width = 0;
-
- /* TODO: Allow some extra room for surrogates. */
WORD *wcode = alloca(nglyphs * sizeof (WORD));
SIZE size;
{
GLYPHMETRICS gm;
MAT2 transform;
- int i, width;
- UINT format = GGO_METRICS;
/* Set transform to the identity matrix. */
bzero (&transform, sizeof (transform));
transform.eM11.value = 1;
transform.eM22.value = 1;
+ metrics->width = 0;
+ metrics->ascent = 0;
+ metrics->descent = 0;
for (i = 0; i < nglyphs; i++)
{
- if (code[i] < 0x10000)
- wcode[i] = code[i];
- else
- {
- /* TODO: Convert to surrogate, reallocating array if needed */
- wcode[i] = 0xffff;
- }
-
- if (GetGlyphOutlineW (dc, *(code + i), format, &gm, 0,
+ if (GetGlyphOutlineW (dc, *(code + i), GGO_METRICS, &gm, 0,
NULL, &transform) != GDI_ERROR)
{
- metrics[i].lbearing = gm.gmptGlyphOrigin.x;
- metrics[i].rbearing = gm.gmptGlyphOrigin.x + gm.gmBlackBoxX;
- metrics[i].width = gm.gmCellIncX;
- metrics[i].ascent = -gm.gmptGlyphOrigin.y;
- metrics[i].descent = gm.gmBlackBoxY + gm.gmptGlyphOrigin.y;
- }
- else if (GetTextExtentPoint32W (dc, wcode + i, 1, &size)
- != GDI_ERROR)
- {
- metrics[i].lbearing = 0;
- metrics[i].rbearing = size.cx
- + ((struct w32font_info *) font)->metrics.tmOverhang;
- metrics[i].width = size.cx;
- metrics[i].ascent = font->ascent;
- metrics[i].descent = font->descent;
+ int new_val = metrics->width + gm.gmBlackBoxX
+ + gm.gmptGlyphOrigin.x;
+
+ metrics->rbearing = max (metrics->rbearing, new_val);
+ metrics->width += gm.gmCellIncX;
+ new_val = -gm.gmptGlyphOrigin.y;
+ metrics->ascent = max (metrics->ascent, new_val);
+ new_val = gm.gmBlackBoxY + gm.gmptGlyphOrigin.y;
+ metrics->descent = max (metrics->descent, new_val);
}
else
{
- metrics[i].lbearing = 0;
- metrics[i].rbearing = font->font.size
- + ((struct w32font_info *) font)->metrics.tmOverhang;
- metrics[i].width = font->font.size;
- metrics[i].ascent = font->ascent;
- metrics[i].descent = font->descent;
+ /* Rely on an estimate based on the overall font metrics. */
+ break;
}
}
+
+ /* If we got through everything, return. */
+ if (i == nglyphs)
+ {
+ /* Restore state and release DC. */
+ SelectObject (dc, old_font);
+ ReleaseDC (NULL, dc);
+
+ return metrics->width;
+ }
}
- else
+
+ for (i = 0; i < nglyphs; i++)
{
- for (i = 0; i < nglyphs; i++)
- {
- if (code[i] < 0x10000)
- wcode[i] = code[i];
- else
- {
- /* TODO: Convert to surrogate, reallocating array if needed */
- wcode[i] = 0xffff;
- }
- }
+ if (code[i] < 0x10000)
+ wcode[i] = code[i];
+ else
+ {
+ /* TODO: Convert to surrogate, reallocating array if needed */
+ wcode[i] = 0xffff;
+ }
}
if (GetTextExtentPoint32W (dc, wcode, nglyphs, &size))
total_width = rect.right;
}
+ if (metrics)
+ {
+ metrics->width = total_width;
+ metrics->ascent = font->ascent;
+ metrics->descent = font->descent;
+ metrics->lbearing = 0;
+ metrics->rbearing = total_width
+ + ((struct w32font_info *) font)->metrics.tmOverhang;
+ }
+
/* Restore state and release DC. */
SelectObject (dc, old_font);
ReleaseDC (NULL, dc);
int from, to, x, y, with_background;
{
UINT options = 0;
+ HRGN orig_clip;
+
+ /* Save clip region for later restoration. */
+ GetClipRgn(s->hdc, orig_clip);
+
+ if (s->num_clips > 0)
+ {
+ HRGN new_clip = CreateRectRgnIndirect (s->clip);
+
+ if (s->num_clips > 1)
+ {
+ HRGN clip2 = CreateRectRgnIndirect (s->clip + 1);
+
+ CombineRgn (new_clip, new_clip, clip2, RGN_OR);
+ DeleteObject (clip2);
+ }
+
+ SelectClipRgn (s->hdc, new_clip);
+ DeleteObject (new_clip);
+ }
if (with_background)
{
+ SetBkColor (s->hdc, s->gc->background);
+ SetBkMode (s->hdc, OPAQUE);
+#if 0
HBRUSH brush;
RECT rect;
rect.bottom = y + ((struct font *) (s->font_info->font))->descent;
FillRect (s->hdc, &rect, brush);
DeleteObject (brush);
+#endif
}
else
SetBkMode (s->hdc, TRANSPARENT);
ExtTextOutW (s->hdc, x, y, options, NULL, s->char2b + from, to - from, NULL);
+
+ /* Restore clip region. */
+ if (s->num_clips > 0)
+ {
+ SelectClipRgn (s->hdc, orig_clip);
+ }
}
/* w32 implementation of free_entity for font backend.
LPARAM list_object;
{
Lisp_Object* list = (Lisp_Object *) list_object;
- Lisp_Object family = intern_downcase (logical_font->elfLogFont.lfFaceName,
- strlen (logical_font->elfLogFont.lfFaceName));
+ Lisp_Object family;
+
+ /* Skip vertical fonts (intended only for printing) */
+ if (logical_font->elfLogFont.lfFaceName[0] == '@')
+ return 1;
+
+ family = intern_downcase (logical_font->elfLogFont.lfFaceName,
+ strlen (logical_font->elfLogFont.lfFaceName));
if (! memq_no_quit (family, *list))
*list = Fcons (family, *list);
int slant = XINT (val);
if ((slant > 150 && !font->ntmTm.tmItalic)
|| (slant <= 150 && font->ntmTm.tmItalic))
- {
- OutputDebugString ("italic mismatch");
return 0;
- }
}
/* Check extra parameters. */
if (logfonts_match (&logical_font->elfLogFont, &match_data->pattern)
&& font_matches_spec (font_type, physical_font,
- match_data->orig_font_spec))
+ match_data->orig_font_spec)
+ /* Avoid Windows substitution so we can control substitution with
+ alternate-fontname-alist. */
+ && !strnicmp (&logical_font->elfFullName,
+ &match_data->pattern.lfFaceName, LF_FACESIZE))
{
Lisp_Object entity
= w32_enumfont_pattern_entity (match_data->frame, logical_font,