* scribo/filter/images_in_paragraph.hh,
* scribo/filter/paragraphs_bbox_overlap.hh,
* scribo/filter/paragraphs_in_image.hh,
* scribo/filter/separators_in_element.hh,
* scribo/filter/separators_in_paragraph.hh: New.
---
scribo/ChangeLog | 10 ++
scribo/scribo/filter/images_in_paragraph.hh | 119 +++++++++++++++
scribo/scribo/filter/paragraphs_bbox_overlap.hh | 176 +++++++++++++++++++++++
scribo/scribo/filter/paragraphs_in_image.hh | 129 +++++++++++++++++
scribo/scribo/filter/separators_in_element.hh | 151 +++++++++++++++++++
scribo/scribo/filter/separators_in_paragraph.hh | 151 +++++++++++++++++++
6 files changed, 736 insertions(+), 0 deletions(-)
create mode 100644 scribo/scribo/filter/images_in_paragraph.hh
create mode 100644 scribo/scribo/filter/paragraphs_bbox_overlap.hh
create mode 100644 scribo/scribo/filter/paragraphs_in_image.hh
create mode 100644 scribo/scribo/filter/separators_in_element.hh
create mode 100644 scribo/scribo/filter/separators_in_paragraph.hh
diff --git a/scribo/ChangeLog b/scribo/ChangeLog
index 959746f..16762ae 100644
--- a/scribo/ChangeLog
+++ b/scribo/ChangeLog
@@ -1,5 +1,15 @@
2011-05-26 Guillaume Lazzara <z(a)lrde.epita.fr>
+ Add new element filters.
+
+ * scribo/filter/images_in_paragraph.hh,
+ * scribo/filter/paragraphs_bbox_overlap.hh,
+ * scribo/filter/paragraphs_in_image.hh,
+ * scribo/filter/separators_in_element.hh,
+ * scribo/filter/separators_in_paragraph.hh: New.
+
+2011-05-26 Guillaume Lazzara <z(a)lrde.epita.fr>
+
Add util::box_intersection.
* scribo/util/box_intersection.hh: New.
diff --git a/scribo/scribo/filter/images_in_paragraph.hh
b/scribo/scribo/filter/images_in_paragraph.hh
new file mode 100644
index 0000000..e05b202
--- /dev/null
+++ b/scribo/scribo/filter/images_in_paragraph.hh
@@ -0,0 +1,119 @@
+// Copyright (C) 2011 EPITA Research and Development Laboratory (LRDE)
+//
+// This file is part of Olena.
+//
+// Olena is free software: you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation, version 2 of the License.
+//
+// Olena is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with Olena. If not, see <http://www.gnu.org/licenses/>.
+//
+// As a special exception, you may use this file as part of a free
+// software project without restriction. Specifically, if other files
+// instantiate templates or use macros or inline functions from this
+// file, or you compile this file and link it with other files to produce
+// an executable, this file does not by itself cause the resulting
+// executable to be covered by the GNU General Public License. This
+// exception does not however invalidate any other reasons why the
+// executable file might be covered by the GNU General Public License.
+
+#ifndef SCRIBO_FILTER_IMAGES_IN_PARAGRAPH_HH
+# define SCRIBO_FILTER_IMAGES_IN_PARAGRAPH_HH
+
+/// \file
+///
+/// Invalidate false positive separators.
+/// \fixme Share same test canvas as text::merging.
+
+
+# include <mln/core/concept/image.hh>
+# include <scribo/core/component_set.hh>
+# include <scribo/core/document.hh>
+
+
+namespace scribo
+{
+
+ namespace filter
+ {
+
+ using namespace mln;
+
+
+ /// Invalidate false positive separators.
+ ///
+ /// \param[in] separators A paragraph set.
+ ///
+ /// \return A doc with invalidated separators.
+ ///
+ /// Warning: it does not remove separators from separator
+ /// image. It only invalidate separator components in their
+ /// respective component_set.
+ ///
+ template <typename L>
+ void
+ images_in_paragraph(document<L>& doc);
+
+
+# ifndef MLN_INCLUDE_ONLY
+
+ template <typename L>
+ void
+ images_in_paragraph(document<L>& doc)
+ {
+ trace::entering("scribo::filter::images_in_paragraph");
+
+ mln_precondition(doc.is_valid());
+
+ if (! doc.has_elements())
+ return;
+
+ mln_ch_value(L,bool) billboard;
+ initialize(billboard, doc.image());
+ data::fill(billboard, false);
+
+ for_all_comps(p, doc.paragraphs())
+ if (doc.paragraphs()(p).is_valid())
+ mln::draw::box_plain(billboard, doc.paragraphs()(p).bbox(), true);
+
+
+ component_set<L> elts = doc.elements();
+ for_all_comps(c, elts)
+ if (elts(c).is_valid() && elts(c).type() == component::Image)
+ {
+ const mln_box(L)& b_ = elts(c).bbox();
+
+ const bool tl = billboard(b_.pmin());
+ const bool tr = billboard.at_(b_.pmin().row(), b_.pmax().col());
+ const bool ml = billboard.at_(b_.pcenter().row(), b_.pmin().col());
+ const bool mc = billboard.at_(b_.pcenter().row(), b_.pcenter().col());
+ const bool mr = billboard.at_(b_.pcenter().row(), b_.pmax().col());
+ const bool bl = billboard.at_(b_.pmax().row(), b_.pmin().col());
+ const bool br = billboard(b_.pmax());
+
+ // This separator is included in an element (picture, drawing...)
+ // => Ignore it.
+ if (tl && tr && ml && mc && mr && bl
&& br)
+ elts(c).update_tag(component::Ignored);
+
+ // FIXME: warning this call may produce inconsistent data
+ // Ignored components are still in the separator image...
+ doc.set_elements(elts);
+ }
+
+ trace::exiting("scribo::filter::images_in_paragraph");
+ }
+
+# endif // ! MLN_INCLUDE_ONLY
+
+ } // end of namespace scribo::filter
+
+} // end of namespace scribo
+
+#endif // ! SCRIBO_FILTER_IMAGES_IN_PARAGRAPH_HH
diff --git a/scribo/scribo/filter/paragraphs_bbox_overlap.hh
b/scribo/scribo/filter/paragraphs_bbox_overlap.hh
new file mode 100644
index 0000000..aa1c8ac
--- /dev/null
+++ b/scribo/scribo/filter/paragraphs_bbox_overlap.hh
@@ -0,0 +1,176 @@
+// Copyright (C) 2011 EPITA Research and Development Laboratory (LRDE)
+//
+// This file is part of Olena.
+//
+// Olena is free software: you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation, version 2 of the License.
+//
+// Olena is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with Olena. If not, see <http://www.gnu.org/licenses/>.
+//
+// As a special exception, you may use this file as part of a free
+// software project without restriction. Specifically, if other files
+// instantiate templates or use macros or inline functions from this
+// file, or you compile this file and link it with other files to produce
+// an executable, this file does not by itself cause the resulting
+// executable to be covered by the GNU General Public License. This
+// exception does not however invalidate any other reasons why the
+// executable file might be covered by the GNU General Public License.
+
+#ifndef SCRIBO_FILTER_PARAGRAPHS_BBOX_OVERLAP_HH
+# define SCRIBO_FILTER_PARAGRAPHS_BBOX_OVERLAP_HH
+
+/// \file
+///
+/// Remove invalid paragraphs.
+/// \fixme Share same test canvas as text::merging.
+
+
+# include <mln/core/concept/image.hh>
+# include <mln/core/concept/neighborhood.hh>
+# include <mln/core/concept/function.hh>
+# include <mln/core/image/dmorph/image_if.hh>
+# include <mln/data/transform.hh>
+# include <mln/util/array.hh>
+
+# include <scribo/core/paragraph_set.hh>
+
+
+namespace scribo
+{
+
+ namespace filter
+ {
+
+ using namespace mln;
+
+
+ /// Remove invalid paragraphs.
+ ///
+ /// \param[in] paragraphs A paragraph set.
+ ///
+ /// \return A paragraph set with invalid paragraphs tag set to
+ /// Paragraph::Ignored.
+ template <typename L>
+ paragraph_set<L>
+ paragraphs_bbox_overlap(const paragraph_set<L>& paragraphs);
+
+
+# ifndef MLN_INCLUDE_ONLY
+
+ namespace internal
+ {
+
+ template <typename L>
+ struct order_paragraphs_id
+ {
+ order_paragraphs_id(const scribo::paragraph_set<L>& paragraphs)
+ : paragraphs_(paragraphs)
+ {
+ }
+
+ bool operator()(const scribo::paragraph_id_t& l1,
+ const scribo::paragraph_id_t& l2) const
+ {
+ const unsigned l1_nsites = paragraphs_(l1).bbox().nsites();
+ const unsigned l2_nsites = paragraphs_(l2).bbox().nsites();
+
+ if (l1_nsites == l2_nsites)
+ return l1 > l2;
+ return l1_nsites > l2_nsites;
+ }
+
+ scribo::paragraph_set<L> paragraphs_;
+ };
+
+ } // end of namespace scribo::filter::internal
+
+
+ template <typename L>
+ paragraph_set<L>
+ paragraphs_bbox_overlap(const paragraph_set<L>& paragraphs)
+ {
+ trace::entering("scribo::filter::paragraphs_bbox_overlap");
+
+ mln_precondition(paragraphs.is_valid());
+
+ L billboard;
+ initialize(billboard, paragraphs.lines().components().labeled_image());
+ data::fill(billboard, 0);
+
+ mln::util::array<bool> not_to_ignore(paragraphs.nelements() + 1, true);
+ not_to_ignore(0) = false;
+
+ for_all_paragraphs(cur_id, paragraphs)
+ {
+ const box2d& b_ = paragraphs(cur_id).bbox();
+
+ if (paragraphs(cur_id).nlines() > 1)
+ {
+ mln::draw::box_plain(billboard, b_, cur_id);
+ continue;
+ }
+
+ const unsigned tl = billboard(b_.pmin());
+ const unsigned tr = billboard.at_(b_.pmin().row(), b_.pmax().col());
+ const unsigned ml = billboard.at_(b_.pcenter().row(), b_.pmin().col());
+ const unsigned mc = billboard.at_(b_.pcenter().row(), b_.pcenter().col());
+ const unsigned mr = billboard.at_(b_.pcenter().row(), b_.pmax().col());
+ const unsigned bl = billboard.at_(b_.pmax().row(), b_.pmin().col());
+ const unsigned br = billboard(b_.pmax());
+
+ typedef std::set<unsigned> set_t;
+ set_t labels;
+ labels.insert(tl);
+ labels.insert(tl);
+ labels.insert(tr);
+ labels.insert(ml);
+ labels.insert(mc);
+ labels.insert(mr);
+ labels.insert(bl);
+ labels.insert(br);
+
+ for (set_t::const_iterator it = labels.begin();
+ it != labels.end();
+ ++it)
+ if (not_to_ignore(*it))
+ {
+ box2d b2 = paragraphs(*it).bbox();
+ box2d b_i = scribo::util::box_intersection(b_, b2);
+
+ // si b_ est inclus dans une boite donc le nombre de comp > 1 => invalid juste
b_
+ // sinon => invalid b_ et b2
+ if ((b_i.nsites() / (float)b_.nsites() > 0.4
+ || (b_i.nsites() / (float)b2.nsites()) > 0.9))
+ {
+ not_to_ignore(cur_id) = false;
+
+ if (paragraphs(*it).nlines() < 4)
+ not_to_ignore(*it) = false;
+ }
+ }
+
+ mln::draw::box_plain(billboard, b_, cur_id);
+ }
+
+ paragraph_set<L> output = paragraphs.duplicate();
+ output.invalidate(not_to_ignore);
+
+ trace::exiting("scribo::filter::paragraphs_bbox_overlap");
+ return output;
+ }
+
+
+# endif // ! MLN_INCLUDE_ONLY
+
+ } // end of namespace scribo::filter
+
+} // end of namespace scribo
+
+#endif // ! SCRIBO_FILTER_PARAGRAPHS_BBOX_OVERLAP_HH
diff --git a/scribo/scribo/filter/paragraphs_in_image.hh
b/scribo/scribo/filter/paragraphs_in_image.hh
new file mode 100644
index 0000000..1029430
--- /dev/null
+++ b/scribo/scribo/filter/paragraphs_in_image.hh
@@ -0,0 +1,129 @@
+// Copyright (C) 2011 EPITA Research and Development Laboratory (LRDE)
+//
+// This file is part of Olena.
+//
+// Olena is free software: you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation, version 2 of the License.
+//
+// Olena is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with Olena. If not, see <http://www.gnu.org/licenses/>.
+//
+// As a special exception, you may use this file as part of a free
+// software project without restriction. Specifically, if other files
+// instantiate templates or use macros or inline functions from this
+// file, or you compile this file and link it with other files to produce
+// an executable, this file does not by itself cause the resulting
+// executable to be covered by the GNU General Public License. This
+// exception does not however invalidate any other reasons why the
+// executable file might be covered by the GNU General Public License.
+
+#ifndef SCRIBO_FILTER_PARAGRAPHS_IN_IMAGE_HH
+# define SCRIBO_FILTER_PARAGRAPHS_IN_IMAGE_HH
+
+/// \file
+///
+/// Remove invalid paragraphs.
+/// \fixme Share same test canvas as text::merging.
+
+
+# include <mln/core/concept/image.hh>
+# include <mln/core/concept/neighborhood.hh>
+# include <mln/core/concept/function.hh>
+# include <mln/core/image/dmorph/image_if.hh>
+
+# include <mln/data/transform.hh>
+
+# include <mln/util/array.hh>
+
+# include <mln/pw/all.hh>
+
+# include <scribo/core/paragraph_set.hh>
+# include <scribo/fun/v2b/objects_small_filter.hh>
+# include <scribo/primitive/extract/components.hh>
+
+
+namespace scribo
+{
+
+ namespace filter
+ {
+
+ using namespace mln;
+
+
+ /// Remove invalid paragraphs.
+ ///
+ /// \param[in] paragraphs A paragraph set.
+ ///
+ /// \return A paragraph set with invalid paragraphs tag set to
+ /// Paragraph::Ignored.
+ template <typename L>
+ void
+ paragraphs_in_image(document<L>& doc);
+
+
+# ifndef MLN_INCLUDE_ONLY
+
+ template <typename L>
+ void
+ paragraphs_in_image(document<L>& doc)
+ {
+ trace::entering("scribo::filter::paragraphs_in_image");
+
+ mln_precondition(doc.has_elements());
+ mln_precondition(doc.has_text());
+
+ image2d<bool> billboard;
+ initialize(billboard, doc.lines().components().labeled_image());
+ data::fill(billboard, false);
+
+ // Draw Image bboxes.
+ for_all_elements(e, doc.elements())
+ if (doc.elements()(e).is_valid()
+ && doc.elements()(e).type() == component::Image)
+ mln::draw::box_plain(billboard, doc.elements()(e).bbox(), true);
+
+ mln::io::pbm::save(billboard, "billboard_parimage.pbm");
+
+ const paragraph_set<L>& parset = doc.paragraphs();
+ mln::util::array<bool> not_to_ignore(parset.nelements() + 1, true);
+ not_to_ignore(0) = false;
+
+ for_all_paragraphs(cur_id, parset)
+ {
+ const box2d& b_ = parset(cur_id).bbox();
+ const bool
+ tl = billboard(b_.pmin()),
+ tr = billboard.at_(b_.pmin().row(), b_.pmax().col()),
+ ml = billboard.at_(b_.pcenter().row(), b_.pmin().col()),
+ mc = billboard.at_(b_.pcenter().row(), b_.pcenter().col()),
+ mr = billboard.at_(b_.pcenter().row(), b_.pmax().col()),
+ bl = billboard.at_(b_.pmax().row(), b_.pmin().col()),
+ br = billboard(b_.pmax());
+
+ // The paragraph is fully included in an image.
+ if (tl && tr && ml && mc && mr && bl &&
br)
+ not_to_ignore(cur_id) = false;
+ }
+
+ paragraph_set<L> output = parset.duplicate();
+ output.invalidate(not_to_ignore);
+ doc.set_paragraphs(output);
+
+ trace::exiting("scribo::filter::paragraphs_in_image");
+ }
+
+
+# endif // ! MLN_INCLUDE_ONLY
+
+ } // end of namespace scribo::filter
+
+} // end of namespace scribo
+
+#endif // ! SCRIBO_FILTER_PARAGRAPHS_IN_IMAGE_HH
diff --git a/scribo/scribo/filter/separators_in_element.hh
b/scribo/scribo/filter/separators_in_element.hh
new file mode 100644
index 0000000..228d82f
--- /dev/null
+++ b/scribo/scribo/filter/separators_in_element.hh
@@ -0,0 +1,151 @@
+// Copyright (C) 2011 EPITA Research and Development Laboratory (LRDE)
+//
+// This file is part of Olena.
+//
+// Olena is free software: you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation, version 2 of the License.
+//
+// Olena is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with Olena. If not, see <http://www.gnu.org/licenses/>.
+//
+// As a special exception, you may use this file as part of a free
+// software project without restriction. Specifically, if other files
+// instantiate templates or use macros or inline functions from this
+// file, or you compile this file and link it with other files to produce
+// an executable, this file does not by itself cause the resulting
+// executable to be covered by the GNU General Public License. This
+// exception does not however invalidate any other reasons why the
+// executable file might be covered by the GNU General Public License.
+
+#ifndef SCRIBO_FILTER_SEPARATORS_IN_ELEMENT_HH
+# define SCRIBO_FILTER_SEPARATORS_IN_ELEMENT_HH
+
+/// \file
+///
+/// Invalidate false positive separators.
+/// \fixme Share same test canvas as text::merging.
+
+
+# include <mln/core/concept/image.hh>
+# include <scribo/core/component_set.hh>
+# include <scribo/core/document.hh>
+
+
+namespace scribo
+{
+
+ namespace filter
+ {
+
+ using namespace mln;
+
+
+ /// Invalidate false positive separators.
+ ///
+ /// \param[in] separators A paragraph set.
+ ///
+ /// \return A doc with invalidated separators.
+ ///
+ /// Warning: it does not remove separators from separator
+ /// image. It only invalidate separator components in their
+ /// respective component_set.
+ ///
+ template <typename L>
+ void
+ separators_in_element(document<L>& doc);
+
+
+# ifndef MLN_INCLUDE_ONLY
+
+ template <typename L>
+ void
+ separators_in_element(document<L>& doc)
+ {
+ trace::entering("scribo::filter::separators_in_element");
+
+ mln_precondition(doc.is_valid());
+ mln_precondition(doc.has_elements());
+ mln_precondition(doc.has_hline_seps() || doc.has_vline_seps());
+
+ if ((doc.has_hline_seps() && !doc.hline_seps_comps().nelements())
+ && (doc.has_vline_seps() && !doc.vline_seps_comps().nelements()))
+ return;
+
+ mln_ch_value(L,bool) billboard;
+ initialize(billboard, doc.image());
+ data::fill(billboard, false);
+
+ for_all_comps(e, doc.elements())
+ if (doc.elements()(e).is_valid())
+ mln::draw::box_plain(billboard, doc.elements()(e).bbox(), true);
+
+ // Horizontal separators
+ if (doc.has_hline_seps())
+ {
+ component_set<L> hline = doc.hline_seps_comps().duplicate();
+ for_all_comps(c, hline)
+ {
+ const mln_box(L)& b_ = hline(c).bbox();
+
+ const bool tl = billboard(b_.pmin());
+ const bool tr = billboard.at_(b_.pmin().row(), b_.pmax().col());
+ const bool ml = billboard.at_(b_.pcenter().row(), b_.pmin().col());
+ const bool mc = billboard.at_(b_.pcenter().row(), b_.pcenter().col());
+ const bool mr = billboard.at_(b_.pcenter().row(), b_.pmax().col());
+ const bool bl = billboard.at_(b_.pmax().row(), b_.pmin().col());
+ const bool br = billboard(b_.pmax());
+
+ // This separator is included in an element (picture, drawing...)
+ // => Ignore it.
+ if (tl && tr && ml && mc && mr && bl
&& br)
+ hline(c).update_tag(component::Ignored);
+
+ // FIXME: warning this call may produce inconsistent data
+ // Ignored components are still in the separator image...
+ doc.set_hline_separators(doc.hline_seps(), hline);
+ }
+ }
+
+ // Vertical separators
+ if (doc.has_vline_seps())
+ {
+ component_set<L> vline = doc.vline_seps_comps().duplicate();
+ for_all_comps(c, vline)
+ {
+ const mln_box(L)& b_ = vline(c).bbox();
+
+ const bool tl = billboard(b_.pmin());
+ const bool tr = billboard.at_(b_.pmin().row(), b_.pmax().col());
+ const bool ml = billboard.at_(b_.pcenter().row(), b_.pmin().col());
+ const bool mc = billboard.at_(b_.pcenter().row(), b_.pcenter().col());
+ const bool mr = billboard.at_(b_.pcenter().row(), b_.pmax().col());
+ const bool bl = billboard.at_(b_.pmax().row(), b_.pmin().col());
+ const bool br = billboard(b_.pmax());
+
+ // This separator is included in an element (picture, drawing...)
+ // => Ignore it.
+ if (tl && tr && ml && mc && mr && bl
&& br)
+ vline(c).update_tag(component::Ignored);
+
+ // FIXME: warning this call may produce inconsistent data
+ // Ignored components are still in the separator image...
+ doc.set_vline_separators(doc.vline_seps(), vline);
+ }
+
+ trace::exiting("scribo::filter::separators_in_element");
+ }
+ }
+
+# endif // ! MLN_INCLUDE_ONLY
+
+ } // end of namespace scribo::filter
+
+} // end of namespace scribo
+
+#endif // ! SCRIBO_FILTER_SEPARATORS_IN_ELEMENT_HH
diff --git a/scribo/scribo/filter/separators_in_paragraph.hh
b/scribo/scribo/filter/separators_in_paragraph.hh
new file mode 100644
index 0000000..3e7a150
--- /dev/null
+++ b/scribo/scribo/filter/separators_in_paragraph.hh
@@ -0,0 +1,151 @@
+// Copyright (C) 2011 EPITA Research and Development Laboratory (LRDE)
+//
+// This file is part of Olena.
+//
+// Olena is free software: you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation, version 2 of the License.
+//
+// Olena is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with Olena. If not, see <http://www.gnu.org/licenses/>.
+//
+// As a special exception, you may use this file as part of a free
+// software project without restriction. Specifically, if other files
+// instantiate templates or use macros or inline functions from this
+// file, or you compile this file and link it with other files to produce
+// an executable, this file does not by itself cause the resulting
+// executable to be covered by the GNU General Public License. This
+// exception does not however invalidate any other reasons why the
+// executable file might be covered by the GNU General Public License.
+
+#ifndef SCRIBO_FILTER_SEPARATORS_IN_PARAGRAPHS_HH
+# define SCRIBO_FILTER_SEPARATORS_IN_PARAGRAPH_HH
+
+/// \file
+///
+/// Invalidate false positive separators.
+/// \fixme Share same test canvas as text::merging.
+
+
+# include <mln/core/concept/image.hh>
+# include <scribo/core/component_set.hh>
+# include <scribo/core/document.hh>
+
+
+namespace scribo
+{
+
+ namespace filter
+ {
+
+ using namespace mln;
+
+
+ /// Invalidate false positive separators.
+ ///
+ /// \param[in] separators A paragraph set.
+ ///
+ /// \return A doc with invalidated separators.
+ ///
+ /// Warning: it does not remove separators from separator
+ /// image. It only invalidate separator components in their
+ /// respective component_set.
+ ///
+ template <typename L>
+ void
+ separators_in_paragraph(document<L>& doc);
+
+
+# ifndef MLN_INCLUDE_ONLY
+
+ template <typename L>
+ void
+ separators_in_paragraph(document<L>& doc)
+ {
+ trace::entering("scribo::filter::separators_in_paragraph");
+
+ mln_precondition(doc.is_valid());
+ mln_precondition(doc.has_elements());
+ mln_precondition(doc.has_hline_seps() || doc.has_vline_seps());
+
+ if ((doc.has_hline_seps() && !doc.hline_seps_comps().nelements())
+ && (doc.has_vline_seps() && !doc.vline_seps_comps().nelements()))
+ return;
+
+ mln_ch_value(L,bool) billboard;
+ initialize(billboard, doc.image());
+ data::fill(billboard, false);
+
+ for_all_comps(p, doc.paragraphs())
+ if (doc.paragraphs()(p).is_valid())
+ mln::draw::box_plain(billboard, doc.paragraphs()(p).bbox(), true);
+
+ // Horizontal separators
+ if (doc.has_hline_seps())
+ {
+ component_set<L> hline = doc.hline_seps_comps().duplicate();
+ for_all_comps(c, hline)
+ {
+ const mln_box(L)& b_ = hline(c).bbox();
+
+ const bool tl = billboard(b_.pmin());
+ const bool tr = billboard.at_(b_.pmin().row(), b_.pmax().col());
+ const bool ml = billboard.at_(b_.pcenter().row(), b_.pmin().col());
+ const bool mc = billboard.at_(b_.pcenter().row(), b_.pcenter().col());
+ const bool mr = billboard.at_(b_.pcenter().row(), b_.pmax().col());
+ const bool bl = billboard.at_(b_.pmax().row(), b_.pmin().col());
+ const bool br = billboard(b_.pmax());
+
+ // This separator is included in an element (picture, drawing...)
+ // => Ignore it.
+ if (tl && tr && ml && mc && mr && bl
&& br)
+ hline(c).update_tag(component::Ignored);
+
+ // FIXME: warning this call may produce inconsistent data
+ // Ignored components are still in the separator image...
+ doc.set_hline_separators(doc.hline_seps(), hline);
+ }
+ }
+
+ // Vertical separators
+ if (doc.has_vline_seps())
+ {
+ component_set<L> vline = doc.vline_seps_comps().duplicate();
+ for_all_comps(c, vline)
+ {
+ const mln_box(L)& b_ = vline(c).bbox();
+
+ const bool tl = billboard(b_.pmin());
+ const bool tr = billboard.at_(b_.pmin().row(), b_.pmax().col());
+ const bool ml = billboard.at_(b_.pcenter().row(), b_.pmin().col());
+ const bool mc = billboard.at_(b_.pcenter().row(), b_.pcenter().col());
+ const bool mr = billboard.at_(b_.pcenter().row(), b_.pmax().col());
+ const bool bl = billboard.at_(b_.pmax().row(), b_.pmin().col());
+ const bool br = billboard(b_.pmax());
+
+ // This separator is included in an element (picture, drawing...)
+ // => Ignore it.
+ if (tl && tr && ml && mc && mr && bl
&& br)
+ vline(c).update_tag(component::Ignored);
+
+ // FIXME: warning this call may produce inconsistent data
+ // Ignored components are still in the separator image...
+ doc.set_vline_separators(doc.vline_seps(), vline);
+ }
+
+ trace::exiting("scribo::filter::separators_in_paragraph");
+ }
+ }
+
+# endif // ! MLN_INCLUDE_ONLY
+
+ } // end of namespace scribo::filter
+
+} // end of namespace scribo
+
+#endif // ! SCRIBO_FILTER_SEPARATORS_IN_PARAGRAPH_HH
--
1.5.6.5