TuttleOFX  1
sections.hpp
Go to the documentation of this file.
00001 // Copyright Tom Brinkman 2008. Distributed under the Boost
00002 // Software License, Version 1.0. (See accompanying
00003 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
00004 
00005 #ifndef _sections_hpp_
00006 #define _sections_hpp_
00007 
00008 #include <boost/function.hpp>
00009 #include <boost/gil/gil_all.hpp>
00010 
00011 struct sections
00012 {
00013         struct section
00014         {
00015                 int pos;
00016                 section* next;
00017         };
00018         
00019         section* head;
00020         section* current;
00021 
00022         operator bool (){return current != NULL;}
00023         operator section * () {return head;}
00024         double operator *(){return current->pos;}
00025         void operator ++(int){current = current->next;}
00026         void operator ++(){current = current->next;}
00027         void reset() {current = head;}
00028 
00029         ~sections()
00030         {
00031                 while (head)
00032                 {
00033                         section* tmp = head->next;
00034                         free(head);
00035                         head = tmp;
00036                 }
00037                 
00038                 head = NULL;
00039         }
00040 
00041         sections(int width, int intervals) : head(NULL), current(NULL)
00042         {
00043                 BOOST_ASSERT(intervals);
00044                 
00045                 int adj = width / intervals;
00046                 int extra = width-adj*intervals;
00047                 int pos = 0;
00048                 int ppos = 0;
00049         
00050                 head = NULL;
00051                 current = NULL;
00052                 
00053                 while (pos < width)
00054                 {
00055                         int add = adj;
00056                         if (extra-- > 0)
00057                                 add++;
00058         
00059                         section* tmp  = (section*)malloc(sizeof(section));
00060                         pos += add;
00061                         tmp->pos = pos - ppos;
00062                         tmp->next = NULL;
00063                         ppos = pos;
00064                         
00065                         if (head == NULL)
00066                                 head = tmp;
00067                         else
00068                                 current->next = tmp;
00069                         
00070                         current = tmp;
00071                 }
00072                 
00073                 current = head;
00074         }
00075 };
00076 
00077 namespace layer
00078 {
00079 
00080 template <typename view_t>
00081 struct columns
00082 {
00083         typedef boost::function<void (view_t&)> layer_t;
00084         typedef std::pair<double, layer_t> pair_t;
00085         
00086         std::vector<pair_t> layers;
00087         int margin;
00088 
00089         columns(pair_t* p, int size, int margin = 0) : margin(margin) 
00090         {
00091                 for (int n = 0; n < size; ++n)
00092                         layers.push_back(p[n]);
00093         }
00094 
00095         void operator()(view_t& view)
00096         {
00097                 int zcount = 0;
00098                 int swidth = 0;
00099                 for (int n = 0; n < layers.size(); ++n)
00100                 {
00101                         BOOST_ASSERT(layers[n].first >= 0);
00102                         if (layers[n].first < 1 && layers[n].first > 0)
00103                                 layers[n].first = (int)(layers[n].first * view.width());
00104 
00105                         swidth += (int)(layers[n].first);
00106                         zcount += layers[n].first == 0 ? 1 : 0;
00107                 }
00108 
00109                 sections curr(view.width()-swidth+margin,zcount);
00110                 int x = 0;
00111                 for (int n = 0; n < layers.size(); ++n)
00112                 {
00113                         if (!layers[n].first)
00114                         {
00115                                 layers[n].first = *curr;
00116                                 curr++;
00117                         }
00118 
00119                         int xwidth = (int)(layers[n].first);
00120                         xwidth -= margin;
00121 
00122                         view_t v = boost::gil::subimage_view(view,x,0,xwidth,view.height());
00123                         layers[n].second(v);
00124                         x += xwidth + margin;
00125                 }
00126         }
00127 };
00128 
00129 template <typename view_t>
00130 struct rows
00131 {
00132         typedef boost::function<void (view_t&)> layer_t;
00133         typedef std::pair<double, layer_t> pair_t;
00134         typedef std::vector<std::pair<double,layer_t> > layers_t; 
00135 
00136         int margin;
00137         layers_t layers;
00138         
00139         rows(pair_t* p, int size, int margin = 0) : margin(margin)
00140         {
00141                 for (int n = 0; n < size; ++n)
00142                         layers.push_back(p[n]);
00143         }
00144 
00145         void operator()(view_t& view)
00146         {
00147                 int zcount = 0;
00148                 int sheight = 0;
00149                 for (int n = 0; n < layers.size(); ++n)
00150                 {
00151                         BOOST_ASSERT(layers[n].first >= 0);
00152                         if (layers[n].first < 1 && layers[n].first > 0)
00153                                 layers[n].first = (int)(layers[n].first * view.height());
00154 
00155                         sheight += (int)(layers[n].first);
00156                         zcount += layers[n].first == 0 ? 1 : 0;
00157                 }
00158 
00159                 sections curr(view.height()-sheight+margin,zcount);
00160                 int y = 0;
00161                 for (int n = 0; n < layers.size(); ++n)
00162                 {
00163                         if (!layers[n].first)
00164                         {
00165                                 layers[n].first = *curr;
00166                                 curr++;
00167                         }
00168                         
00169                         int yheight = (int)(layers[n].first);
00170                         yheight -= margin;
00171                         
00172                         view_t v = boost::gil::subimage_view(view,0,y,view.width(),yheight);
00173                         layers[n].second(v);
00174                         y += yheight+margin;
00175                 }
00176         }
00177 };
00178 
00179 };
00180 
00181 #endif