Kaydet (Commit) 2a063da1 authored tarafından Armin Le Grand's avatar Armin Le Grand

#121297# corrected non-AAed gradient rendering when in rotated metafiles, some cleanups

üst 0eceaca6
...@@ -156,7 +156,6 @@ $(eval $(call gb_Library_add_exception_objects,drawinglayer,\ ...@@ -156,7 +156,6 @@ $(eval $(call gb_Library_add_exception_objects,drawinglayer,\
drawinglayer/source/primitive3d/textureprimitive3d \ drawinglayer/source/primitive3d/textureprimitive3d \
drawinglayer/source/primitive3d/transformprimitive3d \ drawinglayer/source/primitive3d/transformprimitive3d \
drawinglayer/source/processor2d/baseprocessor2d \ drawinglayer/source/processor2d/baseprocessor2d \
drawinglayer/source/processor2d/vclhelpergradient \
drawinglayer/source/processor2d/vclhelperbitmaptransform \ drawinglayer/source/processor2d/vclhelperbitmaptransform \
drawinglayer/source/processor2d/vclhelperbitmaprender \ drawinglayer/source/processor2d/vclhelperbitmaprender \
drawinglayer/source/processor2d/vclhelperbufferdevice \ drawinglayer/source/processor2d/vclhelperbufferdevice \
......
...@@ -97,10 +97,8 @@ namespace drawinglayer ...@@ -97,10 +97,8 @@ namespace drawinglayer
void RenderPolygonHairlinePrimitive2D(const primitive2d::PolygonHairlinePrimitive2D& rPolygonCandidate, bool bPixelBased); void RenderPolygonHairlinePrimitive2D(const primitive2d::PolygonHairlinePrimitive2D& rPolygonCandidate, bool bPixelBased);
void RenderBitmapPrimitive2D(const primitive2d::BitmapPrimitive2D& rBitmapCandidate); void RenderBitmapPrimitive2D(const primitive2d::BitmapPrimitive2D& rBitmapCandidate);
void RenderFillGraphicPrimitive2D(const primitive2d::FillGraphicPrimitive2D& rFillBitmapCandidate); void RenderFillGraphicPrimitive2D(const primitive2d::FillGraphicPrimitive2D& rFillBitmapCandidate);
void RenderPolyPolygonGradientPrimitive2D(const primitive2d::PolyPolygonGradientPrimitive2D& rPolygonCandidate);
void RenderPolyPolygonGraphicPrimitive2D(const primitive2d::PolyPolygonGraphicPrimitive2D& rPolygonCandidate); void RenderPolyPolygonGraphicPrimitive2D(const primitive2d::PolyPolygonGraphicPrimitive2D& rPolygonCandidate);
void RenderPolyPolygonColorPrimitive2D(const primitive2d::PolyPolygonColorPrimitive2D& rPolygonCandidate); void RenderPolyPolygonColorPrimitive2D(const primitive2d::PolyPolygonColorPrimitive2D& rPolygonCandidate);
void RenderMetafilePrimitive2D(const primitive2d::MetafilePrimitive2D& rPolygonCandidate);
void RenderMaskPrimitive2DPixel(const primitive2d::MaskPrimitive2D& rMaskCandidate); void RenderMaskPrimitive2DPixel(const primitive2d::MaskPrimitive2D& rMaskCandidate);
void RenderModifiedColorPrimitive2D(const primitive2d::ModifiedColorPrimitive2D& rModifiedCandidate); void RenderModifiedColorPrimitive2D(const primitive2d::ModifiedColorPrimitive2D& rModifiedCandidate);
void RenderUnifiedTransparencePrimitive2D(const primitive2d::UnifiedTransparencePrimitive2D& rTransCandidate); void RenderUnifiedTransparencePrimitive2D(const primitive2d::UnifiedTransparencePrimitive2D& rTransCandidate);
......
/**************************************************************
*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*
*************************************************************/
#ifndef INCLUDED_DRAWINGLAYER_PROCESSOR2D_VCLHELPERGRADIENT_HXX
#define INCLUDED_DRAWINGLAYER_PROCESSOR2D_VCLHELPERGRADIENT_HXX
#include <sal/types.h>
#include <drawinglayer/attribute/fillgradientattribute.hxx>
//////////////////////////////////////////////////////////////////////////////
// predefines
class OutputDevice;
namespace basegfx {
class B2DPolyPolygon;
class BColor;
}
//////////////////////////////////////////////////////////////////////////////
// support methods for vcl direct gradient renderering
namespace drawinglayer
{
void impDrawGradientToOutDev(
OutputDevice& rOutDev,
const basegfx::B2DPolyPolygon& rTargetForm,
attribute::GradientStyle eGradientStyle,
sal_uInt32 nSteps,
const basegfx::BColor& rStart,
const basegfx::BColor& rEnd,
double fBorder, double fAngle, double fOffsetX, double fOffsetY, bool bSimple);
} // end of namespace drawinglayer
//////////////////////////////////////////////////////////////////////////////
#endif // INCLUDED_DRAWINGLAYER_PROCESSOR2D_VCLHELPERGRADIENT_HXX
// eof
...@@ -34,7 +34,6 @@ ...@@ -34,7 +34,6 @@
#include <drawinglayer/primitive2d/polypolygonprimitive2d.hxx> #include <drawinglayer/primitive2d/polypolygonprimitive2d.hxx>
#include <drawinglayer/primitive2d/polygonprimitive2d.hxx> #include <drawinglayer/primitive2d/polygonprimitive2d.hxx>
#include <drawinglayer/primitive2d/bitmapprimitive2d.hxx> #include <drawinglayer/primitive2d/bitmapprimitive2d.hxx>
#include <drawinglayer/primitive2d/metafileprimitive2d.hxx>
#include <drawinglayer/primitive2d/maskprimitive2d.hxx> #include <drawinglayer/primitive2d/maskprimitive2d.hxx>
#include <basegfx/polygon/b2dpolygonclipper.hxx> #include <basegfx/polygon/b2dpolygonclipper.hxx>
#include <basegfx/polygon/b2dpolypolygontools.hxx> #include <basegfx/polygon/b2dpolypolygontools.hxx>
...@@ -1623,9 +1622,6 @@ namespace drawinglayer ...@@ -1623,9 +1622,6 @@ namespace drawinglayer
impStartSvtGraphicFill(pSvtGraphicFill); impStartSvtGraphicFill(pSvtGraphicFill);
mpOutputDevice->DrawGradient(aToolsPolyPolygon, aVCLGradient); mpOutputDevice->DrawGradient(aToolsPolyPolygon, aVCLGradient);
impEndSvtGraphicFill(pSvtGraphicFill); impEndSvtGraphicFill(pSvtGraphicFill);
// NO usage of common own gradient randerer, not used ATM for VCL MetaFile, see text above
// RenderPolyPolygonGradientPrimitive2D(static_cast< const primitive2d::PolyPolygonGradientPrimitive2D& >(rCandidate));
} }
break; break;
...@@ -1690,23 +1686,6 @@ namespace drawinglayer ...@@ -1690,23 +1686,6 @@ namespace drawinglayer
break; break;
} }
case PRIMITIVE2D_ID_METAFILEPRIMITIVE2D :
{
static bool bUseMetaFilePrimitiveDecomposition(true);
if(bUseMetaFilePrimitiveDecomposition)
{
// use new Metafile decomposition
process(rCandidate.get2DDecomposition(getViewInformation2D()));
}
else
{
// direct draw of MetaFile, use default pocessing
RenderMetafilePrimitive2D(static_cast< const primitive2d::MetafilePrimitive2D& >(rCandidate));
}
break;
}
case PRIMITIVE2D_ID_MASKPRIMITIVE2D : case PRIMITIVE2D_ID_MASKPRIMITIVE2D :
{ {
// mask group. Special handling for MetaFiles. // mask group. Special handling for MetaFiles.
......
...@@ -195,7 +195,29 @@ namespace drawinglayer ...@@ -195,7 +195,29 @@ namespace drawinglayer
case PRIMITIVE2D_ID_POLYPOLYGONGRADIENTPRIMITIVE2D : case PRIMITIVE2D_ID_POLYPOLYGONGRADIENTPRIMITIVE2D :
{ {
// direct draw of gradient // direct draw of gradient
RenderPolyPolygonGradientPrimitive2D(static_cast< const primitive2d::PolyPolygonGradientPrimitive2D& >(rCandidate)); const primitive2d::PolyPolygonGradientPrimitive2D& rPolygonCandidate = static_cast< const primitive2d::PolyPolygonGradientPrimitive2D& >(rCandidate);
const attribute::FillGradientAttribute& rGradient(rPolygonCandidate.getFillGradient());
basegfx::BColor aStartColor(maBColorModifierStack.getModifiedColor(rGradient.getStartColor()));
basegfx::BColor aEndColor(maBColorModifierStack.getModifiedColor(rGradient.getEndColor()));
basegfx::B2DPolyPolygon aLocalPolyPolygon(rPolygonCandidate.getB2DPolyPolygon());
if(aLocalPolyPolygon.count())
{
aLocalPolyPolygon.transform(maCurrentTransformation);
if(aStartColor == aEndColor)
{
// no gradient at all, draw as polygon in AA and non-AA case
mpOutputDevice->SetLineColor();
mpOutputDevice->SetFillColor(Color(aStartColor));
mpOutputDevice->DrawPolyPolygon(aLocalPolyPolygon);
}
else
{
// use the primitive decomposition of the metafile
process(rPolygonCandidate.get2DDecomposition(getViewInformation2D()));
}
}
break; break;
} }
case PRIMITIVE2D_ID_POLYPOLYGONGRAPHICPRIMITIVE2D : case PRIMITIVE2D_ID_POLYPOLYGONGRAPHICPRIMITIVE2D :
...@@ -221,17 +243,8 @@ namespace drawinglayer ...@@ -221,17 +243,8 @@ namespace drawinglayer
mpOutputDevice->SetAntialiasing(nOldAntiAliase | ANTIALIASING_PIXELSNAPHAIRLINE); mpOutputDevice->SetAntialiasing(nOldAntiAliase | ANTIALIASING_PIXELSNAPHAIRLINE);
} }
static bool bTestMetaFilePrimitiveDecomposition(true); // use new Metafile decomposition
if(bTestMetaFilePrimitiveDecomposition) process(rCandidate.get2DDecomposition(getViewInformation2D()));
{
// use new Metafile decomposition
process(rCandidate.get2DDecomposition(getViewInformation2D()));
}
else
{
// direct draw of MetaFile
RenderMetafilePrimitive2D(static_cast< const primitive2d::MetafilePrimitive2D& >(rCandidate));
}
if(bForceLineSnap) if(bForceLineSnap)
{ {
......
...@@ -37,7 +37,6 @@ ...@@ -37,7 +37,6 @@
#include <drawinglayer/attribute/sdrfillgraphicattribute.hxx> #include <drawinglayer/attribute/sdrfillgraphicattribute.hxx>
#include <drawinglayer/primitive2d/fillgraphicprimitive2d.hxx> #include <drawinglayer/primitive2d/fillgraphicprimitive2d.hxx>
#include <drawinglayer/primitive2d/polypolygonprimitive2d.hxx> #include <drawinglayer/primitive2d/polypolygonprimitive2d.hxx>
#include <vclhelpergradient.hxx>
#include <drawinglayer/primitive2d/metafileprimitive2d.hxx> #include <drawinglayer/primitive2d/metafileprimitive2d.hxx>
#include <drawinglayer/primitive2d/maskprimitive2d.hxx> #include <drawinglayer/primitive2d/maskprimitive2d.hxx>
#include <basegfx/polygon/b2dpolypolygontools.hxx> #include <basegfx/polygon/b2dpolypolygontools.hxx>
...@@ -670,44 +669,6 @@ namespace drawinglayer ...@@ -670,44 +669,6 @@ namespace drawinglayer
} }
} }
// direct draw of gradient
void VclProcessor2D::RenderPolyPolygonGradientPrimitive2D(const primitive2d::PolyPolygonGradientPrimitive2D& rPolygonCandidate)
{
const attribute::FillGradientAttribute& rGradient(rPolygonCandidate.getFillGradient());
basegfx::BColor aStartColor(maBColorModifierStack.getModifiedColor(rGradient.getStartColor()));
basegfx::BColor aEndColor(maBColorModifierStack.getModifiedColor(rGradient.getEndColor()));
basegfx::B2DPolyPolygon aLocalPolyPolygon(rPolygonCandidate.getB2DPolyPolygon());
if(aLocalPolyPolygon.count())
{
aLocalPolyPolygon.transform(maCurrentTransformation);
if(aStartColor == aEndColor)
{
// no gradient at all, draw as polygon in AA and non-AA case
mpOutputDevice->SetLineColor();
mpOutputDevice->SetFillColor(Color(aStartColor));
mpOutputDevice->DrawPolyPolygon(aLocalPolyPolygon);
}
else if(getOptionsDrawinglayer().IsAntiAliasing())
{
// For AA, direct render has to be avoided since it uses XOR maskings which will not
// work with AA. Instead, the decompose which uses MaskPrimitive2D with fillings is
// used
process(rPolygonCandidate.get2DDecomposition(getViewInformation2D()));
}
else
{
static bool bSimple = false; // allow testing simple paint in debugger
impDrawGradientToOutDev(
*mpOutputDevice, aLocalPolyPolygon, rGradient.getStyle(), rGradient.getSteps(),
aStartColor, aEndColor, rGradient.getBorder(),
rGradient.getAngle(), rGradient.getOffsetX(), rGradient.getOffsetY(), bSimple);
}
}
}
// direct draw of Graphic // direct draw of Graphic
void VclProcessor2D::RenderPolyPolygonGraphicPrimitive2D(const primitive2d::PolyPolygonGraphicPrimitive2D& rPolygonCandidate) void VclProcessor2D::RenderPolyPolygonGraphicPrimitive2D(const primitive2d::PolyPolygonGraphicPrimitive2D& rPolygonCandidate)
{ {
...@@ -895,97 +856,6 @@ namespace drawinglayer ...@@ -895,97 +856,6 @@ namespace drawinglayer
} }
} }
// direct draw of MetaFile
void VclProcessor2D::RenderMetafilePrimitive2D(const primitive2d::MetafilePrimitive2D& rMetaCandidate)
{
// decompose matrix to check for shear, rotate and mirroring
basegfx::B2DHomMatrix aLocalTransform(maCurrentTransformation * rMetaCandidate.getTransform());
basegfx::B2DVector aScale, aTranslate;
double fRotate, fShearX;
aLocalTransform.decompose(aScale, aTranslate, fRotate, fShearX);
if(basegfx::fTools::less(aScale.getX(), 0.0) && basegfx::fTools::less(aScale.getY(), 0.0))
{
// #i102175# handle special case: If scale is negative in (x,y) (3rd quadrant), it can
// be expressed as rotation by PI. This needs to be done for Metafiles since
// these can be rotated, but not really mirrored
aScale = basegfx::absolute(aScale);
fRotate += F_PI;
}
// get BoundRect
basegfx::B2DRange aOutlineRange(rMetaCandidate.getB2DRange(getViewInformation2D()));
aOutlineRange.transform(maCurrentTransformation);
// Due to the integer MapModes used from VCL aind inside MetaFiles errors of up to three
// pixels in size may happen. As long as there is no better way (e.g. convert the MetaFile
// to primitives) it is necessary to reduce maximum pixel size by 1 in X and Y and to use
// the inner pixel bounds accordingly (ceil resp. floor). This will also be done for logic
// 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()));
// get metafile (copy it)
GDIMetaFile aMetaFile;
if(maBColorModifierStack.count())
{
const basegfx::BColor aRGBBaseColor(0, 0, 0);
const basegfx::BColor aRGBColor(maBColorModifierStack.getModifiedColor(aRGBBaseColor));
aMetaFile = rMetaCandidate.getMetaFile().GetMonochromeMtf(Color(aRGBColor));
}
else
{
aMetaFile = rMetaCandidate.getMetaFile();
}
// rotation
if(!basegfx::fTools::equalZero(fRotate))
{
// #i103530#
// MetaFile::Rotate has no input parameter check, so the parameter needs to be
// well-aligned to the old range [0..3600] 10th degrees with inverse orientation
sal_Int16 nRotation((sal_Int16)((fRotate / F_PI180) * -10.0));
while(nRotation < 0)
nRotation += 3600;
while(nRotation >= 3600)
nRotation -= 3600;
aMetaFile.Rotate(nRotation);
}
// Prepare target output size
Size aDestSize(aDestRectView.GetSize());
if(aDestSize.getWidth() && aDestSize.getHeight())
{
// Get preferred Metafile output size. When it's very equal to the output size, it's probably
// a rounding error somewhere, so correct it to get a 1:1 output without single pixel scalings
// of the Metafile (esp. for contaned Bitmaps, e.g 3D charts)
const Size aPrefSize(mpOutputDevice->LogicToPixel(aMetaFile.GetPrefSize(), aMetaFile.GetPrefMapMode()));
if(aPrefSize.getWidth() && (aPrefSize.getWidth() - 1 == aDestSize.getWidth() || aPrefSize.getWidth() + 1 == aDestSize.getWidth()))
{
aDestSize.setWidth(aPrefSize.getWidth());
}
if(aPrefSize.getHeight() && (aPrefSize.getHeight() - 1 == aDestSize.getHeight() || aPrefSize.getHeight() + 1 == aDestSize.getHeight()))
{
aDestSize.setHeight(aPrefSize.getHeight());
}
// paint it
aMetaFile.WindStart();
aMetaFile.Play(mpOutputDevice, aDestRectView.TopLeft(), aDestSize);
}
}
// mask group. Force output to VDev and create mask from given mask // mask group. Force output to VDev and create mask from given mask
void VclProcessor2D::RenderMaskPrimitive2DPixel(const primitive2d::MaskPrimitive2D& rMaskCandidate) void VclProcessor2D::RenderMaskPrimitive2DPixel(const primitive2d::MaskPrimitive2D& rMaskCandidate)
{ {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment