diff options
author | Chris Sherlock <chris.sherlock79@gmail.com> | 2020-05-13 01:06:32 +1000 |
---|---|---|
committer | Tomaž Vajngerl <quikee@gmail.com> | 2020-05-25 10:50:33 +0200 |
commit | 5ef0f7dfafd8b83818c831914467f93e47a5bb2f (patch) | |
tree | f5648b7f28f524c045dbef43d59cf36637566c82 /vcl | |
parent | 358f654af36fa12102685237f6eadebae4610fb5 (diff) |
vcl: refactor code into GenerateIntersectingConnectedComponents()
Change-Id: I821feafacb5301c7001c68be995df72ba02a64b2
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/94565
Tested-by: Jenkins
Reviewed-by: Tomaž Vajngerl <quikee@gmail.com>
Diffstat (limited to 'vcl')
-rw-r--r-- | vcl/source/gdi/print2.cxx | 118 |
1 files changed, 63 insertions, 55 deletions
diff --git a/vcl/source/gdi/print2.cxx b/vcl/source/gdi/print2.cxx index 1da4393c170a..1258ef26be96 100644 --- a/vcl/source/gdi/print2.cxx +++ b/vcl/source/gdi/print2.cxx @@ -769,6 +769,68 @@ int DetectBackground(ConnectedComponents& rBackgroundComponent, MetaAction* pCur return nActionNum; } +bool GenerateIntersectingConnectedComponents(::std::vector<ConnectedComponents>& rConnectedComponents, + ConnectedComponents& rTotalComponents, + tools::Rectangle & rTotalBounds, bool bTreatSpecial) +{ + bool bSomeComponentsChanged; + // now, this is unfortunate: since changing anyone of + // the aCCList elements (e.g. by merging or addition + // of an action) might generate new intersection with + // other aCCList elements, have to repeat the whole + // element scanning, until nothing changes anymore. + // Thus, this loop here makes us O(n^3) in the worst + // case. + do + { + // only loop here if 'intersects' branch below was hit + bSomeComponentsChanged = false; + + // iterate over all current members of aCCList + for( auto aCurrCC=rConnectedComponents.begin(); aCurrCC != rConnectedComponents.end(); ) + { + // first check if current element's bounds are + // empty. This ensures that empty actions are not + // merged into one component, as a matter of fact, + // they have no position. + + // #107169# Wholly transparent objects need + // not be considered for connected components, + // too. Just put each of them into a separate + // component. + if( !aCurrCC->aBounds.IsEmpty() && + !aCurrCC->bIsFullyTransparent && + aCurrCC->aBounds.IsOver(rTotalBounds)) + { + // union the intersecting aCCList element into aTotalComponents + + // calc union bounding box + rTotalBounds.Union( aCurrCC->aBounds ); + + // extract all aCurr actions to aTotalComponents + rTotalComponents.aComponentList.splice(rTotalComponents.aComponentList.end(), + aCurrCC->aComponentList); + + if (aCurrCC->bIsSpecial) + bTreatSpecial = true; + + // remove and delete aCurrCC element from list (we've now merged its content) + aCurrCC = rConnectedComponents.erase(aCurrCC); + + // at least one component changed, need to rescan everything + bSomeComponentsChanged = true; + } + else + { + ++aCurrCC; + } + } + } + while(bSomeComponentsChanged); + + return bTreatSpecial; +} + } // end anon namespace bool OutputDevice::RemoveTransparenciesFromMetaFile( const GDIMetaFile& rInMtf, GDIMetaFile& rOutMtf, @@ -889,61 +951,7 @@ bool OutputDevice::RemoveTransparenciesFromMetaFile( const GDIMetaFile& rInMtf, bTreatSpecial = true; } - bool bSomeComponentsChanged; - - // now, this is unfortunate: since changing anyone of - // the aCCList elements (e.g. by merging or addition - // of an action) might generate new intersection with - // other aCCList elements, have to repeat the whole - // element scanning, until nothing changes anymore. - // Thus, this loop here makes us O(n^3) in the worst - // case. - do - { - // only loop here if 'intersects' branch below was hit - bSomeComponentsChanged = false; - - // iterate over all current members of aCCList - for( auto aCurrCC=aCCList.begin(); aCurrCC != aCCList.end(); ) - { - // first check if current element's bounds are - // empty. This ensures that empty actions are not - // merged into one component, as a matter of fact, - // they have no position. - - // #107169# Wholly transparent objects need - // not be considered for connected components, - // too. Just put each of them into a separate - // component. - if( !aCurrCC->aBounds.IsEmpty() && - !aCurrCC->bIsFullyTransparent && - aCurrCC->aBounds.IsOver( aTotalBounds ) ) - { - // union the intersecting aCCList element into aTotalComponents - - // calc union bounding box - aTotalBounds.Union( aCurrCC->aBounds ); - - // extract all aCurr actions to aTotalComponents - aTotalComponents.aComponentList.splice( aTotalComponents.aComponentList.end(), - aCurrCC->aComponentList ); - - if( aCurrCC->bIsSpecial ) - bTreatSpecial = true; - - // remove and delete aCurrCC element from list (we've now merged its content) - aCurrCC = aCCList.erase( aCurrCC ); - - // at least one component changed, need to rescan everything - bSomeComponentsChanged = true; - } - else - { - ++aCurrCC; - } - } - } - while( bSomeComponentsChanged ); + bTreatSpecial = GenerateIntersectingConnectedComponents(aCCList, aTotalComponents, aTotalBounds, bTreatSpecial); } // STAGE 2.2: Determine special state for cc element |