changeset 1436:d5536dc7114a

properly handle comma separated lists of font names in CSS
author Johannes Hofmann <Johannes.Hofmann@gmx.de>
date Tue, 17 Nov 2009 21:41:04 +0100
parents c3c2a22e7e4e
children 16602aa5aabc
files dw/fltkplatform.cc dw/fltkplatform.hh dw/layout.hh dw/platform.hh dw/style.cc dw/style.hh src/styleengine.cc
diffstat 7 files changed, 49 insertions(+), 56 deletions(-) [+]
line wrap: on
line diff
--- a/dw/fltkplatform.cc	Mon Nov 16 04:08:27 2009 +0000
+++ b/dw/fltkplatform.cc	Tue Nov 17 21:41:04 2009 +0100
@@ -83,6 +83,12 @@
    fontsTable->remove (this);
 }
 
+bool
+FltkPlatform::fontExists (const char *name)
+{
+   return ::fltk::font(name) != NULL;
+}
+
 FltkFont*
 FltkFont::create (core::style::FontAttrs *attrs)
 {
--- a/dw/fltkplatform.hh	Mon Nov 16 04:08:27 2009 +0000
+++ b/dw/fltkplatform.hh	Tue Nov 17 21:41:04 2009 +0100
@@ -150,6 +150,7 @@
 
    core::style::Font *createFont (core::style::FontAttrs *attrs,
                                       bool tryEverything);
+   bool fontExists (const char *name);
    core::style::Color *createColor (int color);
    core::style::Tooltip *createTooltip (const char *text);
 
--- a/dw/layout.hh	Mon Nov 16 04:08:27 2009 +0000
+++ b/dw/layout.hh	Tue Nov 17 21:41:04 2009 +0100
@@ -322,6 +322,11 @@
       return  platform->createFont (attrs, tryEverything);
    }
 
+   inline bool fontExists (const char *name)
+   {
+      return platform->fontExists (name);
+   }
+
    inline style::Color *createColor (int color)
    {
       return platform->createColor (color);
--- a/dw/platform.hh	Mon Nov 16 04:08:27 2009 +0000
+++ b/dw/platform.hh	Tue Nov 17 21:41:04 2009 +0100
@@ -119,6 +119,8 @@
    virtual style::Font *createFont (style::FontAttrs *attrs,
                                     bool tryEverything) = 0;
 
+   virtual bool fontExists (const char *name) = 0;
+
    /**
     * \brief Create a color resource for a given 0xrrggbb value.
     */
--- a/dw/style.cc	Mon Nov 16 04:08:27 2009 +0000
+++ b/dw/style.cc	Tue Nov 17 21:41:04 2009 +0100
@@ -296,43 +296,9 @@
    return create0 (layout, attrs, false);
 }
 
-Font *Font::createFromList (Layout *layout, FontAttrs *attrs,
-                            char *defaultFamily)
+bool Font::exists (Layout *layout, const char *name)
 {
-   Font *font = NULL;
-   FontAttrs attrs2;
-   char *comma, *list, *current;
-
-   attrs2 = *attrs;
-   current = list = strdup (attrs->name);
-
-   while (current && (font == NULL)) {
-      comma = strchr (current, ',');
-      if (comma) *comma = 0;
-
-      attrs2.name = current;
-      font = create0 (layout, &attrs2, false);
-      if (font)
-         break;
-
-      if (comma) {
-         current = comma + 1;
-         while (isspace (*current)) current++;
-      } else
-         current = NULL;
-   }
-
-   delete list;
-
-   if (font == NULL) {
-      attrs2.name = defaultFamily;
-      font = create0 (layout, &attrs2, true);
-   }
-
-   if (font == NULL)
-      MSG_WARN("Could not find any font.\n");
-
-   return font;
+   return layout->fontExists (name);
 }
 
 // ----------------------------------------------------------------------
--- a/dw/style.hh	Mon Nov 16 04:08:27 2009 +0000
+++ b/dw/style.hh	Tue Nov 17 21:41:04 2009 +0100
@@ -578,8 +578,7 @@
    int xHeight;
 
    static Font *create (Layout *layout, FontAttrs *attrs);
-   static Font *createFromList (Layout *layout, FontAttrs *attrs,
-                                char *defaultFamily);
+   static bool exists (Layout *layout, const char *name);
 
    inline void ref () { refCount++; }
    inline void unref () { if (--refCount == 0) delete this; }
--- a/src/styleengine.cc	Mon Nov 16 04:08:27 2009 +0000
+++ b/src/styleengine.cc	Tue Nov 17 21:41:04 2009 +0100
@@ -204,7 +204,7 @@
 void StyleEngine::apply (StyleAttrs *attrs, CssPropertyList *props) {
    FontAttrs fontAttrs = *attrs->font;
    Font *parentFont = stack->get (stack->size () - 2).style->font;
-   char *c;
+   char *c, *fontName;
 
    /* Determine font first so it can be used to resolve relative lenths.
     * \todo Things should be rearranged so that just one pass is necessary.
@@ -214,24 +214,38 @@
 
       switch (p->name) {
          case CSS_PROPERTY_FONT_FAMILY:
-            // \todo handle comma separated lists of font names
-            // for now simply use the first name in the list
-            if ((c = strchr(p->value.strVal, ',')))
-               *c = '\0';
-            p->value.strVal = dStrstrip(p->value.strVal);
+            // check font names in comma separated list
+            // Note, that p->value.strVal is modified, so that in future calls
+            // the matching font name can be used directly.
+            fontName = NULL;
+            while (p->value.strVal) {
+               if ((c = strchr(p->value.strVal, ',')))
+                  *c = '\0';
+               dStrstrip(p->value.strVal);
 
-            if (strcmp (p->value.strVal, "serif") == 0)
-               fontAttrs.name = prefs.font_serif;
-            else if (strcmp (p->value.strVal, "sans-serif") == 0)
-               fontAttrs.name = prefs.font_sans_serif;
-            else if (strcmp (p->value.strVal, "cursive") == 0)
-               fontAttrs.name = prefs.font_cursive;
-            else if (strcmp (p->value.strVal, "fantasy") == 0)
-               fontAttrs.name = prefs.font_fantasy;
-            else if (strcmp (p->value.strVal, "monospace") == 0)
-               fontAttrs.name = prefs.font_monospace;
-            else
-               fontAttrs.name = p->value.strVal;
+               if (strcmp (p->value.strVal, "serif") == 0)
+                  fontName = prefs.font_serif;
+               else if (strcmp (p->value.strVal, "sans-serif") == 0)
+                  fontName = prefs.font_sans_serif;
+               else if (strcmp (p->value.strVal, "cursive") == 0)
+                  fontName = prefs.font_cursive;
+               else if (strcmp (p->value.strVal, "fantasy") == 0)
+                  fontName = prefs.font_fantasy;
+               else if (strcmp (p->value.strVal, "monospace") == 0)
+                  fontName = prefs.font_monospace;
+               else if (Font::exists(layout, p->value.strVal))
+                  fontName = p->value.strVal;
+
+               if (fontName) {   // font found
+                  fontAttrs.name = fontName;
+                  break;
+               } else if (c) {   // try next from list
+                  memmove(p->value.strVal, c + 1, strlen(c + 1) + 1);
+               } else {          // no font found
+                  break;
+               }
+            }
+
             break;
          case CSS_PROPERTY_FONT_SIZE:
             if (p->type == CSS_TYPE_ENUM) {