-#if OLD_FONT
-
-XCharStruct *w32_per_char_metric P_ ((XFontStruct *, wchar_t *, int));
-static int w32_encode_char P_ ((int, wchar_t *, struct font_info *,
- struct charset *, int *));
-
-
-/* Get metrics of character CHAR2B in FONT. Value is always non-null.
- If CHAR2B is not contained in FONT, the font's default character
- metric is returned. */
-
-static int
-w32_bdf_per_char_metric (font, char2b, dim, pcm)
- XFontStruct *font;
- wchar_t *char2b;
- int dim;
- XCharStruct * pcm;
-{
- glyph_metric * bdf_metric;
- char buf[2];
-
- if (dim == 1)
- buf[0] = (char)(*char2b);
- else
- {
- buf[0] = XCHAR2B_BYTE1 (char2b);
- buf[1] = XCHAR2B_BYTE2 (char2b);
- }
-
- bdf_metric = w32_BDF_TextMetric (font->bdf, buf, dim);
-
- if (bdf_metric)
- {
- pcm->width = bdf_metric->dwidth;
- pcm->lbearing = bdf_metric->bbox;
- pcm->rbearing = bdf_metric->dwidth
- - (bdf_metric->bbox + bdf_metric->bbw);
- pcm->ascent = bdf_metric->bboy + bdf_metric->bbh;
- pcm->descent = -bdf_metric->bboy;
-
- return 1;
- }
- return 0;
-}
-
-
-static int
-w32_native_per_char_metric (font, char2b, font_type, pcm)
- XFontStruct *font;
- wchar_t *char2b;
- enum w32_char_font_type font_type;
- XCharStruct * pcm;
-{
- HDC hdc = GetDC (NULL);
- HFONT old_font;
- BOOL retval = FALSE;
-
- xassert (font && char2b);
- xassert (font->hfont);
- xassert (font_type == UNICODE_FONT || font_type == ANSI_FONT);
-
- old_font = SelectObject (hdc, font->hfont);
-
- if ((font->tm.tmPitchAndFamily & TMPF_TRUETYPE) != 0)
- {
- ABC char_widths;
-
- if (font_type == UNICODE_FONT)
- retval = GetCharABCWidthsW (hdc, *char2b, *char2b, &char_widths);
- else
- retval = GetCharABCWidthsA (hdc, *char2b, *char2b, &char_widths);
-
- if (retval)
- {
-#if 0
- /* Disabled until we can find a way to get the right results
- on all versions of Windows. */
-
- /* Don't trust the ABC widths. For synthesized fonts they are
- wrong, and so is the result of GetCharWidth()! */
- int real_width;
- GetCharWidth (hdc, *char2b, *char2b, &real_width);
-#endif
- if (cleartype_active)
- {
- /* Cleartype antialiasing causes characters to overhang
- by a pixel on each side compared with what GetCharABCWidths
- reports. */
- char_widths.abcA -= 1;
- char_widths.abcC -= 1;
- char_widths.abcB += 2;
- }
-
- pcm->width = char_widths.abcA + char_widths.abcB + char_widths.abcC;
-#if 0
- /* As far as I can tell, this is the best way to determine what
- ExtTextOut will do with the broken font. */
- if (pcm->width != real_width)
- pcm->width = (pcm->width + real_width) / 2;
-#endif
- pcm->lbearing = char_widths.abcA;
- pcm->rbearing = char_widths.abcA + char_widths.abcB;
- pcm->ascent = FONT_BASE (font);
- pcm->descent = FONT_DESCENT (font);
- }
- }
-
- if (!retval)
- {
- /* Either font is not a True-type font, or GetCharABCWidthsW
- failed (it is not supported on Windows 9x for instance), so we
- can't determine the full info we would like. All is not lost
- though - we can call GetTextExtentPoint32 to get rbearing and
- deduce width based on the font's per-string overhang. lbearing
- is assumed to be zero. */
-
- /* TODO: Some Thai characters (and other composites if Windows
- supports them) do have lbearing, and report their total width
- as zero. Need some way of handling them when
- GetCharABCWidthsW fails. */
- SIZE sz;
-
- if (font_type == UNICODE_FONT)
- retval = GetTextExtentPoint32W (hdc, char2b, 1, &sz);
- else
- retval = GetTextExtentPoint32A (hdc, (char*)char2b, 1, &sz);
-
- if (retval)
- {
- pcm->width = sz.cx;
- pcm->rbearing = sz.cx + font->tm.tmOverhang;
- pcm->lbearing = 0;
- pcm->ascent = FONT_BASE (font);
- pcm->descent = FONT_DESCENT (font);
- }
- }
-
-
- if (pcm->width == 0 && (pcm->rbearing - pcm->lbearing) == 0)
- {
- retval = FALSE;
- }
-
- SelectObject (hdc, old_font);
- ReleaseDC (NULL, hdc);
-
- return retval;
-}
-
-
-XCharStruct *
-w32_per_char_metric (font, char2b, font_type)
- XFontStruct *font;
- wchar_t *char2b;
- int /* enum w32_char_font_type */ font_type;
-{
- /* The result metric information. */
- XCharStruct *pcm;
- BOOL retval;
-
- xassert (font && char2b);
-
- /* TODO: This function is currently called through the RIF, and in
- some cases font_type is UNKNOWN_FONT. We currently allow the
- cached metrics to be used, which seems to work, but in cases
- where font_type is UNKNOWN_FONT, we probably haven't encoded
- char2b appropriately. All callers need checking to see what they
- are passing. This is most likely to affect variable width fonts
- outside the Latin-1 range, particularly in languages like Thai
- that rely on rbearing and lbearing to provide composition. I
- don't think that is working currently anyway, but we don't seem
- to have anyone testing such languages on Windows. */
-
- /* Handle the common cases quickly. */
- if (!font->bdf && font->per_char == NULL)
- /* TODO: determine whether char2b exists in font? */
- return &font->max_bounds;
- else if (!font->bdf && *char2b < 128)
- return &font->per_char[*char2b];
-
- xassert (font_type != UNKNOWN_FONT);
-
- pcm = &font->scratch;
-
- if (font_type == BDF_1D_FONT)
- retval = w32_bdf_per_char_metric (font, char2b, 1, pcm);
- else if (font_type == BDF_2D_FONT)
- retval = w32_bdf_per_char_metric (font, char2b, 2, pcm);
- else
- retval = w32_native_per_char_metric (font, char2b, font_type, pcm);
-
- if (retval)
- return pcm;
-
- return NULL;
-}
-
-void
-w32_cache_char_metrics (font)
- XFontStruct *font;
-{
- wchar_t char2b = L'x';
-
- /* Cache char metrics for the common cases. */
- if (font->bdf)
- {
- /* TODO: determine whether font is fixed-pitch. */
- if (!w32_bdf_per_char_metric (font, &char2b, 1, &font->max_bounds))
- {
- /* Use the font width and height as max bounds, as not all BDF
- fonts contain the letter 'x'. */
- font->max_bounds.width = FONT_WIDTH (font);
- font->max_bounds.lbearing = -font->bdf->llx;
- font->max_bounds.rbearing = FONT_WIDTH (font) - font->bdf->urx;
- font->max_bounds.ascent = FONT_BASE (font);
- font->max_bounds.descent = FONT_DESCENT (font);
- }
- }
- else
- {
- if (((font->tm.tmPitchAndFamily & TMPF_FIXED_PITCH) != 0)
- /* Some fonts (eg DBCS fonts) are marked as fixed width even
- though they contain characters of different widths. */
- || (font->tm.tmMaxCharWidth != font->tm.tmAveCharWidth))
- {
- /* Font is not fixed pitch, so cache per_char info for the
- ASCII characters. It would be much more work, and probably
- not worth it, to cache other chars, since we may change
- between using Unicode and ANSI text drawing functions at
- run-time. */
- int i;
-
- font->per_char = xmalloc (128 * sizeof(XCharStruct));
- for (i = 0; i < 128; i++)
- {
- char2b = i;
- w32_native_per_char_metric (font, &char2b, ANSI_FONT,
- &font->per_char[i]);
- }
- }
- else
- w32_native_per_char_metric (font, &char2b, ANSI_FONT,
- &font->max_bounds);
- }
-}
-
-/* Determine if a font is double byte. */
-static int
-w32_font_is_double_byte (XFontStruct *font)
-{
- return font->double_byte_p;
-}
-
-
-static BOOL
-w32_use_unicode_for_codepage (codepage)
- int codepage;
-{
- /* If the current codepage is supported, use Unicode for output. */
- return (w32_enable_unicode_output
- && codepage != CP_8BIT
- && (codepage == CP_UNICODE || IsValidCodePage (codepage)));
-}
-
-/* Encode CHAR2B using encoding information from FONT_INFO. CHAR2B is
- the two-byte form of C. Encoding is returned in *CHAR2B. */
-
-static int /* enum w32_char_font_type */
-w32_encode_char (c, char2b, font_info, charset, two_byte_p)
- int c;
- wchar_t *char2b;
- struct font_info *font_info;
- struct charset *charset;
- int * two_byte_p;
-{
- int codepage;
- int unicode_p = 0;
- int internal_two_byte_p = 0;
-
- XFontStruct *font = font_info->font;
-
- internal_two_byte_p = w32_font_is_double_byte (font);
- codepage = font_info->codepage;
-
- /* If font can output unicode, use the original unicode character. */
- if ( font && !font->bdf && w32_use_unicode_for_codepage (codepage)
- && c >= 0x100)
- {
- *char2b = c;
- unicode_p = 1;
- internal_two_byte_p = 1;
- }
-
- /* FONT_INFO may define a scheme by which to encode byte1 and byte2.
- This may be either a program in a special encoder language or a
- fixed encoding. */
- else if (font_info->font_encoder)
- {
- /* It's a program. */
- struct ccl_program *ccl = font_info->font_encoder;
-
- if (CHARSET_DIMENSION (charset) == 1)
- {
- ccl->reg[0] = CHARSET_ID (charset);
- ccl->reg[1] = XCHAR2B_BYTE2 (char2b);
- ccl->reg[2] = -1;
- }
- else
- {
- ccl->reg[0] = CHARSET_ID (charset);
- ccl->reg[1] = XCHAR2B_BYTE1 (char2b);
- ccl->reg[2] = XCHAR2B_BYTE2 (char2b);
- }
-
- ccl_driver (ccl, NULL, NULL, 0, 0, Qnil);
-
- /* We assume that MSBs are appropriately set/reset by CCL
- program. */
- if (!internal_two_byte_p) /* 1-byte font */
- STORE_XCHAR2B (char2b, 0, ccl->reg[1]);
- else
- STORE_XCHAR2B (char2b, ccl->reg[1], ccl->reg[2]);
- }
- else if (font_info->encoding_type)
- {
- /* Fixed encoding scheme. See fontset.h for the meaning of the
- encoding numbers. */
- unsigned char enc = font_info->encoding_type;
-
- if ((enc == 1 || enc == 2)
- && CHARSET_DIMENSION (charset) == 2)
- STORE_XCHAR2B (char2b, XCHAR2B_BYTE1 (char2b) | 0x80, XCHAR2B_BYTE2 (char2b));
-
- if (enc == 1 || enc == 3 || (enc == 4 && CHARSET_DIMENSION (charset) == 1))
- STORE_XCHAR2B (char2b, XCHAR2B_BYTE1 (char2b), XCHAR2B_BYTE2 (char2b) | 0x80);
- else if (enc == 4)
- {
- int code = (int) (*char2b);
-
- JIS_TO_SJIS (code);
- STORE_XCHAR2B (char2b, (code >> 8), (code & 0xFF));
- }
- }
-
- if (two_byte_p)
- *two_byte_p = internal_two_byte_p;
-
- if (!font)
- return UNKNOWN_FONT;
- else if (font->bdf && CHARSET_DIMENSION (charset) == 1)
- return BDF_1D_FONT;
- else if (font->bdf)
- return BDF_2D_FONT;
- else if (unicode_p)
- return UNICODE_FONT;
- else
- return ANSI_FONT;
-}
-
-
-/* Return a char-table whose elements are t if the font FONT_INFO
- contains a glyph for the corresponding character, and nil if not.
-
- Fixme: For the moment, this function works only for fonts whose
- glyph encoding is the same as Unicode (e.g. ISO10646-1 fonts). */
-
-Lisp_Object
-x_get_font_repertory (f, font_info)
- FRAME_PTR f;
- struct font_info *font_info;
-{
- XFontStruct *font = (XFontStruct *) font_info->font;
- Lisp_Object table;
- int min_byte1, max_byte1, min_byte2, max_byte2;
- int c;
- struct charset *charset = CHARSET_FROM_ID (font_info->charset);
- int offset = CHARSET_OFFSET (charset);
-
- table = Fmake_char_table (Qnil, Qnil);
-
- if (!font->bdf && pfnGetFontUnicodeRanges)
- {
- GLYPHSET *glyphset;
- DWORD glyphset_size;
- HDC display = get_frame_dc (f);
- HFONT prev_font;
- int i;
-
- prev_font = SelectObject (display, font->hfont);
-
- /* First call GetFontUnicodeRanges to find out how big a structure
- we need. */
- glyphset_size = pfnGetFontUnicodeRanges (display, NULL);
- if (glyphset_size)
- {
- glyphset = (GLYPHSET *) alloca (glyphset_size);
- glyphset->cbThis = glyphset_size;
-
- /* Now call it again to get the ranges. */
- glyphset_size = pfnGetFontUnicodeRanges (display, glyphset);
-
- if (glyphset_size)
- {
- /* Store the ranges in TABLE. */
- for (i = 0; i < glyphset->cRanges; i++)
- {
- int from = glyphset->ranges[i].wcLow;
- int to = from + glyphset->ranges[i].cGlyphs - 1;
- char_table_set_range (table, from, to, Qt);
- }
- }
- }
-
- SelectObject (display, prev_font);
- release_frame_dc (f, display);
-
- /* If we got the information we wanted above, then return it. */
- if (glyphset_size)
- return table;
- }
-
-#if 0 /* TODO: Convert to work on Windows so BDF and older platforms work. */
- /* When GetFontUnicodeRanges is not available or does not work,
- work it out manually. */
- min_byte1 = font->min_byte1;
- max_byte1 = font->max_byte1;
- min_byte2 = font->min_char_or_byte2;
- max_byte2 = font->max_char_or_byte2;
- if (min_byte1 == 0 && max_byte1 == 0)
- {
- if (! font->per_char || font->all_chars_exist == True)
- {
- if (offset >= 0)
- char_table_set_range (table, offset + min_byte2,
- offset + max_byte2, Qt);
- else
- for (; min_byte2 <= max_byte2; min_byte2++)
- {
- c = DECODE_CHAR (charset, min_byte2);
- CHAR_TABLE_SET (table, c, Qt);
- }
- }
- else
- {
- XCharStruct *pcm = font->per_char;
- int from = -1;
- int i;
-
- for (i = min_byte2; i <= max_byte2; i++, pcm++)
- {
- if (pcm->width == 0 && pcm->rbearing == pcm->lbearing)
- {
- if (from >= 0)
- {
- if (offset >= 0)
- char_table_set_range (table, offset + from,
- offset + i - 1, Qt);
- else
- for (; from < i; from++)
- {
- c = DECODE_CHAR (charset, from);
- CHAR_TABLE_SET (table, c, Qt);
- }
- from = -1;
- }
- }
- else if (from < 0)
- from = i;
- }
- if (from >= 0)
- {
- if (offset >= 0)
- char_table_set_range (table, offset + from, offset + i - 1,
- Qt);
- else
- for (; from < i; from++)
- {
- c = DECODE_CHAR (charset, from);
- CHAR_TABLE_SET (table, c, Qt);
- }
- }
- }
- }
- else
- {
- if (! font->per_char || font->all_chars_exist == True)
- {
- int i, j;
-
- if (offset >= 0)
- for (i = min_byte1; i <= max_byte1; i++)
- char_table_set_range
- (table, offset + ((i << 8) | min_byte2),
- offset + ((i << 8) | max_byte2), Qt);
- else
- for (i = min_byte1; i <= max_byte1; i++)
- for (j = min_byte2; j <= max_byte2; j++)
- {
- unsiged code = (i << 8) | j;
- c = DECODE_CHAR (charset, code);
- CHAR_TABLE_SET (table, c, Qt);
- }
- }
- else
- {
- XCharStruct *pcm = font->per_char;
- int i;
-
- for (i = min_byte1; i <= max_byte1; i++)
- {
- int from = -1;
- int j;
-
- for (j = min_byte2; j <= max_byte2; j++, pcm++)
- {
- if (pcm->width == 0 && pcm->rbearing == pcm->lbearing)
- {
- if (from >= 0)
- {
- if (offset >= 0)
- char_table_set_range
- (table, offset + ((i << 8) | from),
- offset + ((i << 8) | (j - 1)), Qt);
- else
- {
- for (; from < j; from++)
- {
- unsigned code = (i << 8) | from;
- c = ENCODE_CHAR (charset, code);
- CHAR_TABLE_SET (table, c, Qt);
- }
- }
- from = -1;
- }
- }
- else if (from < 0)
- from = j;
- }
- if (from >= 0)
- {
- if (offset >= 0)
- char_table_set_range
- (table, offset + ((i << 8) | from),
- offset + ((i << 8) | (j - 1)), Qt);
- else
- {
- for (; from < j; from++)
- {
- unsigned code = (i << 8) | from;
- c = DECODE_CHAR (charset, code);
- CHAR_TABLE_SET (table, c, Qt);
- }
- }
- }
- }
- }
- }
-#endif
- return table;
-}
-
-\f
-/***********************************************************************
- Glyph display
- ***********************************************************************/
-
-
-/* Encapsulate the different ways of displaying text under W32. */
-
-static void
-w32_text_out (s, x, y,chars,nchars)
- struct glyph_string * s;
- int x, y;
- wchar_t * chars;
- int nchars;
-{
- int charset_dim = w32_font_is_double_byte (s->font) ? 2 : 1;
- if (s->font->bdf)
- w32_BDF_TextOut (s->font->bdf, s->hdc,
- x, y, (char *) chars, charset_dim,
- nchars * charset_dim, 0);
- else if (s->first_glyph->font_type == UNICODE_FONT)
- ExtTextOutW (s->hdc, x, y, 0, NULL, chars, nchars, NULL);
- else
- ExtTextOutA (s->hdc, x, y, 0, NULL, (char *) chars,
- nchars * charset_dim, NULL);
-}
-
-#endif /* OLD_FONT */
-