+/* Internal implementation of w32font_list.
+ Additional parameter opentype_only restricts the returned fonts to
+ opentype fonts, which can be used with the Uniscribe backend. */
+Lisp_Object
+w32font_list_internal (frame, font_spec, opentype_only)
+ Lisp_Object frame, font_spec;
+ int opentype_only;
+{
+ struct font_callback_data match_data;
+ HDC dc;
+ FRAME_PTR f = XFRAME (frame);
+
+ match_data.orig_font_spec = font_spec;
+ match_data.list = Qnil;
+ match_data.frame = frame;
+
+ bzero (&match_data.pattern, sizeof (LOGFONT));
+ fill_in_logfont (f, &match_data.pattern, font_spec);
+
+ match_data.opentype_only = opentype_only;
+ if (opentype_only)
+ match_data.pattern.lfOutPrecision = OUT_OUTLINE_PRECIS;
+
+ if (match_data.pattern.lfFaceName[0] == '\0')
+ {
+ /* EnumFontFamiliesEx does not take other fields into account if
+ font name is blank, so need to use two passes. */
+ list_all_matching_fonts (&match_data);
+ }
+ else
+ {
+ dc = get_frame_dc (f);
+
+ EnumFontFamiliesEx (dc, &match_data.pattern,
+ (FONTENUMPROC) add_font_entity_to_list,
+ (LPARAM) &match_data, 0);
+ release_frame_dc (f, dc);
+ }
+
+ return NILP (match_data.list) ? Qnil : match_data.list;
+}
+
+/* Internal implementation of w32font_match.
+ Additional parameter opentype_only restricts the returned fonts to
+ opentype fonts, which can be used with the Uniscribe backend. */
+Lisp_Object
+w32font_match_internal (frame, font_spec, opentype_only)
+ Lisp_Object frame, font_spec;
+ int opentype_only;
+{
+ struct font_callback_data match_data;
+ HDC dc;
+ FRAME_PTR f = XFRAME (frame);
+
+ match_data.orig_font_spec = font_spec;
+ match_data.frame = frame;
+ match_data.list = Qnil;
+
+ bzero (&match_data.pattern, sizeof (LOGFONT));
+ fill_in_logfont (f, &match_data.pattern, font_spec);
+
+ match_data.opentype_only = opentype_only;
+ if (opentype_only)
+ match_data.pattern.lfOutPrecision = OUT_OUTLINE_PRECIS;
+
+ dc = get_frame_dc (f);
+
+ EnumFontFamiliesEx (dc, &match_data.pattern,
+ (FONTENUMPROC) add_one_font_entity_to_list,
+ (LPARAM) &match_data, 0);
+ release_frame_dc (f, dc);
+
+ return NILP (match_data.list) ? Qnil : XCAR (match_data.list);
+}
+
+int
+w32font_open_internal (f, font_entity, pixel_size, font_object)
+ FRAME_PTR f;
+ Lisp_Object font_entity;
+ int pixel_size;
+ Lisp_Object font_object;
+{
+ int len, size, i;
+ LOGFONT logfont;
+ HDC dc;
+ HFONT hfont, old_font;
+ Lisp_Object val, extra;
+ /* For backwards compatibility. */
+ W32FontStruct *compat_w32_font;
+ struct w32font_info *w32_font;
+ struct font * font;
+ OUTLINETEXTMETRIC* metrics = NULL;
+
+ w32_font = (struct w32font_info *) XFONT_OBJECT (font_object);
+ font = (struct font *) w32_font;
+
+ if (!font)
+ return 0;
+
+ /* Copy from font entity. */
+ for (i = 0; i < FONT_ENTITY_MAX; i++)
+ ASET (font_object, i, AREF (font_entity, i));
+ ASET (font_object, FONT_SIZE_INDEX, make_number (pixel_size));
+
+ bzero (&logfont, sizeof (logfont));
+ fill_in_logfont (f, &logfont, font_entity);
+
+ /* Prefer truetype fonts, to avoid known problems with type1 fonts, and
+ limitations in bitmap fonts. */
+ val = AREF (font_entity, FONT_FOUNDRY_INDEX);
+ if (!EQ (val, Qraster))
+ logfont.lfOutPrecision = OUT_TT_PRECIS;
+
+ size = XINT (AREF (font_entity, FONT_SIZE_INDEX));
+ if (!size)
+ size = pixel_size;
+
+ logfont.lfHeight = -size;
+ hfont = CreateFontIndirect (&logfont);
+
+ if (hfont == NULL)
+ return 0;
+
+ /* Get the metrics for this font. */
+ dc = get_frame_dc (f);
+ old_font = SelectObject (dc, hfont);
+
+ /* Try getting the outline metrics (only works for truetype fonts). */
+ len = GetOutlineTextMetrics (dc, 0, NULL);
+ if (len)
+ {
+ metrics = (OUTLINETEXTMETRIC *) alloca (len);
+ if (GetOutlineTextMetrics (dc, len, metrics))
+ bcopy (&metrics->otmTextMetrics, &w32_font->metrics,
+ sizeof (TEXTMETRIC));
+ else
+ metrics = NULL;
+
+ /* If it supports outline metrics, it should support Glyph Indices. */
+ w32_font->glyph_idx = ETO_GLYPH_INDEX;
+ }
+
+ if (!metrics)
+ {
+ GetTextMetrics (dc, &w32_font->metrics);
+ w32_font->glyph_idx = 0;
+ }
+
+ w32_font->cached_metrics = NULL;
+ w32_font->n_cache_blocks = 0;
+
+ SelectObject (dc, old_font);
+ release_frame_dc (f, dc);
+
+ /* 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. */
+ w32_font->compat_w32_font = xmalloc (sizeof (W32FontStruct));
+ compat_w32_font = w32_font->compat_w32_font;
+ bzero (compat_w32_font, sizeof (W32FontStruct));
+ compat_w32_font->font_type = UNICODE_FONT;
+ /* Duplicate the text metrics. */
+ bcopy (&w32_font->metrics, &compat_w32_font->tm, sizeof (TEXTMETRIC));
+ compat_w32_font->hfont = hfont;
+
+ {
+ char *name;
+
+ /* We don't know how much space we need for the full name, so start with
+ 96 bytes and go up in steps of 32. */
+ len = 96;
+ name = xmalloc (len);
+ while (name && w32font_full_name (&logfont, font_entity, pixel_size,
+ name, len) < 0)
+ {
+ char *new = xrealloc (name, len += 32);
+
+ if (! new)
+ xfree (name);
+ name = new;
+ }
+ if (name)
+ font->props[FONT_FULLNAME_INDEX]
+ = make_unibyte_string (name, strlen (name));
+ else
+ font->props[FONT_FULLNAME_INDEX] =
+ make_unibyte_string (logfont.lfFaceName, len);
+ }
+
+ font->max_width = w32_font->metrics.tmMaxCharWidth;
+ font->height = w32_font->metrics.tmHeight
+ + w32_font->metrics.tmExternalLeading;
+ font->space_width = font->average_width = w32_font->metrics.tmAveCharWidth;
+
+ font->vertical_centering = 0;
+ font->encoding_type = 0;
+ font->baseline_offset = 0;
+ font->relative_compose = 0;
+ font->default_ascent = w32_font->metrics.tmAscent;
+ font->font_encoder = NULL;
+ 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? */
+ font->min_width = font->space_width;
+ font->ascent = w32_font->metrics.tmAscent;
+ font->descent = w32_font->metrics.tmDescent;
+
+ if (metrics)
+ {
+ font->underline_thickness = metrics->otmsUnderscoreSize;
+ font->underline_position = -metrics->otmsUnderscorePosition;
+ }
+ else
+ {
+ font->underline_thickness = 0;
+ font->underline_position = -1;
+ }
+
+ /* max_descent is used for underlining in w32term.c. Hopefully this
+ is temporary, as we'll want to get rid of the old compatibility
+ stuff later. */
+ compat_w32_font->max_bounds.descent = font->descent;
+
+ /* For temporary compatibility with legacy code that expects the
+ name to be usable in x-list-fonts. Eventually we expect to change
+ x-list-fonts and other places that use fonts so that this can be
+ an fcname or similar. */
+ font->props[FONT_NAME_INDEX] = Ffont_xlfd_name (font_object, Qnil);
+
+ return 1;
+}
+