Code

Tuned icc-color() parsing
authorjoncruz <joncruz@users.sourceforge.net>
Wed, 5 Apr 2006 09:19:22 +0000 (09:19 +0000)
committerjoncruz <joncruz@users.sourceforge.net>
Wed, 5 Apr 2006 09:19:22 +0000 (09:19 +0000)
ChangeLog
src/svg/svg-color-test.h
src/svg/svg-color.cpp

index 4b1e3232cfd76dd12c36b7d90606b24be0a58442..c4e4df38547e1d1e0da40f5f65418011b0df7f78 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,9 @@
+2005-04-05  Jon A. Cruz  <jon@joncruz.org>
+
+       * src/svg/svg-color-test.h, src/svg/svg-color.cpp:
+
+         Tuned icc-color() parsing.
+
 2005-04-02  Jon A. Cruz  <jon@joncruz.org>
 
        * src/color-profile.h, src/color-profile.cpp,
index ac79ac95903a23c10dd4816a612ee099c2c186b7..fc5ddfa004e067d5e05b0ea7dc33d61d66103732 100644 (file)
@@ -1,9 +1,19 @@
+
 #include <cxxtest/TestSuite.h>
+#include <cassert>
+
 #include "svg/svg-color.h"
 #include "svg/svg-icc-color.h"
 
 class SVGColorTest : public CxxTest::TestSuite
 {
+    struct simpleIccCase {
+        int numEntries;
+        bool shouldPass;
+        char const* name;
+        char const* str;
+    };
+
 public:
     void check_rgb24(unsigned const rgb24)
     {
@@ -25,7 +35,7 @@ public:
                 rgb24 = (rgb24 << 8) | component;
                 tmp /= nc;
             }
-            TS_ASSERT_EQUALS( tmp, 0 );
+            assert( tmp == 0 );
             check_rgb24(rgb24);
         }
 
@@ -38,8 +48,8 @@ public:
 
     void testReadColor()
     {
-        gchar* val="#f0f";
-        gchar const * end = 0;
+        gchar const* val="#f0f";
+        gchar const* end = 0;
         guint32 result = sp_svg_read_color( val, &end, 0x3 );
         TS_ASSERT_EQUALS( result, 0xff00ff00 );
         TS_ASSERT_LESS_THAN( val, end );
@@ -47,24 +57,41 @@ public:
 
     void testIccColor()
     {
-        SVGICCColor tmp;
-        gchar* str = "icc-color(named, 3)";
-        gchar const * result = 0;
+        simpleIccCase cases[] = {
+            {1, true, "named", "icc-color(named, 3)"},
+            {0, false, "", "foodle"},
+            {1, true, "a", "icc-color(a, 3)"},
+            {4, true, "named", "icc-color(named, 3, 0, 0.1, 2.5)"},
+            {0, false, "", "icc-color(named, 3"},
+            {0, false, "", "icc-color(space named, 3)"},
+            {0, false, "", "icc-color(tab\tnamed, 3)"},
+            {0, false, "", "icc-color(0name, 3)"},
+            {0, false, "", "icc-color(-name, 3)"},
+            {1, true, "positive", "icc-color(positive, +3)"},
+            {1, true, "negative", "icc-color(negative, -3)"},
+            {1, true, "positive", "icc-color(positive, +0.1)"},
+            {1, true, "negative", "icc-color(negative, -0.1)"},
+            {0, false, "", "icc-color(named, value)"},
+        };
 
-        bool parseRet = sp_svg_read_icc_color( str, &result, &tmp );
-        TS_ASSERT( parseRet );
-        TS_ASSERT_DIFFERS( str, result );
-        TS_ASSERT_EQUALS( std::string("named"), tmp.colorProfile );
-        TS_ASSERT_EQUALS( 1, tmp.colors.size() );
+        for ( size_t i = 0; i < G_N_ELEMENTS(cases); i++ ) {
+            SVGICCColor tmp;
+            gchar const* str = cases[i].str;
+            gchar const* result = 0;
 
+            std::string testDescr( cases[i].str );
 
-        gchar* badThing = "foodle";
-        result = 0;
-        parseRet = sp_svg_read_icc_color( badThing, &result, &tmp );
-        TS_ASSERT( !parseRet );
-        TS_ASSERT_EQUALS( badThing, result );
-        TS_ASSERT_DIFFERS( std::string("named"), tmp.colorProfile );
-        TS_ASSERT_EQUALS( 0, tmp.colors.size() );
+            bool parseRet = sp_svg_read_icc_color( str, &result, &tmp );
+            TSM_ASSERT_EQUALS( testDescr, parseRet, cases[i].shouldPass );
+            TSM_ASSERT_EQUALS( testDescr, tmp.colors.size(), cases[i].numEntries );
+            if ( cases[i].shouldPass ) {
+                TSM_ASSERT_DIFFERS( testDescr, str, result );
+                TSM_ASSERT_EQUALS( testDescr, tmp.colorProfile, std::string(cases[i].name) );
+            } else {
+                TSM_ASSERT_EQUALS( testDescr, str, result );
+                TSM_ASSERT( testDescr, tmp.colorProfile.empty() );
+            }
+        }
     }
 
 };
index 51d68717e96d083f1106ad112a9e0bc1e9ca500b..2bae38641b170413e9642e17afe16e96716d966a 100644 (file)
@@ -466,43 +466,69 @@ bool sp_svg_read_icc_color( gchar const *str, gchar const **end_ptr, SVGICCColor
 
         if ( good ) {
             str += 10;
-
-            while ( *str && !g_ascii_isspace(*str) && *str!= ',' && *str != ')' ) {
-                if ( dest ) {
-                    dest->colorProfile += *str;
-                }
+            while ( g_ascii_isspace(*str) ) {
                 str++;
             }
-            while ( g_ascii_isspace(*str) || *str == ',' ) {
-                str++;
+
+            if ( !g_ascii_isalpha(*str)
+                 && ( !(0x080 & *str) ) ) {
+                // Name must start with a certain type of character
+                good = false;
+            } else {
+                while ( g_ascii_isdigit(*str) || g_ascii_islower(*str) || (*str == '-') ) {
+                    if ( dest ) {
+                        dest->colorProfile += *str;
+                    }
+                    str++;
+                }
+                while ( g_ascii_isspace(*str) || *str == ',' ) {
+                    str++;
+                }
             }
         }
 
-        while ( good && *str && *str != ')' ) {
-            if ( g_ascii_isdigit(*str) || *str == '.' ) {
-                gchar* endPtr = 0;
-                gdouble dbl = g_ascii_strtod( str, &endPtr );
-                if ( !errno ) {
-                    if ( dest ) {
-                        dest->colors.push_back( dbl );
+        if ( good ) {
+            while ( *str && *str != ')' ) {
+                if ( g_ascii_isdigit(*str) || *str == '.' || *str == '-' || *str == '+') {
+                    gchar* endPtr = 0;
+                    gdouble dbl = g_ascii_strtod( str, &endPtr );
+                    if ( !errno ) {
+                        if ( dest ) {
+                            dest->colors.push_back( dbl );
+                        }
+                        str = endPtr;
+                    } else {
+                        good = false;
+                        break;
+                    }
+
+                    while ( g_ascii_isspace(*str) || *str == ',' ) {
+                        str++;
                     }
-                    str = endPtr;
                 } else {
-                    good = false;
                     break;
                 }
+            }
+        }
 
-                while ( good && g_ascii_isspace(*str) || *str == ',' ) {
-                    str++;
-                }
-            } else {
-                break;
+        // We need to have ended on a closing parenthesis
+        if ( good ) {
+            while ( g_ascii_isspace(*str) ) {
+                str++;
             }
+            good &= *str == ')';
         }
     }
 
-    if ( end_ptr ) {
-        *end_ptr = str;
+    if ( good ) {
+        if ( end_ptr ) {
+            *end_ptr = str;
+        }
+    } else {
+        if ( dest ) {
+            dest->colorProfile.clear();
+            dest->colors.clear();
+        }
     }
 
     return good;