Kaydet (Commit) 229a79b9 authored tarafından Armin Le Grand's avatar Armin Le Grand

#121267# added support for taking clipping into account for metafile-based…

#121267# added support for taking clipping into account for metafile-based exporters to vector formats
üst 973e3f96
......@@ -98,6 +98,12 @@ namespace basegfx
*/
B2DRange getRange(const B2DPolyPolygon& rCandidate);
// get signed area of polygon
double getSignedArea(const B2DPolyPolygon& rCandidate);
// get area of polygon
double getArea(const B2DPolyPolygon& rCandidate);
/** Apply given LineDashing to given polyPolygon
For a description see applyLineDashing in b2dpolygontoos.hxx
......
......@@ -519,8 +519,6 @@ namespace basegfx
fRetval -= aPreviousPoint.getY() * aCurrentPoint.getX();
}
fRetval /= 2.0;
// correct to zero if small enough. Also test the quadratic
// of the result since the precision is near quadratic due to
// the algorithm
......
......@@ -263,6 +263,26 @@ namespace basegfx
return aRetval;
}
double getSignedArea(const B2DPolyPolygon& rCandidate)
{
double fRetval(0.0);
const sal_uInt32 nPolygonCount(rCandidate.count());
for(sal_uInt32 a(0L); a < nPolygonCount; a++)
{
const B2DPolygon aCandidate(rCandidate.getB2DPolygon(a));
fRetval += tools::getSignedArea(aCandidate);
}
return fRetval;
}
double getArea(const B2DPolyPolygon& rCandidate)
{
return fabs(getSignedArea(rCandidate));
}
void applyLineDashing(const B2DPolyPolygon& rCandidate, const ::std::vector<double>& rDotDashArray, B2DPolyPolygon* pLineTarget, B2DPolyPolygon* pGapTarget, double fFullDashDotLen)
{
if(0.0 == fFullDashDotLen && rDotDashArray.size())
......
......@@ -1155,14 +1155,29 @@ namespace drawinglayer
// direct draw of hairline; use default processing
// support SvtGraphicStroke MetaCommentAction
const basegfx::BColor aLineColor(maBColorModifierStack.getModifiedColor(rHairlinePrimitive.getBColor()));
SvtGraphicStroke* pSvtGraphicStroke = impTryToCreateSvtGraphicStroke(
rHairlinePrimitive.getB2DPolygon(),
&aLineColor,
0, 0, 0, 0);
SvtGraphicStroke* pSvtGraphicStroke = 0;
// #121267# Not needed, does not give better quality compared with
// the META_POLYPOLYGON_ACTION written by RenderPolygonHairlinePrimitive2D
// below
bool bSupportSvtGraphicStroke(false);
if(bSupportSvtGraphicStroke)
{
pSvtGraphicStroke = impTryToCreateSvtGraphicStroke(
rHairlinePrimitive.getB2DPolygon(),
&aLineColor,
0, 0, 0, 0);
impStartSvtGraphicStroke(pSvtGraphicStroke);
}
impStartSvtGraphicStroke(pSvtGraphicStroke);
RenderPolygonHairlinePrimitive2D(static_cast< const primitive2d::PolygonHairlinePrimitive2D& >(rCandidate), false);
impEndSvtGraphicStroke(pSvtGraphicStroke);
if(bSupportSvtGraphicStroke)
{
impEndSvtGraphicStroke(pSvtGraphicStroke);
}
}
break;
}
......@@ -1631,7 +1646,12 @@ namespace drawinglayer
// XPATHFILL_SEQ_BEGIN/XPATHFILL_SEQ_END support
SvtGraphicFill* pSvtGraphicFill = 0;
if(!mnSvtGraphicFillCount && aLocalPolyPolygon.count())
// #121267# Not needed, does not give better quality compared with
// the META_POLYPOLYGON_ACTION written by the DrawPolyPolygon command
// below
bool bSupportSvtGraphicFill(false);
if(bSupportSvtGraphicFill && !mnSvtGraphicFillCount && aLocalPolyPolygon.count())
{
// setup simple color fill stuff like in impgrfll
pSvtGraphicFill = new SvtGraphicFill(
......@@ -1656,9 +1676,17 @@ namespace drawinglayer
mpOutputDevice->SetLineColor();
// call VCL directly; encapsulate with SvtGraphicFill
impStartSvtGraphicFill(pSvtGraphicFill);
if(bSupportSvtGraphicFill)
{
impStartSvtGraphicFill(pSvtGraphicFill);
}
mpOutputDevice->DrawPolyPolygon(aLocalPolyPolygon);
impEndSvtGraphicFill(pSvtGraphicFill);
if(bSupportSvtGraphicFill)
{
impEndSvtGraphicFill(pSvtGraphicFill);
}
break;
}
......@@ -1716,16 +1744,13 @@ namespace drawinglayer
// Removed subdivision and fixed in Region::ImplPolyPolyRegionToBandRegionFunc() in VCL where
// the ClipRegion is built from the Polygon. A AdaptiveSubdivide on the source polygon was missing there
mpOutputDevice->Push(PUSH_CLIPREGION);
//mpOutputDevice->SetClipRegion(Region(PolyPolygon(basegfx::tools::adaptiveSubdivideByAngle(maClipPolyPolygon))));
//mpOutputDevice->SetClipRegion(Region(PolyPolygon(maClipPolyPolygon)));
mpOutputDevice->SetClipRegion(Region(maClipPolyPolygon));
}
// recursively paint content
process(rMaskCandidate.getChildren());
// recursively paint content
// #121267# Only need to process sub-content when clip polygon is *not* empty.
// If it is empty, the clip is empty and there can be nothing inside.
process(rMaskCandidate.getChildren());
if(maClipPolyPolygon.count())
{
// restore VCL clip region
mpOutputDevice->Pop();
}
......@@ -1817,7 +1842,12 @@ namespace drawinglayer
// XPATHFILL_SEQ_BEGIN/XPATHFILL_SEQ_END support
SvtGraphicFill* pSvtGraphicFill = 0;
if(!mnSvtGraphicFillCount && aLocalPolyPolygon.count())
// #121267# Not needed, does not give better quality compared with
// the META_POLYPOLYGON_ACTION written by the DrawPolyPolygon command
// below
bool bSupportSvtGraphicFill(false);
if(bSupportSvtGraphicFill && !mnSvtGraphicFillCount && aLocalPolyPolygon.count())
{
// setup simple color with transparence fill stuff like in impgrfll
pSvtGraphicFill = new SvtGraphicFill(
......@@ -1843,11 +1873,19 @@ namespace drawinglayer
mpOutputDevice->SetLineColor();
// call VCL directly; encapsulate with SvtGraphicFill
impStartSvtGraphicFill(pSvtGraphicFill);
if(bSupportSvtGraphicFill)
{
impStartSvtGraphicFill(pSvtGraphicFill);
}
mpOutputDevice->DrawTransparent(
PolyPolygon(aLocalPolyPolygon),
nTransPercentVcl);
impEndSvtGraphicFill(pSvtGraphicFill);
if(bSupportSvtGraphicFill)
{
impEndSvtGraphicFill(pSvtGraphicFill);
}
}
else
{
......
......@@ -512,14 +512,16 @@ namespace drawinglayer
// nBWidth, nBHeight is the pixel size of the neede bitmap. To not need to scale it
// in vcl many times, create a size-optimized version
const Size aNeededBitmapSizePixel(nBWidth, nBHeight);
BitmapEx aBitmapEx(rFillGraphicAttribute.getGraphic().GetBitmapEx(
GraphicConversionParameters(
aNeededBitmapSizePixel, // get the correct size immediately
false, // no unlimited size
false, // Use AntiAliasing
false, //SnapHorVerLines
true // ScaleHighQuality
)));
BitmapEx aBitmapEx(rFillGraphicAttribute.getGraphic().GetBitmapEx());
static bool bEnablePreScaling(true);
const bool bPreScaled(bEnablePreScaling && nBWidth * nBHeight < (250 * 250));
if(bPreScaled)
{
// ... but only up to a maximum size, else it gets too expensive
aBitmapEx.Scale(aNeededBitmapSizePixel, BMP_SCALE_INTERPOLATE);
}
bool bPainted(false);
if(maBColorModifierStack.count())
......@@ -606,7 +608,14 @@ namespace drawinglayer
if(aOutRectPixel.IsOver(aVisiblePixel))
{
mpOutputDevice->DrawBitmapEx(aOutRectPixel.TopLeft(), aBitmapEx);
if(bPreScaled)
{
mpOutputDevice->DrawBitmapEx(aOutRectPixel.TopLeft(), aBitmapEx);
}
else
{
mpOutputDevice->DrawBitmapEx(aOutRectPixel.TopLeft(), aNeededBitmapSizePixel, aBitmapEx);
}
}
}
}
......@@ -626,7 +635,14 @@ namespace drawinglayer
if(aOutRectPixel.IsOver(aVisiblePixel))
{
mpOutputDevice->DrawBitmapEx(aOutRectPixel.TopLeft(), aBitmapEx);
if(bPreScaled)
{
mpOutputDevice->DrawBitmapEx(aOutRectPixel.TopLeft(), aBitmapEx);
}
else
{
mpOutputDevice->DrawBitmapEx(aOutRectPixel.TopLeft(), aNeededBitmapSizePixel, aBitmapEx);
}
}
}
}
......
......@@ -41,6 +41,7 @@
#include <vcl/metaact.hxx>
#include <svtools/wmf.hxx>
#include <svtools/filter.hxx>
#include <vcl/gdimetafiletools.hxx>
#include "swfexporter.hxx"
#include "swfwriter.hxx"
......@@ -721,8 +722,18 @@ bool FlashExporter::getMetaFile( Reference< XComponent >&xComponent, GDIMetaFile
}
else
{
rMtf.Read( *aFile.GetStream( STREAM_READ ) );
if(usesClipActions(rMtf))
{
// #121267# It is necessary to prepare the metafile since the export does *not* support
// clip regions. This tooling method clips the geometry content of the metafile internally
// against it's own clip regions, so that the export is safe to ignore clip regions
clipMetafileContentAgainstOwnRegions(rMtf);
}
}
int icount = rMtf.GetActionCount();
return icount != 0;
}
......
......@@ -41,7 +41,7 @@
#include <vcl/svapp.hxx>
#include <vcl/msgbox.hxx>
#include <svl/solar.hrc>
#include <vcl/gdimetafiletools.hxx>
// -----------------------------Feld-Typen-------------------------------
......@@ -2588,8 +2588,20 @@ sal_Bool METWriter::WriteMET( const GDIMetaFile& rMTF, SvStream& rTargetStream,
//================== GraphicExport - die exportierte Funktion ================
extern "C" sal_Bool __LOADONCALLAPI GraphicExport( SvStream & rStream, Graphic & rGraphic, FilterConfigItem* pFilterConfigItem, sal_Bool )
{ METWriter aMETWriter;
{
METWriter aMETWriter;
// #119735# just use GetGDIMetaFile, it will create a bufferd version of contained bitmap now automatically
GDIMetaFile aMetafile(rGraphic.GetGDIMetaFile());
if(usesClipActions(aMetafile))
{
// #121267# It is necessary to prepare the metafile since the export does *not* support
// clip regions. This tooling method clips the geometry content of the metafile internally
// against it's own clip regions, so that the export is safe to ignore clip regions
clipMetafileContentAgainstOwnRegions(aMetafile);
}
// #119735# just use GetGDIMetaFile, it will create a bufferd version of contained bitmap now automatically
return aMETWriter.WriteMET( rGraphic.GetGDIMetaFile(), rStream, pFilterConfigItem );
return aMETWriter.WriteMET( aMetafile, rStream, pFilterConfigItem );
}
......@@ -28,6 +28,7 @@
#include "emfwr.hxx"
#include "wmfwr.hxx"
#include <svtools/wmf.hxx>
#include <vcl/gdimetafiletools.hxx>
// -----------------------------------------------------------------------------
......@@ -83,7 +84,17 @@ sal_Bool ConvertGDIMetaFileToWMF( const GDIMetaFile & rMTF, SvStream & rTargetSt
FilterConfigItem* pConfigItem, sal_Bool bPlaceable)
{
WMFWriter aWMFWriter;
return aWMFWriter.WriteWMF( rMTF, rTargetStream, pConfigItem, bPlaceable );
GDIMetaFile aGdiMetaFile(rMTF);
if(usesClipActions(aGdiMetaFile))
{
// #121267# It is necessary to prepare the metafile since the export does *not* support
// clip regions. This tooling method clips the geometry content of the metafile internally
// against it's own clip regions, so that the export is safe to ignore clip regions
clipMetafileContentAgainstOwnRegions(aGdiMetaFile);
}
return aWMFWriter.WriteWMF( aGdiMetaFile, rTargetStream, pConfigItem, bPlaceable );
}
// -----------------------------------------------------------------------------
......@@ -92,7 +103,17 @@ sal_Bool ConvertGDIMetaFileToEMF( const GDIMetaFile & rMTF, SvStream & rTargetSt
FilterConfigItem* pConfigItem )
{
EMFWriter aEMFWriter;
return aEMFWriter.WriteEMF( rMTF, rTargetStream, pConfigItem );
GDIMetaFile aGdiMetaFile(rMTF);
if(usesClipActions(aGdiMetaFile))
{
// #121267# It is necessary to prepare the metafile since the export does *not* support
// clip regions. This tooling method clips the geometry content of the metafile internally
// against it's own clip regions, so that the export is safe to ignore clip regions
clipMetafileContentAgainstOwnRegions(aGdiMetaFile);
}
return aEMFWriter.WriteEMF( aGdiMetaFile, rTargetStream, pConfigItem );
}
// -----------------------------------------------------------------------------
......
......@@ -337,6 +337,7 @@ $(eval $(call gb_Library_add_exception_objects,vcl,\
vcl/source/gdi/extoutdevdata \
vcl/source/gdi/font \
vcl/source/gdi/gdimtf \
vcl/source/gdi/gdimetafiletools \
vcl/source/gdi/gfxlink \
vcl/source/gdi/gradient \
vcl/source/gdi/graph \
......
......@@ -62,6 +62,7 @@ $(eval $(call gb_Package_add_file,vcl_inc,inc/vcl/fntstyle.hxx,vcl/fntstyle.hxx)
$(eval $(call gb_Package_add_file,vcl_inc,inc/vcl/font.hxx,vcl/font.hxx))
$(eval $(call gb_Package_add_file,vcl_inc,inc/vcl/fontmanager.hxx,vcl/fontmanager.hxx))
$(eval $(call gb_Package_add_file,vcl_inc,inc/vcl/gdimtf.hxx,vcl/gdimtf.hxx))
$(eval $(call gb_Package_add_file,vcl_inc,inc/vcl/gdimetafiletools.hxx,vcl/gdimetafiletools.hxx))
$(eval $(call gb_Package_add_file,vcl_inc,inc/vcl/gfxlink.hxx,vcl/gfxlink.hxx))
$(eval $(call gb_Package_add_file,vcl_inc,inc/vcl/gradient.hxx,vcl/gradient.hxx))
$(eval $(call gb_Package_add_file,vcl_inc,inc/vcl/graph.h,vcl/graph.h))
......
/**************************************************************
*
* 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 _SV_GDIMETAFILETOOLS_HXX
#define _SV_GDIMETAFILETOOLS_HXX
#include <vcl/gdimtf.hxx>
//////////////////////////////////////////////////////////////////////////////
// #121267# Added tooling to be able to support old exporters which are based on
// metafiles as graphic content, but do not implement using the contained clip
// regions.
// The given metafile will internall yclip it's graphic content against the
// included clip regions so that it is safe to ignore clip actions there. This
// is not done completely, but implemented and extended as needed (on demand)
// since all this is a workarund; the better and long term solution will be to
// reimplement these im/exports to use primitives and not metafiles as bese
// information.
void VCL_DLLPUBLIC clipMetafileContentAgainstOwnRegions(GDIMetaFile& rSource);
//////////////////////////////////////////////////////////////////////////////
// Allow to check if a Metafile contains clipping or not
bool VCL_DLLPUBLIC usesClipActions(const GDIMetaFile& rSource);
//////////////////////////////////////////////////////////////////////////////
#endif // _SV_GDIMETAFILETOOLS_HXX
This diff is collapsed.
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