TuttleOFX
1
|
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