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

svn_mapguide at osgeo.org svn_mapguide at osgeo.org
Tue Mar 20 11:08:09 EDT 2007


Author: traianstanev
Date: 2007-03-20 11:08:08 -0400 (Tue, 20 Mar 2007)
New Revision: 1297

Modified:
   trunk/MgDev/Common/Stylization/LabelRenderer.cpp
   trunk/MgDev/Common/Stylization/LabelRendererLocal.cpp
   trunk/MgDev/Common/Stylization/SE_PositioningAlgorithms.cpp
   trunk/MgDev/Common/Stylization/SE_RenderProxies.h
   trunk/MgDev/Common/Stylization/SE_Renderer.cpp
   trunk/MgDev/Common/Stylization/SE_SymbolDefProxies.cpp
Log:
Changed the way cached bounding boxes are stored in styles. Replaced the SE_Bounds object by an array of 4 points. Currently these hold axis aligned boxes, but in the future they should be changed to oriented boxes. 

Modified: trunk/MgDev/Common/Stylization/LabelRenderer.cpp
===================================================================
--- trunk/MgDev/Common/Stylization/LabelRenderer.cpp	2007-03-20 14:04:18 UTC (rev 1296)
+++ trunk/MgDev/Common/Stylization/LabelRenderer.cpp	2007-03-20 15:08:08 UTC (rev 1297)
@@ -445,21 +445,10 @@
     //This needs to be improved to handle text along a path
 
     //get native symbol bounds (in pixels -- the render style is already scaled to pixels)
-    SE_Bounds* b = info.m_sestyle->bounds;
-    if (!b)
-        return false;
-
-    //now we will translate and orient the bounds with the given angle and position of the symbol
     RS_F_Point fpts[4];
-    fpts[0].x = b->min[0];
-    fpts[0].y = b->min[1];
-    fpts[1].x = b->max[0];
-    fpts[1].y = b->min[1];
-    fpts[2].x = b->max[0];
-    fpts[2].y = b->max[1];
-    fpts[3].x = b->min[0];
-    fpts[3].y = b->max[1];
+    memcpy(fpts, info.m_sestyle->bounds, sizeof (fpts));
 
+    //now we will translate and orient the bounds with the given angle and position of the symbol
     //apply position and rotation to the native bounds of the symbol
     double angle = m_serenderer->GetFontEngine()->_Yup() ? info.m_tdef.rotation() : -info.m_tdef.rotation();
     SE_Matrix m;

Modified: trunk/MgDev/Common/Stylization/LabelRendererLocal.cpp
===================================================================
--- trunk/MgDev/Common/Stylization/LabelRendererLocal.cpp	2007-03-20 14:04:18 UTC (rev 1296)
+++ trunk/MgDev/Common/Stylization/LabelRendererLocal.cpp	2007-03-20 15:08:08 UTC (rev 1297)
@@ -981,21 +981,10 @@
 bool LabelRendererLocal::ComputeSELabelBounds(LR_LabelInfoLocal& info)
 {
     //get native symbol bounds (in pixels -- the render style is already scaled to pixels)
-    SE_Bounds* b = info.m_sestyle->bounds;
-    if (!b)
-        return false;
-
-    //now we will translate and orient the bounds with the given angle and position of the symbol
     RS_F_Point fpts[4];
-    fpts[0].x = b->min[0];
-    fpts[0].y = b->min[1];
-    fpts[1].x = b->max[0];
-    fpts[1].y = b->min[1];
-    fpts[2].x = b->max[0];
-    fpts[2].y = b->max[1];
-    fpts[3].x = b->min[0];
-    fpts[3].y = b->max[1];
+    memcpy(fpts, info.m_sestyle->bounds, sizeof (fpts));
 
+    //now we will translate and orient the bounds with the given angle and position of the symbol
     //apply position and rotation to the native bounds of the symbol
     double angle = m_serenderer->GetFontEngine()->_Yup() ? info.m_tdef.rotation() : -info.m_tdef.rotation();
     SE_Matrix m;

Modified: trunk/MgDev/Common/Stylization/SE_PositioningAlgorithms.cpp
===================================================================
--- trunk/MgDev/Common/Stylization/SE_PositioningAlgorithms.cpp	2007-03-20 14:04:18 UTC (rev 1296)
+++ trunk/MgDev/Common/Stylization/SE_PositioningAlgorithms.cpp	2007-03-20 15:08:08 UTC (rev 1297)
@@ -30,7 +30,7 @@
 {
     SE_RenderPointStyle* ret = new SE_RenderPointStyle(); 
     *ret = *st;
-    ret->bounds = st->bounds->Clone(); 
+    memcpy(ret->bounds, st->bounds, sizeof(ret->bounds));
     SE_RenderText* txt = new SE_RenderText(); 
     *txt = *((SE_RenderText*)st->symbol[0]);
     ret->symbol[0] = txt;
@@ -80,15 +80,16 @@
         }
     }
 
-    txt->bounds->min[0] = rotatedBounds.minx;
-    txt->bounds->min[1] = rotatedBounds.miny;
-    txt->bounds->max[0] = rotatedBounds.maxx;
-    txt->bounds->max[1] = rotatedBounds.maxy;
+    txt->bounds[0].x = rotatedBounds.minx;
+    txt->bounds[0].y = rotatedBounds.miny;
+    txt->bounds[1].x = rotatedBounds.maxx;
+    txt->bounds[1].y = rotatedBounds.miny;
+    txt->bounds[2].x = rotatedBounds.maxx;
+    txt->bounds[2].y = rotatedBounds.maxy;
+    txt->bounds[3].x = rotatedBounds.minx;
+    txt->bounds[3].y = rotatedBounds.maxy;
 
-    st->bounds->min[0] = rotatedBounds.minx;
-    st->bounds->min[1] = rotatedBounds.miny;
-    st->bounds->max[0] = rotatedBounds.maxx;
-    st->bounds->max[1] = rotatedBounds.maxy;
+    memcpy(st->bounds, txt->bounds, sizeof(st->bounds));
 }
 
 
@@ -120,7 +121,7 @@
     rstyle2->checkExclusionRegions = rstyle->checkExclusionRegions;
     rstyle2->drawLast = rstyle->drawLast;
     rstyle2->renderPass = rstyle->renderPass;
-    rstyle2->bounds = rstyle->bounds->Clone();
+    memcpy(rstyle2->bounds, rstyle->bounds, sizeof(rstyle2->bounds));
     SE_RenderText* txt = NULL;
     
     for (SE_RenderPrimitiveList::iterator iter = rstyle->symbol.begin(); iter != rstyle->symbol.end(); iter++)

Modified: trunk/MgDev/Common/Stylization/SE_RenderProxies.h
===================================================================
--- trunk/MgDev/Common/Stylization/SE_RenderProxies.h	2007-03-20 14:04:18 UTC (rev 1296)
+++ trunk/MgDev/Common/Stylization/SE_RenderProxies.h	2007-03-20 15:08:08 UTC (rev 1297)
@@ -50,7 +50,7 @@
 {
     SE_RenderPrimitiveType type;
     bool resize;
-    SE_Bounds* bounds;
+    RS_F_Point bounds[4];
 };
 
 
@@ -113,9 +113,8 @@
         : type(stype),
           drawLast(false),
           checkExclusionRegions(false),
-          addToExclusionRegions(false),
-          bounds(NULL)
-    { }
+          addToExclusionRegions(false)
+    { memset (&bounds, 0, sizeof(bounds));}
 
     ~SE_RenderStyle()
     {
@@ -132,13 +131,11 @@
             default: throw; //means there is a bug
             }
         }
-
-        if (bounds) bounds->Free();
     }
 
     SE_RenderStyleType type;
     SE_RenderPrimitiveList symbol;
-    SE_Bounds* bounds;
+    RS_F_Point bounds[4];
 
     int renderPass;
 

Modified: trunk/MgDev/Common/Stylization/SE_Renderer.cpp
===================================================================
--- trunk/MgDev/Common/Stylization/SE_Renderer.cpp	2007-03-20 14:04:18 UTC (rev 1296)
+++ trunk/MgDev/Common/Stylization/SE_Renderer.cpp	2007-03-20 15:08:08 UTC (rev 1297)
@@ -23,7 +23,7 @@
 
 using namespace MDFMODEL_NAMESPACE;
 
-//cloning of RenderSymbols. Unfortunate but nexessary for delay-drawing labels
+//cloning of RenderSymbols. Unfortunate but necessary for delay-drawing labels
 static SE_RenderStyle* CloneRenderStyle(SE_RenderStyle* symbol)
 {
     SE_RenderStyle* ret = NULL;
@@ -74,7 +74,7 @@
 
     //copy all the common properties
     ret->addToExclusionRegions = symbol->addToExclusionRegions;
-    ret->bounds = symbol->bounds->Clone();
+    memcpy(ret->bounds, symbol->bounds, sizeof (ret->bounds));
     ret->checkExclusionRegions = symbol->checkExclusionRegions;
     ret->drawLast = symbol->drawLast;
     ret->renderPass = symbol->renderPass;
@@ -95,7 +95,7 @@
                 if (!rpc) rpc = new SE_RenderPolyline();
                 SE_RenderPolyline* drp = (SE_RenderPolyline*)rpc;
                 SE_RenderPolyline* srp = (SE_RenderPolyline*)rp;
-                drp->bounds = srp->bounds->Clone();
+                memcpy(drp->bounds, srp->bounds, sizeof (drp->bounds));
                 drp->color = srp->color;
                 drp->resize = srp->resize;
                 drp->weight = srp->weight;
@@ -108,7 +108,7 @@
                 SE_RenderText* st = (SE_RenderText*)rp;
                 SE_RenderText* dt = (SE_RenderText*)rpc;
 
-                dt->bounds = st->bounds->Clone();
+                memcpy(dt->bounds, st->bounds, sizeof (dt->bounds));
                 dt->position[0] = st->position[0];
                 dt->position[1] = st->position[1];
                 dt->resize = st->resize;
@@ -123,7 +123,7 @@
                 SE_RenderRaster* dr = (SE_RenderRaster*)rpc;
 
                 dr->angle = sr->angle;
-                dr->bounds = sr->bounds->Clone();
+                memcpy(dr->bounds, sr->bounds, sizeof (dr->bounds));
                 dr->extent[0] = sr->extent[0];
                 dr->extent[1] = sr->extent[1];
                 dr->pngSize = sr->pngSize;
@@ -424,16 +424,8 @@
     xform2.translate(xform.x2, xform.y2);
 
     RS_F_Point* fpts = m_lastExclusionRegion;
+    memcpy(fpts, rstyle->bounds, 4 * sizeof(RS_F_Point));
 
-    fpts[0].x = rstyle->bounds->min[0];
-    fpts[0].y = rstyle->bounds->min[1];
-    fpts[1].x = rstyle->bounds->max[0];
-    fpts[1].y = rstyle->bounds->min[1];
-    fpts[2].x = rstyle->bounds->max[0];
-    fpts[2].y = rstyle->bounds->max[1];
-    fpts[3].x = rstyle->bounds->min[0];
-    fpts[3].y = rstyle->bounds->max[1];
-
     for (int i=0; i<4; i++)
         xform2.transform(fpts[i].x, fpts[i].y);
 

Modified: trunk/MgDev/Common/Stylization/SE_SymbolDefProxies.cpp
===================================================================
--- trunk/MgDev/Common/Stylization/SE_SymbolDefProxies.cpp	2007-03-20 14:04:18 UTC (rev 1296)
+++ trunk/MgDev/Common/Stylization/SE_SymbolDefProxies.cpp	2007-03-20 15:08:08 UTC (rev 1297)
@@ -26,6 +26,63 @@
 #include <algorithm>
 #include <functional>
 
+
+//assumes axis aligned
+static void SetUndefinedBounds(RS_F_Point* pts)
+{
+    pts[0].x = pts[3].x = DBL_MAX;
+    pts[1].x = pts[2].x = -DBL_MAX;
+    pts[0].y = pts[1].y = DBL_MAX;
+    pts[2].y = pts[3].y = -DBL_MAX;
+}
+
+//assumes axis aligned bounds stored in src and dst
+static void BoundsUnion(RS_F_Point* dst, RS_F_Point* src)
+{
+    dst[0].x = dst[3].x = rs_min(dst[0].x, src[0].x);
+    dst[1].x = dst[2].x = rs_max(dst[1].x, src[1].x);
+    dst[0].y = dst[1].y = rs_min(dst[0].y, src[0].y);
+    dst[2].y = dst[3].y = rs_max(dst[2].y, src[2].y);
+}
+
+static void ComputeGrowAmount(RS_F_Point* bounds, double minx, double miny, double maxx, double maxy, double &growx, double &growy)
+{
+    double sx, sy;
+    double cx = (minx + maxx)/2.0;
+    double cy = (miny + maxy)/2.0;
+    minx -= cx;
+    maxx -= cx;
+    miny -= cy;
+    maxy -= cy;
+    double xfminx, xfminy, xfmaxx, xfmaxy;
+    xfminx = bounds[0].x - cx;
+    xfminy = bounds[0].y - cy;
+    xfmaxx = bounds[2].x - cx;
+    xfmaxy = bounds[2].y - cy;
+
+    if (xfminx < minx) // minx always negative
+    {
+        sx = xfminx/minx - 1.0;
+        growx = (growx > sx) ? growx : sx;
+    }
+    if (xfmaxx > maxx) // maxx always positive
+    {
+        sx = xfmaxx/maxx - 1.0;
+        growx = (growx > sx) ? growx : sx;
+    }
+    if (xfminy < miny)
+    {
+        sy = xfminy/miny - 1.0;
+        growy = (growy > sy) ? growy : sy;
+    }
+    if (xfmaxy > maxy)
+    {
+        sy = xfmaxy/maxy - 1.0;
+        growy = (growy > sy) ? growy : sy;
+    }
+}
+
+
 SE_Style::~SE_Style()
 {
     for (SE_PrimitiveList::iterator iter = symbol.begin(); iter != symbol.end(); iter++)
@@ -49,10 +106,22 @@
     if (!cxt->useBox)
     {
         ret->geometry->Transform(*cxt->xform, ret->weight);
-        ret->bounds = ret->geometry->xf_bounds()->Clone();
+        
+        SE_Bounds* seb = ret->geometry->xf_bounds();
+
+        //TODO: here we would implement rotating calipers algorithm to get
+        //a tighter oriented box, but for now we just get the axis aligned bounds of the path
+        ret->bounds[0].x = seb->min[0];
+        ret->bounds[0].y = seb->min[1];
+        ret->bounds[1].x = seb->max[0];
+        ret->bounds[1].y = seb->min[1];
+        ret->bounds[2].x = seb->max[0];
+        ret->bounds[2].y = seb->max[1];
+        ret->bounds[3].x = seb->min[0];
+        ret->bounds[3].y = seb->max[1];
     }
     else
-        ret->bounds = NULL;
+        SetUndefinedBounds(ret->bounds);
 
     return ret;
 }
@@ -73,10 +142,22 @@
     if (!cxt->useBox)
     {
         ret->geometry->Transform(*cxt->xform, ret->weight);
-        ret->bounds = ret->geometry->xf_bounds()->Clone();
+
+        SE_Bounds* seb = ret->geometry->xf_bounds();
+
+        //TODO: here we would implement rotating calipers algorithm to get
+        //a tighter oriented box, but for now we just get the axis aligned bounds of the path
+        ret->bounds[0].x = seb->min[0];
+        ret->bounds[0].y = seb->min[1];
+        ret->bounds[1].x = seb->max[0];
+        ret->bounds[1].y = seb->min[1];
+        ret->bounds[2].x = seb->max[0];
+        ret->bounds[2].y = seb->max[1];
+        ret->bounds[3].x = seb->min[0];
+        ret->bounds[3].y = seb->max[1];
     }
     else
-        ret->bounds = NULL;
+        SetUndefinedBounds(ret->bounds);
 
     return ret;
 }
@@ -143,23 +224,27 @@
     txf.rotate(ret->tdef.rotation() * M_PI180);
     txf.translate(ret->position[0], ret->position[1]);
 
-    double* buffer = (double*)alloca(tm.line_pos.size()*sizeof(double)*8);
-    double* ptr = buffer;
-    for(size_t k = 0; k < tm.line_pos.size(); k++)
+    //compute axis aligned boudns of the text primitive
+    RS_F_Point fpts[4];
+    RS_Bounds xformBounds(+DBL_MAX, +DBL_MAX, -DBL_MAX, -DBL_MAX);
+
+    for (size_t k=0; k<tm.line_pos.size(); ++k)
     {
-        const RS_F_Point* pts = tm.line_pos[k].ext;
-        txf.transform(pts[0].x, pts[0].y, ptr[0], ptr[1]);
-        txf.transform(pts[1].x, pts[1].y, ptr[2], ptr[3]);
-        txf.transform(pts[2].x, pts[2].y, ptr[4], ptr[5]);
-        txf.transform(pts[3].x, pts[3].y, ptr[6], ptr[7]);
-        ptr += 8;
+        //convert the unrotated measured bounds for the current line to a local point array
+        memcpy(fpts, tm.line_pos[k].ext, sizeof(fpts));
+
+        // process the extent points
+        for (int j=0; j<4; ++j)
+        {
+            txf.transform(fpts[j].x, fpts[j].y);
+
+            // update the overall rotated bounds
+            xformBounds.add_point(fpts[j]);
+        }
     }
 
-    std::sort((std::pair<double,double>*)buffer, (std::pair<double,double>*)(ptr - 2), PointLess( ));
-    ret->bounds = AndrewHull<std::pair<double,double>*,SimplePOINT>
-        ((std::pair<double,double>*)buffer,
-        ((std::pair<double,double>*)ptr) - 1,
-        (int)tm.line_pos.size()*4, cxt->pool);
+    //set the bounds into the returned primitive
+    xformBounds.get_points(ret->bounds);
 
     return ret;
 }
@@ -200,11 +285,7 @@
     rxf.transform(-w, -h, pts[2].x, pts[2].y);
     rxf.transform(-w,  h, pts[3].x, pts[3].y);
 
-    std::sort((std::pair<double,double>*)pts, (std::pair<double,double>*)(pts + 3), PointLess( ));
-    ret->bounds = AndrewHull<std::pair<double,double>*,SimplePOINT>
-        ((std::pair<double,double>*)pts,
-        ((std::pair<double,double>*)(pts+3)) - 1,
-        4, cxt->pool);
+    memcpy(ret->bounds, pts, sizeof(ret->bounds));
 
     return ret;
 }
@@ -255,14 +336,7 @@
         {
             if (!rsym->resize)
             {
-                if (rstyle->bounds)
-                {
-                    SE_Bounds* bounds = rstyle->bounds;
-                    rstyle->bounds = bounds->Union(rsym->bounds);
-                    bounds->Free();
-                }
-                else
-                    rstyle->bounds = rsym->bounds->Clone();
+                BoundsUnion(rstyle->bounds, rsym->bounds);
             }
 
             rstyle->symbol.push_back(rsym);
@@ -270,8 +344,9 @@
             if (useBox)
             {
                 const wchar_t* sResizeCtrl = sym->resizeControl.evaluate(cxt->exec);
-                if (sResizeCtrl && wcscmp(sResizeCtrl, L"AddToResizeBox") == 0)
-                    rsym->bounds->Contained(minx, miny, maxx, maxy, growx, growy);
+
+                if (wcscmp(sResizeCtrl, L"AddToResizeBox") == 0)
+                    ComputeGrowAmount(rstyle->bounds, minx, miny, maxx, maxy, growx, growy);
             }
         }
     }
@@ -322,7 +397,15 @@
                     {
                         SE_RenderPolyline* rp = (SE_RenderPolyline*)rsym;
                         rp->geometry->Transform(totalxf, rp->weight);
-                        rp->bounds = rp->geometry->xf_bounds()->Clone();
+                        SE_Bounds* seb = rp->geometry->xf_bounds();
+                        rp->bounds[0].x = seb->min[0];
+                        rp->bounds[0].y = seb->min[1];
+                        rp->bounds[1].x = seb->max[0];
+                        rp->bounds[1].y = seb->min[1];
+                        rp->bounds[2].x = seb->max[0];
+                        rp->bounds[2].y = seb->max[1];
+                        rp->bounds[3].x = seb->min[0];
+                        rp->bounds[3].y = seb->max[1];
                         break;
                     }
                 case SE_RenderTextPrimitive:
@@ -330,7 +413,8 @@
                         SE_RenderText* rt = (SE_RenderText*)rsym;
                         growxf.transform(rt->position[0], rt->position[1]);
                         rt->tdef.font().height() *= growxf.y1;
-                        rt->bounds->Transform(growxf);
+                        for (int j=0; j<4; j++) 
+                            growxf.transform(rt->bounds[j].x, rt->bounds[j].y);
                         break;
                     }
                 case SE_RenderRasterPrimitive:
@@ -339,19 +423,13 @@
                         growxf.transform(rr->position[0], rr->position[1]);
                         rr->extent[0] *= growxf.x0;
                         rr->extent[1] *= growxf.y1;
-                        rr->bounds->Transform(growxf);
+                        for (int j=0; j<4; j++) 
+                            growxf.transform(rr->bounds[j].x, rr->bounds[j].y);
                         break;
                     }
                 }
 
-                if (rstyle->bounds)
-                {
-                    SE_Bounds* bounds = rstyle->bounds;
-                    rstyle->bounds = bounds->Union(rsym->bounds);
-                    bounds->Free();
-                }
-                else
-                    rstyle->bounds = rsym->bounds->Clone();
+                BoundsUnion(rstyle->bounds, rsym->bounds);
             }
         }
     }



More information about the mapguide-commits mailing list