/* Either a fontconfig-style name with no size and property
data, or a GTK-style name. */
Lisp_Object prop;
- int word_len, prop_found = 0;
+ Lisp_Object weight = Qnil, slant = Qnil;
+ Lisp_Object width = Qnil, size = Qnil;
+ char *word_start;
+ int word_len;
+ int size_found = 0;
+
+ /* Scan backwards from the end, looking for a size. */
+ for (p = name + len - 1; p >= name; p--)
+ if (!isdigit (*p))
+ break;
+
+ if ((p < name + len - 1) && ((p + 1 == name) || *p == ' '))
+ /* Found a font size. */
+ size = make_float (strtod (p + 1, NULL));
+ else
+ p = name + len;
- for (p = name; *p; p = *q ? q + 1 : q)
+ /* Now P points to the termination of the string, sans size.
+ Scan backwards, looking for font properties. */
+ for (; p > name; p = q)
{
- if (isdigit (*p))
+ for (q = p - 1; q >= name; q--)
{
- int size_found = 1;
-
- for (q = p + 1; *q && *q != ' '; q++)
- if (! isdigit (*q) && *q != '.')
- {
- size_found = 0;
- break;
- }
- if (size_found)
- {
- double point_size = strtod (p, &q);
- ASET (font, FONT_SIZE_INDEX, make_float (point_size));
- continue;
- }
+ if (q > name && *(q-1) == '\\')
+ --q; /* Skip quoting backslashes. */
+ else if (*q == ' ')
+ break;
}
- for (q = p + 1; *q && *q != ' '; q++)
- if (*q == '\\' && q[1])
- q++;
- word_len = q - p;
+ word_start = q + 1;
+ word_len = p - word_start;
-#define PROP_MATCH(STR,N) ((word_len == N) && memcmp (p, STR, N) == 0)
+#define PROP_MATCH(STR,N) \
+ ((word_len == N) && memcmp (word_start, STR, N) == 0)
+#define PROP_SAVE(VAR,STR,N) \
+ (VAR = NILP (VAR) ? font_intern_prop (STR, N, 1) : VAR)
if (PROP_MATCH ("Ultra-Light", 11))
- {
- prop_found = 1;
- prop = font_intern_prop ("ultra-light", 11, 1);
- FONT_SET_STYLE (font, FONT_WEIGHT_INDEX, prop);
- }
+ PROP_SAVE (weight, "ultra-light", 11);
else if (PROP_MATCH ("Light", 5))
- {
- prop_found = 1;
- prop = font_intern_prop ("light", 5, 1);
- FONT_SET_STYLE (font, FONT_WEIGHT_INDEX, prop);
- }
+ PROP_SAVE (weight, "light", 5);
else if (PROP_MATCH ("Book", 4))
- {
- prop_found = 1;
- prop = font_intern_prop ("book", 4, 1);
- FONT_SET_STYLE (font, FONT_WEIGHT_INDEX, prop);
- }
+ PROP_SAVE (weight, "book", 4);
else if (PROP_MATCH ("Medium", 6))
- {
- prop_found = 1;
- prop = font_intern_prop ("medium", 6, 1);
- FONT_SET_STYLE (font, FONT_WEIGHT_INDEX, prop);
- }
+ PROP_SAVE (weight, "medium", 6);
else if (PROP_MATCH ("Semi-Bold", 9))
- {
- prop_found = 1;
- prop = font_intern_prop ("semi-bold", 9, 1);
- FONT_SET_STYLE (font, FONT_WEIGHT_INDEX, prop);
- }
+ PROP_SAVE (weight, "semi-bold", 9);
else if (PROP_MATCH ("Bold", 4))
- {
- prop_found = 1;
- prop = font_intern_prop ("bold", 4, 1);
- FONT_SET_STYLE (font, FONT_WEIGHT_INDEX, prop);
- }
+ PROP_SAVE (weight, "bold", 4);
else if (PROP_MATCH ("Italic", 6))
- {
- prop_found = 1;
- prop = font_intern_prop ("italic", 4, 1);
- FONT_SET_STYLE (font, FONT_SLANT_INDEX, prop);
- }
+ PROP_SAVE (slant, "italic", 6);
else if (PROP_MATCH ("Oblique", 7))
- {
- prop_found = 1;
- prop = font_intern_prop ("oblique", 7, 1);
- FONT_SET_STYLE (font, FONT_SLANT_INDEX, prop);
- }
+ PROP_SAVE (slant, "oblique", 7);
else if (PROP_MATCH ("Semi-Condensed", 14))
- {
- prop_found = 1;
- prop = font_intern_prop ("semi-condensed", 14, 1);
- FONT_SET_STYLE (font, FONT_WIDTH_INDEX, prop);
- }
+ PROP_SAVE (width, "semi-condensed", 14);
else if (PROP_MATCH ("Condensed", 9))
+ PROP_SAVE (width, "condensed", 9);
+ /* An unknown word must be part of the font name. */
+ else
{
- prop_found = 1;
- prop = font_intern_prop ("condensed", 9, 1);
- FONT_SET_STYLE (font, FONT_WIDTH_INDEX, prop);
+ family_end = p;
+ break;
}
- else {
- if (prop_found)
- return -1; /* Unknown property in GTK-style font name. */
- family_end = q;
- }
}
#undef PROP_MATCH
if (family_end)
- {
- Lisp_Object family;
- family = font_intern_prop (name, family_end - name, 1);
- ASET (font, FONT_FAMILY_INDEX, family);
- }
+ ASET (font, FONT_FAMILY_INDEX,
+ font_intern_prop (name, family_end - name, 1));
+ if (!NILP (size))
+ ASET (font, FONT_SIZE_INDEX, size);
+ if (!NILP (weight))
+ FONT_SET_STYLE (font, FONT_WEIGHT_INDEX, weight);
+ if (!NILP (slant))
+ FONT_SET_STYLE (font, FONT_SLANT_INDEX, slant);
+ if (!NILP (width))
+ FONT_SET_STYLE (font, FONT_WIDTH_INDEX, width);
}
return 0;
--- /dev/null
+;;; redisplay-testsuite.el --- Test suite for redisplay.
+
+;; Copyright (C) 2011 Free Software Foundation, Inc.
+
+;; Author: Chong Yidong <cyd@stupidchicken.com>
+;; Keywords: internal
+;; Human-Keywords: internal
+
+;; This file is part of GNU Emacs.
+
+;; GNU Emacs is free software: you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation, either version 3 of the License, or
+;; (at your option) any later version.
+
+;; GNU Emacs is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+;; GNU General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;; Type M-x test-font-parse RET to generate the test buffer.
+
+;; TODO: Convert to ERT format.
+
+;;; Code:
+
+(defvar test-font-parse-data
+ '((" " " " nil nil nil nil)
+ ("Monospace" "Monospace" nil nil nil nil)
+ ("Foo1" "Foo1" nil nil nil nil)
+ ("12" "nil" 12.0 nil nil nil)
+ ("12 " "12 " nil nil nil nil)
+ ;; Fontconfig format
+ ("Foo:" "Foo" nil nil nil nil)
+ ("Foo-8" "Foo" 8.0 nil nil nil)
+ ("Foo-18:" "Foo" 18.0 nil nil nil)
+ ("Foo-18:light" "Foo" 18.0 light nil nil)
+ ("Foo 10:weight=bold" "Foo 10" nil bold nil nil)
+ ("Foo-12:weight=bold" "Foo" 12.0 bold nil nil)
+ ("Foo 8-20:slant=oblique" "Foo 8" 20.0 nil oblique nil)
+ ("Foo:light:roman" "Foo" nil light roman nil)
+ ("Foo:italic:roman" "Foo" nil nil roman nil)
+ ("Foo 12:light:oblique" "Foo 12" nil light oblique nil)
+ ("Foo-12:demibold:oblique" "Foo" 12.0 demibold oblique nil)
+ ("Foo:black:proportional" "Foo" nil black nil 0)
+ ("Foo-10:black:proportional" "Foo" 10.0 black nil 0)
+ ("Foo:weight=normal" "Foo" nil normal nil nil)
+ ("Foo:weight=bold" "Foo" nil bold nil nil)
+ ("Foo:weight=bold:slant=italic" "Foo" nil bold italic)
+ ("Foo:weight=bold:slant=italic:mono" "Foo" nil bold italic 100)
+ ("Foo-10:demibold:slant=normal" "Foo" 10.0 demibold normal nil)
+ ("Foo 11-16:oblique:weight=bold" "Foo 11" 16.0 bold oblique nil)
+ ("Foo:oblique:randomprop=randomtag:weight=bold"
+ "Foo" nil bold oblique nil)
+ ("Foo:randomprop=randomtag:bar=baz" "Foo" nil nil nil nil)
+ ("Foo Book Light:bar=baz" "Foo Book Light" nil nil nil nil)
+ ("Foo Book Light 10:bar=baz" "Foo Book Light 10" nil nil nil nil)
+ ("Foo Book Light-10:bar=baz" "Foo Book Light" 10.0 nil nil nil)
+ ;; GTK format
+ ("Oblique" "nil" nil nil oblique nil)
+ ("Bold 17" "nil" 17.0 bold nil nil)
+ ("17 Bold" "17" nil bold nil nil)
+ ("Book Oblique 2" "nil" 2.0 book oblique nil)
+ ("Bar 7" "Bar" 7.0 nil nil nil)
+ ("Bar Ultra-Light" "Bar" nil ultra-light nil nil)
+ ("Bar Light 8" "Bar" 8.0 light nil nil)
+ ("Bar Book Medium 9" "Bar" 9.0 medium nil nil)
+ ("Bar Semi-Bold Italic 10" "Bar" 10.0 semi-bold italic nil)
+ ("Bar Semi-Condensed Bold Italic 11" "Bar" 11.0 bold italic nil)
+ ("Foo 10 11" "Foo 10" 11.0 nil nil nil)
+ ("Foo 1985 Book" "Foo 1985" nil book nil nil)
+ ("Foo 1985 A Book" "Foo 1985 A" nil book nil nil)
+ ("Foo A Book 12 A" "Foo A Book 12 A" nil nil nil nil)
+ ("Foo 1985 Book 12 Oblique" "Foo 1985 Book 12" nil nil oblique nil)
+ ("Foo 1985 Book 12 Italic 10" "Foo 1985 Book 12" 10.0 nil italic nil)
+ ("Foo Book Bar 6 Italic" "Foo Book Bar 6" nil nil italic nil)
+ ("Foo Book Bar Bold" "Foo Book Bar" nil bold nil nil))
+ "List of font names parse data.
+Each element should have the form
+ (NAME FAMILY SIZE WEIGHT SLANT SPACING)
+where NAME is the name to parse, and the remainder are the
+expected font properties from parsing NAME.")
+
+(defun test-font-parse ()
+ "Test font name parsing."
+ (interactive)
+ (switch-to-buffer (generate-new-buffer "*Font Pase Test*"))
+ (setq show-trailing-whitespace nil)
+ (let ((pass-face '((t :foreground "green")))
+ (fail-face '((t :foreground "red"))))
+ (dolist (test test-font-parse-data)
+ (let* ((name (nth 0 test))
+ (fs (font-spec :name name))
+ (family (symbol-name (font-get fs :family)))
+ (size (font-get fs :size))
+ (weight (font-get fs :weight))
+ (slant (font-get fs :slant))
+ (spacing (font-get fs :spacing)))
+ (insert name)
+ (if (> (current-column) 20)
+ (insert "\n"))
+ (indent-to-column 21)
+ (insert (propertize family
+ 'face (if (equal family (nth 1 test))
+ pass-face
+ fail-face)))
+ (indent-to-column 40)
+ (insert (propertize (format "%s" size)
+ 'face (if (equal size (nth 2 test))
+ pass-face
+ fail-face)))
+ (indent-to-column 48)
+ (insert (propertize (format "%s" weight)
+ 'face (if (eq weight (nth 3 test))
+ pass-face
+ fail-face)))
+ (indent-to-column 60)
+ (insert (propertize (format "%s" slant)
+ 'face (if (eq slant (nth 4 test))
+ pass-face
+ fail-face)))
+ (indent-to-column 69)
+ (insert (propertize (format "%s" spacing)
+ 'face (if (eq spacing (nth 5 test))
+ pass-face
+ fail-face)))
+ (insert "\n"))))
+ (goto-char (point-min)))
+
+;;; font-parse-testsuite.el ends here.