$extrastylesheet
Olena  User documentation 2.1
An Image Processing Platform
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
compute_anchor.hh
1 // Copyright (C) 2009, 2010, 2011, 2013 EPITA Research and Development
2 // Laboratory (LRDE)
3 //
4 // This file is part of Olena.
5 //
6 // Olena is free software: you can redistribute it and/or modify it under
7 // the terms of the GNU General Public License as published by the Free
8 // Software Foundation, version 2 of the License.
9 //
10 // Olena is distributed in the hope that it will be useful,
11 // but WITHOUT ANY WARRANTY; without even the implied warranty of
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 // General Public License for more details.
14 //
15 // You should have received a copy of the GNU General Public License
16 // along with Olena. If not, see <http://www.gnu.org/licenses/>.
17 //
18 // As a special exception, you may use this file as part of a free
19 // software project without restriction. Specifically, if other files
20 // instantiate templates or use macros or inline functions from this
21 // file, or you compile this file and link it with other files to produce
22 // an executable, this file does not by itself cause the resulting
23 // executable to be covered by the GNU General Public License. This
24 // exception does not however invalidate any other reasons why the
25 // executable file might be covered by the GNU General Public License.
26 
27 #ifndef SCRIBO_PRIMITIVE_LINK_INTERNAL_COMPUTE_ANCHOR_HH
28 # define SCRIBO_PRIMITIVE_LINK_INTERNAL_COMPUTE_ANCHOR_HH
29 
33 
34 # include <mln/math/min.hh>
35 
36 # include <scribo/core/tag/anchor.hh>
37 # include <scribo/core/component_set.hh>
38 
39 
40 namespace scribo
41 {
42 
43  namespace primitive
44  {
45 
46  namespace link
47  {
48 
49  namespace internal
50  {
51  using namespace mln;
52 
76  template <typename L>
77  mln_site(L)
78  compute_anchor(const component_set<L>& components,
79  unsigned current_object, anchor::Type anchor);
80 
81 
82 # ifndef MLN_INCLUDE_ONLY
83 
84  template <typename L>
85  mln_site(L)
86  compute_anchor(const component_set<L>& components,
87  unsigned current_object, anchor::Type anchor)
88  {
89  typedef mln_site(L) P;
90 
91  unsigned h = components(current_object).bbox().height();
92  unsigned w = components(current_object).bbox().width();
93 
94  mln_site(L) sp = components(current_object).bbox().pcenter();
95 
96  switch (anchor)
97  {
98  // Component masss center
99  case anchor::MassCenter:
100  return components(current_object).mass_center();
101 
102 
103  // Bounding box top center
104  case anchor::Top:
105  if (h < 30)
106  sp.row() = components(current_object).bbox().pmin().row()
107  + math::min(2u, (h + 1) / 2 - 1);
108  else
109  sp.row() = components(current_object).bbox().pmin().row()
110  + math::min(10u, h /10);
111  break;
112 
113 
114  // Bounding box Strict top center
115  case anchor::StrictTopCenter:
116  sp.row() = components(current_object).bbox().pmin().row();
117  break;
118 
119 
120  // Bounding box top left
121  case anchor::TopStrictLeft:
122  sp.col() = components(current_object).bbox().pmin().col();
123  sp.row() = components(current_object).bbox().pmin().row()
124  + math::min(2u, (h + 1) / 2 - 1);
125  break;
126 
127 
128  // Bounding box bottom right
129  case anchor::BottomStrictRight:
130  sp.col() = components(current_object).bbox().pmax().col();
131  sp.row() = components(current_object).bbox().pmax().row()
132  - math::min(2u, (h + 1) / 2 - 1);
133  break;
134 
135 
136  // Bounding box bottom center
137  case anchor::Bottom:
138  if (h < 30)
139  sp.row() = components(current_object).bbox().pmax().row()
140  - math::min(2u, (h + 1) / 2 - 1);
141  else
142  sp.row() = components(current_object).bbox().pmax().row()
143  - math::min(10u, h /10);
144  break;
145 
146 
147  // Bounding box strict bottom center.
148  case anchor::StrictBottomCenter:
149  sp.row() = components(current_object).bbox().pmax().row();
150  break;
151 
152 
153  // Bounding box center
154  case anchor::Center:
155  return components(current_object).bbox().pcenter();
156 
157 
158  // Bounding box actual left center
159  case anchor::StrictLeft:
160  return P(components(current_object).bbox().pcenter().row(),
161  components(current_object).bbox().pmin().col());
162 
163 
164  // Bounding box left center
165  case anchor::Left:
166  if (w < 30)
167  sp.col() = components(current_object).bbox().pmin().col()
168  + math::min(2u, (w + 1) / 2 - 1);
169  else
170  sp.col() = components(current_object).bbox().pmin().col()
171  + math::min(10u, w /10);
172  break;
173 
174 
175  // Bounding box actual right center
176  case anchor::StrictRight:
177  return P(components(current_object).bbox().pcenter().row(),
178  components(current_object).bbox().pmax().col());
179 
180 
181  // Bounding box right center
182  case anchor::Right:
183  if (w < 30)
184  sp.col() = components(current_object).bbox().pmax().col()
185  - math::min(2u, (w + 1) / 2 - 1);
186  else
187  sp.col() = components(current_object).bbox().pmax().col()
188  - math::min(10u, w /10);
189  break;
190 
191 
192  // Bounding box top left
193  case anchor::TopLeft:
194  if (h < 30)
195  sp.row() = components(current_object).bbox().pmin().row()
196  + math::min(2u, (h + 1) / 2 - 1);
197  else
198  sp.row() = components(current_object).bbox().pmin().row()
199  + math::min(10u, h /10);
200  if (w < 30)
201  sp.col() = components(current_object).bbox().pmin().col()
202  + math::min(2u, (w + 1) / 2 - 1);
203  else
204  sp.col() = components(current_object).bbox().pmin().col()
205  + math::min(10u, w /10);
206  break;
207 
208 
209  // Bounding box top right
210  case anchor::TopRight:
211  if (h < 30)
212  sp.row() = components(current_object).bbox().pmin().row()
213  + math::min(2u, (h + 1) / 2 - 1);
214  else
215  sp.row() = components(current_object).bbox().pmin().row()
216  + math::min(10u, h /10);
217  if (w < 30)
218  sp.col() = components(current_object).bbox().pmax().col()
219  - math::min(2u, (w + 1) / 2 - 1);
220  else
221  sp.col() = components(current_object).bbox().pmax().col()
222  - math::min(10u, w /10);
223  break;
224 
225 
226  // Bounding box bottom left
227  case anchor::BottomLeft:
228  if (h < 30)
229  sp.row() = components(current_object).bbox().pmax().row()
230  - math::min(2u, (h + 1) / 2 - 1);
231  else
232  sp.row() = components(current_object).bbox().pmax().row()
233  - math::min(10u, h /10);
234  if (w < 30)
235  sp.col() = components(current_object).bbox().pmin().col()
236  + math::min(2u, (w + 1) / 2 - 1);
237  else
238  sp.col() = components(current_object).bbox().pmin().col()
239  + math::min(10u, w /10);
240  break;
241 
242  // Bounding box bottom right
243  case anchor::BottomRight:
244  if (h < 30)
245  sp.row() = components(current_object).bbox().pmax().row()
246  - math::min(2u, (h + 1) / 2 - 1);
247  else
248  sp.row() = components(current_object).bbox().pmax().row()
249  - math::min(10u, h /10);
250  if (w < 30)
251  sp.col() = components(current_object).bbox().pmax().col()
252  - math::min(2u, (w + 1) / 2 - 1);
253  else
254  sp.col() = components(current_object).bbox().pmax().col()
255  - math::min(10u, w /10);
256  break;
257 
258 
259 
260  default:
261  mln_trace_warning("Non handled anchor");
262  mln_assertion(anchor < anchor::Invalid);
263  }
264 
265  return sp;
266  }
267 
268 # endif // ! MLN_INCLUDE_ONLY
269 
270  } // end of namespace scribo::primitive::link::internal
271 
272  } // end of namespace scribo::primitive::link
273 
274  } // end of namespace scribo::primitive
275 
276 } // end of namespace scribo
277 
278 #endif // ! SCRIBO_PRIMITIVE_LINK_INTERNAL_COMPUTE_ANCHOR_HH