Use Gmprat for Path bounds with TRANSFORM_BEZIERS_TO_PATH
[ipdf/code.git] / src / path.cpp
index c58d3df..251de1e 100644 (file)
@@ -5,7 +5,7 @@ using namespace std;
 namespace IPDF
 {
 
-Path::Path(const Objects & objects, unsigned start, unsigned end, const Colour & fill, const Colour & stroke)
+Path::Path(Objects & objects, unsigned start, unsigned end, const Colour & fill, const Colour & stroke)
        : m_start(start), m_end(end), m_fill(fill), m_stroke(stroke)
 {
        Real xmin = 0; Real ymin = 0; 
@@ -14,13 +14,15 @@ Path::Path(const Objects & objects, unsigned start, unsigned end, const Colour &
        // Find the bounds coordinates
        //  and identify the top left and bottom right objects
        
-       unsigned left;
-       unsigned right;
-       unsigned top;
-       unsigned bottom;
+       unsigned left = m_start;
+       unsigned right = m_start;
+       unsigned top = m_start;
+       unsigned bottom = m_start;
        
        for (unsigned i = m_start; i <= m_end; ++i)
        {
+               if (i >= objects.bounds.size())
+                       break;
                const Rect & objb = objects.bounds[i];
                
                if (i == m_start || objb.x < xmin)
@@ -43,68 +45,29 @@ Path::Path(const Objects & objects, unsigned start, unsigned end, const Colour &
                {
                        ymax = (objb.y+objb.h);
                        bottom = i;
-               }
-               
-               // find fill points
-               Vec2 pt;
-               // left
-               pt = Vec2(objb.x, objb.y+objb.h/Real(2));
-               if (PointInside(objects, pt))
-                       m_fill_points.push_back(pt);
-               // right
-               pt = Vec2(objb.x+objb.w, objb.y+objb.h/Real(2));
-               if (PointInside(objects, pt))
-                       m_fill_points.push_back(pt);
-               // bottom
-               pt = Vec2(objb.x+objb.w/Real(2), objb.y+objb.h);
-               if (PointInside(objects, pt))
-                       m_fill_points.push_back(pt);
-               // top
-               pt = Vec2(objb.x+objb.w/Real(2), objb.y);
-               if (PointInside(objects, pt))
-                       m_fill_points.push_back(pt);
-                       
-               // topleft
-               pt = Vec2(objb.x, objb.y);
-               if (PointInside(objects, pt))
-                       m_fill_points.push_back(pt);
-               // topright
-               pt = Vec2(objb.x+objb.w, objb.y);
-               if (PointInside(objects, pt))
-                       m_fill_points.push_back(pt);
-               // bottom left
-               pt = Vec2(objb.x, objb.y+objb.h);
-               if (PointInside(objects, pt))
-                       m_fill_points.push_back(pt);
-               // bottom right
-               pt = Vec2(objb.x+objb.w, objb.y);
-               if (PointInside(objects, pt))
-                       m_fill_points.push_back(pt);
-                       
-               // mid
-               pt = Vec2(objb.x+objb.w/Real(2), objb.y+objb.h/Real(2));
-               if (PointInside(objects, pt))
-                       m_fill_points.push_back(pt);
-               
-               
+               }       
        }
        
        // Get actual turning point coords of the 4 edge case beziers
        m_top = objects.beziers[objects.data_indices[top]].ToAbsolute(objects.bounds[top]).GetTop();
        m_bottom = objects.beziers[objects.data_indices[bottom]].ToAbsolute(objects.bounds[bottom]).GetBottom();
        m_left = objects.beziers[objects.data_indices[left]].ToAbsolute(objects.bounds[left]).GetLeft();
-       m_right = objects.beziers[objects.data_indices[right]].ToAbsolute(objects.bounds[right]).GetRight();
+       m_right = objects.beziers[objects.data_indices[right]].ToAbsolute(objects.bounds[right]).GetRight();    
        
-       Vec2 pt = (m_top + m_bottom)/2;
-       if (PointInside(objects, pt))
-               m_fill_points.push_back(pt);
-       pt = (m_left + m_right)/2;
-       if (PointInside(objects, pt))
-               m_fill_points.push_back(pt);
-       pt = (m_left + m_right + m_top + m_bottom)/4;
-       if (PointInside(objects, pt))
-               m_fill_points.push_back(pt);
-               
+       #ifdef TRANSFORM_BEZIERS_TO_PATH
+       x = m_left.x;
+       y = m_top.y;
+       w = m_right.x - m_left.x;
+       h = m_bottom.y - m_top.y;
+       
+       Rect bounds = SolveBounds(objects);
+       for (unsigned i = m_start; i <= m_end; ++i)
+       {
+               //Debug("Transform %s -> %s", objects.bounds[i].Str().c_str(), bounds.Str().c_str());
+               objects.bounds[i] = TransformRectCoordinates(bounds, objects.bounds[i]);
+               //Debug("-> %s", objects.bounds[i].Str().c_str());
+       }
+       #endif
 }
 
 
@@ -166,9 +129,88 @@ bool Path::PointInside(const Objects & objects, const Vec2 & pt, bool debug) con
        return true;
 }
 
-Rect Path::SolveBounds(const Objects & objects) const
+vector<Vec2> & Path::FillPoints(const Objects & objects, const View & view)
 {
+       if (m_fill_points.size() != 0)
+               return m_fill_points;
+               
+       
+       for (unsigned i = m_start; i <= m_end; ++i)
+       {
+               const Rect & objb = objects.bounds[i];
+               // find fill points
+               Vec2 pt;
+               // left
+               pt = Vec2(objb.x, objb.y+objb.h/Real(2));
+               if (PointInside(objects, pt))
+                       m_fill_points.push_back(pt);
+               // right
+               pt = Vec2(objb.x+objb.w, objb.y+objb.h/Real(2));
+               if (PointInside(objects, pt))
+                       m_fill_points.push_back(pt);
+               // bottom
+               pt = Vec2(objb.x+objb.w/Real(2), objb.y+objb.h);
+               if (PointInside(objects, pt))
+                       m_fill_points.push_back(pt);
+               // top
+               pt = Vec2(objb.x+objb.w/Real(2), objb.y);
+               if (PointInside(objects, pt))
+                       m_fill_points.push_back(pt);
+                       
+               // topleft
+               pt = Vec2(objb.x, objb.y);
+               if (PointInside(objects, pt))
+                       m_fill_points.push_back(pt);
+               // topright
+               pt = Vec2(objb.x+objb.w, objb.y);
+               if (PointInside(objects, pt))
+                       m_fill_points.push_back(pt);
+               // bottom left
+               pt = Vec2(objb.x, objb.y+objb.h);
+               if (PointInside(objects, pt))
+                       m_fill_points.push_back(pt);
+               // bottom right
+               pt = Vec2(objb.x+objb.w, objb.y);
+               if (PointInside(objects, pt))
+                       m_fill_points.push_back(pt);
+                       
+               // mid
+               pt = Vec2(objb.x+objb.w/Real(2), objb.y+objb.h/Real(2));
+               if (PointInside(objects, pt))
+                       m_fill_points.push_back(pt);
+               
+               
+       }
+       
+       // 4 extrema
+       Vec2 pt = (m_top + m_bottom)/2;
+       if (PointInside(objects, pt))
+               m_fill_points.push_back(pt);
+       pt = (m_left + m_right)/2;
+       if (PointInside(objects, pt))
+               m_fill_points.push_back(pt);
+       pt = (m_left + m_right + m_top + m_bottom)/4;
+       if (PointInside(objects, pt))
+               m_fill_points.push_back(pt);
+               
+       return m_fill_points;
+}
+
+Rect Path::SolveBounds(const Objects & objects)
+{
+       #ifdef TRANSFORM_BEZIERS_TO_PATH
+               return Rect(Real(x.ToDouble()), Real(y.ToDouble()), Real(w.ToDouble()), Real(h.ToDouble()));
+       #else
                return Rect(m_left.x, m_top.y, m_right.x-m_left.x, m_bottom.y-m_top.y);
+       #endif
+}
+
+Rect & Path::GetBounds(Objects & objects) 
+{
+       #ifdef TRANSFORM_BEZIERS_TO_PATH
+               objects.bounds[m_index] = Rect(Real(x.ToDouble()), Real(y.ToDouble()), Real(w.ToDouble()), Real(h.ToDouble()));
+       #endif
+       return objects.bounds[m_index];
 }
 
 }

UCC git Repository :: git.ucc.asn.au