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

svn_mapguide at osgeo.org svn_mapguide at osgeo.org
Thu Mar 15 12:03:22 EDT 2007


Author: traianstanev
Date: 2007-03-15 12:03:22 -0400 (Thu, 15 Mar 2007)
New Revision: 1235

Modified:
   trunk/MgDev/Common/Stylization/LabelRenderer.cpp
   trunk/MgDev/Common/Stylization/SE_Include.h
   trunk/MgDev/Common/Stylization/SE_LineBuffer.cpp
   trunk/MgDev/Common/Stylization/SE_PositioningAlgorithms.cpp
   trunk/MgDev/Common/Stylization/SE_Renderer.cpp
   trunk/MgDev/Common/Stylization/SE_Renderer.h
   trunk/MgDev/Common/Stylization/SE_StyleVisitor.h
   trunk/MgDev/Common/Stylization/SE_SymbolManager.h
   trunk/MgDev/Common/Stylization/StylizationEngine.cpp
Log:
This submission adds some initial memory management code -- meaning that I added calls to free all the memory that the new style engine allocates. Previously, all memory was leaked. I had to add support for cloning of render proxy graphics objects so that I can ensure they are not shared (and therefore not deleted twice). 
Also, I am still seeing some sort of heap corruption in STL when I delete the MDF proxy objects, so those are leaked for now, until I track than down.

Modified: trunk/MgDev/Common/Stylization/LabelRenderer.cpp
===================================================================
--- trunk/MgDev/Common/Stylization/LabelRenderer.cpp	2007-03-15 11:43:58 UTC (rev 1234)
+++ trunk/MgDev/Common/Stylization/LabelRenderer.cpp	2007-03-15 16:03:22 UTC (rev 1235)
@@ -511,8 +511,8 @@
 
     //here are done with the style and we free it.
     //it was cloned when it was passed to the LabelRenderer.
-    //delete info.m_sestyle;
-    //info.m_sestyle = NULL;
+    delete info.m_sestyle;
+    info.m_sestyle = NULL;
 
     return true;
 }

Modified: trunk/MgDev/Common/Stylization/SE_Include.h
===================================================================
--- trunk/MgDev/Common/Stylization/SE_Include.h	2007-03-15 11:43:58 UTC (rev 1234)
+++ trunk/MgDev/Common/Stylization/SE_Include.h	2007-03-15 16:03:22 UTC (rev 1235)
@@ -287,6 +287,7 @@
     SE_Boolean weightScalable;
 
     SE_INLINE SE_Polyline() : weight(0.0) { type = SE_PolylinePrimitive; }
+    ~SE_Polyline() { geometry->Free(); }
 };
 
 struct SE_Polygon : public SE_Polyline
@@ -294,6 +295,7 @@
     SE_Color fill;
 
     SE_INLINE SE_Polygon() { type = SE_PolygonPrimitive; weight = 0.0; } 
+    ~SE_Polygon() { geometry->Free(); }
 };
 
 /* Font/properties caching is left to the implementor of SE_Renderer */
@@ -320,7 +322,7 @@
 struct SE_Raster : public SE_Primitive
 {
     SE_String pngPath;
-    unsigned char* pngPtr;
+    const unsigned char* pngPtr;
     int pngSize;
     SE_Double position[2];
     SE_Double extent[2];
@@ -350,6 +352,7 @@
     unsigned int color;
 
     SE_INLINE SE_RenderPolyline() { type = SE_PolylinePrimitive; }
+    ~SE_RenderPolyline() { if (geometry) geometry->Free(); }
 };
 
 struct SE_RenderPolygon : public SE_RenderPolyline
@@ -357,6 +360,7 @@
     unsigned int fill;
 
     SE_INLINE SE_RenderPolygon() { type = SE_PolygonPrimitive; }
+    ~SE_RenderPolygon() {  }
 };
 
 struct SE_RenderText : public SE_RenderPrimitive
@@ -372,7 +376,7 @@
 /* Caching, if any, is left to the implementor of SE_Renderer */
 struct SE_RenderRaster : public SE_RenderPrimitive
 {
-    unsigned char* pngPtr;
+    const unsigned char* pngPtr;
     int pngSize;
     double position[2];
     double extent[2];
@@ -381,8 +385,8 @@
     SE_INLINE SE_RenderRaster() : pngPtr(0), pngSize(0) { type = SE_RasterPrimitive; }
 };
 
-typedef std::vector<SE_Primitive*> SE_Symbol;
-typedef std::vector<SE_RenderPrimitive*> SE_RenderSymbol;
+typedef std::vector<SE_Primitive*> SE_PrimitiveList;
+typedef std::vector<SE_RenderPrimitive*> SE_RenderPrimitiveList;
 
 //^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 //
@@ -393,7 +397,7 @@
 struct SE_Style
 {
     SE_StyleType type;
-    SE_Symbol symbol;
+    SE_PrimitiveList symbol;
     SE_Integer renderPass;
 
     bool useBox;
@@ -405,7 +409,7 @@
 
     ~SE_Style()
     {
-        for (SE_Symbol::iterator iter = symbol.begin(); iter != symbol.end(); iter++)
+        for (SE_PrimitiveList::iterator iter = symbol.begin(); iter != symbol.end(); iter++)
             delete *iter;
     }
 };
@@ -467,14 +471,25 @@
 
     ~SE_RenderStyle()
     {
-        for (SE_RenderSymbol::iterator iter = symbol.begin(); iter != symbol.end(); iter++)
-            delete *iter;
+        for (SE_RenderPrimitiveList::iterator iter = symbol.begin(); iter != symbol.end(); iter++)
+        {
+            //necessary since destructor of SE_RenderPrimitive is not virtual
+            //we may want to figure out a better scheme to manage render primitives
+            switch ((*iter)->type)
+            {
+            case SE_PolylinePrimitive: delete (SE_RenderPolyline*)(*iter);break;
+            case SE_PolygonPrimitive: delete (SE_RenderPolygon*)(*iter);break;
+            case SE_RasterPrimitive: delete (SE_RenderRaster*)(*iter);break;
+            case SE_TextPrimitive: delete (SE_RenderText*)(*iter);break;
+            default: throw; //means there is a bug
+            }
+        }
 
         if (bounds) bounds->Free();
     }
 
     SE_StyleType type;
-    SE_RenderSymbol symbol;
+    SE_RenderPrimitiveList symbol;
     SE_Bounds* bounds;
 
     int renderPass;
@@ -561,6 +576,8 @@
     ~SE_Symbolization()
     {
         for (std::vector<SE_Style*>::iterator iter = styles.begin(); iter != styles.end(); iter++)
+            //TODO: SE_Styles have no virtual destructor but they don't seem to need
+            //to free stuff specific to the derived classes
             delete *iter;
 
         styles.clear();

Modified: trunk/MgDev/Common/Stylization/SE_LineBuffer.cpp
===================================================================
--- trunk/MgDev/Common/Stylization/SE_LineBuffer.cpp	2007-03-15 11:43:58 UTC (rev 1234)
+++ trunk/MgDev/Common/Stylization/SE_LineBuffer.cpp	2007-03-15 16:03:22 UTC (rev 1235)
@@ -15,11 +15,14 @@
 //  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 //
 
-#include "stdafx.h"
 #include "SE_LineBuffer.h"
 #include "SE_ConvexHull.h"
 #include "SE_Bounds.h"
 
+#define _USE_MATH_DEFINES
+#include <math.h>
+#include <float.h>
+
 #define GROWTH_FACTOR 1.5
 
 #define ENSURE_POINT_BUFFER(points) \

Modified: trunk/MgDev/Common/Stylization/SE_PositioningAlgorithms.cpp
===================================================================
--- trunk/MgDev/Common/Stylization/SE_PositioningAlgorithms.cpp	2007-03-15 11:43:58 UTC (rev 1234)
+++ trunk/MgDev/Common/Stylization/SE_PositioningAlgorithms.cpp	2007-03-15 16:03:22 UTC (rev 1235)
@@ -12,10 +12,10 @@
 
 SE_RenderPointStyle* DeepClonePointStyle(SE_RenderPointStyle* st)
 {
-    SE_RenderPointStyle* ret = new SE_RenderPointStyle(); //LEAK
+    SE_RenderPointStyle* ret = new SE_RenderPointStyle(); 
     *ret = *st;
-    ret->bounds = st->bounds->Clone(); //LEAK
-    SE_RenderText* txt = new SE_RenderText(); //LEAK
+    ret->bounds = st->bounds->Clone(); 
+    SE_RenderText* txt = new SE_RenderText(); 
     *txt = *((SE_RenderText*)st->symbol[0]);
     ret->symbol[0] = txt;
 
@@ -97,7 +97,7 @@
 
     //assume there is a single text label in the render symbol
     //and extract it from in there
-    SE_RenderPointStyle* rstyle2 = new SE_RenderPointStyle(); //LEAK
+    SE_RenderPointStyle* rstyle2 = new SE_RenderPointStyle();
     rstyle2->addToExclusionRegions = rstyle->addToExclusionRegions;
     rstyle2->checkExclusionRegions = rstyle->checkExclusionRegions;
     rstyle2->drawLast = rstyle->drawLast;
@@ -105,7 +105,7 @@
     rstyle2->bounds = rstyle->bounds->Clone();
     SE_RenderText* txt = NULL;
     
-    for (SE_RenderSymbol::iterator iter = rstyle->symbol.begin(); iter != rstyle->symbol.end(); iter++)
+    for (SE_RenderPrimitiveList::iterator iter = rstyle->symbol.begin(); iter != rstyle->symbol.end(); iter++)
     {
         if ((*iter)->type == SE_TextPrimitive)
         {

Modified: trunk/MgDev/Common/Stylization/SE_Renderer.cpp
===================================================================
--- trunk/MgDev/Common/Stylization/SE_Renderer.cpp	2007-03-15 11:43:58 UTC (rev 1234)
+++ trunk/MgDev/Common/Stylization/SE_Renderer.cpp	2007-03-15 16:03:22 UTC (rev 1235)
@@ -23,6 +23,127 @@
 
 using namespace MDFMODEL_NAMESPACE;
 
+//cloning of RenderSymbols. Unfortunate but nexessary for delay-drawing labels
+static SE_RenderStyle* CloneRenderStyle(SE_RenderStyle* symbol)
+{
+    SE_RenderStyle* ret = NULL;
+
+    //first determine what kind of style it is and copy all the 
+    //style specific properties
+    switch (symbol->type)
+    {
+    case SE_PointStyleType:
+        {
+        SE_RenderPointStyle* dps = new SE_RenderPointStyle();
+        ret = dps;
+        }
+        break;
+    case SE_LineStyleType:
+        {
+            SE_RenderLineStyle* dls = new SE_RenderLineStyle();
+            SE_RenderLineStyle* sls = (SE_RenderLineStyle*)symbol;
+            ret = dls;
+            dls->angle = sls->angle;
+            dls->angleControl = sls->angleControl;
+            dls->endOffset = sls->endOffset;
+            dls->repeat = sls->repeat;
+            dls->startOffset = sls->startOffset;
+            dls->unitsControl = sls->unitsControl;
+            dls->vertexAngleLimit = sls->vertexAngleLimit;
+            dls->vertexControl = sls->vertexControl;
+        }
+        break;
+    case SE_AreaStyleType:
+        {
+            SE_RenderAreaStyle* das = new SE_RenderAreaStyle();
+            SE_RenderAreaStyle* sas = (SE_RenderAreaStyle*)symbol;
+            ret = das;
+            das->angle = sas->angle;
+            das->angleControl = sas->angleControl;
+            das->bufferWidth = sas->bufferWidth;
+            das->clippingControl = sas->clippingControl;
+            das->origin[0] = sas->origin[0];
+            das->origin[1] = sas->origin[1];
+            das->originControl = sas->originControl;
+            das->repeat[0] = sas->repeat[0];
+            das->repeat[1] = sas->repeat[1];
+        }
+    default:
+        break;
+    }
+
+    //copy all the common properties
+    ret->addToExclusionRegions = symbol->addToExclusionRegions;
+    ret->bounds = symbol->bounds->Clone();
+    ret->checkExclusionRegions = symbol->checkExclusionRegions;
+    ret->drawLast = symbol->drawLast;
+    ret->renderPass = symbol->renderPass;
+
+    //copy the graphics for the symbol
+    for (size_t i=0; i<symbol->symbol.size(); i++)
+    {
+        SE_RenderPrimitive* rp = symbol->symbol[i];
+        SE_RenderPrimitive* rpc = NULL;
+
+        switch (rp->type)
+        {
+        case SE_PolygonPrimitive:
+            rpc = new SE_RenderPolygon();
+            ((SE_RenderPolygon*)rpc)->fill = ((SE_RenderPolygon*)rp)->fill;
+        case SE_PolylinePrimitive:
+            {
+                if (!rpc) rpc = new SE_RenderPolyline();
+                SE_RenderPolyline* drp = (SE_RenderPolyline*)rpc;
+                SE_RenderPolyline* srp = (SE_RenderPolyline*)rp;
+                drp->bounds = srp->bounds->Clone();
+                drp->color = srp->color;
+                drp->resize = srp->resize;
+                drp->weight = srp->weight;
+                drp->geometry = srp->geometry->Clone();
+            }
+            break;
+        case SE_TextPrimitive:
+            {
+                rpc = new SE_RenderText();
+                SE_RenderText* st = (SE_RenderText*)rp;
+                SE_RenderText* dt = (SE_RenderText*)rpc;
+
+                dt->bounds = st->bounds->Clone();
+                dt->position[0] = st->position[0];
+                dt->position[1] = st->position[1];
+                dt->resize = st->resize;
+                dt->tdef = st->tdef;
+                dt->text = st->text;
+            }
+            break;
+        case SE_RasterPrimitive:
+            {
+                rpc = new SE_RenderRaster();
+                SE_RenderRaster* sr = (SE_RenderRaster*)rp;
+                SE_RenderRaster* dr = (SE_RenderRaster*)rpc;
+
+                dr->angle = sr->angle;
+                dr->bounds = sr->bounds->Clone();
+                dr->extent[0] = sr->extent[0];
+                dr->extent[1] = sr->extent[1];
+                dr->pngSize = sr->pngSize;
+                dr->pngPtr = sr->pngPtr; //this pointer is managed/cached by the SE_SymbolManager
+                dr->position[0] = sr->position[0];
+                dr->position[1] = sr->position[1];
+                dr->resize = sr->resize;
+            }
+        }
+
+        if (rpc)
+        {
+            ret->symbol.push_back(rpc);
+        }
+    }
+
+    return ret;
+}
+
+
 SE_Renderer::SE_Renderer()
 : m_bSelectionMode(false)
 , m_selWeight(0.0)
@@ -83,7 +204,7 @@
 void SE_Renderer::ProcessLine(LineBuffer* geometry, SE_RenderLineStyle* style)
 {
     //determine if the style is a simple straight solid line
-    SE_RenderSymbol& rs = style->symbol;
+    SE_RenderPrimitiveList& rs = style->symbol;
 
     //check if it is a single symbol that is not a label participant
     if (rs.size() == 1 
@@ -199,7 +320,7 @@
 {
 }
 
-void SE_Renderer::DrawSymbol(SE_RenderSymbol& symbol, const SE_Matrix& posxform, double anglerad)
+void SE_Renderer::DrawSymbol(SE_RenderPrimitiveList& symbol, const SE_Matrix& posxform, double anglerad)
 {
     for (unsigned i = 0; i < symbol.size(); i++)
     {
@@ -262,7 +383,7 @@
             double x, y;
             posxform.transform(rp->position[0], rp->position[1], x, y);
 
-            DrawScreenRaster(rp->pngPtr, rp->pngSize, RS_ImageFormat_PNG, -1, -1, x, y, rp->extent[0], rp->extent[1], anglerad / M_PI180);
+            DrawScreenRaster((unsigned char*)rp->pngPtr, rp->pngSize, RS_ImageFormat_PNG, -1, -1, x, y, rp->extent[0], rp->extent[1], anglerad / M_PI180);
         }
     }
 }
@@ -270,7 +391,12 @@
 
 void SE_Renderer::AddLabel(LineBuffer* geom, SE_RenderStyle* style, SE_Matrix& xform, double angle)
 {
-    SE_LabelInfo info(xform.x2, xform.y2, 0.0, 0.0, RS_Units_Device, angle, style);
+    //clone the SE_RenderStyle so that the label renderer can keep track of it until 
+    //the end of rendering when it draws all the labels
+    //TODO: cloning is bad.
+    SE_RenderStyle* copied_style = CloneRenderStyle(style);
+
+    SE_LabelInfo info(xform.x2, xform.y2, 0.0, 0.0, RS_Units_Device, angle, copied_style);
     
     RS_OverpostType type = RS_OverpostType_AllFit;
 

Modified: trunk/MgDev/Common/Stylization/SE_Renderer.h
===================================================================
--- trunk/MgDev/Common/Stylization/SE_Renderer.h	2007-03-15 11:43:58 UTC (rev 1234)
+++ trunk/MgDev/Common/Stylization/SE_Renderer.h	2007-03-15 16:03:22 UTC (rev 1235)
@@ -34,7 +34,7 @@
     STYLIZATION_API virtual void ProcessLine(LineBuffer* geometry, SE_RenderLineStyle* style);
     STYLIZATION_API virtual void ProcessArea(LineBuffer* geometry, SE_RenderAreaStyle* style);
 
-    STYLIZATION_API virtual void DrawSymbol(SE_RenderSymbol& symbol, const SE_Matrix& xform, double anglerad);
+    STYLIZATION_API virtual void DrawSymbol(SE_RenderPrimitiveList& symbol, const SE_Matrix& xform, double anglerad);
 
     virtual void DrawScreenPolyline(LineBuffer* polyline, unsigned int color, double weight) = 0; // px
     virtual void DrawScreenPolygon(LineBuffer* polygon, unsigned int fill) = 0;
@@ -74,6 +74,7 @@
 
     RS_F_Point m_lastExclusionRegion[4];
 
+    
 protected:
     SE_LineBufferPool* m_lbp;
     bool m_bSelectionMode;

Modified: trunk/MgDev/Common/Stylization/SE_StyleVisitor.h
===================================================================
--- trunk/MgDev/Common/Stylization/SE_StyleVisitor.h	2007-03-15 11:43:58 UTC (rev 1234)
+++ trunk/MgDev/Common/Stylization/SE_StyleVisitor.h	2007-03-15 16:03:22 UTC (rev 1235)
@@ -60,7 +60,7 @@
     void Convert(std::vector<SE_Symbolization*>& styles, MdfModel::CompositeSymbolization* symbolization);
 private:
     SE_Style* ParseSymbol(MdfModel::CompoundSymbolDefinition* symbol);
-    void ParseSymbol(SimpleSymbolDefinition* symbol, SE_Matrix& xform, SE_Symbol* primitives, SE_RenderSymbol* renderPrimitives);
+    void ParseSymbol(SimpleSymbolDefinition* symbol, SE_Matrix& xform, SE_PrimitiveList* primitives, SE_RenderPrimitiveList* renderPrimitives);
     bool ParseDouble(const wchar_t*& str, double& val);
     bool ParseDoublePair(const wchar_t*& str, double& x, double& y);
     bool ParseGeometry(const MdfModel::MdfString& geometry, SE_LineBuffer& buffer);

Modified: trunk/MgDev/Common/Stylization/SE_SymbolManager.h
===================================================================
--- trunk/MgDev/Common/Stylization/SE_SymbolManager.h	2007-03-15 11:43:58 UTC (rev 1234)
+++ trunk/MgDev/Common/Stylization/SE_SymbolManager.h	2007-03-15 16:03:22 UTC (rev 1235)
@@ -27,7 +27,7 @@
 {
 public:
     virtual SymbolDefinition* GetSymbolDefinition(const wchar_t* resource) = 0;
-    virtual unsigned char* GetImageData(const wchar_t* resource, int& length) = 0;
+    virtual const unsigned char* GetImageData(const wchar_t* resource, int& length) = 0;
 };
 
 #endif

Modified: trunk/MgDev/Common/Stylization/StylizationEngine.cpp
===================================================================
--- trunk/MgDev/Common/Stylization/StylizationEngine.cpp	2007-03-15 11:43:58 UTC (rev 1234)
+++ trunk/MgDev/Common/Stylization/StylizationEngine.cpp	2007-03-15 16:03:22 UTC (rev 1235)
@@ -215,9 +215,9 @@
                 }
             }
 
-            //TODO: LEAK: the RenderStyles used for labeling are leaked because of this -- we need to free them somehow
-            if (!sym->drawLast.evaluate(m_exec))
-                delete rstyle;
+            //Free the render style. If the style was needed for drawing as a label,
+            //the renderer would have cloned it and created its own pointer
+            delete rstyle;
         }
     }
     m_pool->FreeLineBuffer(xformGeom);
@@ -330,7 +330,7 @@
         growy = 0.0;
     }
 
-    for (SE_Symbol::const_iterator src = style->symbol.begin(); src != style->symbol.end(); src++)
+    for (SE_PrimitiveList::const_iterator src = style->symbol.begin(); src != style->symbol.end(); src++)
     {
         SE_Primitive* sym = *src;
         SE_RenderPrimitive* rsym = NULL;
@@ -350,13 +350,13 @@
                     m_renderer->GetPixelsPerMillimeterWorld() : 
                     m_renderer->GetPixelsPerMillimeterScreen();
                 rp->weight = p->weight.evaluate(m_exec)*wx;
-                rp->geometry = p->geometry;
+                rp->geometry = p->geometry->Clone();
                 rp->color = p->color.evaluate(m_exec);
                 /* Defer transformation */
                 if (sym->resize != GraphicElement::AdjustToResizeBox)
                 {
                     rp->geometry->Transform(xform, rp->weight);
-                    rp->bounds = p->geometry->xf_bounds();
+                    rp->bounds = rp->geometry->xf_bounds()->Clone();
                 }
                 else
                     rp->bounds = NULL;
@@ -537,7 +537,7 @@
         growxf.translate(dx, dy);
         totalxf.premultiply(growxf);
 
-        for (SE_RenderSymbol::iterator rs = renderStyle->symbol.begin(); rs != renderStyle->symbol.end(); rs++)
+        for (SE_RenderPrimitiveList::iterator rs = renderStyle->symbol.begin(); rs != renderStyle->symbol.end(); rs++)
         {
             SE_RenderPrimitive* rsym = *rs;
             if (rsym->resize)
@@ -549,7 +549,7 @@
                     {
                         SE_RenderPolyline* rp = (SE_RenderPolyline*)rsym;
                         rp->geometry->Transform(totalxf, rp->weight);
-                        rp->bounds = rp->geometry->xf_bounds();
+                        rp->bounds = rp->geometry->xf_bounds()->Clone();
                         break;
                     }
                 case SE_TextPrimitive:



More information about the mapguide-commits mailing list