[mapguide-commits] r1208 - trunk/MgDev/Common/Stylization

svn_mapguide at osgeo.org svn_mapguide at osgeo.org
Tue Mar 13 13:50:54 EDT 2007


Author: jasonnogar
Date: 2007-03-13 13:50:50 -0400 (Tue, 13 Mar 2007)
New Revision: 1208

Modified:
   trunk/MgDev/Common/Stylization/SE_Bounds.cpp
   trunk/MgDev/Common/Stylization/SE_Bounds.h
   trunk/MgDev/Common/Stylization/SE_ExpressionBase.cpp
   trunk/MgDev/Common/Stylization/SE_Include.h
   trunk/MgDev/Common/Stylization/SE_StyleVisitor.cpp
   trunk/MgDev/Common/Stylization/StylizationEngine.cpp
Log:
Symbology:  
 * Add support for Path::WeightScalable
 * Added SE_Bounds fix to avoid infinite loop on invalid input
 * Added whitespace trimming for all expressions to SE_ExpressionBase (improves detection of constant expressions, e.g. " true " instead of "true").

KNOWN ISSUE: I noticed that when one uses an invalid, unknown, or non-TTF font for a Text graphic element, the first font, which is not TTF, will be used, causing divides by zero in text metrics and elsewhere.

Modified: trunk/MgDev/Common/Stylization/SE_Bounds.cpp
===================================================================
--- trunk/MgDev/Common/Stylization/SE_Bounds.cpp	2007-03-13 14:06:09 UTC (rev 1207)
+++ trunk/MgDev/Common/Stylization/SE_Bounds.cpp	2007-03-13 17:50:50 UTC (rev 1208)
@@ -167,6 +167,11 @@
     }
 }
 
+bool SE_Bounds::Contained(double minx, double miny, double maxx, double maxy)
+{
+    return (minx < min[0]) && (miny < min[1]) && (maxx > max[0]) && (maxy > max[1]);
+}
+
 SE_Bounds* SE_Bounds::Union(SE_Bounds* bounds)
 {
     /* Andrew Convex Hull again, but this time in linear time (the points of the
@@ -206,6 +211,18 @@
                 ly = *(start[i]+1);
                 index = i;
             }
+
+        _ASSERT(index != -1);
+        if (index == -1)
+        {
+            /* For some reason, one of the bounds we are combining is has invalid points,
+               which can only be caused by an error somewhere else in the code.
+               Rather than loop infinitely, we will return NULL */
+            if (usize > 4096)
+                delete[] vec;
+            return NULL;
+        }
+
         if (index & 1) // U array
             start[index] -= 2;
         else // L array

Modified: trunk/MgDev/Common/Stylization/SE_Bounds.h
===================================================================
--- trunk/MgDev/Common/Stylization/SE_Bounds.h	2007-03-13 14:06:09 UTC (rev 1207)
+++ trunk/MgDev/Common/Stylization/SE_Bounds.h	2007-03-13 17:50:50 UTC (rev 1208)
@@ -43,6 +43,7 @@
     STYLIZATION_API void Add(double x, double y);
     STYLIZATION_API void Transform(const SE_Matrix& xform);
     STYLIZATION_API void Transform(const SE_Matrix& xform, SE_Bounds* src);
+    STYLIZATION_API bool Contained(double minx, double miny, double maxx, double maxy);
     STYLIZATION_API void Contained(double minx, double miny, double maxx, double maxy, double &growx, double &growy);
     STYLIZATION_API void Free();
     STYLIZATION_API SE_Bounds* Clone();

Modified: trunk/MgDev/Common/Stylization/SE_ExpressionBase.cpp
===================================================================
--- trunk/MgDev/Common/Stylization/SE_ExpressionBase.cpp	2007-03-13 14:06:09 UTC (rev 1207)
+++ trunk/MgDev/Common/Stylization/SE_ExpressionBase.cpp	2007-03-13 17:50:50 UTC (rev 1208)
@@ -60,9 +60,14 @@
 {
     MdfString::size_type startIdx, endIdx, count;
     MdfString::iterator beginIter;
-    const wchar_t *name, *value;
+    const wchar_t *name, *value, *trim;
 
-    m_buffer.assign(exprstr);
+    /* Trim whitespace from the beginning */
+    trim = exprstr.c_str();
+    while (iswspace(*trim))
+        trim++;
+
+    m_buffer.assign(trim);
     startIdx = endIdx = 0;
 
     for(;;)
@@ -75,24 +80,11 @@
         if (endIdx == MdfString::npos)
             break;
 
+        /* We have found matched % characters--it must be a parameter */
         count = endIdx - startIdx - 1;
         m_param.assign(m_buffer, startIdx + 1, count);
         name = m_param.c_str();
 
-        /* If there is a space in the parameter name, this is not a parameter.  This way,
-         * if we add a modulus operator or something, parsing will not be completely screwed up,
-         * although we should probably check for a few more illegal characters as well (checking
-         * for legal characters doesn't seem viable in the face of localization) */
-        bool notParam = false;
-        for (size_t i = 0; i < count; i++)
-            if (iswspace(name[i]))
-                notParam = true;
-        if (notParam)
-        {
-            startIdx = endIdx;
-            continue;
-        }
-
         ParameterMap::const_iterator paramIter = m_parameters.find(ParamId(m_symbol, name));
 
         if (paramIter == m_parameters.end())
@@ -110,6 +102,13 @@
         m_buffer.replace(beginIter + startIdx, beginIter + endIdx + 1, value);
         startIdx += wcslen(value);
     }
+
+    /* Trim whitespace from the end */
+    size_t len = m_buffer.size();
+    trim = m_buffer.c_str() + len - 1;
+    while (iswspace(*trim--))
+        len--;
+    m_buffer.resize(len);
 }
 
 void SE_ExpressionBase::ParseDoubleExpression(const MdfModel::MdfString& exprstr, SE_Double& val)
@@ -122,7 +121,7 @@
 
     if (len == 0)
     {
-        val.value = 0;
+        val = 0;
         return;
     }
 
@@ -144,11 +143,11 @@
 
     if (len == 0)
     {
-        val.value = 0;
+        val = 0;
         return;
     }
 
-    int ret = swscanf(cstr, L"%d%n", &val.value, &chars);
+    int ret = swscanf(cstr, L"%d%n", &val, &chars);
 
     if (ret == 1 && chars == len)
         return;
@@ -165,18 +164,18 @@
 
     if (len == 0)
     {
-        val.value = false;
+        val = false;
         return;
     }
     
-    if (_wcsnicmp(cstr, L"true", 5) == 0)
+    if (wcsicmp(cstr, L"true") == 0)
     {
-        val.value = true;
+        val = true;
         return;
     }
-    else if (_wcsnicmp(cstr, L"false", 6) == 0)
+    else if (wcsicmp(cstr, L"false") == 0)
     {
-        val.value = false;
+        val = false;
         return;
     }
 
@@ -187,9 +186,6 @@
 {
     ReplaceParameters(exprstr, L"");
 
-    //TODO: we need to add Parse functions that know what the string they are parsing represents.
-    //for example ParseHorizontalAlignment. This way we can determine if the value is a constant
-    //or an expression that needs to be evaluated all the time.
     if (exprstr.empty())
     {
         val.expression = NULL;
@@ -197,31 +193,37 @@
     }
     else
     {
-        const wchar_t* str = m_buffer.c_str();
-        while (iswspace(*str)) 
-            str++;
+        const wchar_t* start = m_buffer.c_str();
+        const wchar_t* str = start;
+
+        /* Literal expression must start with a single quote (after trimming) */
         if (*str++ != L'\'')
         {
-            val.expression = FdoExpression::Parse(m_buffer.c_str());
+            val.expression = FdoExpression::Parse(start);
             return;
         }
 
-        const wchar_t* begin = str;
-
         while(*str != L'\0' && *str != L'\'')
             str++;
 
-        if (*str == L'\0')
+        if (*str++ == L'\0')
         {
-            val.expression = FdoExpression::Parse(m_buffer.c_str());
+            val.expression = FdoExpression::Parse(start);
             return;
         }
 
-        size_t len = str - begin;
+        /* Last character of the literal expression should be a single quote as well */
+        if (*str != L'\0')
+        {
+            val.expression = FdoExpression::Parse(start);
+            return;
+        }
+
+        size_t len = m_buffer.size() - 2;
         wchar_t* copy = new wchar_t[len + 1];
-        memcpy(copy, begin, sizeof(wchar_t)*len);
+        memcpy(copy, start + 1, sizeof(wchar_t)*len);
         copy[len] = L'\0';
-        val.value = copy;
+        val = copy;
     }
 }
 

Modified: trunk/MgDev/Common/Stylization/SE_Include.h
===================================================================
--- trunk/MgDev/Common/Stylization/SE_Include.h	2007-03-13 14:06:09 UTC (rev 1207)
+++ trunk/MgDev/Common/Stylization/SE_Include.h	2007-03-13 17:50:50 UTC (rev 1208)
@@ -284,6 +284,7 @@
     SE_LineBuffer* geometry;
     SE_Double weight;
     SE_Color color;
+    SE_Boolean weightScalable;
 
     SE_INLINE SE_Polyline() : weight(0.0) { type = SE_PolylinePrimitive; }
 };

Modified: trunk/MgDev/Common/Stylization/SE_StyleVisitor.cpp
===================================================================
--- trunk/MgDev/Common/Stylization/SE_StyleVisitor.cpp	2007-03-13 14:06:09 UTC (rev 1207)
+++ trunk/MgDev/Common/Stylization/SE_StyleVisitor.cpp	2007-03-13 17:50:50 UTC (rev 1208)
@@ -389,12 +389,15 @@
         ParseGeometry(geometry, *line->geometry);
         ParseDoubleExpression(path.GetLineWeight(), line->weight);
         ParseColorExpression(path.GetLineColor(), line->color);
+        ParseBooleanExpression(path.GetLineWeightScalable(), line->weightScalable);
+
         /* If the color is transparent, there is no point in drawing this path,
          * so we will change it to black. */
         if (line->color.argb() == 0)
             line->color.a = 255;
         line->cacheable = !(line->weight.expression ||
-                            line->color.expression);
+                            line->color.expression ||
+                            line->weightScalable.expression);
     }
     else
     {
@@ -405,9 +408,11 @@
         ParseDoubleExpression(path.GetLineWeight(), polygon->weight);
         polygon->fill = color;
         ParseColorExpression(path.GetLineColor(), polygon->color);
-        polygon->cacheable = !(polygon->weight.expression ||
-                            polygon->color.expression ||
-                            polygon->fill.expression);
+        ParseBooleanExpression(path.GetLineWeightScalable(), polygon->weightScalable);
+        polygon->cacheable = !(polygon->weight.expression || 
+                            polygon->color.expression || 
+                            polygon->fill.expression ||
+                            polygon->weightScalable.expression);
     }
 }
 

Modified: trunk/MgDev/Common/Stylization/StylizationEngine.cpp
===================================================================
--- trunk/MgDev/Common/Stylization/StylizationEngine.cpp	2007-03-13 14:06:09 UTC (rev 1207)
+++ trunk/MgDev/Common/Stylization/StylizationEngine.cpp	2007-03-13 17:50:50 UTC (rev 1208)
@@ -147,7 +147,7 @@
     
     SE_LineBuffer* xformGeom = m_pool->NewLineBuffer(geometry->point_count());
     xformGeom->compute_bounds() = false;
-        
+
     xformGeom->Transform(geometry, w2s);
 
     for (std::vector<SE_Symbolization*>::const_iterator iter = symbolization->begin(); iter != symbolization->end(); iter++)
@@ -166,7 +166,7 @@
         {
             SE_Style* style = *siter;
 
-            SE_Matrix tmpxform = xform; //TODO: this is lame, but necessary since the xform can be modified
+            SE_Matrix tmpxform(xform); //TODO: this is lame, but necessary since the xform can be modified
                                         //when we evalute the style, in the case of point style set on a
                                         //non-point geometry
 
@@ -348,7 +348,10 @@
                 if (!rsym) rsym = new SE_RenderPolyline();
                 SE_Polyline* p = (SE_Polyline*) sym;
                 SE_RenderPolyline* rp = (SE_RenderPolyline*)rsym;
-                rp->weight = p->weight.evaluate(m_exec)*mm2px;
+                double wx = p->weightScalable.evaluate(m_exec) ? 
+                    m_renderer->GetPixelsPerMillimeterWorld() : 
+                    m_renderer->GetPixelsPerMillimeterScreen();
+                rp->weight = p->weight.evaluate(m_exec)*wx;
                 rp->geometry = p->geometry;
                 rp->color = p->color.evaluate(m_exec);
                 /* Defer transformation */



More information about the mapguide-commits mailing list