* scribo/scribo/core/component_info.hh: Remove useless line_id.
* scribo/scribo/core/line_set.hh,
* scribo/scribo/core/component_set.hh: Add new constructors.
* scribo/scribo/core/document.hh: Store line separators.
* scribo/scribo/core/line_info.hh: Share attributes and add new
constructors.
(is_textline): New method.
* scribo/scribo/core/line_links.hh: Do not allocate useless data.
* scribo/scribo/core/paragraph_info.hh (operator<<): New.
* scribo/scribo/core/paragraph_set.hh: Share attributes and add new
constructors.
---
scribo/ChangeLog | 22 ++
scribo/scribo/core/component_info.hh | 17 +--
scribo/scribo/core/component_set.hh | 65 +++++--
scribo/scribo/core/document.hh | 48 +++++-
scribo/scribo/core/line_info.hh | 367 ++++++++++++++++++----------------
scribo/scribo/core/line_links.hh | 2 +-
scribo/scribo/core/line_set.hh | 29 +++-
scribo/scribo/core/paragraph_info.hh | 10 +
scribo/scribo/core/paragraph_set.hh | 84 +++++++-
9 files changed, 425 insertions(+), 219 deletions(-)
diff --git a/scribo/ChangeLog b/scribo/ChangeLog
index fa99f5b..2d66a58 100644
--- a/scribo/ChangeLog
+++ b/scribo/ChangeLog
@@ -1,5 +1,27 @@
2011-02-17 Guillaume Lazzara <z(a)lrde.epita.fr>
+ Various changes in scribo core structures.
+
+ * scribo/scribo/core/component_info.hh: Remove useless line_id.
+
+ * scribo/scribo/core/line_set.hh,
+ * scribo/scribo/core/component_set.hh: Add new constructors.
+
+ * scribo/scribo/core/document.hh: Store line separators.
+
+ * scribo/scribo/core/line_info.hh: Share attributes and add new
+ constructors.
+ (is_textline): New method.
+
+ * scribo/scribo/core/line_links.hh: Do not allocate useless data.
+
+ * scribo/scribo/core/paragraph_info.hh (operator<<): New.
+
+ * scribo/scribo/core/paragraph_set.hh: Share attributes and add new
+ constructors.
+
+2011-02-17 Guillaume Lazzara <z(a)lrde.epita.fr>
+
Rename files in Scribo.
* scribo/primitive/extract/elements.hh,
diff --git a/scribo/scribo/core/component_info.hh b/scribo/scribo/core/component_info.hh
index 4ed6db7..1b03318 100644
--- a/scribo/scribo/core/component_info.hh
+++ b/scribo/scribo/core/component_info.hh
@@ -47,7 +47,6 @@ namespace scribo
class component_info
{
typedef mln::util::object_id<scribo::ComponentId, unsigned> component_id_t;
- typedef mln::util::object_id<scribo::LineId, unsigned> line_id_t;
public:
component_info();
@@ -69,9 +68,6 @@ namespace scribo
component::Type type() const;
void update_type(component::Type type);
- // The line it is rattached to. 0 means an invalid line.
- line_id_t line_id() const;
-
bool is_valid() const;
private:
@@ -82,8 +78,6 @@ namespace scribo
component::Tag tag_;
component::Type type_;
-
- line_id_t line_id_;
};
@@ -109,7 +103,7 @@ namespace scribo
const mln::point2d& mass_center,
unsigned card)
: id_(id), bbox_(bbox), mass_center_(mass_center), card_(card),
- tag_(component::None), type_(component::Undefined), line_id_(0)
+ tag_(component::None), type_(component::Undefined)
{
}
@@ -179,14 +173,6 @@ namespace scribo
inline
- component_info::line_id_t
- component_info::line_id() const
- {
- return line_id_;
- }
-
-
- inline
bool
component_info::is_valid() const
{
@@ -204,7 +190,6 @@ namespace scribo
<< ", mass_center=" << info.mass_center()
<< ", card=" << info.card()
<< ", tag=" << info.tag()
- << ", line_id=" << info.line_id()
<< ")" << std::endl;
}
diff --git a/scribo/scribo/core/component_set.hh b/scribo/scribo/core/component_set.hh
index 103826f..7ddcf16 100644
--- a/scribo/scribo/core/component_set.hh
+++ b/scribo/scribo/core/component_set.hh
@@ -1,5 +1,5 @@
-// Copyright (C) 2009, 2010 EPITA Research and Development Laboratory
-// (LRDE)
+// Copyright (C) 2009, 2010, 2011 EPITA Research and Development
+// Laboratory (LRDE)
//
// This file is part of Olena.
//
@@ -55,6 +55,8 @@
# include <mln/core/routine/duplicate.hh>
+# include <mln/value/next.hh>
+
# include <scribo/core/macros.hh>
# include <scribo/core/component_info.hh>
@@ -95,6 +97,8 @@ namespace scribo
void fill_infos(const mln::util::array<pair_data_t>& attribs);
+ // Useful while constructing incrementaly (XML loading).
+ void soft_init(const mln_value(L) ncomps);
L ima_;
mln_value(L) ncomps_;
@@ -128,6 +132,9 @@ namespace scribo
/// Constructor without argument.
component_set();
+ // Constructor from internal data.
+ component_set(const mln::util::tracked_ptr<data_t>& data);
+
/// Constructor from an image \p ima and the number of labels \p ncomps.
component_set(const L& ima, const mln_value(L)& ncomps);
@@ -348,6 +355,19 @@ namespace scribo
}
+ template <typename L>
+ inline
+ void
+ component_set_data<L>::soft_init(const mln_value(L) ncomps)
+ {
+ mln_precondition(infos_.nelements() == 0);
+
+ ncomps_ = ncomps;
+ infos_.reserve(ncomps_);
+ infos_.append(component_info()); // Component 0, i.e. the background.
+ }
+
+
} // end of namespace mln::internal
@@ -361,6 +381,13 @@ namespace scribo
template <typename L>
inline
+ component_set<L>::component_set(const mln::util::tracked_ptr<data_t>&
data)
+ {
+ data_ = data;
+ }
+
+ template <typename L>
+ inline
component_set<L>::component_set(const L& ima, const mln_value(L)&
ncomps)
{
data_ = new internal::component_set_data<L>(ima, ncomps);
@@ -400,7 +427,7 @@ namespace scribo
const component_info&
component_set<L>::info(const mln_value(L)& id) const
{
- return this->data_->infos_[id];
+ return data_->infos_[id];
}
template <typename L>
@@ -408,7 +435,7 @@ namespace scribo
component_info&
component_set<L>::info(const mln_value(L)& id)
{
- return this->data_->infos_[id];
+ return data_->infos_[id];
}
// template <typename L>
@@ -416,7 +443,7 @@ namespace scribo
// const component_info&
// component_set<L>::operator()(const mln_value(L)& id) const
// {
-// return this->data_->infos_[id];
+// return data_->infos_[id];
// }
// template <typename L>
@@ -424,7 +451,7 @@ namespace scribo
// component_info&
// component_set<L>::operator()(const mln_value(L)& id)
// {
-// return this->data_->infos_[id];
+// return data_->infos_[id];
// }
template <typename L>
@@ -432,7 +459,7 @@ namespace scribo
const component_info&
component_set<L>::operator()(const component_id_t& id) const
{
- return this->data_->infos_[id];
+ return data_->infos_[id];
}
template <typename L>
@@ -440,7 +467,7 @@ namespace scribo
component_info&
component_set<L>::operator()(const component_id_t& id)
{
- return this->data_->infos_[id];
+ return data_->infos_[id];
}
@@ -476,7 +503,7 @@ namespace scribo
const L&
component_set<L>::labeled_image() const
{
- return this->data_->ima_;
+ return data_->ima_;
}
@@ -485,7 +512,7 @@ namespace scribo
bool
component_set<L>::is_valid() const
{
- return this->data_->ima_.is_valid();
+ return data_ != 0 && data_->ima_.is_valid();
}
@@ -503,7 +530,7 @@ namespace scribo
L&
component_set<L>::labeled_image_()
{
- return this->data_->ima_;
+ return data_->ima_;
}
@@ -512,7 +539,7 @@ namespace scribo
mln_concrete(L)
component_set<L>::valid_comps_image_() const
{
- mln::util::array<bool> f(mln::value::next(this->data_->ncomps_));
+ mln::util::array<bool> f(mln::value::next(data_->ncomps_));
f(0) = true;
for_all_comps(c, (*this))
@@ -520,8 +547,8 @@ namespace scribo
mln_value(L) new_ncomps;
mln_concrete(L)
- output = mln::labeling::relabel(this->data_->ima_,
- this->data_->ncomps_,
+ output = mln::labeling::relabel(data_->ima_,
+ data_->ncomps_,
new_ncomps,
f);
@@ -534,7 +561,7 @@ namespace scribo
bool
component_set<L>::has_separators() const
{
- return this->data_->separators_.is_valid();
+ return data_->separators_.is_valid();
}
@@ -544,9 +571,9 @@ namespace scribo
component_set<L>::add_separators(const mln_ch_value(L, bool)& ima)
{
if (! has_separators())
- this->data_->separators_ = ima;
+ data_->separators_ = ima;
else
- mln::logical::or_inplace(this->data_->separators_, ima);
+ mln::logical::or_inplace(data_->separators_, ima);
}
@@ -555,7 +582,7 @@ namespace scribo
const mln_ch_value(L, bool)&
component_set<L>::separators() const
{
- return this->data_->separators_;
+ return data_->separators_;
}
@@ -564,7 +591,7 @@ namespace scribo
void
component_set<L>::clear_separators()
{
- this->data_->separators_.destroy();
+ data_->separators_.destroy();
}
diff --git a/scribo/scribo/core/document.hh b/scribo/scribo/core/document.hh
index f112410..e5ac825 100644
--- a/scribo/scribo/core/document.hh
+++ b/scribo/scribo/core/document.hh
@@ -91,16 +91,24 @@ namespace scribo
const component_set<L>& whitespace_seps_comps() const;
void set_whitespace_separators(const image2d<bool>& whitespace_seps);
+ bool has_line_seps() const;
+ const mln::image2d<bool>& line_seps() const;
+ const component_set<L>& line_seps_comps() const;
+ void set_line_separators(const image2d<bool>& line_seps);
+
+
private:
const char *filename_;
mln::image2d<mln::value::rgb8> image_;
- line_set<L> lines_;
paragraph_set<L> parset_;
component_set<L> elements_;
mln::image2d<bool> whitespace_seps_;
component_set<L> whitespace_seps_comps_;
+
+ mln::image2d<bool> line_seps_;
+ component_set<L> line_seps_comps_;
};
@@ -201,7 +209,6 @@ namespace scribo
return parset_.lines();
}
-
template <typename L>
const paragraph_set<L>&
document<L>::paragraphs() const
@@ -294,6 +301,43 @@ namespace scribo
}
+ template <typename L>
+ bool
+ document<L>::has_line_seps() const
+ {
+ return line_seps_.is_valid();
+ }
+
+
+ template <typename L>
+ const mln::image2d<bool>&
+ document<L>::line_seps() const
+ {
+ return line_seps_;
+ }
+
+
+ template <typename L>
+ const component_set<L>&
+ document<L>::line_seps_comps() const
+ {
+ return line_seps_comps_;
+ }
+
+
+ template <typename L>
+ void
+ document<L>::set_line_separators(const image2d<bool>& line_seps)
+ {
+ line_seps_ = line_seps;
+
+ mln_value(L) ncomps;
+ line_seps_comps_ = primitive::extract::components(line_seps,
+ mln::c8(), ncomps);
+ }
+
+
+
# endif // ! MLN_INCLUDE_ONLY
diff --git a/scribo/scribo/core/line_info.hh b/scribo/scribo/core/line_info.hh
index 54a5094..c82160a 100644
--- a/scribo/scribo/core/line_info.hh
+++ b/scribo/scribo/core/line_info.hh
@@ -58,12 +58,76 @@ namespace scribo
// Forward declarations.
template <typename L> class line_set;
+ template <typename L> class line_info;
typedef mln::util::object_id<scribo::LineId, unsigned> line_id_t;
+
+ namespace internal
+ {
+ /// Data structure for \c scribo::line_info<I>.
+ template <typename L>
+ struct line_info_data
+ {
+ line_info_data();
+ line_info_data(const line_set<L>& holder,
+ const mln::util::array<component_id_t>& comps);
+
+
+ bool hidden_;
+ line::Tag tag_;
+ mln::box2d bbox_;
+ mln::box2d ebbox_;
+ mln::util::array<component_id_t> components_;
+
+ // Values relative to the line bbox.
+ int baseline_;
+ int meanline_;
+
+ // Values relative to the baseline.
+ unsigned x_height_;
+ int d_height_;
+ int a_height_;
+
+ // Character related stats.
+ unsigned char_space_;
+ unsigned char_width_;
+
+ // Words related stats.
+ unsigned word_space_;
+
+ // Reading direction
+ line::ReadingDirection reading_direction_;
+
+ // Line type
+ line::Type type_;
+
+ // Is this line in reverse video?
+ bool reverse_video_;
+
+ // Text orientation
+ float orientation_;
+
+ // Text reading orientation
+ float reading_orientation_;
+
+ bool indented_;
+
+ std::string text_;
+
+ // Line set holding this element.
+ line_set<L> holder_;
+
+ };
+
+ } // end of namespace scribo::internal
+
+
+
template <typename L>
class line_info
{
+ typedef internal::line_info_data<L> data_t;
typedef mln::util::object_id<scribo::ComponentId, unsigned> component_id_t;
typedef mln::util::object_id<scribo::LineId, unsigned> line_id_t;
@@ -74,6 +138,8 @@ namespace scribo
line_info();
+ line_info(const line_id_t& id, data_t* data);
+
line_info(const line_set<L>& holder,
const line_id_t& id,
const mln::util::array<component_id_t>& comps);
@@ -134,9 +200,10 @@ namespace scribo
const std::string& text() const;
void update_text(const std::string& str);
-
bool is_valid() const;
+ bool is_textline() const;
+
/// Hidden status.
///
/// When a line is hidden, it should not be used in routines
@@ -180,6 +247,9 @@ namespace scribo
/// Returns the delta used to compute the extended bbox.
int delta_of_line() const;
+ /// Update the extended bbox.
+ void update_ebbox();
+
private: // Members
void copy_data(const line_info<L>& other);
@@ -189,81 +259,59 @@ namespace scribo
/// Update bbox and ebbox_ attributes.
void update_bbox_and_ebox(line_info<L>& other);
- /// Update the extended bbox.
- void update_ebbox();
-
mln::box2d merged_ebbox(const scribo::line_info<L>& info_l,
const scribo::line_info<L>& info);
void update_components_type(component::Type type);
private: // Attributes
- // WARNING: NEVER FORGET TO UPDATE COPY CONSTRUCTOR REDEFINITION!!!!
-
line_id_t id_;
- bool hidden_;
- line::Tag tag_;
- mln::box2d bbox_;
- mln::box2d ebbox_;
- mln::util::array<component_id_t> components_;
-
- // Values relative to the line bbox.
- int baseline_;
- int meanline_;
-
- // Values relative to the baseline.
- unsigned x_height_;
- int d_height_;
- int a_height_;
-
- // WARNING: NEVER FORGET TO UPDATE COPY CONSTRUCTOR REDEFINITION!!!!
-
- // Character related stats.
- unsigned char_space_;
- unsigned char_width_;
-
- // Words related stats.
- unsigned word_space_;
-
- // Reading direction
- line::ReadingDirection reading_direction_;
-
- // Line type
- line::Type type_;
+ mln::util::tracked_ptr<data_t> data_;
+ };
- // Is this line in reverse video?
- bool reverse_video_;
- // Text orientation
- float orientation_;
+ template <typename L>
+ std::ostream&
+ operator<<(std::ostream& ostr, const line_info<L>& info);
- // Text reading orientation
- float reading_orientation_;
- bool indented_;
+# ifndef MLN_INCLUDE_ONLY
- std::string text_;
+ namespace internal
+ {
- // Line set holding this element.
- line_set<L> holder_;
+ template <typename L>
+ line_info_data<L>::line_info_data()
+ {
+ hidden_ = false;
+ }
- // WARNING: NEVER FORGET TO UPDATE COPY CONSTRUCTOR REDEFINITION!!!!
- };
+ template <typename L>
+ line_info_data<L>::line_info_data(const line_set<L>& holder,
+ const mln::util::array<component_id_t>& comps)
+ : hidden_(false), tag_(line::None), components_(comps),
+ type_(line::Undefined), holder_(holder)
+ {
+ // FIXME: set valid information for these attributes in
+ // force_stats_update.
+ word_space_ = 0;
+ reading_direction_ = line::LeftToRight;
+ reverse_video_ = false;
- template <typename L>
- std::ostream&
- operator<<(std::ostream& ostr, const line_info<L>& info);
+ orientation_ = 0.;
+ reading_orientation_ = 0.;
+ indented_ = false;
+ }
-# ifndef MLN_INCLUDE_ONLY
+ } // end of namespace scribo::internal
template <typename L>
line_info<L>::line_info()
- : id_(0), hidden_(false)
+ : id_(0)
{
-
}
template <typename L>
@@ -275,47 +323,24 @@ namespace scribo
if (! is_valid())
id_ = other.id();
- hidden_ = other.hidden_;
-
- tag_ = other.tag();
- bbox_ = other.bbox();
- ebbox_ = other.ebbox();
- components_ = other.components();
-
- baseline_ = other.baseline();
- meanline_ = other.meanline();
-
- x_height_ = other.x_height();
- d_height_ = other.d_height();
- a_height_ = other.a_height();
-
- char_space_ = other.char_space();
- char_width_ = other.char_width();
-
- word_space_ = other.word_space();
-
- reading_direction_ = other.reading_direction();
-
- type_ = other.type();
-
- reverse_video_ = other.reverse_video();
-
- orientation_ = other.orientation();
-
- reading_orientation_ = other.reading_orientation();
-
- indented_ = other.indented();
+ data_ = other.data_;
+ }
- text_ = other.text();
- holder_ = other.holder();
+ template <typename L>
+ inline
+ line_info<L>::line_info(const line_id_t& id, data_t *data)
+ : id_(id), data_(data)
+ {
}
+
template <typename L>
inline
line_info<L>::line_info(const line_info<L>& other)
- : id_(0), hidden_(false)
+ : id_(0)
{
+ //data_->hidden_ = false;
copy_data(other);
}
@@ -357,22 +382,10 @@ namespace scribo
line_info<L>::line_info(const line_set<L>& holder,
const line_id_t& id,
const mln::util::array<component_id_t>& comps)
- : id_(id), hidden_(false), tag_(line::None), components_(comps),
- type_(line::Undefined), holder_(holder)
+ : id_(id)
{
-
+ data_ = new data_t(holder, comps);
force_stats_update();
-
- // FIXME: set valid information for these attributes in
- // force_stats_update.
- word_space_ = 0;
- reading_direction_ = line::LeftToRight;
- reverse_video_ = false;
-
- orientation_ = 0.;
- reading_orientation_ = 0.;
-
- indented_ = false;
}
@@ -397,7 +410,7 @@ namespace scribo
line::Tag
line_info<L>::tag() const
{
- return tag_;
+ return data_->tag_;
}
@@ -405,7 +418,7 @@ namespace scribo
void
line_info<L>::update_tag(line::Tag tag)
{
- tag_ = tag;
+ data_->tag_ = tag;
}
@@ -413,14 +426,14 @@ namespace scribo
const mln::box2d&
line_info<L>::bbox() const
{
- return bbox_;
+ return data_->bbox_;
}
template <typename L>
const mln::box2d&
line_info<L>::ebbox() const
{
- return ebbox_;
+ return data_->ebbox_;
}
@@ -428,14 +441,14 @@ namespace scribo
const mln::util::array<typename line_info<L>::component_id_t>&
line_info<L>::components() const
{
- return components_;
+ return data_->components_;
}
template <typename L>
unsigned
line_info<L>::card() const
{
- return components_.size();
+ return data_->components_.size();
}
@@ -443,7 +456,7 @@ namespace scribo
int
line_info<L>::baseline() const
{
- return baseline_;
+ return data_->baseline_;
}
@@ -451,7 +464,7 @@ namespace scribo
int
line_info<L>::meanline() const
{
- return meanline_;
+ return data_->meanline_;
}
@@ -459,7 +472,7 @@ namespace scribo
int
line_info<L>::ascent() const
{
- return baseline_ - a_height() + 1;
+ return data_->baseline_ - a_height() + 1;
}
@@ -467,7 +480,7 @@ namespace scribo
int
line_info<L>::descent() const
{
- return baseline_ - d_height();
+ return data_->baseline_ - d_height();
}
@@ -475,7 +488,7 @@ namespace scribo
unsigned
line_info<L>::x_height() const
{
- return x_height_;
+ return data_->x_height_;
}
@@ -483,7 +496,7 @@ namespace scribo
int
line_info<L>::d_height() const
{
- return d_height_;
+ return data_->d_height_;
}
@@ -491,7 +504,7 @@ namespace scribo
int
line_info<L>::a_height() const
{
- return a_height_;
+ return data_->a_height_;
}
@@ -499,7 +512,7 @@ namespace scribo
unsigned
line_info<L>::char_space() const
{
- return char_space_;
+ return data_->char_space_;
}
@@ -507,7 +520,7 @@ namespace scribo
unsigned
line_info<L>::char_width() const
{
- return char_width_;
+ return data_->char_width_;
}
@@ -515,7 +528,7 @@ namespace scribo
unsigned
line_info<L>::word_space() const
{
- return word_space_;
+ return data_->word_space_;
}
@@ -523,14 +536,14 @@ namespace scribo
line::ReadingDirection
line_info<L>::reading_direction() const
{
- return reading_direction_;
+ return data_->reading_direction_;
}
template <typename L>
line::Type
line_info<L>::type() const
{
- return type_;
+ return data_->type_;
}
@@ -538,10 +551,10 @@ namespace scribo
void
line_info<L>::update_components_type(component::Type type)
{
- for_all_elements(i, components_)
+ for_all_elements(i, data_->components_)
{
- unsigned c = components_[i];
- holder_.components_()(c).update_type(type);
+ unsigned c = data_->components_[i];
+ data_->holder_.components_()(c).update_type(type);
}
}
@@ -550,7 +563,7 @@ namespace scribo
void
line_info<L>::update_type(line::Type type)
{
- type_ = type;
+ data_->type_ = type;
// Some line types may involve updating components type as well.
if (type == line::Punctuation)
@@ -564,7 +577,7 @@ namespace scribo
bool
line_info<L>::reverse_video() const
{
- return reverse_video_;
+ return data_->reverse_video_;
}
@@ -572,7 +585,7 @@ namespace scribo
float
line_info<L>::orientation() const
{
- return orientation_;
+ return data_->orientation_;
}
@@ -580,7 +593,7 @@ namespace scribo
float
line_info<L>::reading_orientation() const
{
- return reading_orientation_;
+ return data_->reading_orientation_;
}
@@ -588,21 +601,21 @@ namespace scribo
bool
line_info<L>::indented() const
{
- return indented_;
+ return data_->indented_;
}
template <typename L>
bool
line_info<L>::has_text() const
{
- return !text_.empty();
+ return !data_->text_.empty();
}
template <typename L>
const std::string&
line_info<L>::text() const
{
- return text_;
+ return data_->text_;
}
@@ -610,7 +623,7 @@ namespace scribo
void
line_info<L>::update_text(const std::string& str)
{
- text_ = str;
+ data_->text_ = str;
}
@@ -624,9 +637,19 @@ namespace scribo
template <typename L>
bool
+ line_info<L>::is_textline() const
+ {
+ return is_valid()
+ && !is_hidden()
+ && type() == line::Text;
+ }
+
+
+ template <typename L>
+ bool
line_info<L>::is_hidden() const
{
- return hidden_;
+ return data_->hidden_;
}
@@ -634,7 +657,7 @@ namespace scribo
void
line_info<L>::set_hidden(bool b)
{
- hidden_ = b;
+ data_->hidden_ = b;
}
@@ -665,8 +688,8 @@ namespace scribo
void
line_info<L>::update_ebbox()
{
- int A = a_height_ - x_height_;
- int D = - d_height_;
+ int A = data_->a_height_ - data_->x_height_;
+ int D = - data_->d_height_;
if (A <= 2 && D > 2)
A = D;
if (D <= 2 && A > 2)
@@ -674,10 +697,12 @@ namespace scribo
int delta = delta_of_line();
- ebbox_ = mln::make::box2d(meanline_ - A, bbox().pmin().col() - delta,
- baseline_ + D, bbox().pmax().col() + delta);
+ data_->ebbox_ = mln::make::box2d(data_->meanline_ - A,
+ bbox().pmin().col() - delta,
+ data_->baseline_ + D,
+ bbox().pmax().col() + delta);
- ebbox_.crop_wrt(holder_.components().labeled_image().domain());
+ data_->ebbox_.crop_wrt(data_->holder_.components().labeled_image().domain());
}
@@ -729,20 +754,20 @@ namespace scribo
// Adjusting ebboxes with the highest delta and merging ebboxes.
int d_delta = other.delta_of_line() - this->delta_of_line();
if (d_delta < 0) // other.delta_of_line() < this->delta_of_line()
- ebbox_.merge(enlarge(other.ebbox(), - d_delta));
+ data_->ebbox_.merge(enlarge(other.ebbox(), - d_delta));
else
{
- mln::box2d b = ebbox_;
- ebbox_ = other.bbox();
- ebbox_.merge(enlarge(b, d_delta));
+ mln::box2d b = data_->ebbox_;
+ data_->ebbox_ = other.bbox();
+ data_->ebbox_.merge(enlarge(b, d_delta));
}
- ebbox_.crop_wrt(holder_.components().labeled_image().domain());
+ data_->ebbox_.crop_wrt(data_->holder_.components().labeled_image().domain());
}
else // /other/ IS NOT a text line.
{
- ebbox_.merge(other.ebbox());
- ebbox_.merge(merged_ebbox(*this, other));
+ data_->ebbox_.merge(other.ebbox());
+ data_->ebbox_.merge(merged_ebbox(*this, other));
}
}
else // /this/ is NOT a text line
@@ -755,15 +780,15 @@ namespace scribo
}
update_type(line::Text);
- ebbox_.merge(other.ebbox());
- ebbox_.merge(merged_ebbox(other, *this));
+ data_->ebbox_.merge(other.ebbox());
+ data_->ebbox_.merge(merged_ebbox(other, *this));
}
// Merging bboxes.
- bbox_.merge(other.bbox());
+ data_->bbox_.merge(other.bbox());
// Make sure the ebbox is included in the image domain.
- ebbox_.crop_wrt(holder_.components().labeled_image().domain());
+ data_->ebbox_.crop_wrt(data_->holder_.components().labeled_image().domain());
}
@@ -771,14 +796,14 @@ namespace scribo
void
line_info<L>::fast_merge(line_info<L>& other, bool hide)
{
- tag_ = line::Needs_Precise_Stats_Update;
+ data_->tag_ = line::Needs_Precise_Stats_Update;
other.update_tag(line::Merged);
other.set_hidden(hide);
// Update bbox and ebbox
update_bbox_and_ebox(other);
- components_.append(other.components());
+ data_->components_.append(other.components());
}
@@ -795,7 +820,7 @@ namespace scribo
line_info<L>::force_stats_update()
{
typedef mln_site(L) P;
- const component_set<L>& comp_set = holder_.components();
+ const component_set<L>& comp_set = data_->holder_.components();
// Init.
typedef mln::value::int_u<12> median_data_t;
@@ -814,21 +839,21 @@ namespace scribo
// Workaround to avoid overflow with int_u<12> in median accumulators.
//
// FIXME: not optimal...
- for_all_elements(i, components_)
+ for_all_elements(i, data_->components_)
{
- unsigned c = components_(i);
+ unsigned c = data_->components_(i);
// Ignore punctuation for stats computation but not for bbox
// computation.
- if (holder_.components()(c).type() == component::Punctuation)
+ if (data_->holder_.components()(c).type() == component::Punctuation)
continue;
ref_line = mln::math::min(comp_set(c).bbox().pmin().row(), ref_line);
}
- for_all_elements(i, components_)
+ for_all_elements(i, data_->components_)
{
- unsigned c = components_(i);
+ unsigned c = data_->components_(i);
const mln::box2d& bb = comp_set(c).bbox();
@@ -837,7 +862,7 @@ namespace scribo
// Ignore punctuation for stats computation but not for bbox
// computation.
- if (holder_.components()(c).type() == component::Punctuation)
+ if (data_->holder_.components()(c).type() == component::Punctuation)
continue;
@@ -853,11 +878,11 @@ namespace scribo
// (right link) (left link)
// Space between characters.
- if (holder_.links()(c) != c)
+ if (data_->holder_.links()(c) != c)
{
int
space = bb.pmin().col()
- - comp_set(holder_.links()(c)).bbox().pmax().col() - 1;
+ - comp_set(data_->holder_.links()(c)).bbox().pmax().col() - 1;
// -- Ignore overlapped characters.
if (space > 0)
@@ -884,31 +909,31 @@ namespace scribo
// Finalization
{
- tag_ = line::None;
- bbox_ = bbox.to_result();
+ data_->tag_ = line::None;
+ data_->bbox_ = bbox.to_result();
// Char space
if (char_space.card() < 2)
- char_space_ = 0;
+ data_->char_space_ = 0;
else
- char_space_ = char_space.to_result();
+ data_->char_space_ = char_space.to_result();
// Char width
if (card() == 2)
- char_width_ = (comp_set(components_[0]).bbox().width()
- + comp_set(components_[1]).bbox().width()) / 2;
+ data_->char_width_ = (comp_set(data_->components_[0]).bbox().width()
+ + comp_set(data_->components_[1]).bbox().width()) / 2;
else
- char_width_ = char_width.to_result();
+ data_->char_width_ = char_width.to_result();
mln::def::coord
absolute_baseline_r = baseline.to_result() + ref_line,
absolute_meanline_r = meanline.to_result() + ref_line;
- baseline_ = absolute_baseline_r;
- meanline_ = absolute_meanline_r;
- x_height_ = baseline_ - meanline_ + 1;
- d_height_ = baseline_ - bbox.to_result().pmax().row();
- a_height_ = baseline_ - bbox.to_result().pmin().row() + 1;
+ data_->baseline_ = absolute_baseline_r;
+ data_->meanline_ = absolute_meanline_r;
+ data_->x_height_ = data_->baseline_ - data_->meanline_ + 1;
+ data_->d_height_ = data_->baseline_ - bbox.to_result().pmax().row();
+ data_->a_height_ = data_->baseline_ - bbox.to_result().pmin().row() + 1;
//FIXME
//
@@ -929,7 +954,7 @@ namespace scribo
const line_set<L>&
line_info<L>::holder() const
{
- return holder_;
+ return data_->holder_;
}
diff --git a/scribo/scribo/core/line_links.hh b/scribo/scribo/core/line_links.hh
index 85c45e8..de62158 100644
--- a/scribo/scribo/core/line_links.hh
+++ b/scribo/scribo/core/line_links.hh
@@ -139,8 +139,8 @@ namespace scribo
template <typename L>
line_links<L>::line_links()
+ : data_(0)
{
- data_ = new data_t();
}
diff --git a/scribo/scribo/core/line_set.hh b/scribo/scribo/core/line_set.hh
index 29795b2..bfa9240 100644
--- a/scribo/scribo/core/line_set.hh
+++ b/scribo/scribo/core/line_set.hh
@@ -99,6 +99,10 @@ namespace scribo
/// Constructor from object groups.
line_set(const object_groups<L>& groups);
+
+ /// Constructor useful for delayed construction (loading from file).
+ line_set(const object_groups<L>& groups,
+ const mln::util::array<line_info<L> >& line_data);
/// @}
/// Compute line stats and fill the underlying information.
@@ -155,8 +159,14 @@ namespace scribo
/// @}
+ /// Return false if it is not initialized (built with the default
+ /// constructor).
bool is_valid() const;
+
+ void update_line_data_(const mln::util::array<line_info<L> >&
line_data);
+
+
private:
/// Duplicate the underlying image and create a new line_set.
void init_(const line_set<L>& model);
@@ -233,6 +243,15 @@ namespace scribo
template <typename L>
+ inline
+ line_set<L>::line_set(const object_groups<L>& groups,
+ const mln::util::array<line_info<L> >& line_data)
+ {
+ data_ = new internal::line_set_data<L>(line_data, groups);
+ }
+
+
+ template <typename L>
void
line_set<L>::compute_lines(const object_groups<L>& groups)
{
@@ -396,7 +415,15 @@ namespace scribo
bool
line_set<L>::is_valid() const
{
- return data_->links_.is_valid() && data_->groups_.is_valid();
+ return data_ && data_->groups_.is_valid();
+ }
+
+ template <typename L>
+ inline
+ void
+ line_set<L>::update_line_data_(const mln::util::array<line_info<L>
>& line_data)
+ {
+ data_->infos_ = line_data;
}
template <typename L>
diff --git a/scribo/scribo/core/paragraph_info.hh b/scribo/scribo/core/paragraph_info.hh
index a8c623a..17f847f 100644
--- a/scribo/scribo/core/paragraph_info.hh
+++ b/scribo/scribo/core/paragraph_info.hh
@@ -113,6 +113,16 @@ namespace scribo
}
+ template <typename L>
+ std::ostream&
+ operator<<(std::ostream& ostr, const paragraph_info<L>& info)
+ {
+ return ostr << "paragraph_info("
+ << "line_ids=" << info.line_ids()
+ << ", bbox=" << info.bbox()
+ << ")" << std::endl;
+ }
+
# endif // ! MLN_INCLUDE_ONLY
} // end of namespace scribo
diff --git a/scribo/scribo/core/paragraph_set.hh b/scribo/scribo/core/paragraph_set.hh
index 355eaa9..6597189 100644
--- a/scribo/scribo/core/paragraph_set.hh
+++ b/scribo/scribo/core/paragraph_set.hh
@@ -36,6 +36,25 @@
namespace scribo
{
+ namespace internal
+ {
+
+ /// Data structure for \c scribo::paragraph_set<I>.
+ template <typename L>
+ struct paragraph_set_data
+ {
+ paragraph_set_data();
+ paragraph_set_data(const line_links<L>& llines, unsigned npars);
+
+ mln::util::array<paragraph_info<L> > pars_;
+ line_set<L> lines_;
+ line_links<L> links_;
+ };
+
+ } // end of namespace scribo::internal
+
+
+
/*! \brief Paragraph container.
Paragraph ids start from 1.
@@ -46,6 +65,7 @@ namespace scribo
{
public:
paragraph_set();
+ paragraph_set(internal::paragraph_set_data<L>* data);
paragraph_set(const line_links<L>& llinks, unsigned npars);
unsigned nelements() const;
@@ -57,9 +77,10 @@ namespace scribo
const line_set<L>& lines() const;
+ const line_links<L>& links() const;
+
private:
- mln::util::array<paragraph_info<L> > pars_;
- line_set<L> lines_;
+ mln::util::tracked_ptr< internal::paragraph_set_data<L> > data_;
};
@@ -77,37 +98,72 @@ namespace scribo
# ifndef MLN_INCLUDE_ONLY
+ // paragraph_set_data<L> >
+
+ namespace internal
+ {
+
+ // data< paragraph_set<L> >
+
+
+ template <typename L>
+ inline
+ paragraph_set_data<L>::paragraph_set_data()
+ {
+ }
+
+
+ template <typename L>
+ inline
+ paragraph_set_data<L>::paragraph_set_data(const line_links<L>&
llinks, unsigned npars)
+ : pars_(npars + 1, paragraph_info<L>(llinks)), links_(llinks)
+ {
+ lines_ = llinks.lines();
+ }
+
+ } // end of namespace mln::internal
+
+
template <typename L>
paragraph_set<L>::paragraph_set()
+ : data_(0)
{
}
template <typename L>
+ paragraph_set<L>::paragraph_set(internal::paragraph_set_data<L>* data)
+ {
+ data_ = data;
+ }
+
+ template <typename L>
paragraph_set<L>::paragraph_set(const line_links<L>& llinks, unsigned
npars)
- : pars_(npars + 1, paragraph_info<L>(llinks))
{
- lines_ = llinks.lines();
+ data_ = new internal::paragraph_set_data<L>(llinks, npars);
}
template <typename L>
unsigned
paragraph_set<L>::nelements() const
{
- return pars_.nelements() - 1;
+ mln_precondition(data_ != 0);
+ return data_->pars_.nelements() - 1;
}
template <typename L>
paragraph_info<L>&
paragraph_set<L>::operator()(unsigned i)
{
- return pars_[i];
+ mln_precondition(data_ != 0);
+ return data_->pars_[i];
}
template <typename L>
const paragraph_info<L>&
paragraph_set<L>::operator()(unsigned i) const
{
- return pars_[i];
+ mln_precondition(data_ != 0);
+ return data_->pars_[i];
}
@@ -115,7 +171,7 @@ namespace scribo
bool
paragraph_set<L>::is_valid() const
{
- return !pars_.is_empty();
+ return data_ && !data_->pars_.is_empty();
}
@@ -123,7 +179,17 @@ namespace scribo
const line_set<L>&
paragraph_set<L>::lines() const
{
- return lines_;
+ mln_precondition(data_ != 0);
+ return data_->lines_;
+ }
+
+
+ template <typename L>
+ const line_links<L>&
+ paragraph_set<L>::links() const
+ {
+ mln_precondition(data_ != 0);
+ return data_->links_;
}
--
1.5.6.5