diff options
Diffstat (limited to 'drawinglayer/source')
5 files changed, 195 insertions, 13 deletions
diff --git a/drawinglayer/source/primitive2d/textdecoratedprimitive2d.cxx b/drawinglayer/source/primitive2d/textdecoratedprimitive2d.cxx index 14352c4a8595..4faa85fe898c 100644 --- a/drawinglayer/source/primitive2d/textdecoratedprimitive2d.cxx +++ b/drawinglayer/source/primitive2d/textdecoratedprimitive2d.cxx @@ -186,7 +186,7 @@ namespace drawinglayer if(bWaveLine) { eLineJoin = basegfx::B2DLINEJOIN_ROUND; - fLineHeight *= 0.5; + fLineHeight *= 0.25; } // prepare Line and Stroke Attributes @@ -215,7 +215,7 @@ namespace drawinglayer if(bWaveLine) { - double fWaveWidth(4.0 * fLineHeight); + double fWaveWidth(10.6 * fLineHeight); if(FONT_UNDERLINE_SMALLWAVE == eLineStyle) { @@ -227,7 +227,7 @@ namespace drawinglayer fWaveWidth *= 2.0; } - aNewPrimitive = Primitive2DReference(new PolygonWavePrimitive2D(aLine, aLineAttribute, aStrokeAttribute, fWaveWidth, 0.5 * fWaveWidth)); + aNewPrimitive = Primitive2DReference(new PolygonWavePrimitive2D(aLine, aLineAttribute, aStrokeAttribute, fWaveWidth, fWaveWidth * 0.5)); } else { @@ -241,7 +241,13 @@ namespace drawinglayer { // double line, create 2nd primitive with offset using TransformPrimitive based on // already created NewPrimitive - const double fLineDist((bWaveLine ? 3.0 : 2.0) * fLineHeight); + double fLineDist(2.3 * fLineHeight); + + if(bWaveLine) + { + fLineDist = 6.3 * fLineHeight; + } + basegfx::B2DHomMatrix aTransform; // move base point of text to 0.0 and de-rotate @@ -482,6 +488,16 @@ namespace drawinglayer // init word iterator, get first word and truncate to possibilities ::com::sun::star::i18n::Boundary aNextWordBoundary(xLocalBreakIterator->getWordBoundary( getText(), getTextPosition(), getLocale(), ::com::sun::star::i18n::WordType::ANYWORD_IGNOREWHITESPACES, sal_True)); + + if(aNextWordBoundary.endPos == getTextPosition() && getTextLength() > 0) + { + // #i96474# + // a word before was found (this can happen when search starts on a whitespace and a word + // in front of it exists), force to look one position further + aNextWordBoundary = xLocalBreakIterator->getWordBoundary( + getText(), getTextPosition() + 1, getLocale(), ::com::sun::star::i18n::WordType::ANYWORD_IGNOREWHITESPACES, sal_True); + } + impCorrectTextBoundary(aNextWordBoundary); // prepare new font attributes WITHOUT outline @@ -791,6 +807,33 @@ namespace drawinglayer return false; } + // #i96475# + // Added missing implementation. Decorations may (will) stick out of the text's + // inking area, so add them if needed + basegfx::B2DRange TextDecoratedPortionPrimitive2D::getB2DRange(const geometry::ViewInformation2D& rViewInformation) const + { + const bool bDecoratedIsNeeded( + FONT_UNDERLINE_NONE != getFontOverline() + || FONT_UNDERLINE_NONE != getFontUnderline() + || FONT_STRIKEOUT_NONE != getFontStrikeout() + || FONT_EMPHASISMARK_NONE != getFontEmphasisMark() + || FONT_RELIEF_NONE != getFontRelief() + || getShadow()); + + if(bDecoratedIsNeeded) + { + // decoration is used, fallback to BasePrimitive2D::getB2DRange which uses + // the own local decomposition for computation and thus creates all necessary + // geometric objects + return BasePrimitive2D::getB2DRange(rViewInformation); + } + else + { + // no relevant decoration used, fallback to TextSimplePortionPrimitive2D::getB2DRange + return TextSimplePortionPrimitive2D::getB2DRange(rViewInformation); + } + } + // provide unique ID ImplPrimitrive2DIDBlock(TextDecoratedPortionPrimitive2D, PRIMITIVE2D_ID_TEXTDECORATEDPORTIONPRIMITIVE2D) diff --git a/drawinglayer/source/primitive2d/texthierarchyprimitive2d.cxx b/drawinglayer/source/primitive2d/texthierarchyprimitive2d.cxx index 7148a004a595..72249e673c1b 100644 --- a/drawinglayer/source/primitive2d/texthierarchyprimitive2d.cxx +++ b/drawinglayer/source/primitive2d/texthierarchyprimitive2d.cxx @@ -146,4 +146,21 @@ namespace drawinglayer } // end of namespace drawinglayer ////////////////////////////////////////////////////////////////////////////// + +namespace drawinglayer +{ + namespace primitive2d + { + TextHierarchyEditPrimitive2D::TextHierarchyEditPrimitive2D(const Primitive2DSequence& rChildren) + : GroupPrimitive2D(rChildren) + { + } + + // provide unique ID + ImplPrimitrive2DIDBlock(TextHierarchyEditPrimitive2D, PRIMITIVE2D_ID_TEXTHIERARCHYEDITPRIMITIVE2D) + + } // end of namespace primitive2d +} // end of namespace drawinglayer + +////////////////////////////////////////////////////////////////////////////// // eof diff --git a/drawinglayer/source/processor2d/vclmetafileprocessor2d.cxx b/drawinglayer/source/processor2d/vclmetafileprocessor2d.cxx index bc7e659a8996..dc5589200c15 100644 --- a/drawinglayer/source/processor2d/vclmetafileprocessor2d.cxx +++ b/drawinglayer/source/processor2d/vclmetafileprocessor2d.cxx @@ -73,6 +73,7 @@ #include <basegfx/polygon/b2dpolygontools.hxx> #include <drawinglayer/primitive2d/pagepreviewprimitive2d.hxx> #include <helperchartrenderer.hxx> +#include <drawinglayer/primitive2d/hittestprimitive2d.hxx> ////////////////////////////////////////////////////////////////////////////// // for PDFExtOutDevData Graphic support @@ -983,7 +984,7 @@ namespace drawinglayer SvtGraphicStroke* pSvtGraphicStroke = impTryToCreateSvtGraphicStroke(rHairlinePrimitive.getB2DPolygon(), &aLineColor, 0, 0, 0, 0); impStartSvtGraphicStroke(pSvtGraphicStroke); - RenderPolygonHairlinePrimitive2D(static_cast< const primitive2d::PolygonHairlinePrimitive2D& >(rCandidate)); + RenderPolygonHairlinePrimitive2D(static_cast< const primitive2d::PolygonHairlinePrimitive2D& >(rCandidate), false); impEndSvtGraphicStroke(pSvtGraphicStroke); break; } @@ -1652,6 +1653,27 @@ namespace drawinglayer break; } + case PRIMITIVE2D_ID_HITTESTPRIMITIVE2D : + { + // #i99123# + // invisible primitive; to rebuilt the old MetaFile creation, it is necessary to + // not ignore them (as it was thought), but to add a MetaFile entry for them. + basegfx::B2DRange aInvisibleRange(rCandidate.getB2DRange(getViewInformation2D())); + + if(!aInvisibleRange.isEmpty()) + { + aInvisibleRange.transform(maCurrentTransformation); + const Rectangle aRectLogic( + (sal_Int32)floor(aInvisibleRange.getMinX()), (sal_Int32)floor(aInvisibleRange.getMinY()), + (sal_Int32)ceil(aInvisibleRange.getMaxX()), (sal_Int32)ceil(aInvisibleRange.getMaxY())); + + mpOutputDevice->SetFillColor(); + mpOutputDevice->SetLineColor(); + mpOutputDevice->DrawRect(aRectLogic); + } + + break; + } default : { // process recursively diff --git a/drawinglayer/source/processor2d/vclpixelprocessor2d.cxx b/drawinglayer/source/processor2d/vclpixelprocessor2d.cxx index 70cb4dcb4b43..b1d508795cac 100644 --- a/drawinglayer/source/processor2d/vclpixelprocessor2d.cxx +++ b/drawinglayer/source/processor2d/vclpixelprocessor2d.cxx @@ -65,6 +65,7 @@ #include <tools/diagnose_ex.h> #include <com/sun/star/awt/PosSize.hpp> #include <cstdio> +#include <drawinglayer/primitive2d/backgroundcolorprimitive2d.hxx> ////////////////////////////////////////////////////////////////////////////// @@ -139,13 +140,13 @@ namespace drawinglayer case PRIMITIVE2D_ID_TEXTSIMPLEPORTIONPRIMITIVE2D : { // directdraw of text simple portion; added test possibility to check text decompose - static bool bHandleSimpleTextDirectly(true); + static bool bForceSimpleTextDecomposition(false); // Adapt evtl. used special DrawMode const sal_uInt32 nOriginalDrawMode(mpOutputDevice->GetDrawMode()); adaptTextToFillDrawMode(); - if(bHandleSimpleTextDirectly) + if(!bForceSimpleTextDecomposition && getOptionsDrawinglayer().IsRenderSimpleTextDirect()) { RenderTextSimpleOrDecoratedPortionPrimitive2D(static_cast< const primitive2d::TextSimplePortionPrimitive2D& >(rCandidate)); } @@ -162,13 +163,13 @@ namespace drawinglayer case PRIMITIVE2D_ID_TEXTDECORATEDPORTIONPRIMITIVE2D : { // directdraw of text simple portion; added test possibility to check text decompose - static bool bHandleComplexTextDirectly(false); + static bool bForceComplexTextDecomposition(false); // Adapt evtl. used special DrawMode const sal_uInt32 nOriginalDrawMode(mpOutputDevice->GetDrawMode()); adaptTextToFillDrawMode(); - if(bHandleComplexTextDirectly) + if(!bForceComplexTextDecomposition && getOptionsDrawinglayer().IsRenderDecoratedTextDirect()) { RenderTextSimpleOrDecoratedPortionPrimitive2D(static_cast< const primitive2d::TextSimplePortionPrimitive2D& >(rCandidate)); } @@ -185,7 +186,7 @@ namespace drawinglayer case PRIMITIVE2D_ID_POLYGONHAIRLINEPRIMITIVE2D : { // direct draw of hairline - RenderPolygonHairlinePrimitive2D(static_cast< const primitive2d::PolygonHairlinePrimitive2D& >(rCandidate)); + RenderPolygonHairlinePrimitive2D(static_cast< const primitive2d::PolygonHairlinePrimitive2D& >(rCandidate), true); break; } case PRIMITIVE2D_ID_BITMAPPRIMITIVE2D : @@ -224,8 +225,23 @@ namespace drawinglayer } case PRIMITIVE2D_ID_METAFILEPRIMITIVE2D : { + // #i98289# + const bool bForceLineSnap(getOptionsDrawinglayer().IsAntiAliasing() && getOptionsDrawinglayer().IsSnapHorVerLinesToDiscrete()); + const sal_uInt16 nOldAntiAliase(mpOutputDevice->GetAntialiasing()); + + if(bForceLineSnap) + { + mpOutputDevice->SetAntialiasing(nOldAntiAliase | ANTIALIASING_PIXELSNAPHAIRLINE); + } + // direct draw of MetaFile RenderMetafilePrimitive2D(static_cast< const primitive2d::MetafilePrimitive2D& >(rCandidate)); + + if(bForceLineSnap) + { + mpOutputDevice->SetAntialiasing(nOldAntiAliase); + } + break; } case PRIMITIVE2D_ID_MASKPRIMITIVE2D : @@ -479,6 +495,43 @@ namespace drawinglayer } break; } + case PRIMITIVE2D_ID_BACKGROUNDCOLORPRIMITIVE2D : + { + // #i98404# Handle directly, especially when AA is active + const primitive2d::BackgroundColorPrimitive2D& rPrimitive = static_cast< const primitive2d::BackgroundColorPrimitive2D& >(rCandidate); + const sal_uInt16 nOriginalAA(mpOutputDevice->GetAntialiasing()); + + // switch AA off in all cases + mpOutputDevice->SetAntialiasing(mpOutputDevice->GetAntialiasing() & ~ANTIALIASING_ENABLE_B2DDRAW); + + // create color for fill + const basegfx::BColor aPolygonColor(maBColorModifierStack.getModifiedColor(rPrimitive.getBColor())); + mpOutputDevice->SetFillColor(Color(aPolygonColor)); + mpOutputDevice->SetLineColor(); + + // create rectangle for fill + const basegfx::B2DRange& aViewport(getViewInformation2D().getDiscreteViewport()); + const Rectangle aRectangle( + (sal_Int32)floor(aViewport.getMinX()), (sal_Int32)floor(aViewport.getMinY()), + (sal_Int32)ceil(aViewport.getMaxX()), (sal_Int32)ceil(aViewport.getMaxY())); + mpOutputDevice->DrawRect(aRectangle); + + // restore AA setting + mpOutputDevice->SetAntialiasing(nOriginalAA); + + break; + } + case PRIMITIVE2D_ID_TEXTHIERARCHYEDITPRIMITIVE2D : + { + // #i97628# + // This primitive means that the content is derived from an active text edit, + // not from model data itself. Some renderers need to suppress this content, e.g. + // the pixel renderer used for displaying the edit view (like this one). It's + // not to be suppressed by the MetaFile renderers, so that the edited text is + // part of the MetaFile, e.g. needed for presentation previews. + // Action: Ignore here, do nothing. + break; + } default : { // process recursively diff --git a/drawinglayer/source/processor2d/vclprocessor2d.cxx b/drawinglayer/source/processor2d/vclprocessor2d.cxx index be30e9fe6e77..b8a21767b839 100644 --- a/drawinglayer/source/processor2d/vclprocessor2d.cxx +++ b/drawinglayer/source/processor2d/vclprocessor2d.cxx @@ -66,6 +66,7 @@ #include <vcl/svapp.hxx> #include <drawinglayer/primitive2d/pagepreviewprimitive2d.hxx> #include <tools/diagnose_ex.h> +#include <vcl/metric.hxx> ////////////////////////////////////////////////////////////////////////////// // control support @@ -158,9 +159,42 @@ namespace drawinglayer if(basegfx::fTools::more(aScale.getX(), 0.0) && basegfx::fTools::more(aScale.getY(), 0.0)) { - // prepare everything that is not sheared and mirrored + // #i96581# Get the font forced without FontStretching (use FontHeight as FontWidth) Font aFont(primitive2d::getVclFontFromFontAttributes( - rTextCandidate.getFontAttributes(), aScale.getX(), aScale.getY(), fRotate, *mpOutputDevice)); + rTextCandidate.getFontAttributes(), + aScale.getY(), + aScale.getY(), + fRotate, + *mpOutputDevice)); + + if(!basegfx::fTools::equal(aScale.getX(), aScale.getY())) + { + // #i96581# font stretching is needed; examine how big the difference between X and Y scaling is + const double fPercent(fabs(1.0 - (aScale.getX() / aScale.getY()))); + static double fMaximumAcceptedPercent(0.05); + static bool bForceAdaption(false); + + if(bForceAdaption || fPercent > fMaximumAcceptedPercent) + { + // #i96581# Need to adapt to a FontStretching bigger than acceptable maximum. + // Get font's real width using FontMetric and adapt font to stretched + // font + const FontMetric aFontMetric(mpOutputDevice->GetFontMetric(aFont)); + const double fRealFontWidth(aFontMetric.GetWidth()); + + aFont = primitive2d::getVclFontFromFontAttributes( + rTextCandidate.getFontAttributes(), + fRealFontWidth, + aScale.getY(), + fRotate, + *mpOutputDevice); + } + else + { + // #i96581# less than allowed maximum (probably SC's generated MapModes). React + // pragmatically by ignoring the stretching up to this point + } + } // handle additional font attributes const primitive2d::TextDecoratedPortionPrimitive2D* pTCPP = @@ -317,7 +351,7 @@ namespace drawinglayer } // direct draw of hairline - void VclProcessor2D::RenderPolygonHairlinePrimitive2D(const primitive2d::PolygonHairlinePrimitive2D& rPolygonCandidate) + void VclProcessor2D::RenderPolygonHairlinePrimitive2D(const primitive2d::PolygonHairlinePrimitive2D& rPolygonCandidate, bool bPixelBased) { const basegfx::BColor aHairlineColor(maBColorModifierStack.getModifiedColor(rPolygonCandidate.getBColor())); mpOutputDevice->SetLineColor(Color(aHairlineColor)); @@ -325,6 +359,17 @@ namespace drawinglayer basegfx::B2DPolygon aLocalPolygon(rPolygonCandidate.getB2DPolygon()); aLocalPolygon.transform(maCurrentTransformation); + + if(bPixelBased && getOptionsDrawinglayer().IsAntiAliasing() && getOptionsDrawinglayer().IsSnapHorVerLinesToDiscrete()) + { + // #i98289# + // when a Hairline is painted and AntiAliasing is on the option SnapHorVerLinesToDiscrete + // allows to suppress AntiAliasing for pure horizontal or vertical lines. This is done since + // not-AntiAliased such lines look more pleasing to the eye (e.g. 2D chart content). This + // NEEDS to be done in discrete coordinates, so only useful for pixel based rendering. + aLocalPolygon = basegfx::tools::snapPointsOfHorizontalOrVerticalEdges(aLocalPolygon); + } + mpOutputDevice->DrawPolyLine(aLocalPolygon, 0.0); } @@ -623,6 +668,8 @@ namespace drawinglayer // units e.g. when creating a new MetaFile, but since much huger value ranges are used // there typically will be okay for this compromize. Rectangle aDestRectView( + // !!CAUTION!! Here, ceil and floor are exchanged BY PURPOSE, do NOT copy when + // looking for a standard conversion to rectangle (!) (sal_Int32)ceil(aOutlineRange.getMinX()), (sal_Int32)ceil(aOutlineRange.getMinY()), (sal_Int32)floor(aOutlineRange.getMaxX()), (sal_Int32)floor(aOutlineRange.getMaxY())); |