26 #ifndef SCRIBO_CORE_PARAGRAPH_SET_HH
27 # define SCRIBO_CORE_PARAGRAPH_SET_HH
29 # include <mln/util/array.hh>
30 # include <mln/make/relabelfun.hh>
31 # include <mln/value/int_u16.hh>
32 # include <mln/core/concept/function.hh>
33 # include <scribo/core/line_links.hh>
34 # include <scribo/core/line_set.hh>
35 # include <scribo/core/paragraph_info.hh>
36 # include <scribo/core/stats.hh>
38 # include <scribo/core/concept/serializable.hh>
39 # include <scribo/core/tag/paragraph.hh>
80 unsigned nelements()
const;
85 bool is_valid()
const;
102 template <
typename L>
109 template <
typename L>
115 template <
typename L>
121 template <
typename L>
129 # ifndef MLN_INCLUDE_ONLY
139 template <
typename L>
141 paragraph_set_data<L>::paragraph_set_data()
146 template <
typename L>
148 paragraph_set_data<L>::paragraph_set_data(
const line_links<L>& llinks,
unsigned npars)
149 : pars_(npars + 1, paragraph_info<L>(llinks)), links_(llinks)
151 lines_ = llinks.lines();
157 template <
typename L>
158 paragraph_set<L>::paragraph_set()
163 template <
typename L>
164 paragraph_set<L>::paragraph_set(internal::paragraph_set_data<L>*
data)
169 template <
typename L>
170 paragraph_set<L>::paragraph_set(
const line_links<L>& llinks,
unsigned npars)
172 data_ =
new internal::paragraph_set_data<L>(llinks, npars);
175 template <
typename L>
177 paragraph_set<L>::nelements()
const
179 mln_precondition(data_ != 0);
180 return data_->pars_.nelements() - 1;
183 template <
typename L>
185 paragraph_set<L>::operator()(
const paragraph_id_t& i)
187 mln_precondition(data_ != 0);
188 return data_->pars_[i];
191 template <
typename L>
192 const paragraph_info<L>&
193 paragraph_set<L>::operator()(
const paragraph_id_t& i)
const
195 mln_precondition(data_ != 0);
196 return data_->pars_[i];
200 template <
typename L>
202 paragraph_set<L>::is_valid()
const
204 return data_ && !data_->pars_.is_empty();
207 template <
typename L>
208 template <
typename F>
212 const F& f =
exact(f_);
214 for_all_paragraphs(p, (*
this))
216 (*this)(p).invalidate();
219 template <typename L>
221 paragraph_set<L>::lines()
const
223 mln_precondition(data_ != 0);
224 return data_->lines_;
228 template <
typename L>
230 paragraph_set<L>::links()
const
232 mln_precondition(data_ != 0);
233 return data_->links_;
237 template <
typename L>
242 paragraph_set<L> output;
243 output.data_ =
new data_t();
245 *(output.data_.ptr_) = *(data_.ptr_);
250 template <
typename L>
251 bool operator==(
const paragraph_set<L>& lhs,
const paragraph_set<L>& rhs)
253 if (! (lhs.lines() == rhs.lines() && lhs.nelements() == rhs.nelements()))
258 for_all_paragraphs(p, lhs)
259 if (!(lhs(p) == rhs(p)))
274 template <
typename L>
277 find_root(line_links<L>& parent,
unsigned x)
281 while (parent(tmp_x) != tmp_x)
282 tmp_x = parent(tmp_x);
284 while (parent(x) != x)
286 const unsigned tmp = parent(x);
294 template <
typename L>
297 set_root(line_links<L>& parent,
unsigned x,
const unsigned root)
299 while (parent(x) != x && parent(x) != root)
301 const unsigned tmp = parent(x);
314 template <
typename L>
317 const line_links<L>& rlinks)
319 line_links<L> links = llinks.duplicate();
321 for_all_links(l, links)
323 const line_id_t current_neighbor = llinks(l);
324 links(l) = internal::find_root(links, l);
325 const line_id_t root_index = links(l);
327 for (
unsigned j = 0; j < rlinks.nelements(); ++j)
330 current_neighbor != l &&
332 internal::set_root(links, j, root_index);
339 links.nelements() - 1, npars);
340 paragraph_set<L> parset(links, npars);
343 for_all_links(l, links)
346 value::int_u16 par_id = par_ids(l);
347 parset(par_id).add_line(lines(l));
350 for_all_paragraphs(p, parset)
352 paragraph_info<L>& current_par = parset(p);
356 current_par.force_stats_update();
362 for (
unsigned i = 0; i < nelements; ++i)
364 const line_id_t& current_id = line_ids(i);
366 if (llinks(current_id) != current_id)
368 const line_info<L>& current_line = lines(current_id);
369 const line_info<L>& left_line = lines(llinks(current_id));
371 delta.take(left_line.baseline() - current_line.baseline());
378 median = lines(current_par.line_ids()(0)).x_height();
380 current_par.set_delta_baseline(median);
387 template <
typename L>
391 line_links<L> links = llinks.duplicate();
393 for_all_links(l, links)
394 links(l) = internal::find_root(links, l);
397 mln::fun::i2v::array<
unsigned>
398 par_ids = mln::make::relabelfun(links.line_to_link(),
399 links.nelements() - 1, npars);
400 paragraph_set<L> parset(links, npars);
402 const scribo::line_set<L>& lines = links.lines();
403 for_all_links(l, links)
406 value::int_u16 par_id = par_ids(l);
407 parset(par_id).add_line(lines(l));
410 for_all_paragraphs(p, parset)
411 parset(p).force_stats_update();
417 template <typename L>
418 scribo::paragraph_set<L>
419 paragraph(const scribo::line_set<L>& lines)
421 line_links<L> links(lines);
427 links.nelements() - 1, npars);
428 paragraph_set<L> parset(links, npars);
430 for_all_links(l, links)
433 value::int_u16 par_id = par_ids(l);
434 parset(par_id).add_line(lines(l));
437 for_all_paragraphs(p, parset)
438 parset(p).force_stats_update();
448 # endif // ! MLN_INCLUDE_ONLY
452 #endif // ! SCRIBO_CORE_PARAGRAPH_SET_HH