diff options
Diffstat (limited to 'drawinglayer/source/primitive2d/metafileprimitive2d.cxx')
-rw-r--r-- | drawinglayer/source/primitive2d/metafileprimitive2d.cxx | 207 |
1 files changed, 162 insertions, 45 deletions
diff --git a/drawinglayer/source/primitive2d/metafileprimitive2d.cxx b/drawinglayer/source/primitive2d/metafileprimitive2d.cxx index ab78bc3456..9d65643a27 100644 --- a/drawinglayer/source/primitive2d/metafileprimitive2d.cxx +++ b/drawinglayer/source/primitive2d/metafileprimitive2d.cxx @@ -45,10 +45,10 @@ #include <drawinglayer/primitive2d/discretebitmapprimitive2d.hxx> #include <drawinglayer/primitive2d/bitmapprimitive2d.hxx> #include <vcl/salbtype.hxx> -#include <drawinglayer/primitive2d/unifiedalphaprimitive2d.hxx> +#include <drawinglayer/primitive2d/unifiedtransparenceprimitive2d.hxx> #include <drawinglayer/primitive2d/fillgradientprimitive2d.hxx> #include <vcl/svapp.hxx> -#include <drawinglayer/primitive2d/alphaprimitive2d.hxx> +#include <drawinglayer/primitive2d/transparenceprimitive2d.hxx> #include <drawinglayer/primitive2d/fillhatchprimitive2d.hxx> #include <drawinglayer/primitive2d/maskprimitive2d.hxx> #include <basegfx/polygon/b2dpolygonclipper.hxx> @@ -581,7 +581,14 @@ namespace drawinglayer Primitive2DSequence NonOverlappingFillGradientPrimitive2D::create2DDecomposition( const geometry::ViewInformation2D& /*rViewInformation*/) const { - return createFill(false); + if(!getFillGradient().isDefault()) + { + return createFill(false); + } + else + { + return Primitive2DSequence(); + } } } // end of namespace primitive2d } // end of namespace drawinglayer @@ -833,7 +840,7 @@ namespace } /** helper to create a regular BotmapEx from a MaskAction (definitions - which use a bitmap without alpha but define one of the colors as + which use a bitmap without transparence but define one of the colors as transparent) */ BitmapEx createMaskBmpEx(const Bitmap& rBitmap, const Color& rMaskColor) @@ -966,7 +973,42 @@ namespace TargetHolders& rTargetHolders, PropertyHolders& rPropertyHolders) { - // process evtl. created primitives which belong to the current region settings + const bool bNewActive(pRegion && !pRegion->IsEmpty()); + + // #i108636# The handlig of new ClipRegions was not done as good as possible + // in the first version of this interpreter; e.g. when a ClipRegion was set + // initially and then using a lot of push/pop actions, the pop always leads + // to setting a 'new' ClipRegion which indeed is the return to the ClipRegion + // of the properties next on the stack. + // This ClipRegion is identical to the current one, so there is no need to + // create a MaskPrimitive2D containing the up-to-now created primitives, but + // this was done before. While this does not lead to wrong primitive + // representations of the metafile data, it creates unneccesarily expensive + // representations. Just detecting when no really 'new' ClipRegion gets set + // solves the problem. + + if(!rPropertyHolders.Current().getRegionActive() && !bNewActive) + { + // no active region exchanged by no new one, done + return; + } + + if(rPropertyHolders.Current().getRegionActive() && bNewActive) + { + // active region and new active region + if(rPropertyHolders.Current().getRegion() == *pRegion) + { + // new region is the same as the old region, done + return; + } + } + + // Here the old region and the new one are definitively different, maybe + // old one and/or new one is not active. + + // Handle deletion of old region.The process evtl. created primitives which + // belong to this active region. These need to be embedded to a + // MaskPrimitive2D accordingly. if(rPropertyHolders.Current().getRegionActive() && rTargetHolders.size() > 1) { drawinglayer::primitive2d::Primitive2DSequence aSubContent; @@ -986,8 +1028,8 @@ namespace } } - // apply new settings - const bool bNewActive(pRegion && !pRegion->IsEmpty()); + // apply new settings to current properties by setting + // the new region now rPropertyHolders.Current().setRegionActive(bNewActive); if(bNewActive) @@ -1244,13 +1286,12 @@ namespace const XubString& rText, sal_uInt16 nTextStart, sal_uInt16 nTextLength, - sal_Int32* pDXArray, + const ::std::vector< double >& rDXArray, TargetHolder& rTarget, PropertyHolder& rProperty) { drawinglayer::primitive2d::BasePrimitive2D* pResult = 0; const Font& rFont = rProperty.getFont(); - std::vector< double > aDXArray; basegfx::B2DVector aAlignmentOffset(0.0, 0.0); if(nTextLength) @@ -1268,17 +1309,6 @@ namespace // add TextStartPosition aTextTransform.translate(rTextStartPosition.X(), rTextStartPosition.Y()); - // preapare DXArray (if used) - if(pDXArray && nTextLength) - { - aDXArray.reserve(nTextLength); - - for(xub_StrLen a(0); a < nTextLength; a++) - { - aDXArray.push_back((double)(*(pDXArray + a))); - } - } - // prepare FontColor and Locale const basegfx::BColor aFontColor(rProperty.getTextColor()); const com::sun::star::lang::Locale aLocale(MsLangId::convertLanguageToLocale(rProperty.getLanguageType())); @@ -1338,7 +1368,7 @@ namespace rText, nTextStart, nTextLength, - aDXArray, + rDXArray, aFontAttribute, aLocale, aFontColor, @@ -1365,7 +1395,7 @@ namespace rText, nTextStart, nTextLength, - aDXArray, + rDXArray, aFontAttribute, aLocale, aFontColor); @@ -1381,13 +1411,13 @@ namespace // get text width double fTextWidth(0.0); - if(aDXArray.empty()) + if(rDXArray.empty()) { fTextWidth = aTextLayouterDevice.getTextWidth(rText, nTextStart, nTextLength); } else { - fTextWidth = aDXArray.back(); + fTextWidth = rDXArray.back(); } if(basegfx::fTools::more(fTextWidth, 0.0)) @@ -1942,15 +1972,24 @@ namespace { /** CHECKED, WORKS WELL */ const MetaTextAction* pA = (const MetaTextAction*)pAction; + sal_uInt32 nTextLength(pA->GetLen()); + const sal_uInt32 nTextIndex(pA->GetIndex()); + const sal_uInt32 nStringLength(pA->GetText().Len()); + + if(nTextLength + nTextIndex > nStringLength) + { + nTextLength = nStringLength - nTextIndex; + } - if(pA->GetLen() && rPropertyHolders.Current().getTextColorActive()) + if(nTextLength && rPropertyHolders.Current().getTextColorActive()) { + const std::vector< double > aDXArray; proccessMetaTextAction( pA->GetPoint(), pA->GetText(), - pA->GetIndex(), - pA->GetLen(), - 0, + nTextIndex, + nTextLength, + aDXArray, rTargetHolders.Current(), rPropertyHolders.Current()); } @@ -1961,15 +2000,37 @@ namespace { /** CHECKED, WORKS WELL */ const MetaTextArrayAction* pA = (const MetaTextArrayAction*)pAction; + sal_uInt32 nTextLength(pA->GetLen()); + const sal_uInt32 nTextIndex(pA->GetIndex()); + const sal_uInt32 nStringLength(pA->GetText().Len()); + + if(nTextLength + nTextIndex > nStringLength) + { + nTextLength = nStringLength - nTextIndex; + } - if(pA->GetLen() && rPropertyHolders.Current().getTextColorActive()) + if(nTextLength && rPropertyHolders.Current().getTextColorActive()) { + // preapare DXArray (if used) + std::vector< double > aDXArray; + sal_Int32* pDXArray = pA->GetDXArray(); + + if(pDXArray) + { + aDXArray.reserve(nTextLength); + + for(sal_uInt32 a(0); a < nTextLength; a++) + { + aDXArray.push_back((double)(*(pDXArray + a))); + } + } + proccessMetaTextAction( pA->GetPoint(), pA->GetText(), - pA->GetIndex(), - pA->GetLen(), - pA->GetDXArray(), + nTextIndex, + nTextLength, + aDXArray, rTargetHolders.Current(), rPropertyHolders.Current()); } @@ -1978,10 +2039,65 @@ namespace } case META_STRETCHTEXT_ACTION : { - /** NEEDS IMPLEMENTATION */ - OSL_ENSURE(false, "META_STRETCHTEXT_ACTION requested (!)"); - // use OutputDevice::GetTextArray() to map the... - // const MetaStretchTextAction* pA = (const MetaStretchTextAction*)pAction; + // #i108440# StarMath uses MetaStretchTextAction, thus support is needed. + // It looks as if it pretty never really uses a width different from + // the default text-layout width, but it's not possible to be sure. + // Implemented getting the DXArray and checking for scale at all. If + // scale is more than 3.5% different, scale the DXArray before usage. + // New status: + + /** CHECKED, WORKS WELL */ + const MetaStretchTextAction* pA = (const MetaStretchTextAction*)pAction; + sal_uInt32 nTextLength(pA->GetLen()); + const sal_uInt32 nTextIndex(pA->GetIndex()); + const sal_uInt32 nStringLength(pA->GetText().Len()); + + if(nTextLength + nTextIndex > nStringLength) + { + nTextLength = nStringLength - nTextIndex; + } + + if(nTextLength && rPropertyHolders.Current().getTextColorActive()) + { + drawinglayer::primitive2d::TextLayouterDevice aTextLayouterDevice; + aTextLayouterDevice.setFont(rPropertyHolders.Current().getFont()); + + ::std::vector< double > aTextArray( + aTextLayouterDevice.getTextArray( + pA->GetText(), + nTextIndex, + nTextLength)); + + if(!aTextArray.empty()) + { + const double fTextLength(aTextArray.back()); + + if(0.0 != fTextLength && pA->GetWidth()) + { + const double fRelative(pA->GetWidth() / fTextLength); + + if(fabs(fRelative - 1.0) >= 0.035) + { + // when derivation is more than 3,5% from default text size, + // scale the DXArray + for(sal_uInt32 a(0); a < aTextArray.size(); a++) + { + aTextArray[a] *= fRelative; + } + } + } + } + + proccessMetaTextAction( + pA->GetPoint(), + pA->GetText(), + nTextIndex, + nTextLength, + aTextArray, + rTargetHolders.Current(), + rPropertyHolders.Current()); + } + break; } case META_TEXTRECT_ACTION : @@ -1990,8 +2106,9 @@ namespace // OSL_ENSURE(false, "META_TEXTRECT_ACTION requested (!)"); const MetaTextRectAction* pA = (const MetaTextRectAction*)pAction; const Rectangle& rRectangle = pA->GetRect(); + const sal_uInt32 nStringLength(pA->GetText().Len()); - if(!rRectangle.IsEmpty() && 0 != pA->GetText().Len()) + if(!rRectangle.IsEmpty() && 0 != nStringLength) { // The problem with this action is that it describes unlayouted text // and the layout capabilities are in EditEngine/Outliner in SVX. The @@ -2720,7 +2837,7 @@ namespace if(aSubContent.hasElements()) { rTargetHolders.Current().append( - new drawinglayer::primitive2d::UnifiedAlphaPrimitive2D( + new drawinglayer::primitive2d::UnifiedTransparencePrimitive2D( aSubContent, nTransparence * 0.01)); } @@ -2831,9 +2948,9 @@ namespace if(aAttribute.getStartColor() == aAttribute.getEndColor()) { - // not really a gradient; create UnifiedAlphaPrimitive2D + // not really a gradient; create UnifiedTransparencePrimitive2D rTargetHolders.Current().append( - new drawinglayer::primitive2d::UnifiedAlphaPrimitive2D( + new drawinglayer::primitive2d::UnifiedTransparencePrimitive2D( xSubContent, aAttribute.getStartColor().luminance())); } @@ -2845,17 +2962,17 @@ namespace aTargetRectangle.Right(), aTargetRectangle.Bottom()); aRange.transform(rPropertyHolders.Current().getTransformation()); - // prepare gradient for alpha content - const drawinglayer::primitive2d::Primitive2DReference xAlpha( + // prepare gradient for transparent content + const drawinglayer::primitive2d::Primitive2DReference xTransparence( new drawinglayer::primitive2d::FillGradientPrimitive2D( aRange, aAttribute)); - // create alpha primitive + // create transparence primitive rTargetHolders.Current().append( - new drawinglayer::primitive2d::AlphaPrimitive2D( + new drawinglayer::primitive2d::TransparencePrimitive2D( xSubContent, - drawinglayer::primitive2d::Primitive2DSequence(&xAlpha, 1))); + drawinglayer::primitive2d::Primitive2DSequence(&xTransparence, 1))); } } } |