Mercurial > emacs
diff src/w32font.c @ 95894:76261fd18708
* w32fns.c (Fw32_select_font): Removed old font API function.
* w32font.c (logfont_to_fcname): New function.
(Fx_select_font): New font dialog function compatible with
GTK/fontconfig version.
* font.c (font_style_symbolic_from_value): New function.
(font_style_symbolic): Use it.
* font.h (font_style_symbolic_from_value): Declare new function.
author | Jason Rumney <jasonr@gnu.org> |
---|---|
date | Fri, 13 Jun 2008 14:29:47 +0000 |
parents | cb4bf2ae5ac2 |
children | 66f0213be62a |
line wrap: on
line diff
--- a/src/w32font.c Fri Jun 13 14:28:13 2008 +0000 +++ b/src/w32font.c Fri Jun 13 14:29:47 2008 +0000 @@ -20,6 +20,7 @@ #include <windows.h> #include <math.h> #include <ctype.h> +#include <commdlg.h> #include "lisp.h" #include "w32term.h" @@ -1861,7 +1862,7 @@ if (outline) len += 11; /* -SIZE */ else - len = strlen (font->lfFaceName) + 21; + len += 21; if (font->lfItalic) len += 7; /* :italic */ @@ -1911,6 +1912,66 @@ return (p - name); } +/* Convert a logfont and point size into a fontconfig style font name. + POINTSIZE is in tenths of points. + If SIZE indicates the size of buffer FCNAME, into which the font name + is written. If the buffer is not large enough to contain the name, + the function returns -1, otherwise it returns the number of bytes + written to FCNAME. */ +static int logfont_to_fcname(font, pointsize, fcname, size) + LOGFONT* font; + int pointsize; + char *fcname; + int size; +{ + int len, height; + char *p = fcname; + Lisp_Object weight = Qnil; + + len = strlen (font->lfFaceName) + 2; + height = pointsize / 10; + while (height /= 10) + len++; + + if (pointsize % 10) + len += 2; + + if (font->lfItalic) + len += 7; /* :italic */ + if (font->lfWeight && font->lfWeight != FW_NORMAL) + { + int fc_weight = w32_decode_weight (font->lfWeight); + weight = font_style_symbolic_from_value (FONT_WEIGHT_INDEX, + make_number (fc_weight), 0); + len += 8; /* :weight= */ + if (SYMBOLP (weight)) + len += SBYTES (SYMBOL_NAME (weight)); + else + { + weight = make_number (fc_weight); + len++; + while (fc_weight /= 10) + len++; + } + } + + if (len > size) + return -1; + + p += sprintf (p, "%s-%d", font->lfFaceName, pointsize / 10); + if (pointsize % 10) + p += sprintf (p, ".%d", pointsize % 10); + + if (font->lfItalic) + p += sprintf (p, ":italic"); + + if (SYMBOLP (weight) && !NILP (weight)) + p += sprintf (p, "weight=%s", SDATA (SYMBOL_NAME (weight))); + else if (INTEGERP (weight)) + p += sprintf (p, "weight=%d", XINT (weight)); + + return (p - fcname); +} static void compute_metrics (dc, w32_font, code, metrics) @@ -1963,6 +2024,63 @@ } } +DEFUN ("x-select-font", Fx_select_font, Sx_select_font, 0, 2, 0, + doc: /* Read a font name using a W32 font selection dialog. +Return fontconfig style font string corresponding to the selection. + +If FRAME is omitted or nil, it defaults to the selected frame. +If INCLUDE-PROPORTIONAL is non-nil, include proportional fonts +in the font selection dialog. */) + (frame, include_proportional) + Lisp_Object frame, include_proportional; +{ + FRAME_PTR f = check_x_frame (frame); + CHOOSEFONT cf; + LOGFONT lf; + TEXTMETRIC tm; + HDC hdc; + HANDLE oldobj; + char buf[100]; + + bzero (&cf, sizeof (cf)); + bzero (&lf, sizeof (lf)); + + cf.lStructSize = sizeof (cf); + cf.hwndOwner = FRAME_W32_WINDOW (f); + cf.Flags = CF_FORCEFONTEXIST | CF_SCREENFONTS | CF_NOVERTFONTS; + + /* Unless include_proportional is non-nil, limit the selection to + monospaced fonts. */ + if (NILP (include_proportional)) + cf.Flags |= CF_FIXEDPITCHONLY; + + cf.lpLogFont = &lf; + + /* Initialize as much of the font details as we can from the current + default font. */ + hdc = GetDC (FRAME_W32_WINDOW (f)); + oldobj = SelectObject (hdc, FONT_COMPAT (FRAME_FONT (f))->hfont); + GetTextFace (hdc, LF_FACESIZE, lf.lfFaceName); + if (GetTextMetrics (hdc, &tm)) + { + lf.lfHeight = tm.tmInternalLeading - tm.tmHeight; + lf.lfWeight = tm.tmWeight; + lf.lfItalic = tm.tmItalic; + lf.lfUnderline = tm.tmUnderlined; + lf.lfStrikeOut = tm.tmStruckOut; + lf.lfCharSet = tm.tmCharSet; + cf.Flags |= CF_INITTOLOGFONTSTRUCT; + } + SelectObject (hdc, oldobj); + ReleaseDC (FRAME_W32_WINDOW (f), hdc); + + if (!ChooseFont (&cf) + || logfont_to_fcname (&lf, cf.iPointSize, buf, 100) < 0) + return Qnil; + + return build_string (buf); +} + struct font_driver w32font_driver = { 0, /* Qgdi */ @@ -2100,6 +2218,8 @@ DEFSYM (Qtifinagh, "tifinagh"); DEFSYM (Qugaritic, "ugaritic"); + defsubr (&Sx_select_font); + w32font_driver.type = Qgdi; register_font_driver (&w32font_driver, NULL); }