From 805b0f3386e85f304849e27c5c29bafc38f7fa81 Mon Sep 17 00:00:00 2001 From: Pino Toscano Date: Wed, 5 Sep 2007 14:57:15 +0000 Subject: [PATCH] Introduce a selective merging strategy for text areas, so we merge only all the areas of a text "line" together, not also with the areas above (if the lines overlap). Adapt the text selection to merge correctly depending on the current rotation. Drawback: darker overlap zones if two lines overlap. svn path=/trunk/KDE/kdegraphics/okular/; revision=708745 --- core/area.h | 55 ++++++++++++++++++++++++++++++++++++++++++++--- core/global.h | 12 +++++++++++ core/textpage.cpp | 4 +++- 3 files changed, 67 insertions(+), 4 deletions(-) diff --git a/core/area.h b/core/area.h index 3828a3b83..4e3603494 100644 --- a/core/area.h +++ b/core/area.h @@ -15,6 +15,7 @@ #include #include +#include #include class QPolygonF; @@ -469,7 +470,7 @@ template class RegularArea : public QList< /** * Appends the given @p shape to the regular area. */ - void appendShape( const NormalizedShape& shape ); + void appendShape( const NormalizedShape& shape, MergeSide side = MergeAll ); /** * Simplifies the regular area by merging its intersecting subareas. @@ -599,7 +600,7 @@ void RegularArea::appendArea( const RegularArea -void RegularArea::appendShape( const NormalizedShape& shape ) +void RegularArea::appendShape( const NormalizedShape& shape, MergeSide side ) { if ( !this ) return; @@ -612,9 +613,57 @@ void RegularArea::appendShape( const NormalizedShape& sh } else { + bool intersection = false; + NormalizedShape& last = (*this)[size - 1]; +#define O_LAST givePtr( last ) +# define O_LAST_R O_LAST->right +# define O_LAST_L O_LAST->left +# define O_LAST_T O_LAST->top +# define O_LAST_B O_LAST->bottom +#define O_NEW givePtr( shape ) +# define O_NEW_R O_NEW->right +# define O_NEW_L O_NEW->left +# define O_NEW_T O_NEW->top +# define O_NEW_B O_NEW->bottom + switch ( side ) + { + case MergeRight: + intersection = ( O_LAST_R >= O_NEW_L ) && ( O_LAST_L <= O_NEW_R ) + && ( ( O_LAST_T <= O_NEW_T && O_LAST_B >= O_NEW_B ) + || ( O_LAST_T >= O_NEW_T && O_LAST_B <= O_NEW_B ) ); + break; + case MergeBottom: + intersection = ( O_LAST_B >= O_NEW_T ) && ( O_LAST_T <= O_NEW_B ) + && ( ( O_LAST_R <= O_NEW_R && O_LAST_L >= O_NEW_L ) + || ( O_LAST_R >= O_NEW_R && O_LAST_L <= O_NEW_L ) ); + break; + case MergeLeft: + intersection = ( O_LAST_L <= O_NEW_R ) && ( O_LAST_R >= O_NEW_L ) + && ( ( O_LAST_T <= O_NEW_T && O_LAST_B >= O_NEW_B ) + || ( O_LAST_T >= O_NEW_T && O_LAST_B <= O_NEW_B ) ); + break; + case MergeTop: + intersection = ( O_LAST_T <= O_NEW_B ) && ( O_LAST_B >= O_NEW_T ) + && ( ( O_LAST_R <= O_NEW_R && O_LAST_L >= O_NEW_L ) + || ( O_LAST_R >= O_NEW_R && O_LAST_L <= O_NEW_L ) ); + break; + case MergeAll: + intersection = O_LAST->intersects( shape ); + break; + } +#undef O_LAST +# undef O_LAST_R +# undef O_LAST_L +# undef O_LAST_T +# undef O_LAST_B +#undef O_NEW +# undef O_NEW_R +# undef O_NEW_L +# undef O_NEW_T +# undef O_NEW_B // if the new shape intersects with the last shape in the list, then // merge it with that and delete the shape - if ( givePtr((*this)[size - 1])->intersects( shape ) ) + if ( intersection ) { deref((*this)[size - 1]) |= deref( shape ); doDelete( const_cast( shape ) ); diff --git a/core/global.h b/core/global.h index 57261fc6f..92a922f6f 100644 --- a/core/global.h +++ b/core/global.h @@ -58,6 +58,18 @@ enum GenerationType Asynchronous ///< Will create the object in an asynchronous way }; +/** + * The side(s) to be considered when merging areas. + */ +enum MergeSide +{ + MergeRight = 0, ///< Merge only if the right side of the first area intersect. + MergeBottom = 1, ///< Merge only if the bottom side of the first area intersect. + MergeLeft = 2, ///< Merge only if the left side of the first area intersect. + MergeTop = 3, ///< Merge only if the top side of the first area intersect. + MergeAll = 4 ///< Merge if the areas intersects, no matter which side(s). +}; + } #endif diff --git a/core/textpage.cpp b/core/textpage.cpp index 6336678ff..2340bf193 100644 --- a/core/textpage.cpp +++ b/core/textpage.cpp @@ -15,6 +15,7 @@ #include "area.h" #include "debug_p.h" #include "misc.h" +#include "page.h" #include "page_p.h" using namespace Okular; @@ -224,13 +225,14 @@ RegularAreaRect * TextPage::textArea ( TextSelection * sel) const double endCy = endC.y; TextEntity::List::ConstIterator it = d->m_words.begin(), itEnd = d->m_words.end(); + MergeSide side = d->m_page ? (MergeSide)d->m_page->m_page->totalOrientation() : MergeRight; for ( ; it != itEnd; ++it ) { tmp = *(*it)->area(); if ( ( tmp.top > startCy || ( tmp.bottom > startCy && tmp.right > startCx ) ) && ( tmp.bottom < endCy || ( tmp.top < endCy && tmp.left < endCx ) ) ) { - ret->appendShape( (*it)->transformedArea( matrix ) ); + ret->appendShape( (*it)->transformedArea( matrix ), side ); } } #endif