diff options
author | Ivo Hinkelmann <ihi@openoffice.org> | 2011-03-29 15:25:13 +0200 |
---|---|---|
committer | Ivo Hinkelmann <ihi@openoffice.org> | 2011-03-29 15:25:13 +0200 |
commit | 020f84b9be7ca00070fa832e48cd377cae462ad9 (patch) | |
tree | cccbac5ee51fe26f25b0a3f90ee11d8da916a240 | |
parent | 4c2b65f2c0966fa8528dcf0eac25168ced65b633 (diff) | |
parent | 44775760807ba1d60153208899eec2d583e16fe6 (diff) |
CWS-TOOLING: integrate CWS ka102
-rw-r--r-- | cppcanvas/source/mtfrenderer/implrenderer.cxx | 27 | ||||
-rw-r--r-- | cppcanvas/source/mtfrenderer/makefile.mk | 3 | ||||
-rw-r--r-- | cppcanvas/source/mtfrenderer/rendergraphicaction.cxx | 201 | ||||
-rw-r--r-- | cppcanvas/source/mtfrenderer/rendergraphicaction.hxx | 77 | ||||
-rw-r--r-- | cppcanvas/source/mtfrenderer/transparencygroupaction.cxx | 1 | ||||
-rw-r--r-- | svtools/AllLangResTarget_svt.mk | 2 | ||||
-rw-r--r-- | svtools/Library_svt.mk | 44 | ||||
-rw-r--r-- | svtools/inc/svtools/filter.hxx | 52 | ||||
-rw-r--r-- | svtools/inc/svtools/grfmgr.hxx | 33 | ||||
-rw-r--r-- | svtools/source/filter/FilterConfigCache.cxx (renamed from svtools/source/filter.vcl/filter/FilterConfigCache.cxx) | 3 | ||||
-rw-r--r-- | svtools/source/filter/FilterConfigCache.hxx (renamed from svtools/source/filter.vcl/filter/FilterConfigCache.hxx) | 0 | ||||
-rw-r--r--[-rwxr-xr-x] | svtools/source/filter/FilterConfigItem.cxx (renamed from svtools/source/filter.vcl/filter/FilterConfigItem.cxx) | 0 | ||||
-rw-r--r-- | svtools/source/filter/SvFilterOptionsDialog.cxx (renamed from svtools/source/filter.vcl/filter/SvFilterOptionsDialog.cxx) | 0 | ||||
-rw-r--r-- | svtools/source/filter/SvFilterOptionsDialog.hxx (renamed from svtools/source/filter.vcl/filter/SvFilterOptionsDialog.hxx) | 0 | ||||
-rw-r--r-- | svtools/source/filter/exportdialog.cxx (renamed from svtools/source/filter.vcl/filter/exportdialog.cxx) | 1 | ||||
-rw-r--r--[-rwxr-xr-x] | svtools/source/filter/exportdialog.hrc (renamed from svtools/source/filter.vcl/filter/exportdialog.hrc) | 0 | ||||
-rw-r--r--[-rwxr-xr-x] | svtools/source/filter/exportdialog.hxx (renamed from svtools/source/filter.vcl/filter/exportdialog.hxx) | 0 | ||||
-rw-r--r-- | svtools/source/filter/exportdialog.src (renamed from svtools/source/filter.vcl/filter/exportdialog.src) | 0 | ||||
-rw-r--r-- | svtools/source/filter/filter.cxx (renamed from svtools/source/filter.vcl/filter/filter.cxx) | 119 | ||||
-rw-r--r-- | svtools/source/filter/filter2.cxx (renamed from svtools/source/filter.vcl/filter/filter2.cxx) | 19 | ||||
-rw-r--r-- | svtools/source/filter/igif/decode.cxx (renamed from svtools/source/filter.vcl/igif/decode.cxx) | 0 | ||||
-rw-r--r-- | svtools/source/filter/igif/decode.hxx (renamed from svtools/source/filter.vcl/igif/decode.hxx) | 0 | ||||
-rw-r--r-- | svtools/source/filter/igif/gifread.cxx (renamed from svtools/source/filter.vcl/igif/gifread.cxx) | 0 | ||||
-rw-r--r-- | svtools/source/filter/ixbm/xbmread.cxx (renamed from svtools/source/filter.vcl/ixbm/xbmread.cxx) | 0 | ||||
-rw-r--r-- | svtools/source/filter/ixpm/rgbtable.hxx (renamed from svtools/source/filter.vcl/ixpm/rgbtable.hxx) | 0 | ||||
-rw-r--r-- | svtools/source/filter/ixpm/xpmread.cxx (renamed from svtools/source/filter.vcl/ixpm/xpmread.cxx) | 0 | ||||
-rw-r--r-- | svtools/source/filter/jpeg/jpeg.cxx (renamed from svtools/source/filter.vcl/jpeg/jpeg.cxx) | 0 | ||||
-rw-r--r-- | svtools/source/filter/jpeg/jpeg.h (renamed from svtools/source/filter.vcl/jpeg/jpeg.h) | 0 | ||||
-rw-r--r-- | svtools/source/filter/jpeg/jpegc.c (renamed from svtools/source/filter.vcl/jpeg/jpegc.c) | 0 | ||||
-rw-r--r-- | svtools/source/filter/sgf.ini (renamed from svtools/source/filter.vcl/filter/sgf.ini) | 0 | ||||
-rw-r--r-- | svtools/source/filter/sgfbram.cxx (renamed from svtools/source/filter.vcl/filter/sgfbram.cxx) | 0 | ||||
-rw-r--r-- | svtools/source/filter/sgvmain.cxx (renamed from svtools/source/filter.vcl/filter/sgvmain.cxx) | 0 | ||||
-rw-r--r-- | svtools/source/filter/sgvspln.cxx (renamed from svtools/source/filter.vcl/filter/sgvspln.cxx) | 0 | ||||
-rw-r--r-- | svtools/source/filter/sgvtext.cxx (renamed from svtools/source/filter.vcl/filter/sgvtext.cxx) | 0 | ||||
-rw-r--r-- | svtools/source/filter/wmf/emfwr.cxx (renamed from svtools/source/filter.vcl/wmf/emfwr.cxx) | 27 | ||||
-rw-r--r-- | svtools/source/filter/wmf/emfwr.hxx (renamed from svtools/source/filter.vcl/wmf/emfwr.hxx) | 0 | ||||
-rw-r--r-- | svtools/source/filter/wmf/enhwmf.cxx (renamed from svtools/source/filter.vcl/wmf/enhwmf.cxx) | 13 | ||||
-rw-r--r-- | svtools/source/filter/wmf/winmtf.cxx (renamed from svtools/source/filter.vcl/wmf/winmtf.cxx) | 1 | ||||
-rw-r--r-- | svtools/source/filter/wmf/winmtf.hxx (renamed from svtools/source/filter.vcl/wmf/winmtf.hxx) | 2 | ||||
-rw-r--r-- | svtools/source/filter/wmf/winwmf.cxx (renamed from svtools/source/filter.vcl/wmf/winwmf.cxx) | 1 | ||||
-rw-r--r-- | svtools/source/filter/wmf/wmf.cxx (renamed from svtools/source/filter.vcl/wmf/wmf.cxx) | 0 | ||||
-rw-r--r-- | svtools/source/filter/wmf/wmfwr.cxx (renamed from svtools/source/filter.vcl/wmf/wmfwr.cxx) | 28 | ||||
-rw-r--r-- | svtools/source/filter/wmf/wmfwr.hxx (renamed from svtools/source/filter.vcl/wmf/wmfwr.hxx) | 4 | ||||
-rw-r--r-- | svtools/source/graphic/descriptor.cxx | 1 | ||||
-rw-r--r-- | svtools/source/graphic/grfmgr.cxx | 16 | ||||
-rw-r--r-- | svtools/source/graphic/grfmgr2.cxx | 3 | ||||
-rw-r--r-- | vcl/inc/vcl/gdimtf.hxx | 12 | ||||
-rw-r--r-- | vcl/inc/vcl/gfxlink.hxx | 3 | ||||
-rw-r--r-- | vcl/inc/vcl/graph.hxx | 16 | ||||
-rw-r--r-- | vcl/inc/vcl/impgraph.hxx | 20 | ||||
-rw-r--r-- | vcl/inc/vcl/metaact.hxx | 51 | ||||
-rw-r--r--[-rwxr-xr-x] | vcl/inc/vcl/outdev.hxx | 23 | ||||
-rw-r--r-- | vcl/inc/vcl/rendergraphic.hxx | 124 | ||||
-rw-r--r-- | vcl/inc/vcl/rendergraphicrasterizer.hxx | 111 | ||||
-rw-r--r-- | vcl/inc/vcl/salctype.hxx | 1 | ||||
-rw-r--r-- | vcl/inc/vcl/svgread.hxx | 80 | ||||
-rw-r--r-- | vcl/prj/d.lst | 3 | ||||
-rw-r--r-- | vcl/source/components/factory.cxx | 15 | ||||
-rw-r--r-- | vcl/source/components/makefile.mk | 21 | ||||
-rw-r--r-- | vcl/source/components/rasterizer_rsvg.cxx | 640 | ||||
-rw-r--r-- | vcl/source/gdi/gdimtf.cxx | 768 | ||||
-rw-r--r-- | vcl/source/gdi/gfxlink.cxx | 1 | ||||
-rw-r--r-- | vcl/source/gdi/graph.cxx | 28 | ||||
-rw-r--r-- | vcl/source/gdi/impgraph.cxx | 54 | ||||
-rwxr-xr-x | vcl/source/gdi/makefile.mk | 94 | ||||
-rw-r--r-- | vcl/source/gdi/metaact.cxx | 90 | ||||
-rw-r--r-- | vcl/source/gdi/outdev6.cxx | 29 | ||||
-rw-r--r-- | vcl/source/gdi/pdfwriter_impl2.cxx | 12 | ||||
-rw-r--r-- | vcl/source/gdi/print2.cxx | 30 | ||||
-rw-r--r-- | vcl/source/gdi/rendergraphic.cxx | 240 | ||||
-rw-r--r-- | vcl/source/gdi/rendergraphicrasterizer.cxx | 400 | ||||
-rw-r--r-- | vcl/source/gdi/svgread.cxx | 131 | ||||
-rw-r--r-- | vcl/util/makefile.mk | 2 | ||||
-rw-r--r-- | vcl/util/vcl.component | 3 | ||||
-rw-r--r-- | vcl/util/vcl.macosx.component | 3 | ||||
-rw-r--r-- | vcl/util/vcl.windows.component | 3 |
76 files changed, 3173 insertions, 513 deletions
diff --git a/cppcanvas/source/mtfrenderer/implrenderer.cxx b/cppcanvas/source/mtfrenderer/implrenderer.cxx index 1e0611ab037a..d0382997a9db 100644 --- a/cppcanvas/source/mtfrenderer/implrenderer.cxx +++ b/cppcanvas/source/mtfrenderer/implrenderer.cxx @@ -83,6 +83,7 @@ #include <lineaction.hxx> #include <pointaction.hxx> #include <polypolyaction.hxx> +#include <rendergraphicaction.hxx> #include <textaction.hxx> #include <transparencygroupaction.hxx> #include <vector> @@ -2653,6 +2654,32 @@ namespace cppcanvas } break; + case META_RENDERGRAPHIC_ACTION: + { + MetaRenderGraphicAction* pAct = static_cast<MetaRenderGraphicAction*>(pCurrAct); + + ActionSharedPtr pRenderGraphicAction( + internal::RenderGraphicActionFactory::createRenderGraphicAction( + pAct->GetRenderGraphic(), + getState( rStates ).mapModeTransform * + ::vcl::unotools::b2DPointFromPoint( pAct->GetPoint() ), + getState( rStates ).mapModeTransform * + ::vcl::unotools::b2DSizeFromSize( pAct->GetSize() ), + rCanvas, + getState( rStates ) ) ); + + if( pRenderGraphicAction ) + { + maActions.push_back( + MtfAction( + pRenderGraphicAction, + io_rCurrActionIndex ) ); + + io_rCurrActionIndex += pRenderGraphicAction->getActionCount()-1; + } + } + break; + default: OSL_ENSURE( false, "Unknown meta action type encountered" ); diff --git a/cppcanvas/source/mtfrenderer/makefile.mk b/cppcanvas/source/mtfrenderer/makefile.mk index dfe6e28030bf..92ae7e1200bc 100644 --- a/cppcanvas/source/mtfrenderer/makefile.mk +++ b/cppcanvas/source/mtfrenderer/makefile.mk @@ -1,7 +1,7 @@ #************************************************************************* # # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -# +# # Copyright 2000, 2010 Oracle and/or its affiliates. # # OpenOffice.org - a multi-platform office productivity suite @@ -48,6 +48,7 @@ SLOFILES = $(SLO)$/cachedprimitivebase.obj \ $(SLO)$/lineaction.obj \ $(SLO)$/pointaction.obj \ $(SLO)$/polypolyaction.obj \ + $(SLO)$/rendergraphicaction.obj \ $(SLO)$/textaction.obj \ $(SLO)$/transparencygroupaction.obj \ $(SLO)$/mtftools.obj diff --git a/cppcanvas/source/mtfrenderer/rendergraphicaction.cxx b/cppcanvas/source/mtfrenderer/rendergraphicaction.cxx new file mode 100644 index 000000000000..764d3eabc6af --- /dev/null +++ b/cppcanvas/source/mtfrenderer/rendergraphicaction.cxx @@ -0,0 +1,201 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_cppcanvas.hxx" + +#include <rtl/logfile.hxx> +#include <com/sun/star/rendering/XBitmap.hpp> +#include <com/sun/star/rendering/RepaintResult.hpp> +#include <com/sun/star/rendering/XCachedPrimitive.hpp> +#include <vcl/rendergraphicrasterizer.hxx> +#include <tools/gen.hxx> +#include <vcl/canvastools.hxx> +#include <canvas/canvastools.hxx> +#include <basegfx/matrix/b2dhommatrix.hxx> +#include <basegfx/vector/b2dsize.hxx> +#include <basegfx/point/b2dpoint.hxx> +#include <basegfx/range/b2drange.hxx> +#include <basegfx/tools/canvastools.hxx> +#include <boost/utility.hpp> +#include "cachedprimitivebase.hxx" +#include "rendergraphicaction.hxx" +#include "outdevstate.hxx" +#include "mtftools.hxx" +#include <basegfx/matrix/b2dhommatrixtools.hxx> + + +using namespace ::com::sun::star; + +namespace cppcanvas +{ + namespace internal + { + namespace + { + + class RenderGraphicAction : public CachedPrimitiveBase + { + public: + RenderGraphicAction( const ::vcl::RenderGraphic& rRenderGraphic, + const ::basegfx::B2DPoint& rDstPoint, + const ::basegfx::B2DVector& rDstSize, + const CanvasSharedPtr&, + const OutDevState& ); + + virtual bool render( const ::basegfx::B2DHomMatrix& rTransformation, + const Subset& rSubset ) const; + + virtual ::basegfx::B2DRange getBounds( const ::basegfx::B2DHomMatrix& rTransformation ) const; + virtual ::basegfx::B2DRange getBounds( const ::basegfx::B2DHomMatrix& rTransformation, + const Subset& rSubset ) const; + + virtual sal_Int32 getActionCount() const; + + private: + using Action::render; + virtual bool render( uno::Reference< rendering::XCachedPrimitive >& rCachedPrimitive, + const ::basegfx::B2DHomMatrix& rTransformation ) const; + + ::vcl::RenderGraphic maRenderGraphic; + uno::Reference< rendering::XBitmap > mxBitmap; + CanvasSharedPtr mpCanvas; + rendering::RenderState maState; + }; + + RenderGraphicAction::RenderGraphicAction( const ::vcl::RenderGraphic& rRenderGraphic, + const ::basegfx::B2DPoint& rDstPoint, + const ::basegfx::B2DVector& rDstSize, + const CanvasSharedPtr& rCanvas, + const OutDevState& rState ) : + CachedPrimitiveBase( rCanvas, true ), + maRenderGraphic( rRenderGraphic ), + mpCanvas( rCanvas ) + { + tools::initRenderState( maState,rState ); + + const ::vcl::RenderGraphicRasterizer aRasterizer( rRenderGraphic ); + const BitmapEx aBmpEx( aRasterizer.Rasterize( ::vcl::unotools::sizeFromB2DSize( rDstSize ) ) ); + const Size aRasteredSizePixel( aBmpEx.GetSizePixel() ); + + if( aRasteredSizePixel.Width() && aRasteredSizePixel.Height() ) + { + const ::basegfx::B2DVector aScale( rDstSize.getX() / aRasteredSizePixel.Width(), + rDstSize.getY() / aRasteredSizePixel.Height() ); + const basegfx::B2DHomMatrix aLocalTransformation( + basegfx::tools::createScaleTranslateB2DHomMatrix( aScale, rDstPoint)) ; + + ::canvas::tools::appendToRenderState( maState, aLocalTransformation ); + + // correct clip (which is relative to original transform) + tools::modifyClip( maState, rState, rCanvas, rDstPoint, &aScale, NULL ); + + mxBitmap = ::vcl::unotools::xBitmapFromBitmapEx( rCanvas->getUNOCanvas()->getDevice(), aBmpEx ); + } + } + + bool RenderGraphicAction::render( uno::Reference< rendering::XCachedPrimitive >& rCachedPrimitive, + const ::basegfx::B2DHomMatrix& rTransformation ) const + { + RTL_LOGFILE_CONTEXT( aLog, "::cppcanvas::internal::RenderGraphicAction::render()" ); + RTL_LOGFILE_CONTEXT_TRACE1( aLog, "::cppcanvas::internal::RenderGraphicAction: 0x%X", this ); + + if( mxBitmap.is() ) + { + rendering::RenderState aLocalState( maState ); + ::canvas::tools::prependToRenderState(aLocalState, rTransformation); + + rCachedPrimitive = mpCanvas->getUNOCanvas()->drawBitmap( mxBitmap, + mpCanvas->getViewState(), + aLocalState ); + } + + return true; + } + + bool RenderGraphicAction::render( const ::basegfx::B2DHomMatrix& rTransformation, + const Subset& rSubset ) const + { + // rendergraphic only contains a single action, fail if subset + // requests different range + if( rSubset.mnSubsetBegin != 0 || + rSubset.mnSubsetEnd != 1 ) + return false; + + return CachedPrimitiveBase::render( rTransformation ); + } + + ::basegfx::B2DRange RenderGraphicAction::getBounds( const ::basegfx::B2DHomMatrix& rTransformation ) const + { + ::basegfx::B2DRange aRet; + + if( mxBitmap.is() ) + { + rendering::RenderState aLocalState( maState ); + ::canvas::tools::prependToRenderState(aLocalState, rTransformation); + + geometry::IntegerSize2D aSize( mxBitmap->getSize() ); + + aRet = tools::calcDevicePixelBounds( ::basegfx::B2DRange( 0, 0, aSize.Width, aSize.Height ), + mpCanvas->getViewState(), aLocalState ); + } + + return( aRet ); + } + + ::basegfx::B2DRange RenderGraphicAction::getBounds( const ::basegfx::B2DHomMatrix& rTransformation, + const Subset& rSubset ) const + { + // rendergraphic only contains a single action, empty bounds + // if subset requests different range + if( rSubset.mnSubsetBegin != 0 || + rSubset.mnSubsetEnd != 1 ) + return ::basegfx::B2DRange(); + + return getBounds( rTransformation ); + } + + sal_Int32 RenderGraphicAction::getActionCount() const + { + return 1; + } + } + + ActionSharedPtr RenderGraphicActionFactory::createRenderGraphicAction( const ::vcl::RenderGraphic& rRenderGraphic, + const ::basegfx::B2DPoint& rDstPoint, + const ::basegfx::B2DVector& rDstSize, + const CanvasSharedPtr& rCanvas, + const OutDevState& rState ) + { + return ActionSharedPtr( new RenderGraphicAction(rRenderGraphic, + rDstPoint, + rDstSize, + rCanvas, + rState ) ); + } + } +} diff --git a/cppcanvas/source/mtfrenderer/rendergraphicaction.hxx b/cppcanvas/source/mtfrenderer/rendergraphicaction.hxx new file mode 100644 index 000000000000..f1e2dccdfe0d --- /dev/null +++ b/cppcanvas/source/mtfrenderer/rendergraphicaction.hxx @@ -0,0 +1,77 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#ifndef _CPPCANVAS_RENDERGRAPHICACTION_HXX +#define _CPPCANVAS_RENDERGRAPHICACTION_HXX + +#include <cppcanvas/canvas.hxx> +#include <action.hxx> + +namespace basegfx { + class B2DPoint; + class B2DVector; +} +namespace vcl { + class RenderGraphic; +} + +/* Definition of internal::RenderGraphicActionFactory class */ + +namespace cppcanvas +{ + namespace internal + { + struct OutDevState; + + /** Creates encapsulated converters between GDIMetaFile and + XCanvas. The Canvas argument is deliberately placed at the + constructor, to force reconstruction of this object for a + new canvas. This considerably eases internal state + handling, since a lot of the internal state (e.g. fonts, + text layout) is Canvas-dependent. + */ + class RenderGraphicActionFactory + { + public: + /// Scaled rendergraphic action, dest point and dest size + static ActionSharedPtr createRenderGraphicAction( const ::vcl::RenderGraphic& rRenderGraphic, + const ::basegfx::B2DPoint& rDstPoint, + const ::basegfx::B2DVector& rDstSize, + const CanvasSharedPtr&, + const OutDevState& ); + + private: + // static factory, disable big four + RenderGraphicActionFactory(); + ~RenderGraphicActionFactory(); + RenderGraphicActionFactory(const RenderGraphicActionFactory&); + RenderGraphicActionFactory& operator=( const RenderGraphicActionFactory& ); + }; + } +} + +#endif /*_CPPCANVAS_RENDERGRAPHICACTION_HXX */ diff --git a/cppcanvas/source/mtfrenderer/transparencygroupaction.cxx b/cppcanvas/source/mtfrenderer/transparencygroupaction.cxx index a8984d41e585..7255df14cd47 100644 --- a/cppcanvas/source/mtfrenderer/transparencygroupaction.cxx +++ b/cppcanvas/source/mtfrenderer/transparencygroupaction.cxx @@ -391,6 +391,7 @@ namespace cppcanvas case META_TEXTLINE_ACTION: case META_TEXTRECT_ACTION: case META_STRETCHTEXT_ACTION: + case META_RENDERGRAPHIC_ACTION: // output-generating action - only // copy, if we're within the // requested subset diff --git a/svtools/AllLangResTarget_svt.mk b/svtools/AllLangResTarget_svt.mk index 6c13a6fcdb3f..59088cb126c3 100644 --- a/svtools/AllLangResTarget_svt.mk +++ b/svtools/AllLangResTarget_svt.mk @@ -60,7 +60,7 @@ $(eval $(call gb_SrsTarget_add_files,svt/res,\ svtools/source/dialogs/prnsetup.src \ svtools/source/dialogs/so3res.src \ svtools/source/dialogs/wizardmachine.src \ - svtools/source/filter.vcl/filter/exportdialog.src \ + svtools/source/filter/exportdialog.src \ svtools/source/java/javaerror.src \ svtools/source/misc/ehdl.src \ svtools/source/misc/helpagent.src \ diff --git a/svtools/Library_svt.mk b/svtools/Library_svt.mk index 01bc05ebaeca..39b135f16b1e 100644 --- a/svtools/Library_svt.mk +++ b/svtools/Library_svt.mk @@ -178,27 +178,27 @@ $(eval $(call gb_Library_add_exception_objects,svt,\ svtools/source/edit/textwindowpeer \ svtools/source/edit/txtattr \ svtools/source/edit/xtextedt \ - svtools/source/filter.vcl/filter/FilterConfigCache \ - svtools/source/filter.vcl/filter/FilterConfigItem \ - svtools/source/filter.vcl/filter/SvFilterOptionsDialog \ - svtools/source/filter.vcl/filter/exportdialog \ - svtools/source/filter.vcl/filter/filter \ - svtools/source/filter.vcl/filter/filter2 \ - svtools/source/filter.vcl/filter/sgfbram \ - svtools/source/filter.vcl/filter/sgvmain \ - svtools/source/filter.vcl/filter/sgvspln \ - svtools/source/filter.vcl/filter/sgvtext \ - svtools/source/filter.vcl/igif/decode \ - svtools/source/filter.vcl/igif/gifread \ - svtools/source/filter.vcl/ixbm/xbmread \ - svtools/source/filter.vcl/ixpm/xpmread \ - svtools/source/filter.vcl/jpeg/jpeg \ - svtools/source/filter.vcl/wmf/emfwr \ - svtools/source/filter.vcl/wmf/enhwmf \ - svtools/source/filter.vcl/wmf/winmtf \ - svtools/source/filter.vcl/wmf/winwmf \ - svtools/source/filter.vcl/wmf/wmf \ - svtools/source/filter.vcl/wmf/wmfwr \ + svtools/source/filter/FilterConfigCache \ + svtools/source/filter/FilterConfigItem \ + svtools/source/filter/SvFilterOptionsDialog \ + svtools/source/filter/exportdialog \ + svtools/source/filter/filter \ + svtools/source/filter/filter2 \ + svtools/source/filter/sgfbram \ + svtools/source/filter/sgvmain \ + svtools/source/filter/sgvspln \ + svtools/source/filter/sgvtext \ + svtools/source/filter/igif/decode \ + svtools/source/filter/igif/gifread \ + svtools/source/filter/ixbm/xbmread \ + svtools/source/filter/ixpm/xpmread \ + svtools/source/filter/jpeg/jpeg \ + svtools/source/filter/wmf/emfwr \ + svtools/source/filter/wmf/enhwmf \ + svtools/source/filter/wmf/winmtf \ + svtools/source/filter/wmf/winwmf \ + svtools/source/filter/wmf/wmf \ + svtools/source/filter/wmf/wmfwr \ svtools/source/graphic/descriptor \ svtools/source/graphic/graphic \ svtools/source/graphic/graphicunofactory \ @@ -291,7 +291,7 @@ $(eval $(call gb_Library_add_exception_objects,svt,\ )) $(eval $(call gb_Library_add_cobjects,svt,\ - svtools/source/filter.vcl/jpeg/jpegc \ + svtools/source/filter/jpeg/jpegc \ )) ifeq ($(OS),WNT) diff --git a/svtools/inc/svtools/filter.hxx b/svtools/inc/svtools/filter.hxx index 66c80dde2d79..3245200605d4 100644 --- a/svtools/inc/svtools/filter.hxx +++ b/svtools/inc/svtools/filter.hxx @@ -83,6 +83,7 @@ class Graphic; #define IMP_JPEG "SVIJPEG" #define IMP_XBM "SVIXBM" #define IMP_XPM "SVIXPM" +#define IMP_SVG "SVISVG" #define EXP_BMP "SVBMP" #define EXP_SVMETAFILE "SVMETAFILE" #define EXP_WMF "SVWMF" @@ -101,6 +102,7 @@ class Graphic; #define TIF_SHORTNAME "TIF" #define WMF_SHORTNAME "WMF" #define EMF_SHORTNAME "EMF" +#define SVG_SHORTNAME "SVG" // ------------------------------------ // - Info-Klasse fuer alle von uns @@ -132,6 +134,7 @@ class Graphic; #define GFF_WMF ( (sal_uInt16)0x00f6 ) #define GFF_SGV ( (sal_uInt16)0x00f7 ) #define GFF_EMF ( (sal_uInt16)0x00f8 ) +#define GFF_SVG ( (sal_uInt16)0x00f9 ) #define GFF_XXX ( (sal_uInt16)0xffff ) // --------------------- @@ -153,30 +156,31 @@ class SVT_DLLPUBLIC GraphicDescriptor void ImpConstruct(); - sal_Bool ImpDetectBMP( SvStream& rStm, sal_Bool bExtendedInfo ); - sal_Bool ImpDetectGIF( SvStream& rStm, sal_Bool bExtendedInfo ); - sal_Bool ImpDetectJPG( SvStream& rStm, sal_Bool bExtendedInfo ); - sal_Bool ImpDetectPCD( SvStream& rStm, sal_Bool bExtendedInfo ); - sal_Bool ImpDetectPCX( SvStream& rStm, sal_Bool bExtendedInfo ); - sal_Bool ImpDetectPNG( SvStream& rStm, sal_Bool bExtendedInfo ); - sal_Bool ImpDetectTIF( SvStream& rStm, sal_Bool bExtendedInfo ); - sal_Bool ImpDetectXBM( SvStream& rStm, sal_Bool bExtendedInfo ); - sal_Bool ImpDetectXPM( SvStream& rStm, sal_Bool bExtendedInfo ); - sal_Bool ImpDetectPBM( SvStream& rStm, sal_Bool bExtendedInfo ); - sal_Bool ImpDetectPGM( SvStream& rStm, sal_Bool bExtendedInfo ); - sal_Bool ImpDetectPPM( SvStream& rStm, sal_Bool bExtendedInfo ); - sal_Bool ImpDetectRAS( SvStream& rStm, sal_Bool bExtendedInfo ); - sal_Bool ImpDetectTGA( SvStream& rStm, sal_Bool bExtendedInfo ); - sal_Bool ImpDetectPSD( SvStream& rStm, sal_Bool bExtendedInfo ); - sal_Bool ImpDetectEPS( SvStream& rStm, sal_Bool bExtendedInfo ); - sal_Bool ImpDetectDXF( SvStream& rStm, sal_Bool bExtendedInfo ); - sal_Bool ImpDetectMET( SvStream& rStm, sal_Bool bExtendedInfo ); - sal_Bool ImpDetectPCT( SvStream& rStm, sal_Bool bExtendedInfo ); - sal_Bool ImpDetectSGF( SvStream& rStm, sal_Bool bExtendedInfo ); - sal_Bool ImpDetectSVM( SvStream& rStm, sal_Bool bExtendedInfo ); - sal_Bool ImpDetectWMF( SvStream& rStm, sal_Bool bExtendedInfo ); - sal_Bool ImpDetectSGV( SvStream& rStm, sal_Bool bExtendedInfo ); - sal_Bool ImpDetectEMF( SvStream& rStm, sal_Bool bExtendedInfo ); + sal_Bool ImpDetectBMP( SvStream& rStm, sal_Bool bExtendedInfo ); + sal_Bool ImpDetectGIF( SvStream& rStm, sal_Bool bExtendedInfo ); + sal_Bool ImpDetectJPG( SvStream& rStm, sal_Bool bExtendedInfo ); + sal_Bool ImpDetectPCD( SvStream& rStm, sal_Bool bExtendedInfo ); + sal_Bool ImpDetectPCX( SvStream& rStm, sal_Bool bExtendedInfo ); + sal_Bool ImpDetectPNG( SvStream& rStm, sal_Bool bExtendedInfo ); + sal_Bool ImpDetectTIF( SvStream& rStm, sal_Bool bExtendedInfo ); + sal_Bool ImpDetectXBM( SvStream& rStm, sal_Bool bExtendedInfo ); + sal_Bool ImpDetectXPM( SvStream& rStm, sal_Bool bExtendedInfo ); + sal_Bool ImpDetectPBM( SvStream& rStm, sal_Bool bExtendedInfo ); + sal_Bool ImpDetectPGM( SvStream& rStm, sal_Bool bExtendedInfo ); + sal_Bool ImpDetectPPM( SvStream& rStm, sal_Bool bExtendedInfo ); + sal_Bool ImpDetectRAS( SvStream& rStm, sal_Bool bExtendedInfo ); + sal_Bool ImpDetectTGA( SvStream& rStm, sal_Bool bExtendedInfo ); + sal_Bool ImpDetectPSD( SvStream& rStm, sal_Bool bExtendedInfo ); + sal_Bool ImpDetectEPS( SvStream& rStm, sal_Bool bExtendedInfo ); + sal_Bool ImpDetectDXF( SvStream& rStm, sal_Bool bExtendedInfo ); + sal_Bool ImpDetectMET( SvStream& rStm, sal_Bool bExtendedInfo ); + sal_Bool ImpDetectPCT( SvStream& rStm, sal_Bool bExtendedInfo ); + sal_Bool ImpDetectSGF( SvStream& rStm, sal_Bool bExtendedInfo ); + sal_Bool ImpDetectSVM( SvStream& rStm, sal_Bool bExtendedInfo ); + sal_Bool ImpDetectWMF( SvStream& rStm, sal_Bool bExtendedInfo ); + sal_Bool ImpDetectSGV( SvStream& rStm, sal_Bool bExtendedInfo ); + sal_Bool ImpDetectEMF( SvStream& rStm, sal_Bool bExtendedInfo ); + sal_Bool ImpDetectSVG( SvStream& rStm, sal_Bool bExtendedInfo ); GraphicDescriptor( const GraphicDescriptor& ); GraphicDescriptor& operator=( const GraphicDescriptor& ); diff --git a/svtools/inc/svtools/grfmgr.hxx b/svtools/inc/svtools/grfmgr.hxx index 9841d4e312ef..155bd8402a74 100644 --- a/svtools/inc/svtools/grfmgr.hxx +++ b/svtools/inc/svtools/grfmgr.hxx @@ -213,14 +213,16 @@ private: sal_uLong mnAnimationLoopCount; void* mpDummy1; void* mpDummy2; - sal_Bool mbAutoSwapped : 1; - sal_Bool mbTransparent : 1; - sal_Bool mbAnimated : 1; - sal_Bool mbEPS : 1; - sal_Bool mbIsInSwapIn : 1; - sal_Bool mbIsInSwapOut : 1; - sal_Bool mbAlpha : 1; - sal_Bool mbDummyFlag8 : 1; + sal_Bool mbAutoSwapped : 1; + sal_Bool mbTransparent : 1; + sal_Bool mbAnimated : 1; + sal_Bool mbEPS : 1; + sal_Bool mbIsInSwapIn : 1; + sal_Bool mbIsInSwapOut : 1; + sal_Bool mbAlpha : 1; + sal_Bool mbDummyFlag8 : 1; + sal_Bool mbIsRenderGraphic : 1; + sal_Bool mbHasRenderGraphic : 1; void SVT_DLLPRIVATE ImplConstruct(); void SVT_DLLPRIVATE ImplAssignGraphicData(); @@ -396,12 +398,14 @@ public: GraphicType GetType() const { return meType; } const Size& GetPrefSize() const { return maPrefSize; } const MapMode& GetPrefMapMode() const { return maPrefMapMode; } - sal_uLong GetSizeBytes() const { return mnSizeBytes; } - sal_uLong GetChecksum() const; - sal_Bool IsTransparent() const { return mbTransparent; } - sal_Bool IsAlpha() const { return mbAlpha; } - sal_Bool IsAnimated() const { return mbAnimated; } - sal_Bool IsEPS() const { return mbEPS; } + sal_uLong GetSizeBytes() const { return mnSizeBytes; } + sal_uLong GetChecksum() const; + sal_Bool IsTransparent() const { return mbTransparent; } + sal_Bool IsAlpha() const { return mbAlpha; } + sal_Bool IsAnimated() const { return mbAnimated; } + sal_Bool IsEPS() const { return mbEPS; } + sal_Bool IsRenderGraphic() const { return mbIsRenderGraphic; } + sal_Bool HasRenderGraphic() const { return mbHasRenderGraphic; } void ResetAnimationLoopCount(); List* GetAnimationInfoList() const; @@ -568,4 +572,3 @@ public: }; #endif // _GRFMGR_HXX - diff --git a/svtools/source/filter.vcl/filter/FilterConfigCache.cxx b/svtools/source/filter/FilterConfigCache.cxx index 48408609cf98..979eba91767d 100644 --- a/svtools/source/filter.vcl/filter/FilterConfigCache.cxx +++ b/svtools/source/filter/FilterConfigCache.cxx @@ -56,7 +56,7 @@ const char* FilterConfigCache::FilterConfigCacheEntry::InternalPixelFilterNameLi const char* FilterConfigCache::FilterConfigCacheEntry::InternalVectorFilterNameList[] = { - IMP_SVMETAFILE, IMP_WMF, IMP_EMF, IMP_SVSGF, IMP_SVSGV, + IMP_SVMETAFILE, IMP_WMF, IMP_EMF, IMP_SVSGF, IMP_SVSGV, IMP_SVG, EXP_SVMETAFILE, EXP_WMF, EXP_EMF, EXP_SVG, NULL }; @@ -303,6 +303,7 @@ const char* FilterConfigCache::InternalFilterListForSvxLight[] = "xbm","1","SVIXBM", "xpm","1","SVIXPM", "xpm","2","exp", + "svg","1","SVISVG", "svg","2","SVESVG", NULL }; diff --git a/svtools/source/filter.vcl/filter/FilterConfigCache.hxx b/svtools/source/filter/FilterConfigCache.hxx index 2c6b7361e540..2c6b7361e540 100644 --- a/svtools/source/filter.vcl/filter/FilterConfigCache.hxx +++ b/svtools/source/filter/FilterConfigCache.hxx diff --git a/svtools/source/filter.vcl/filter/FilterConfigItem.cxx b/svtools/source/filter/FilterConfigItem.cxx index 8d7752ddd7df..8d7752ddd7df 100755..100644 --- a/svtools/source/filter.vcl/filter/FilterConfigItem.cxx +++ b/svtools/source/filter/FilterConfigItem.cxx diff --git a/svtools/source/filter.vcl/filter/SvFilterOptionsDialog.cxx b/svtools/source/filter/SvFilterOptionsDialog.cxx index 1c4eeeff1bbf..1c4eeeff1bbf 100644 --- a/svtools/source/filter.vcl/filter/SvFilterOptionsDialog.cxx +++ b/svtools/source/filter/SvFilterOptionsDialog.cxx diff --git a/svtools/source/filter.vcl/filter/SvFilterOptionsDialog.hxx b/svtools/source/filter/SvFilterOptionsDialog.hxx index 027fac99c2e8..027fac99c2e8 100644 --- a/svtools/source/filter.vcl/filter/SvFilterOptionsDialog.hxx +++ b/svtools/source/filter/SvFilterOptionsDialog.hxx diff --git a/svtools/source/filter.vcl/filter/exportdialog.cxx b/svtools/source/filter/exportdialog.cxx index 701619d31f6c..472fe327329d 100644 --- a/svtools/source/filter.vcl/filter/exportdialog.cxx +++ b/svtools/source/filter/exportdialog.cxx @@ -1510,4 +1510,3 @@ IMPL_LINK( ExportDialog, OK, void *, EMPTYARG ) return 0; } - diff --git a/svtools/source/filter.vcl/filter/exportdialog.hrc b/svtools/source/filter/exportdialog.hrc index e230bcd2c5c3..e230bcd2c5c3 100755..100644 --- a/svtools/source/filter.vcl/filter/exportdialog.hrc +++ b/svtools/source/filter/exportdialog.hrc diff --git a/svtools/source/filter.vcl/filter/exportdialog.hxx b/svtools/source/filter/exportdialog.hxx index 20a9ac3ea832..20a9ac3ea832 100755..100644 --- a/svtools/source/filter.vcl/filter/exportdialog.hxx +++ b/svtools/source/filter/exportdialog.hxx diff --git a/svtools/source/filter.vcl/filter/exportdialog.src b/svtools/source/filter/exportdialog.src index c9e87989a314..c9e87989a314 100644 --- a/svtools/source/filter.vcl/filter/exportdialog.src +++ b/svtools/source/filter/exportdialog.src diff --git a/svtools/source/filter.vcl/filter/filter.cxx b/svtools/source/filter/filter.cxx index 9c2c28dfbe3b..78d97cc25c5c 100644 --- a/svtools/source/filter.vcl/filter/filter.cxx +++ b/svtools/source/filter/filter.cxx @@ -39,6 +39,7 @@ #include <vcl/salctype.hxx> #include <vcl/pngread.hxx> #include <vcl/pngwrite.hxx> +#include <vcl/svgread.hxx> #include <vcl/virdev.hxx> #include <vcl/svapp.hxx> #include <osl/file.hxx> @@ -555,7 +556,7 @@ static sal_Bool ImpPeekGraphicFormat( SvStream& rStream, String& rFormatExtensio for ( nOffset = 0; ( nOffset <= 512 ) && ( ( nStreamPos + nOffset + 14 ) <= nStreamLen ); nOffset += 512 ) { short y1,x1,y2,x2; - bool bdBoxOk = true; + sal_Bool bdBoxOk = sal_True; rStream.Seek( nStreamPos + nOffset); // size of the pict in version 1 pict ( 2bytes) : ignored @@ -568,7 +569,7 @@ static sal_Bool ImpPeekGraphicFormat( SvStream& rStream, String& rFormatExtensio if (x1 > x2 || y1 > y2 || // bad bdbox (x1 == x2 && y1 == y2) || // 1 pixel picture x2-x1 > 2048 || y2-y1 > 2048 ) // picture anormaly big - bdBoxOk = false; + bdBoxOk = sal_False; // read version op rStream.Read( sBuf,3 ); @@ -677,10 +678,22 @@ static sal_Bool ImpPeekGraphicFormat( SvStream& rStream, String& rFormatExtensio return sal_True; } + //--------------------------- SVG ------------------------------------ + if( !bTest || ( rFormatExtension.CompareToAscii( "SVG", 3 ) == COMPARE_EQUAL ) ) + { + bSomethingTested=sal_True; + + // just a simple test for the extension + if( rFormatExtension.CompareToAscii( "SVG", 3 ) == COMPARE_EQUAL ) + return sal_True; + } + //--------------------------- TGA ------------------------------------ if( !bTest || ( rFormatExtension.CompareToAscii( "TGA", 3 ) == COMPARE_EQUAL ) ) { bSomethingTested = sal_True; + + // just a simple test for the extension if( rFormatExtension.CompareToAscii( "TGA", 3 ) == COMPARE_EQUAL ) return sal_True; } @@ -689,6 +702,8 @@ static sal_Bool ImpPeekGraphicFormat( SvStream& rStream, String& rFormatExtensio if( !bTest || ( rFormatExtension.CompareToAscii( "SGV", 3 ) == COMPARE_EQUAL ) ) { bSomethingTested = sal_True; + + // just a simple test for the extension if( rFormatExtension.CompareToAscii( "SGV", 3 ) == COMPARE_EQUAL ) return sal_True; } @@ -1486,6 +1501,27 @@ sal_uInt16 GraphicFilter::ImportGraphic( Graphic& rGraphic, const String& rPath, else eLinkType = GFX_LINK_TYPE_NATIVE_JPG; } + else if( aFilterName.EqualsIgnoreCaseAscii( IMP_SVG ) ) + { + if( rGraphic.GetContext() == (GraphicReader*) 1 ) + rGraphic.SetContext( NULL ); + + vcl::SVGReader aSVGReader( rIStream ); + GDIMetaFile aSVGMtf; + + if( 0 == aSVGReader.Read( aSVGMtf ).GetActionCount() ) + nStatus = GRFILTER_FILTERERROR; + else + rGraphic = Graphic( aSVGMtf ); + + // Dont set any GfxLink here, since the MetaRenderGraphicAction + // inside the just read MetaFile contains excatly this native data; + // setting a Ç´fxLink would also affect other program parts, since + // GfxLinks are preferably written to the file format in general, + // which would be a bad idea in case of SVG files, since earlier + // implementations are not able to handle native SVG data in any + // case. (KA 01/19/2011) + } else if( aFilterName.EqualsIgnoreCaseAscii( IMP_XBM ) ) { if( rGraphic.GetContext() == (GraphicReader*) 1 ) @@ -1748,7 +1784,7 @@ sal_uInt16 GraphicFilter::ExportGraphic( const Graphic& rGraphic, const String& // Maximalen Speicherbedarf fuer das Bildes holen: // if( GetOptionsConfig() ) -// nMaxMem = (sal_uInt32)GetOptionsConfig()->ReadKey( "VEC-TO-PIX-MAX-KB", "1024" ).ToInt32(); +// nMaxMem = (UINT32)GetOptionsConfig()->ReadKey( "VEC-TO-PIX-MAX-KB", "1024" ).ToInt32(); // else nMaxMem = 1024; @@ -1826,7 +1862,7 @@ sal_uInt16 GraphicFilter::ExportGraphic( const Graphic& rGraphic, const String& aMTF.SetPrefSize( aGraphic.GetPrefSize() ); aMTF.SetPrefMapMode( aGraphic.GetPrefMapMode() ); } - rOStm << aMTF; + aMTF.Write( rOStm, GDIMETAFILE_WRITE_REPLACEMENT_RENDERGRAPHIC ); if( rOStm.GetError() ) nStatus = GRFILTER_IOERROR; } @@ -1943,44 +1979,69 @@ sal_uInt16 GraphicFilter::ExportGraphic( const Graphic& rGraphic, const String& } else if( aFilterName.EqualsIgnoreCaseAscii( EXP_SVG ) ) { - try + sal_Bool bDone = sal_False; + + // do we have a native SVG RenderGraphic, whose data can be written directly? + if( ( GRAPHIC_GDIMETAFILE == eType ) && aGraphic.IsRenderGraphic() ) { - ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory > xMgr( ::comphelper::getProcessServiceFactory() ); + const ::vcl::RenderGraphic aRenderGraphic( aGraphic.GetRenderGraphic() ); - if( xMgr.is() ) + if( aRenderGraphic.GetGraphicDataLength() && + aRenderGraphic.GetGraphicDataMimeType().equalsIgnoreAsciiCase( + ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "image/svg+xml" ) ) ) ) { - ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XDocumentHandler > xSaxWriter( xMgr->createInstance( - ::rtl::OUString::createFromAscii( "com.sun.star.xml.sax.Writer" ) ), ::com::sun::star::uno::UNO_QUERY ); + rOStm.Write( aRenderGraphic.GetGraphicData().get(), + aRenderGraphic.GetGraphicDataLength() ); - ::com::sun::star::uno::Reference< ::com::sun::star::svg::XSVGWriter > xSVGWriter( xMgr->createInstance( - ::rtl::OUString::createFromAscii( "com.sun.star.svg.SVGWriter" ) ), ::com::sun::star::uno::UNO_QUERY ); + if( rOStm.GetError() ) + { + nStatus = GRFILTER_IOERROR; + } + } + } - if( xSaxWriter.is() && xSVGWriter.is() ) + if( !bDone ) + { + // do the normal GDIMetaFile export instead + try + { + ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory > xMgr( ::comphelper::getProcessServiceFactory() ); + + if( xMgr.is() ) { - ::com::sun::star::uno::Reference< ::com::sun::star::io::XActiveDataSource > xActiveDataSource( - xSaxWriter, ::com::sun::star::uno::UNO_QUERY ); + ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XDocumentHandler > xSaxWriter( xMgr->createInstance( + ::rtl::OUString::createFromAscii( "com.sun.star.xml.sax.Writer" ) ), ::com::sun::star::uno::UNO_QUERY ); - if( xActiveDataSource.is() ) + ::com::sun::star::uno::Reference< ::com::sun::star::svg::XSVGWriter > xSVGWriter( xMgr->createInstance( + ::rtl::OUString::createFromAscii( "com.sun.star.svg.SVGWriter" ) ), ::com::sun::star::uno::UNO_QUERY ); + + if( xSaxWriter.is() && xSVGWriter.is() ) { - const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface > xStmIf( - static_cast< ::cppu::OWeakObject* >( new ImpFilterOutputStream( rOStm ) ) ); + ::com::sun::star::uno::Reference< ::com::sun::star::io::XActiveDataSource > xActiveDataSource( + xSaxWriter, ::com::sun::star::uno::UNO_QUERY ); - SvMemoryStream aMemStm( 65535, 65535 ); + if( xActiveDataSource.is() ) + { + const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface > xStmIf( + static_cast< ::cppu::OWeakObject* >( new ImpFilterOutputStream( rOStm ) ) ); - aMemStm.SetCompressMode( COMPRESSMODE_FULL ); - ( (GDIMetaFile&) aGraphic.GetGDIMetaFile() ).Write( aMemStm ); + SvMemoryStream aMemStm( 65535, 65535 ); - xActiveDataSource->setOutputStream( ::com::sun::star::uno::Reference< ::com::sun::star::io::XOutputStream >( - xStmIf, ::com::sun::star::uno::UNO_QUERY ) ); - ::com::sun::star::uno::Sequence< sal_Int8 > aMtfSeq( (sal_Int8*) aMemStm.GetData(), aMemStm.Tell() ); - xSVGWriter->write( xSaxWriter, aMtfSeq ); + aMemStm.SetCompressMode( COMPRESSMODE_FULL ); + ( (GDIMetaFile&) aGraphic.GetGDIMetaFile() ).Write( aMemStm ); + + xActiveDataSource->setOutputStream( ::com::sun::star::uno::Reference< ::com::sun::star::io::XOutputStream >( + xStmIf, ::com::sun::star::uno::UNO_QUERY ) ); + ::com::sun::star::uno::Sequence< sal_Int8 > aMtfSeq( (sal_Int8*) aMemStm.GetData(), aMemStm.Tell() ); + xSVGWriter->write( xSaxWriter, aMtfSeq ); + } } } } - } - catch( ::com::sun::star::uno::Exception& ) - { - nStatus = GRFILTER_IOERROR; + catch( ::com::sun::star::uno::Exception& ) + { + nStatus = GRFILTER_IOERROR; + } } } else @@ -2127,6 +2188,7 @@ IMPL_LINK( GraphicFilter, FilterCallback, ConvertData*, pData ) case( CVT_TIF ): aShortName = TIF_SHORTNAME; break; case( CVT_WMF ): aShortName = WMF_SHORTNAME; break; case( CVT_EMF ): aShortName = EMF_SHORTNAME; break; + case( CVT_SVG ): aShortName = SVG_SHORTNAME; break; default: break; @@ -2196,4 +2258,3 @@ int GraphicFilter::LoadGraphic( const String &rPath, const String &rFilterName, return nRes; } - diff --git a/svtools/source/filter.vcl/filter/filter2.cxx b/svtools/source/filter/filter2.cxx index 9b655c732036..58fafc47c0f2 100644 --- a/svtools/source/filter.vcl/filter/filter2.cxx +++ b/svtools/source/filter/filter2.cxx @@ -114,6 +114,7 @@ sal_Bool GraphicDescriptor::Detect( sal_Bool bExtendedInfo ) else if ( ImpDetectSVM( rStm, bExtendedInfo ) ) bRet = sal_True; else if ( ImpDetectWMF( rStm, bExtendedInfo ) ) bRet = sal_True; else if ( ImpDetectEMF( rStm, bExtendedInfo ) ) bRet = sal_True; + else if ( ImpDetectSVG( rStm, bExtendedInfo ) ) bRet = sal_True; else if ( ImpDetectPCT( rStm, bExtendedInfo ) ) bRet = sal_True; else if ( ImpDetectXBM( rStm, bExtendedInfo ) ) bRet = sal_True; else if ( ImpDetectXPM( rStm, bExtendedInfo ) ) bRet = sal_True; @@ -1301,6 +1302,21 @@ sal_Bool GraphicDescriptor::ImpDetectEMF( SvStream&, sal_Bool ) |* \************************************************************************/ +sal_Bool GraphicDescriptor::ImpDetectSVG( SvStream& /*rStm*/, sal_Bool /*bExtendedInfo*/ ) +{ + sal_Bool bRet = aPathExt.CompareToAscii( "svg", 3 ) == COMPARE_EQUAL; + if (bRet) + nFormat = GFF_SVG; + + return bRet; +} + +/************************************************************************* +|* +|* +|* +\************************************************************************/ + String GraphicDescriptor::GetImportFormatShortName( sal_uInt16 nFormat ) { ByteString aKeyName; @@ -1331,9 +1347,8 @@ String GraphicDescriptor::GetImportFormatShortName( sal_uInt16 nFormat ) case( GFF_SVM ) : aKeyName = "svm"; break; case( GFF_WMF ) : aKeyName = "wmf"; break; case( GFF_EMF ) : aKeyName = "emf"; break; + case( GFF_SVG ) : aKeyName = "svg"; break; } return String( aKeyName, RTL_TEXTENCODING_ASCII_US ); } - - diff --git a/svtools/source/filter.vcl/igif/decode.cxx b/svtools/source/filter/igif/decode.cxx index ddea94a5555e..ddea94a5555e 100644 --- a/svtools/source/filter.vcl/igif/decode.cxx +++ b/svtools/source/filter/igif/decode.cxx diff --git a/svtools/source/filter.vcl/igif/decode.hxx b/svtools/source/filter/igif/decode.hxx index e85cc30eaf9e..e85cc30eaf9e 100644 --- a/svtools/source/filter.vcl/igif/decode.hxx +++ b/svtools/source/filter/igif/decode.hxx diff --git a/svtools/source/filter.vcl/igif/gifread.cxx b/svtools/source/filter/igif/gifread.cxx index 16318e5b143e..16318e5b143e 100644 --- a/svtools/source/filter.vcl/igif/gifread.cxx +++ b/svtools/source/filter/igif/gifread.cxx diff --git a/svtools/source/filter.vcl/ixbm/xbmread.cxx b/svtools/source/filter/ixbm/xbmread.cxx index 5084f7267e46..5084f7267e46 100644 --- a/svtools/source/filter.vcl/ixbm/xbmread.cxx +++ b/svtools/source/filter/ixbm/xbmread.cxx diff --git a/svtools/source/filter.vcl/ixpm/rgbtable.hxx b/svtools/source/filter/ixpm/rgbtable.hxx index 054e1e86b064..054e1e86b064 100644 --- a/svtools/source/filter.vcl/ixpm/rgbtable.hxx +++ b/svtools/source/filter/ixpm/rgbtable.hxx diff --git a/svtools/source/filter.vcl/ixpm/xpmread.cxx b/svtools/source/filter/ixpm/xpmread.cxx index 425ed6323bcc..425ed6323bcc 100644 --- a/svtools/source/filter.vcl/ixpm/xpmread.cxx +++ b/svtools/source/filter/ixpm/xpmread.cxx diff --git a/svtools/source/filter.vcl/jpeg/jpeg.cxx b/svtools/source/filter/jpeg/jpeg.cxx index dff6ec8ff51f..dff6ec8ff51f 100644 --- a/svtools/source/filter.vcl/jpeg/jpeg.cxx +++ b/svtools/source/filter/jpeg/jpeg.cxx diff --git a/svtools/source/filter.vcl/jpeg/jpeg.h b/svtools/source/filter/jpeg/jpeg.h index ca9b294d2f9d..ca9b294d2f9d 100644 --- a/svtools/source/filter.vcl/jpeg/jpeg.h +++ b/svtools/source/filter/jpeg/jpeg.h diff --git a/svtools/source/filter.vcl/jpeg/jpegc.c b/svtools/source/filter/jpeg/jpegc.c index 8d3a82a86ef3..8d3a82a86ef3 100644 --- a/svtools/source/filter.vcl/jpeg/jpegc.c +++ b/svtools/source/filter/jpeg/jpegc.c diff --git a/svtools/source/filter.vcl/filter/sgf.ini b/svtools/source/filter/sgf.ini index 7444e40c8836..7444e40c8836 100644 --- a/svtools/source/filter.vcl/filter/sgf.ini +++ b/svtools/source/filter/sgf.ini diff --git a/svtools/source/filter.vcl/filter/sgfbram.cxx b/svtools/source/filter/sgfbram.cxx index 9b981f8c0d94..9b981f8c0d94 100644 --- a/svtools/source/filter.vcl/filter/sgfbram.cxx +++ b/svtools/source/filter/sgfbram.cxx diff --git a/svtools/source/filter.vcl/filter/sgvmain.cxx b/svtools/source/filter/sgvmain.cxx index 3b0f3ebd2912..3b0f3ebd2912 100644 --- a/svtools/source/filter.vcl/filter/sgvmain.cxx +++ b/svtools/source/filter/sgvmain.cxx diff --git a/svtools/source/filter.vcl/filter/sgvspln.cxx b/svtools/source/filter/sgvspln.cxx index aac7e1f04e0a..aac7e1f04e0a 100644 --- a/svtools/source/filter.vcl/filter/sgvspln.cxx +++ b/svtools/source/filter/sgvspln.cxx diff --git a/svtools/source/filter.vcl/filter/sgvtext.cxx b/svtools/source/filter/sgvtext.cxx index f0130b21c9d6..f0130b21c9d6 100644 --- a/svtools/source/filter.vcl/filter/sgvtext.cxx +++ b/svtools/source/filter/sgvtext.cxx diff --git a/svtools/source/filter.vcl/wmf/emfwr.cxx b/svtools/source/filter/wmf/emfwr.cxx index d82f11cdce5a..99ca92c76abb 100644 --- a/svtools/source/filter.vcl/wmf/emfwr.cxx +++ b/svtools/source/filter/wmf/emfwr.cxx @@ -33,6 +33,7 @@ #include <basegfx/polygon/b2dpolygon.hxx> #include <basegfx/polygon/b2dpolypolygon.hxx> #include <vcl/lineinfo.hxx> +#include <vcl/rendergraphicrasterizer.hxx> // ----------- // - Defines - @@ -1186,7 +1187,7 @@ void EMFWriter::ImplWrite( const GDIMetaFile& rMtf ) case META_BMP_ACTION: { const MetaBmpAction* pA = (const MetaBmpAction *) pAction; - ImplWriteBmpRecord( pA->GetBitmap(), pA->GetPoint(), pA->GetBitmap().GetSizePixel(), WIN_SRCCOPY ); + ImplWriteBmpRecord( pA->GetBitmap(), pA->GetPoint(), maVDev.PixelToLogic( pA->GetBitmap().GetSizePixel() ), WIN_SRCCOPY ); } break; @@ -1217,8 +1218,8 @@ void EMFWriter::ImplWrite( const GDIMetaFile& rMtf ) { aBmp.Replace( aMsk, COL_WHITE ); aMsk.Invert(); - ImplWriteBmpRecord( aMsk, pA->GetPoint(), aMsk.GetSizePixel(), WIN_SRCPAINT ); - ImplWriteBmpRecord( aBmp, pA->GetPoint(), aBmp.GetSizePixel(), WIN_SRCAND ); + ImplWriteBmpRecord( aMsk, pA->GetPoint(), maVDev.PixelToLogic( aMsk.GetSizePixel() ), WIN_SRCPAINT ); + ImplWriteBmpRecord( aBmp, pA->GetPoint(), maVDev.PixelToLogic( aBmp.GetSizePixel() ), WIN_SRCAND ); } else ImplWriteBmpRecord( aBmp, pA->GetPoint(), aBmp.GetSizePixel(), WIN_SRCCOPY ); @@ -1407,6 +1408,26 @@ void EMFWriter::ImplWrite( const GDIMetaFile& rMtf ) } break; + case( META_RENDERGRAPHIC_ACTION ): + { + const MetaRenderGraphicAction* pA = (const MetaRenderGraphicAction*) pAction; + const ::vcl::RenderGraphicRasterizer aRasterizer( pA->GetRenderGraphic() ); + const BitmapEx aBmpEx( aRasterizer.Rasterize( maVDev.LogicToPixel( pA->GetSize() ) ) ); + Bitmap aBmp( aBmpEx.GetBitmap() ); + Bitmap aMsk( aBmpEx.GetMask() ); + + if( !!aMsk ) + { + aBmp.Replace( aMsk, COL_WHITE ); + aMsk.Invert(); + ImplWriteBmpRecord( aMsk, pA->GetPoint(), pA->GetSize(), WIN_SRCPAINT ); + ImplWriteBmpRecord( aBmp, pA->GetPoint(), pA->GetSize(), WIN_SRCAND ); + } + else + ImplWriteBmpRecord( aBmp, pA->GetPoint(), pA->GetSize(), WIN_SRCCOPY ); + } + break; + default: DBG_ERROR( ( ByteString( "EMFWriter::ImplWriteActions: unsupported MetaAction #" ) += ByteString::CreateFromInt32( nType ) ).GetBuffer() ); break; diff --git a/svtools/source/filter.vcl/wmf/emfwr.hxx b/svtools/source/filter/wmf/emfwr.hxx index 8c65e91e5f73..8c65e91e5f73 100644 --- a/svtools/source/filter.vcl/wmf/emfwr.hxx +++ b/svtools/source/filter/wmf/emfwr.hxx diff --git a/svtools/source/filter.vcl/wmf/enhwmf.cxx b/svtools/source/filter/wmf/enhwmf.cxx index 29128ffd7904..ec7fec9fdb1e 100644 --- a/svtools/source/filter.vcl/wmf/enhwmf.cxx +++ b/svtools/source/filter/wmf/enhwmf.cxx @@ -1268,13 +1268,13 @@ sal_Bool EnhWMFReader::ReadEnhWMF() sal_Bool EnhWMFReader::ReadHeader() { - sal_uInt32 nUINT32, nHeaderSize, nPalEntries; + sal_uInt32 nsal_uInt32, nHeaderSize, nPalEntries; sal_Int32 nLeft, nTop, nRight, nBottom; // METAFILEHEADER SPARE ICH MIR HIER // Einlesen des METAHEADER - *pWMF >> nUINT32 >> nHeaderSize; - if ( nUINT32 != 1 ) // Typ + *pWMF >> nsal_uInt32 >> nHeaderSize; + if ( nsal_uInt32 != 1 ) // Typ return sal_False; // bound size @@ -1293,12 +1293,12 @@ sal_Bool EnhWMFReader::ReadHeader() rclFrame.Right() = nRight; rclFrame.Bottom() = nBottom; - *pWMF >> nUINT32; // signature + *pWMF >> nsal_uInt32; // signature - if ( nUINT32 != 0x464d4520 ) + if ( nsal_uInt32 != 0x464d4520 ) return sal_False; - *pWMF >> nUINT32; // nVersion + *pWMF >> nsal_uInt32; // nVersion *pWMF >> nEndPos; // size of metafile nEndPos += nStartPos; @@ -1340,4 +1340,3 @@ EnhWMFReader::~EnhWMFReader() { }; - diff --git a/svtools/source/filter.vcl/wmf/winmtf.cxx b/svtools/source/filter/wmf/winmtf.cxx index feff21933ab6..30fc670ac22f 100644 --- a/svtools/source/filter.vcl/wmf/winmtf.cxx +++ b/svtools/source/filter/wmf/winmtf.cxx @@ -2200,4 +2200,3 @@ void WinMtfOutput::AddFromGDIMetaFile( GDIMetaFile& rGDIMetaFile ) { rGDIMetaFile.Play( *mpGDIMetaFile, 0xFFFFFFFF ); } - diff --git a/svtools/source/filter.vcl/wmf/winmtf.hxx b/svtools/source/filter/wmf/winmtf.hxx index 299d297c90bc..ca7b62b38ef3 100644 --- a/svtools/source/filter.vcl/wmf/winmtf.hxx +++ b/svtools/source/filter/wmf/winmtf.hxx @@ -773,5 +773,3 @@ public: }; #endif - - diff --git a/svtools/source/filter.vcl/wmf/winwmf.cxx b/svtools/source/filter/wmf/winwmf.cxx index 880841cd36f8..feb1a2895793 100644 --- a/svtools/source/filter.vcl/wmf/winwmf.cxx +++ b/svtools/source/filter/wmf/winwmf.cxx @@ -1428,4 +1428,3 @@ WMFReader::~WMFReader() if( pEMFStream ) delete pEMFStream; } - diff --git a/svtools/source/filter.vcl/wmf/wmf.cxx b/svtools/source/filter/wmf/wmf.cxx index 4e84cd920b56..4e84cd920b56 100644 --- a/svtools/source/filter.vcl/wmf/wmf.cxx +++ b/svtools/source/filter/wmf/wmf.cxx diff --git a/svtools/source/filter.vcl/wmf/wmfwr.cxx b/svtools/source/filter/wmf/wmfwr.cxx index 36b84316271b..26bda76a11d9 100644 --- a/svtools/source/filter.vcl/wmf/wmfwr.cxx +++ b/svtools/source/filter/wmf/wmfwr.cxx @@ -29,6 +29,7 @@ #include "precompiled_svtools.hxx" #include <vcl/salbtype.hxx> +#include <vcl/rendergraphicrasterizer.hxx> #include "wmfwr.hxx" #include <unotools/fontcvt.hxx> #include "emfwr.hxx" @@ -318,6 +319,7 @@ void WMFWriter::CountActionsAndBitmaps( const GDIMetaFile & rMTF ) case META_BMPEX_ACTION: case META_BMPEXSCALE_ACTION: case META_BMPEXSCALEPART_ACTION: + case META_RENDERGRAPHIC_ACTION: nNumberOfBitmaps++; break; } @@ -1796,6 +1798,32 @@ void WMFWriter::WriteRecords( const GDIMetaFile & rMTF ) DBG_ERROR( "Unsupported action: MetaMoveClipRegionAction!" ); } break; + + case( META_RENDERGRAPHIC_ACTION ): + { + const MetaRenderGraphicAction* pA = (const MetaRenderGraphicAction*) pMA; + const ::vcl::RenderGraphicRasterizer aRasterizer( pA->GetRenderGraphic() ); + const BitmapEx aBmpEx( aRasterizer.Rasterize( pVirDev->LogicToPixel( pA->GetSize(), aSrcMapMode ) ) ); + Bitmap aBmp( aBmpEx.GetBitmap() ); + Bitmap aMsk( aBmpEx.GetMask() ); + + if( !!aMsk ) + { + aBmp.Replace( aMsk, COL_WHITE ); + aMsk.Invert(); + WMFRecord_StretchDIB( pA->GetPoint(), pA->GetSize(), aMsk, W_SRCPAINT ); + WMFRecord_StretchDIB( pA->GetPoint(), pA->GetSize(), aBmp, W_SRCAND ); + } + else + WMFRecord_StretchDIB( pA->GetPoint(), pA->GetSize(), aBmp ); + } + break; + + default: + { + DBG_ERROR( "Unsupported meta action!" ); + } + break; } nWrittenActions++; diff --git a/svtools/source/filter.vcl/wmf/wmfwr.hxx b/svtools/source/filter/wmf/wmfwr.hxx index c5830b3bab8f..a76b39ad154f 100644 --- a/svtools/source/filter.vcl/wmf/wmfwr.hxx +++ b/svtools/source/filter/wmf/wmfwr.hxx @@ -132,7 +132,7 @@ private: void MayCallback(); // Berechnet anhand der obigen 5 Parameter eine Prozentzahl - // und macht dann ggf. einen Callback. Setzt bStatus auf sal_False wenn User abbrechen + // und macht dann ggf. einen Callback. Setzt bStatus auf FALSE wenn User abbrechen // moechte. void CountActionsAndBitmaps(const GDIMetaFile & rMTF); @@ -154,7 +154,7 @@ private: void UpdateRecordHeader(); // berichtig die Groesse des Records nach dem Schreiben der Parameter, wenn // nSizeWords bei Aufruf von WriteRecordHeader(..) unbekannt war. - // fuegt ggf. noch ein sal_uInt8 0 ein damit Anzahl Bytes immer gerade. + // fuegt ggf. noch ein BYTE 0 ein damit Anzahl Bytes immer gerade. void WMFRecord_Arc(const Rectangle & rRect, const Point & rStartPt, const Point & rEndPt); void WMFRecord_Chord(const Rectangle & rRect, const Point & rStartPt, const Point & rEndPt); diff --git a/svtools/source/graphic/descriptor.cxx b/svtools/source/graphic/descriptor.cxx index 6c808baa169d..395d3dfea0de 100644 --- a/svtools/source/graphic/descriptor.cxx +++ b/svtools/source/graphic/descriptor.cxx @@ -169,6 +169,7 @@ void GraphicDescriptor::implCreate( SvStream& rIStm, const ::rtl::OUString* pURL case( GFF_WMF ): pMimeType = MIMETYPE_WMF; cType = graphic::GraphicType::VECTOR; break; case( GFF_SGV ): pMimeType = MIMETYPE_SGV; cType = graphic::GraphicType::VECTOR; break; case( GFF_EMF ): pMimeType = MIMETYPE_EMF; cType = graphic::GraphicType::VECTOR; break; + case( GFF_SVG ): pMimeType = MIMETYPE_SVG; cType = graphic::GraphicType::VECTOR; break; default: break; diff --git a/svtools/source/graphic/grfmgr.cxx b/svtools/source/graphic/grfmgr.cxx index 77a582e5ae20..9241cbd04d51 100644 --- a/svtools/source/graphic/grfmgr.cxx +++ b/svtools/source/graphic/grfmgr.cxx @@ -190,15 +190,10 @@ void GraphicObject::ImplAssignGraphicData() mbTransparent = maGraphic.IsTransparent(); mbAlpha = maGraphic.IsAlpha(); mbAnimated = maGraphic.IsAnimated(); + mbEPS = maGraphic.IsEPS(); + mbIsRenderGraphic = maGraphic.IsRenderGraphic(); + mbHasRenderGraphic = maGraphic.HasRenderGraphic(); mnAnimationLoopCount = ( mbAnimated ? maGraphic.GetAnimationLoopCount() : 0 ); - - if( maGraphic.GetType() == GRAPHIC_GDIMETAFILE ) - { - const GDIMetaFile& rMtf = GetGraphic().GetGDIMetaFile(); - mbEPS = ( rMtf.GetActionCount() >= 1 ) && ( META_EPS_ACTION == rMtf.GetAction( 0 )->GetType() ); - } - else - mbEPS = sal_False; } // ----------------------------------------------------------------------------- @@ -447,7 +442,7 @@ void GraphicObject::Assign( const SvDataCopyStream& rCopyStream ) ByteString GraphicObject::GetUniqueID() const { - if ( !IsInSwapIn() && IsEPS() ) + if ( !IsInSwapIn() && ( IsEPS() || IsRenderGraphic() ) ) const_cast<GraphicObject*>(this)->FireSwapInRequest(); ByteString aRet; @@ -751,7 +746,7 @@ sal_Bool GraphicObject::DrawWithPDFHandling( OutputDevice& rOutDev, const GraphicAttr aGrfAttr( pGrfAttr ? *pGrfAttr : GetAttr() ); // Notify PDF writer about linked graphic (if any) - bool bWritingPdfLinkedGraphic( false ); + sal_Bool bWritingPdfLinkedGraphic( sal_False ); Point aPt( rPt ); Size aSz( rSz ); Rectangle aCropRect; @@ -1379,4 +1374,3 @@ GraphicObject GraphicObject::CreateGraphicObjectFromURL( const ::rtl::OUString & return GraphicObject( aGraphic ); } } - diff --git a/svtools/source/graphic/grfmgr2.cxx b/svtools/source/graphic/grfmgr2.cxx index 9c86c7e44130..4a6fb67187bc 100644 --- a/svtools/source/graphic/grfmgr2.cxx +++ b/svtools/source/graphic/grfmgr2.cxx @@ -869,6 +869,8 @@ sal_Bool GraphicManager::ImplCreateOutput( OutputDevice* pOut, // FALLTHROUGH intended case META_GRADIENTEX_ACTION: // FALLTHROUGH intended + case META_RENDERGRAPHIC_ACTION: + // FALLTHROUGH intended // OutDev state changes that _do_ affect bitmap // output @@ -2379,4 +2381,3 @@ void GraphicObject::ImplTransformBitmap( BitmapEx& rBmpEx, } } } - diff --git a/vcl/inc/vcl/gdimtf.hxx b/vcl/inc/vcl/gdimtf.hxx index a83920b6674c..b69e5a847066 100644 --- a/vcl/inc/vcl/gdimtf.hxx +++ b/vcl/inc/vcl/gdimtf.hxx @@ -68,6 +68,15 @@ class Gradient; #define MTF_MIRROR_HORZ 0x00000001UL #define MTF_MIRROR_VERT 0x00000002UL +// ----------------------------- +// - Write flags for streaming - +// ----------------------------- + +#define GDIMETAFILE_WRITE_DEFAULT 0x00000000 +#define GDIMETAFILE_WRITE_REPLACEMENT_RENDERGRAPHIC 0x00000001 + +typedef sal_uInt32 GDIMetaFileWriteFlags; + // --------- // - Enums - // --------- @@ -237,7 +246,7 @@ public: // Methoden zum Lesen und Schreiben des neuen Formats; // die Read-Methode kann auch das alte Format lesen SvStream& Read( SvStream& rIStm ); - SvStream& Write( SvStream& rOStm ); + SvStream& Write( SvStream& rOStm, GDIMetaFileWriteFlags = GDIMETAFILE_WRITE_DEFAULT ); // Stream-Operatoren schreiben das alte Format (noch) // und lesen sowohl das alte wie auch das neue Format @@ -248,4 +257,3 @@ public: }; #endif // _SV_GDIMTF_HXX - diff --git a/vcl/inc/vcl/gfxlink.hxx b/vcl/inc/vcl/gfxlink.hxx index ce2cec67e1f4..29668f0dfa58 100644 --- a/vcl/inc/vcl/gfxlink.hxx +++ b/vcl/inc/vcl/gfxlink.hxx @@ -109,11 +109,12 @@ enum GfxLinkType GFX_LINK_TYPE_NATIVE_WMF = 6, // Don't forget to update the following defines GFX_LINK_TYPE_NATIVE_MET = 7, // Don't forget to update the following defines GFX_LINK_TYPE_NATIVE_PCT = 8, // Don't forget to update the following defines + GFX_LINK_TYPE_NATIVE_SVG = 9, // Don't forget to update the following defines GFX_LINK_TYPE_USER = 0xffff }; #define GFX_LINK_FIRST_NATIVE_ID GFX_LINK_TYPE_NATIVE_GIF -#define GFX_LINK_LAST_NATIVE_ID GFX_LINK_TYPE_NATIVE_PCT +#define GFX_LINK_LAST_NATIVE_ID GFX_LINK_TYPE_NATIVE_SVG // ----------- // - GfxLink - diff --git a/vcl/inc/vcl/graph.hxx b/vcl/inc/vcl/graph.hxx index 61ec67ce8a79..31c7b20b9c77 100644 --- a/vcl/inc/vcl/graph.hxx +++ b/vcl/inc/vcl/graph.hxx @@ -35,6 +35,7 @@ #include <vcl/bitmapex.hxx> #include <vcl/animate.hxx> #include <vcl/gdimtf.hxx> +#include <vcl/rendergraphic.hxx> #include <vcl/graph.h> #include <vcl/gfxlink.hxx> #include <com/sun/star/uno/Reference.hxx> @@ -119,9 +120,12 @@ public: void SetDefaultType(); sal_Bool IsSupportedGraphic() const; - sal_Bool IsTransparent() const; - sal_Bool IsAlpha() const; - sal_Bool IsAnimated() const; + sal_Bool IsTransparent() const; + sal_Bool IsAlpha() const; + sal_Bool IsAnimated() const; + sal_Bool IsEPS() const; + sal_Bool IsRenderGraphic() const; + sal_Bool HasRenderGraphic() const; // #i102089# Access of Bitmap potentially will have to rasterconvert the Graphic // if it is a MetaFile. To be able to control this conversion it is necessary to @@ -131,8 +135,9 @@ public: Bitmap GetBitmap(const GraphicConversionParameters& rParameters = GraphicConversionParameters()) const; BitmapEx GetBitmapEx(const GraphicConversionParameters& rParameters = GraphicConversionParameters()) const; - Animation GetAnimation() const; - const GDIMetaFile& GetGDIMetaFile() const; + Animation GetAnimation() const; + const GDIMetaFile& GetGDIMetaFile() const; + ::vcl::RenderGraphic GetRenderGraphic() const; ::com::sun::star::uno::Reference< ::com::sun::star::graphic::XGraphic > GetXGraphic() const; @@ -219,4 +224,3 @@ public: }; #endif // _SV_GRAPH_HXX - diff --git a/vcl/inc/vcl/impgraph.hxx b/vcl/inc/vcl/impgraph.hxx index 7164952ea51b..e136fcc06ade 100644 --- a/vcl/inc/vcl/impgraph.hxx +++ b/vcl/inc/vcl/impgraph.hxx @@ -33,6 +33,7 @@ #include <vcl/bitmapex.hxx> #include <vcl/animate.hxx> #include <vcl/gdimtf.hxx> +#include <vcl/rendergraphic.hxx> #include <vcl/graph.h> // --------------- @@ -96,14 +97,19 @@ private: void ImplSetDefaultType(); sal_Bool ImplIsSupportedGraphic() const; - sal_Bool ImplIsTransparent() const; - sal_Bool ImplIsAlpha() const; - sal_Bool ImplIsAnimated() const; + sal_Bool ImplIsTransparent() const; + sal_Bool ImplIsAlpha() const; + sal_Bool ImplIsAnimated() const; + sal_Bool ImplIsEPS() const; + sal_Bool ImplIsRenderGraphic() const; + sal_Bool ImplHasRenderGraphic() const; + + Bitmap ImplGetBitmap(const GraphicConversionParameters& rParameters) const; + BitmapEx ImplGetBitmapEx(const GraphicConversionParameters& rParameters) const; + Animation ImplGetAnimation() const; + const GDIMetaFile& ImplGetGDIMetaFile() const; + ::vcl::RenderGraphic ImplGetRenderGraphic() const; - Bitmap ImplGetBitmap(const GraphicConversionParameters& rParameters) const; - BitmapEx ImplGetBitmapEx(const GraphicConversionParameters& rParameters) const; - Animation ImplGetAnimation() const; - const GDIMetaFile& ImplGetGDIMetaFile() const; Size ImplGetPrefSize() const; void ImplSetPrefSize( const Size& rPrefSize ); diff --git a/vcl/inc/vcl/metaact.hxx b/vcl/inc/vcl/metaact.hxx index 33120b288a98..b1bd5d91d20e 100644 --- a/vcl/inc/vcl/metaact.hxx +++ b/vcl/inc/vcl/metaact.hxx @@ -42,6 +42,7 @@ #include <vcl/gdimtf.hxx> #include <vcl/gfxlink.hxx> #include <vcl/lineinfo.hxx> +#include <vcl/rendergraphic.hxx> class SvStream; @@ -102,6 +103,7 @@ class SvStream; #define META_LAYOUTMODE_ACTION (149) #define META_TEXTLANGUAGE_ACTION (150) #define META_OVERLINECOLOR_ACTION (151) +#define META_RENDERGRAPHIC_ACTION (152) #define META_COMMENT_ACTION (512) @@ -110,6 +112,11 @@ class SvStream; struct ImplMetaReadData { rtl_TextEncoding meActualCharSet; + + ImplMetaReadData() : + meActualCharSet( RTL_TEXTENCODING_ASCII_US ) + { + } }; // ------------------------------------------------------------------------ @@ -117,6 +124,13 @@ struct ImplMetaReadData struct ImplMetaWriteData { rtl_TextEncoding meActualCharSet; + GDIMetaFileWriteFlags mnWriteFlags; + + ImplMetaWriteData() : + meActualCharSet( RTL_TEXTENCODING_ASCII_US ), + mnWriteFlags( GDIMETAFILE_WRITE_DEFAULT ) + { + } }; // ------------------------------------------------------------------------ @@ -1543,4 +1557,41 @@ public: LanguageType GetTextLanguage() const { return meTextLanguage; } }; +// --------------------------- +// - MetaRenderGraphicAction - +// --------------------------- + +class VCL_DLLPUBLIC MetaRenderGraphicAction : public MetaAction +{ +private: + + ::vcl::RenderGraphic maRenderGraphic; + Point maPoint; + Size maSize; + double mfRotateAngle; + double mfShearAngleX; + double mfShearAngleY; + + virtual sal_Bool Compare( const MetaAction& ) const; + +public: + DECL_META_ACTION( RenderGraphic, META_RENDERGRAPHIC_ACTION ) + + MetaRenderGraphicAction( const Point& rPoint, const Size& rSize, + const vcl::RenderGraphic& rRenderData, + double fRotateAngle = 0.0, + double fShearAngleX = 0.0, + double fShearAngleY = 0.0 ); + + virtual void Move( long nHorzMove, long nVertMove ); + virtual void Scale( double fScaleX, double fScaleY ); + + const ::vcl::RenderGraphic& GetRenderGraphic() const { return maRenderGraphic; } + const Point& GetPoint() const { return maPoint; } + const Size& GetSize() const { return maSize; } + double GetRotateAngle() const { return mfRotateAngle; } + double GetShearAngleX() const { return mfShearAngleX; } + double GetShearAngleY() const { return mfShearAngleY; } +}; + #endif // _SV_METAACT_HXX diff --git a/vcl/inc/vcl/outdev.hxx b/vcl/inc/vcl/outdev.hxx index 1130db5bd4a2..601670592194 100755..100644 --- a/vcl/inc/vcl/outdev.hxx +++ b/vcl/inc/vcl/outdev.hxx @@ -108,6 +108,7 @@ namespace vcl class PDFWriterImpl; class ExtOutDevData; class ITextLayout; + class RenderGraphic; } #define OUTDEV_BUFFER_SIZE 128 @@ -808,7 +809,19 @@ public: void DrawTransparent( const PolyPolygon& rPolyPoly, sal_uInt16 nTransparencePercent ); void DrawTransparent( const basegfx::B2DPolyPolygon& rB2DPolyPoly, double fTransparency); - void DrawTransparent( const GDIMetaFile& rMtf, const Point& rPos, const Size& rSize, const Gradient& rTransparenceGradient ); + void DrawTransparent( const GDIMetaFile& rMtf, const Point& rPos, const Size& rSize, + const Gradient& rTransparenceGradient ); + + /** Added return value to see if EPS could be painted directly. + Theoreticaly, handing over a matrix would be needed to handle + painting rotated EPS files (e.g. contained in Metafiles). This + would then need to be supported for Mac and PS printers, but + that's too much for now, wrote #i107046# for this */ + bool DrawEPS( const Point& rPt, const Size& rSz, + const GfxLink& rGfxLink, GDIMetaFile* pSubst = NULL ); + + void DrawRenderGraphic( const Point& rPt, const Size& rSz, + const ::vcl::RenderGraphic& rRenderGraphic ); Color GetPixel( const Point& rPt ) const; Color* GetPixel( const Polygon& rPts ) const; @@ -1117,14 +1130,6 @@ public: */ sal_Bool HasAlpha(); - /** Added return value to see if EPS could be painted directly. - Theoreticaly, handing over a matrix would be needed to handle - painting rotated EPS files (e.g. contained in Metafiles). This - would then need to be supported for Mac and PS printers, but - that's too much for now, wrote #i107046# for this */ - bool DrawEPS( const Point& rPt, const Size& rSz, - const GfxLink& rGfxLink, GDIMetaFile* pSubst = NULL ); - /// request XCanvas render interface for this OutputDevice ::com::sun::star::uno::Reference< ::com::sun::star::rendering::XCanvas > GetCanvas() const; diff --git a/vcl/inc/vcl/rendergraphic.hxx b/vcl/inc/vcl/rendergraphic.hxx new file mode 100644 index 000000000000..0a0f475decd6 --- /dev/null +++ b/vcl/inc/vcl/rendergraphic.hxx @@ -0,0 +1,124 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#ifndef _SV_RENDERGRAPHIC_HXX +#define _SV_RENDERGRAPHIC_HXX + +#include <vcl/dllapi.h> +#include <rtl/ustring.hxx> +#include <boost/shared_array.hpp> +#include <memory> + +class SvStream; +class MapMode; +class Size; +class BitmapEx; + +namespace vcl +{ + // ----------------- + // - RenderGraphic - + // ----------------- + class VCL_DLLPUBLIC RenderGraphic + { + public: + + typedef boost::shared_array< sal_uInt8 > GraphicData; + + friend VCL_DLLPUBLIC ::SvStream& operator>>( ::SvStream& rIStm, RenderGraphic& rRenderGraphic ); + friend VCL_DLLPUBLIC ::SvStream& operator<<( ::SvStream& rOStm, const RenderGraphic& rRenderGraphic ); + + public: + + RenderGraphic( ); + + RenderGraphic( const RenderGraphic& rRenderGraphic ); + + RenderGraphic( const GraphicData& rGraphicData, + sal_uInt32 nGraphicDataLength, + const rtl::OUString& rGraphicDataMimeType ); + + RenderGraphic( const rtl::OUString& rGraphicDataMimeType, + sal_uInt32 nGraphicDataLength, + const sal_uInt8* pGraphicData = NULL ); + + virtual ~RenderGraphic(); + + RenderGraphic& operator=(const RenderGraphic& rRenderGraphic ); + + bool operator==(const RenderGraphic& rRenderGraphic ) const; + + inline bool operator!=(const RenderGraphic& rRenderGraphic ) const + { + return( !( rRenderGraphic == *this ) ); + } + + bool IsEqual( const RenderGraphic& rRenderGraphic ) const; + + bool operator!() const; + + inline bool IsEmpty( ) const + { + return( !( *this ) ); + } + + inline const GraphicData& GetGraphicData( ) const + { + return( maGraphicData ); + } + + inline sal_uInt32 GetGraphicDataLength( ) const + { + return( mnGraphicDataLength ); + } + + inline const rtl::OUString& GetGraphicDataMimeType( ) const + { + return( maGraphicDataMimeType ); + } + + const MapMode& GetPrefMapMode() const; + const Size& GetPrefSize() const; + + BitmapEx GetReplacement() const; + + private: + + void ImplCheckData(); + void ImplGetDefaults() const; + + private: + + GraphicData maGraphicData; + sal_uInt32 mnGraphicDataLength; + rtl::OUString maGraphicDataMimeType; + mutable ::std::auto_ptr< MapMode > mapPrefMapMode; + mutable ::std::auto_ptr< Size > mapPrefSize; + }; +} + +#endif // _SV_RENDERHRAPHIC_HXX diff --git a/vcl/inc/vcl/rendergraphicrasterizer.hxx b/vcl/inc/vcl/rendergraphicrasterizer.hxx new file mode 100644 index 000000000000..f2166b03ffb3 --- /dev/null +++ b/vcl/inc/vcl/rendergraphicrasterizer.hxx @@ -0,0 +1,111 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#ifndef _SV_RENDERGRAPHICRASTERIZER_HXX +#define _SV_RENDERGRAPHICRASTERIZER_HXX + +#include <vcl/rendergraphic.hxx> +#include <vcl/bitmapex.hxx> + +#include <com/sun/star/graphic/XGraphicRasterizer.hpp> + +#include <memory> +#include <deque> + +#define VCL_RASTERIZER_UNLIMITED_EXTENT 0x00000000 +#define VCL_RASTERIZER_DEFAULT_EXTENT 0xffffffff + +namespace vcl +{ + // --------------------------- + // - RenderGraphicRasterizer - + // --------------------------- + + class VCL_DLLPUBLIC RenderGraphicRasterizer + { + public: + + RenderGraphicRasterizer( const RenderGraphic& rData ); + + + RenderGraphicRasterizer( const RenderGraphicRasterizer& rRenderGraphicRasterizer ); + + virtual ~RenderGraphicRasterizer(); + + RenderGraphicRasterizer& operator=( const RenderGraphicRasterizer& rRenderGraphicRasterizer ); + + inline const RenderGraphic& GetRenderGraphic() const + { + return( maRenderGraphic ); + } + + const Size& GetDefaultSizePixel() const; + + BitmapEx GetReplacement() const; + + virtual Size GetPrefSize() const; + + virtual MapMode GetPrefMapMode() const; + + virtual const BitmapEx& Rasterize( const Size& rSizePixel_UnrotatedUnsheared, + double fRotateAngle = 0.0, + double fShearAngleX = 0.0, + double fShearAngleY = 0.0, + sal_uInt32 nMaxExtent = VCL_RASTERIZER_DEFAULT_EXTENT ) const; + + protected: + + RenderGraphic maRenderGraphic; + mutable com::sun::star::uno::Reference< com::sun::star::graphic::XGraphicRasterizer > mxRasterizer; + + virtual void InitializeRasterizer(); + + private: + + RenderGraphicRasterizer(); + + mutable BitmapEx maBitmapEx; + mutable Size maDefaultSizePixel; + mutable double mfRotateAngle; + mutable double mfShearAngleX; + mutable double mfShearAngleY; + + private: + + typedef ::std::deque< RenderGraphicRasterizer > RenderGraphicRasterizerCache; + + static RenderGraphicRasterizerCache& ImplGetCache(); + + static bool ImplInitializeFromCache( RenderGraphicRasterizer& rRasterizer ); + static bool ImplRasterizeFromCache( RenderGraphicRasterizer& rRasterizer, + const Size& rSizePixel, double fRotateAngle, + double fShearAngleX, double fShearAngleY ); + static void ImplUpdateCache( const RenderGraphicRasterizer& rRasterizer ); +}; +} + +#endif // _SV_RENDERGRAPHICRASTERIZER_HXX diff --git a/vcl/inc/vcl/salctype.hxx b/vcl/inc/vcl/salctype.hxx index aa7741c69034..1894143f78be 100644 --- a/vcl/inc/vcl/salctype.hxx +++ b/vcl/inc/vcl/salctype.hxx @@ -48,6 +48,7 @@ #define CVT_TIF (0x00000008UL) #define CVT_WMF (0x00000009UL) #define CVT_EMF (0x0000000aUL) +#define CVT_SVG (0x0000000bUL) // --------------- // - ConvertData - diff --git a/vcl/inc/vcl/svgread.hxx b/vcl/inc/vcl/svgread.hxx new file mode 100644 index 000000000000..ea4388767d02 --- /dev/null +++ b/vcl/inc/vcl/svgread.hxx @@ -0,0 +1,80 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#ifndef _SV_SVGREAD_HXX +#define _SV_SVGREAD_HXX + +#include <vcl/dllapi.h> +#include <memory> + +// ------------- +// - SVGReader - +// ------------- + +class SvStream; +class GDIMetaFile; + +namespace vcl +{ + class SVGReaderImpl; + + class VCL_DLLPUBLIC SVGReader + { + public: + + SVGReader( SvStream& rStm ); + ~SVGReader(); + + /* rSVGMtf is an output parameter, that is also returned + by the method as well. + + In case of a failure, the GDIMetaFile will not contain + any actions at all and thus GDIMetaFile::GetActionCount + will return 0. + + In case of success, the GDIMetaFile will contain a + META_RENDERGRAPHIC_ACTION, containing the SVG raw data. The + data can be rendered by using the standard ways to output a + GDIMetaFile, e.g. calling GDIMetaFile::Play + + */ + GDIMetaFile& Read( GDIMetaFile& rSVGMtf ); + + private: + + SVGReader(); + SVGReader( const SVGReader& rReader ); + + inline SVGReader& operator=( const SVGReader& /* rReader */ ) { return( *this ); } + + private: + + std::auto_ptr< SVGReaderImpl > mapImpl; + }; +} + +#endif // _SV_SVGREAD_HXX diff --git a/vcl/prj/d.lst b/vcl/prj/d.lst index 5a7dd7d9ef91..bb5d8427af82 100644 --- a/vcl/prj/d.lst +++ b/vcl/prj/d.lst @@ -91,6 +91,8 @@ mkdir: %_DEST%\inc%_EXT%\vcl ..\inc\vcl\ptrstyle.hxx %_DEST%\inc%_EXT%\vcl\ptrstyle.hxx ..\inc\vcl\regband.hxx %_DEST%\inc%_EXT%\vcl\regband.hxx ..\inc\vcl\region.hxx %_DEST%\inc%_EXT%\vcl\region.hxx +..\inc\vcl\rendergraphic.hxx %_DEST%\inc%_EXT%\vcl\rendergraphic.hxx +..\inc\vcl\rendergraphicrasterizer.hxx %_DEST%\inc%_EXT%\vcl\rendergraphicrasterizer.hxx ..\inc\vcl\salbtype.hxx %_DEST%\inc%_EXT%\vcl\salbtype.hxx ..\inc\vcl\salctype.hxx %_DEST%\inc%_EXT%\vcl\salctype.hxx ..\inc\vcl\salgtype.hxx %_DEST%\inc%_EXT%\vcl\salgtype.hxx @@ -153,6 +155,7 @@ mkdir: %_DEST%\inc%_EXT%\vcl ..\inc\vcl\helper.hxx %_DEST%\inc%_EXT%\vcl\helper.hxx ..\inc\vcl\strhelper.hxx %_DEST%\inc%_EXT%\vcl\strhelper.hxx ..\inc\vcl\lazydelete.hxx %_DEST%\inc%_EXT%\vcl\lazydelete.hxx +..\inc\vcl\svgread.hxx %_DEST%\inc%_EXT%\vcl\svgread.hxx ..\inc\vcl\arrange.hxx %_DEST%\inc%_EXT%\vcl\arrange.hxx ..\inc\vcl\wpropset.hxx %_DEST%\inc%_EXT%\vcl\wpropset.hxx ..\%__SRC%\misc\vcl.component %_DEST%\xml%_EXT%\vcl.component diff --git a/vcl/source/components/factory.cxx b/vcl/source/components/factory.cxx index 7cfdecbfdb00..48fb3aac653a 100644 --- a/vcl/source/components/factory.cxx +++ b/vcl/source/components/factory.cxx @@ -45,9 +45,7 @@ using ::rtl::OUStringBuffer; using namespace com::sun::star::uno; using namespace com::sun::star::lang; - // service implementation - extern Sequence< OUString > SAL_CALL vcl_session_getSupportedServiceNames(); extern OUString SAL_CALL vcl_session_getImplementationName(); extern Reference< XInterface > SAL_CALL vcl_session_createInstance( const Reference< XMultiServiceFactory > & ); @@ -77,6 +75,13 @@ extern Reference< XInterface > SAL_CALL DragSource_createInstance( const Referen extern Sequence< OUString > SAL_CALL DropTarget_getSupportedServiceNames(); extern OUString SAL_CALL DropTarget_getImplementationName(); extern Reference< XInterface > SAL_CALL DropTarget_createInstance( const Reference< XMultiServiceFactory > & ); + +namespace rsvg +{ + extern Sequence< OUString > SAL_CALL Rasterizer_getSupportedServiceNames(); + extern OUString SAL_CALL Rasterizer_getImplementationName(); + extern Reference< XInterface > SAL_CALL Rasterizer_createInstance( const Reference< XMultiServiceFactory > & ); +} } extern "C" { @@ -142,6 +147,12 @@ extern "C" { xMgr, vcl::DropTarget_getImplementationName(), vcl::DropTarget_createInstance, vcl::DropTarget_getSupportedServiceNames() ); } + else if( vcl::rsvg::Rasterizer_getImplementationName().equalsAscii( pImplementationName ) ) + { + xFactory = ::cppu::createSingleFactory( + xMgr, vcl::rsvg::Rasterizer_getImplementationName(), vcl::rsvg::Rasterizer_createInstance, + vcl::rsvg::Rasterizer_getSupportedServiceNames() ); + } if( xFactory.is() ) { xFactory->acquire(); diff --git a/vcl/source/components/makefile.mk b/vcl/source/components/makefile.mk index 982687104c01..41f21bfa3749 100644 --- a/vcl/source/components/makefile.mk +++ b/vcl/source/components/makefile.mk @@ -33,20 +33,23 @@ ENABLE_EXCEPTIONS=TRUE # --- Settings ----------------------------------------------------- -.INCLUDE : $(PRJ)$/util$/makefile.pmk -.INCLUDE : settings.mk +.INCLUDE : $(PRJ)$/util$/makefile.pmk +.INCLUDE : settings.mk .INCLUDE : $(PRJ)$/util$/makefile2.pmk # --- Files -------------------------------------------------------- -SLOFILES= $(SLO)$/display.obj \ - $(SLO)$/dtranscomp.obj \ - $(SLO)$/fontident.obj \ - $(SLO)$/stringmirror.obj \ +SLOFILES= $(SLO)$/display.obj \ + $(SLO)$/dtranscomp.obj \ + $(SLO)$/fontident.obj \ + $(SLO)$/stringmirror.obj \ + $(SLO)$/rasterizer_rsvg.obj \ $(SLO)$/factory.obj -# --- Targets ------------------------------------------------------ +EXCEPTIONSFILES= $(SLO)$/rasterizer_rsvg.obj + -.INCLUDE : target.mk -.INCLUDE : $(PRJ)$/util$/target.pmk +# --- Targets ------------------------------------------------------ +.INCLUDE : target.mk +.INCLUDE : $(PRJ)$/util$/target.pmk diff --git a/vcl/source/components/rasterizer_rsvg.cxx b/vcl/source/components/rasterizer_rsvg.cxx new file mode 100644 index 000000000000..5547b179d227 --- /dev/null +++ b/vcl/source/components/rasterizer_rsvg.cxx @@ -0,0 +1,640 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_vcl.hxx" + +#include <vcl/graph.hxx> +#include <vcl/bmpacc.hxx> +#include <vcl/alpha.hxx> +#include <com/sun/star/graphic/XGraphicRasterizer.hpp> +#include <com/sun/star/lang/XServiceInfo.hpp> +#include <com/sun/star/io/XSeekable.hpp> +#include <cppuhelper/implbase2.hxx> +#include <osl/module.h> + +#include <vector> + +#if defined MACOSX + #define VCL_RSVG_GOBJECT_LIBNAME "libgobject-2.0.0.dylib" + #define VCL_RSVG_CAIRO_LIBNAME "libcairo.2.dylib" + #define VCL_RSVG_LIBRSVG_LIBNAME "librsvg-2.2.dylib" +#elif defined UNX + #define VCL_RSVG_GOBJECT_LIBNAME "libgobject-2.0.so" + #define VCL_RSVG_CAIRO_LIBNAME "libcairo.so" + #define VCL_RSVG_LIBRSVG_LIBNAME "librsvg-2.so" +#elif defined WNT + #define VCL_RSVG_GOBJECT_LIBNAME "libgobject-2.0-0.dll" + #define VCL_RSVG_CAIRO_LIBNAME "cairo.dll" + #define VCL_RSVG_LIBRSVG_LIBNAME "librsvg-2-2.dll" +#else + #define VCL_RSVG_GOBJECT_LIBNAME "nogobjectlib" + #define VCL_RSVG_CAIRO_LIBNAME "nocairolib" + #define VCL_RSVG_LIBRSVG_LIBNAME "nolibrsvglib" +#endif + +#define VCL_RSVG_DEFAULT_DPI 72 + +using namespace ::com::sun::star; + +// ----------------------------------------------------- +// - external stuff for dynamic library function calls - +// ----------------------------------------------------- + +typedef int gboolean; +typedef unsigned char guint8; +typedef sal_Size gsize; +typedef void* gpointer; + +struct GError; + +enum cairo_format_t { CAIRO_FORMAT_ARGB32 = 0 }; +enum cairo_status_t { CAIRO_STATUS_SUCCESS = 0 }; + +struct cairo_surface_t; +struct cairo_t; +struct cairo_matrix_t +{ + double xx; double yx; + double xy; double yy; + double x0; double y0; +}; + +struct RsvgHandle; +struct RsvgDimensionData +{ + int width; + int height; + double em; + double ex; +}; + +namespace vcl +{ +namespace rsvg +{ +// ----------------- +// - Uno functions - +// ---------------- + +uno::Sequence< ::rtl::OUString > Rasterizer_getSupportedServiceNames() +{ + static ::rtl::OUString aServiceName( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.graphic.GraphicRasterizer_RSVG" ) ); + static uno::Sequence< ::rtl::OUString > aServiceNames( &aServiceName, 1 ); + + return( aServiceNames ); +} + +// ----------------------------------------------------------------------------- + +::rtl::OUString Rasterizer_getImplementationName() +{ + return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "vcl::rsvg::Rasterizer" ) ); +} + +// ------------------ +// - LibraryWrapper - +// ------------------ + +class LibraryWrapper +{ +public: + + static LibraryWrapper& get(); + + bool isValid() const { return( ( mpGObjectLib != NULL ) && ( mpCairoLib != NULL ) && ( mpRSVGLib != NULL ) ); } + + // G-Object + gpointer g_object_unref( gpointer pointer ) { return( (*mp_g_object_unref)( pointer ) ); }; + + // LibRSVG + + // Cairo + cairo_surface_t* image_surface_create( cairo_format_t format, int width, int height ) { return( (*mp_image_surface_create)( format, width, height ) ); } + void surface_destroy( cairo_surface_t* surface ) { (*mp_surface_destroy)( surface ); } + cairo_status_t surface_status( cairo_surface_t* surface ) { return( (*mp_surface_status)( surface ) ); } + cairo_t* create( cairo_surface_t* surface ) { return( (*mp_create)( surface ) ); } + void destroy( cairo_t* cairo ) { (*mp_destroy )( cairo ); } + void matrix_init_identity( cairo_matrix_t* matrix ){ (*mp_matrix_init_identity)( matrix ); } + void matrix_translate( cairo_matrix_t* matrix, double nx, double ny ) { (*mp_matrix_translate)( matrix, nx, ny ); } + void matrix_scale( cairo_matrix_t* matrix, double sx, double sy ) {( *mp_matrix_scale )( matrix, sx, sy ); } + void matrix_rotate( cairo_matrix_t* matrix, double radians ) { ( *mp_matrix_rotate )( matrix, radians ); } + void transform( cairo_t* cairo, cairo_matrix_t *matrix ) { (*mp_transform)( cairo, matrix ); } + unsigned char* image_surface_get_data(cairo_surface_t* surface) { return( (*mp_image_surface_get_data)( surface ) ); } + int image_surface_get_width(cairo_surface_t* surface) { return( (*mp_image_surface_get_width)( surface ) ); } + int image_surface_get_height(cairo_surface_t* surface) { return( (*mp_image_surface_get_height)( surface ) ); } + int image_surface_get_stride(cairo_surface_t* surface) { return( (*mp_image_surface_get_stride)( surface ) ); } + + // LibRSVG + void rsvg_init() { (*mp_rsvg_init)(); } + RsvgHandle* rsvg_handle_new_from_data( const guint8* data, gsize size, GError** error) { return( (*mp_rsvg_handle_new_from_data)( data, size, error ) ); } + gboolean rsvg_handle_close( RsvgHandle* handle, GError** error ) { return( (*mp_rsvg_handle_close)( handle, error ) ); } + void rsvg_handle_set_dpi_x_y( RsvgHandle* handle, double dpix, double dpiy ) { (*mp_rsvg_handle_set_dpi_x_y)( handle, dpix, dpiy ); } + void rsvg_handle_get_dimensions( RsvgHandle* handle, RsvgDimensionData* dimensions ) { (*mp_rsvg_handle_get_dimensions)( handle, dimensions ); } + gboolean rsvg_handle_render_cairo( RsvgHandle* handle, cairo_t* cairo ) { return( (*mp_rsvg_handle_render_cairo)( handle, cairo ) ); } + +private: + + LibraryWrapper(); + +private: + + oslModule mpGObjectLib; + oslModule mpCairoLib; + oslModule mpRSVGLib; + + // GObject + gpointer (*mp_g_object_unref)( gpointer ); + + // Cairo + cairo_surface_t* (*mp_image_surface_create)(cairo_format_t,int,int); + void (*mp_surface_destroy )(cairo_surface_t*); + cairo_status_t (*mp_surface_status)(cairo_surface_t*); + cairo_t* (*mp_create)(cairo_surface_t*); + void (*mp_destroy)(cairo_t*); + void (*mp_matrix_init_identity)(cairo_matrix_t*); + void (*mp_matrix_translate)( cairo_matrix_t*, double, double); + void (*mp_matrix_scale )( cairo_matrix_t*, double, double); + void (*mp_matrix_rotate)( cairo_matrix_t*, double); + void (*mp_transform)( cairo_t*, cairo_matrix_t*); + unsigned char* (*mp_image_surface_get_data)( cairo_surface_t* ); + int (*mp_image_surface_get_width)(cairo_surface_t* surface); + int (*mp_image_surface_get_height)(cairo_surface_t* surface); + int (*mp_image_surface_get_stride)(cairo_surface_t* surface); + + // LibRSVG + void (*mp_rsvg_init)( void ); + RsvgHandle* (*mp_rsvg_handle_new_from_data)( const guint8*, gsize, GError** ); + gboolean (*mp_rsvg_handle_close)( RsvgHandle*, GError** ); + void (*mp_rsvg_handle_set_dpi_x_y)( RsvgHandle*, double, double ); + void (*mp_rsvg_handle_get_dimensions)( RsvgHandle*, RsvgDimensionData* ); + gboolean (*mp_rsvg_handle_render_cairo)( RsvgHandle*, cairo_t* ); +}; + +// ----------------------------------------------------------------------------- + +LibraryWrapper& LibraryWrapper::get() +{ + static LibraryWrapper* pLibraryInstance = NULL; + + if( !pLibraryInstance ) + pLibraryInstance = new LibraryWrapper; + + return( *pLibraryInstance ); +} + +// ----------------------------------------------------------------------------- + +LibraryWrapper::LibraryWrapper() : + mpGObjectLib( NULL ), + mpCairoLib( NULL ), + mpRSVGLib( NULL ) +{ + const ::rtl::OUString aGObjectLibName( RTL_CONSTASCII_USTRINGPARAM( VCL_RSVG_GOBJECT_LIBNAME ) ); + const ::rtl::OUString aCairoLibName( RTL_CONSTASCII_USTRINGPARAM( VCL_RSVG_CAIRO_LIBNAME ) ); + const ::rtl::OUString aRSVGLibName( RTL_CONSTASCII_USTRINGPARAM( VCL_RSVG_LIBRSVG_LIBNAME ) ); + bool bCont = true; + + // GObject + if( bCont && ( NULL != ( mpGObjectLib = osl_loadModule( aGObjectLibName.pData, SAL_LOADMODULE_DEFAULT ) ) || + NULL != ( mpGObjectLib = osl_loadModuleRelative( (oslGenericFunction)LibraryWrapper::get, + aGObjectLibName.pData, SAL_LOADMODULE_DEFAULT ) ) + + ) ) + { + mp_g_object_unref = ( gpointer (*)( gpointer ) ) osl_getAsciiFunctionSymbol( mpGObjectLib, "g_object_unref" ); + + if( !( mp_g_object_unref ) ) + { + OSL_TRACE( "not all needed symbols were found in g-object library" ); + bCont = false; + } + } + + // Cairo + if( bCont && ( NULL != ( mpCairoLib = osl_loadModule( aCairoLibName.pData, SAL_LOADMODULE_DEFAULT ) ) || + NULL != ( mpCairoLib = osl_loadModuleRelative( (oslGenericFunction)LibraryWrapper::get, + aCairoLibName.pData, SAL_LOADMODULE_DEFAULT ) ) + ) ) + { + mp_image_surface_create = ( cairo_surface_t* (*)( cairo_format_t, int, int ) ) osl_getAsciiFunctionSymbol( mpCairoLib, "cairo_image_surface_create" ); + mp_surface_destroy = ( void (*)( cairo_surface_t* ) ) osl_getAsciiFunctionSymbol( mpCairoLib, "cairo_surface_destroy" ); + mp_surface_status = ( cairo_status_t (*)( cairo_surface_t* ) ) osl_getAsciiFunctionSymbol( mpCairoLib, "cairo_surface_status" ); + mp_create = ( cairo_t* (*)( cairo_surface_t* ) ) osl_getAsciiFunctionSymbol( mpCairoLib, "cairo_create" ); + mp_destroy = ( void (*)( cairo_t* ) ) osl_getAsciiFunctionSymbol( mpCairoLib, "cairo_destroy" ); + mp_matrix_init_identity = ( void (*)( cairo_matrix_t* ) ) osl_getAsciiFunctionSymbol( mpCairoLib, "cairo_matrix_init_identity" ); + mp_matrix_translate = ( void (*)( cairo_matrix_t*, double, double ) ) osl_getAsciiFunctionSymbol( mpCairoLib, "cairo_matrix_translate" ); + mp_matrix_scale = ( void (*)( cairo_matrix_t*, double, double ) ) osl_getAsciiFunctionSymbol( mpCairoLib, "cairo_matrix_scale" ); + mp_matrix_rotate = ( void (*)( cairo_matrix_t*, double ) ) osl_getAsciiFunctionSymbol( mpCairoLib, "cairo_matrix_rotate" ); + mp_transform = ( void (*)( cairo_t*, cairo_matrix_t* ) ) osl_getAsciiFunctionSymbol( mpCairoLib, "cairo_transform" ); + mp_image_surface_get_data = ( unsigned char* (*)( cairo_surface_t* ) ) osl_getAsciiFunctionSymbol( mpCairoLib, "cairo_image_surface_get_data" ); + mp_image_surface_get_width = ( int (*)( cairo_surface_t* ) ) osl_getAsciiFunctionSymbol( mpCairoLib, "cairo_image_surface_get_width" ); + mp_image_surface_get_height = ( int (*)( cairo_surface_t* ) ) osl_getAsciiFunctionSymbol( mpCairoLib, "cairo_image_surface_get_height" ); + mp_image_surface_get_stride = ( int (*)( cairo_surface_t* ) ) osl_getAsciiFunctionSymbol( mpCairoLib, "cairo_image_surface_get_stride" ); + + if( !( mp_image_surface_create && + mp_surface_destroy && + mp_surface_status && + mp_create && + mp_destroy && + mp_matrix_init_identity && + mp_matrix_translate && + mp_matrix_scale && + mp_matrix_rotate && + mp_transform && + mp_image_surface_get_data && + mp_image_surface_get_width && + mp_image_surface_get_height && + mp_image_surface_get_stride ) ) + { + OSL_TRACE( "not all needed symbols were found in cairo library" ); + bCont = false; + } + } + + // LibRSVG + if( bCont && ( NULL != ( mpRSVGLib = osl_loadModule( aRSVGLibName.pData, SAL_LOADMODULE_DEFAULT ) ) || + NULL != ( mpRSVGLib = osl_loadModuleRelative( (oslGenericFunction)LibraryWrapper::get, + aRSVGLibName.pData, SAL_LOADMODULE_DEFAULT ) ) + ) ) + { + mp_rsvg_init = ( void (*)( void ) ) osl_getAsciiFunctionSymbol( mpRSVGLib, "rsvg_init" ); + mp_rsvg_handle_new_from_data = ( RsvgHandle* (*)( const guint8*, gsize, GError** ) ) osl_getAsciiFunctionSymbol( mpRSVGLib, "rsvg_handle_new_from_data" ); + mp_rsvg_handle_close = ( gboolean (*)( RsvgHandle*, GError** ) ) osl_getAsciiFunctionSymbol( mpRSVGLib, "rsvg_handle_close" ); + mp_rsvg_handle_set_dpi_x_y = ( void (*)( RsvgHandle*, double, double ) ) osl_getAsciiFunctionSymbol( mpRSVGLib, "rsvg_handle_set_dpi_x_y" ); + mp_rsvg_handle_get_dimensions = ( void (*)( RsvgHandle*, RsvgDimensionData* ) ) osl_getAsciiFunctionSymbol( mpRSVGLib, "rsvg_handle_get_dimensions" ); + mp_rsvg_handle_render_cairo = ( gboolean (*)( RsvgHandle*, cairo_t* ) ) osl_getAsciiFunctionSymbol( mpRSVGLib, "rsvg_handle_render_cairo" ); + + if( !( mp_rsvg_init && + mp_rsvg_handle_new_from_data && + mp_rsvg_handle_close && + mp_rsvg_handle_set_dpi_x_y && + mp_rsvg_handle_get_dimensions && + mp_rsvg_handle_render_cairo ) ) + { + OSL_TRACE( "not all needed symbols were found in librsvg library" ); + bCont = false; + } + } + + OSL_ENSURE( mpGObjectLib, "g-object library could not be loaded" ); + OSL_ENSURE( mpCairoLib, "cairo library could not be loaded" ); + OSL_ENSURE( mpRSVGLib, "librsvg library could not be loaded" ); + + bCont = bCont && mpGObjectLib != NULL && mpCairoLib != NULL && mpRSVGLib != NULL; + + // unload all libraries in case of failure + if( !bCont ) + { + if( mpRSVGLib ) + { + osl_unloadModule( mpRSVGLib ); + mpRSVGLib = NULL; + } + + if( mpCairoLib ) + { + osl_unloadModule( mpCairoLib ); + mpCairoLib = NULL; + } + + if( mpGObjectLib ) + { + osl_unloadModule( mpGObjectLib ); + mpGObjectLib = NULL; + } + } + else + rsvg_init(); +} + +// --------------------------- +// - ::vcl::rsvg::Rasterizer - +// --------------------------- + +class Rasterizer : public ::cppu::WeakAggImplHelper2< graphic::XGraphicRasterizer, lang::XServiceInfo > +{ +public: + Rasterizer(); + virtual ~Rasterizer(); + + // XGraphicRasterizer + virtual ::sal_Bool SAL_CALL initializeData( const uno::Reference< io::XInputStream >& DataStream, + ::sal_uInt32 DPI_X, ::sal_uInt32 DPI_Y, + awt::Size& DefaultSizePixel ) + throw ( uno::RuntimeException ); + + virtual uno::Reference< graphic::XGraphic > SAL_CALL rasterize( ::sal_uInt32 Width, + ::sal_uInt32 Height, + double RotateAngle, + double ShearAngle_X, + double ShearAngle_Y, + const uno::Sequence< beans::PropertyValue >& RasterizeProperties ) + throw (uno::RuntimeException); + + // XServiceInfo + virtual ::rtl::OUString SAL_CALL getImplementationName() + throw( uno::RuntimeException); + + virtual ::sal_Bool SAL_CALL supportsService( const ::rtl::OUString& ) + throw( uno::RuntimeException ); + + virtual uno::Sequence< ::rtl::OUString > SAL_CALL getSupportedServiceNames() + throw( uno::RuntimeException ); + +protected: + + void implFreeRsvgHandle(); + + uno::Reference< graphic::XGraphic > implGetXGraphicFromSurface( cairo_surface_t* pSurface ) const; + +private: + + Rasterizer( const Rasterizer& ); + Rasterizer& operator=( const Rasterizer& ); + +private: + + RsvgHandle* mpRsvgHandle; + sal_Int32 mnDefaultWidth; + sal_Int32 mnDefaultHeight; + bool mbLibInit; +}; + +// ----------------------------------------------------------------------------- + +Rasterizer::Rasterizer() : + mpRsvgHandle( NULL ), + mnDefaultWidth( 0 ), + mnDefaultHeight( 0 ), + mbLibInit( true ) +{ + try + { + LibraryWrapper& rLib = LibraryWrapper::get(); + mbLibInit = rLib.isValid(); + } + catch( ... ) + { + mbLibInit = false; + } +} + +// ----------------------------------------------------------------------------- + +Rasterizer::~Rasterizer() +{ + implFreeRsvgHandle(); +} + +// ----------------------------------------------------------------------------- + +void Rasterizer::implFreeRsvgHandle() +{ + if( mpRsvgHandle ) + { + LibraryWrapper::get().g_object_unref( static_cast< gpointer >( mpRsvgHandle ) ); + mpRsvgHandle = NULL; + } +} + +// ----------------------------------------------------------------------------- + +uno::Reference< graphic::XGraphic > Rasterizer::implGetXGraphicFromSurface( cairo_surface_t* pSurface ) const +{ + LibraryWrapper& rLib = LibraryWrapper::get(); + unsigned char* pData = rLib.image_surface_get_data( pSurface ); + const sal_Int32 nWidth = rLib.image_surface_get_width( pSurface ); + const sal_Int32 nHeight =rLib.image_surface_get_height( pSurface ); + const sal_Int32 nStride = rLib.image_surface_get_stride( pSurface ); + + uno::Reference< graphic::XGraphic > xRet; + + if( pData && nWidth && nHeight && nStride ) + { + Size aSize( nWidth, nHeight ); + Bitmap aBmp( aSize, 24 ); + AlphaMask aAlphaMask( aSize ); + BitmapWriteAccess* pBmpAcc = aBmp.AcquireWriteAccess(); + BitmapWriteAccess* pAlpAcc = aAlphaMask.AcquireWriteAccess(); + + if( pBmpAcc && pAlpAcc ) + { + BitmapColor aPixel, aWhitePixel( 255, 255, 255 ), aAlpha( 0 ), aFullAlpha( 255 ); + sal_uInt32* pRow = reinterpret_cast< sal_uInt32* >( pData ); + + for( sal_Int32 nY = 0; nY < nHeight; ++nY, pRow = reinterpret_cast< sal_uInt32* >( pData += nStride ) ) + { + for( sal_Int32 nX = 0; nX < nWidth; ++nX ) + { + const register sal_uInt32 nPixel = *pRow++; + const register sal_uInt32 nAlpha = nPixel >> 24; + + if( !nAlpha ) + { + pBmpAcc->SetPixel( nY, nX, aWhitePixel ); + pAlpAcc->SetPixel( nY, nX, aFullAlpha ); + } + else + { + aPixel.SetRed( static_cast< sal_uInt8 >( ( ( ( nPixel & 0x00ff0000 ) >> 16 ) * 255 ) / nAlpha ) ); + aPixel.SetGreen( static_cast< sal_uInt8 >( ( ( ( nPixel & 0x0000ff00 ) >> 8 ) * 255 ) / nAlpha ) ); + aPixel.SetBlue( static_cast< sal_uInt8 >( ( ( nPixel & 0x000000ff ) * 255 ) / nAlpha ) ); + pBmpAcc->SetPixel( nY, nX, aPixel ); + + aAlpha.SetIndex( static_cast< sal_uInt8 >( 255 - nAlpha ) ); + pAlpAcc->SetPixel( nY, nX, aAlpha ); + } + } + } + + aBmp.ReleaseAccess( pBmpAcc ); + aAlphaMask.ReleaseAccess( pAlpAcc ); + + const Graphic aGraphic( BitmapEx( aBmp, aAlphaMask ) ); + xRet.set( aGraphic.GetXGraphic(), uno::UNO_QUERY ); + } + else + { + aBmp.ReleaseAccess( pBmpAcc ); + aAlphaMask.ReleaseAccess( pAlpAcc ); + } + } + + return( xRet ); +} + +// ----------------------------------------------------------------------------- + +::sal_Bool SAL_CALL Rasterizer::initializeData( const uno::Reference< io::XInputStream >& rDataStream, + ::sal_uInt32 nDPI_X, ::sal_uInt32 nDPI_Y, + awt::Size& rDefaultSizePixel ) + throw ( uno::RuntimeException ) +{ + LibraryWrapper& rLib = LibraryWrapper::get(); + + implFreeRsvgHandle(); + + if( mbLibInit && rDataStream.is() ) + { + ::std::vector< sal_Int8 > aDataBuffer; + uno::Reference< io::XSeekable > xSeekable( rDataStream, uno::UNO_QUERY ); + sal_Int32 nReadSize, nBlockSize = ( xSeekable.is() ? xSeekable->getLength() : 65536 ); + uno::Sequence< sal_Int8 > aStmBuffer( nBlockSize ); + + do + { + nReadSize = rDataStream->readBytes( aStmBuffer, nBlockSize ); + + if( nReadSize > 0 ) + { + const sal_Int8* pArray = aStmBuffer.getArray(); + aDataBuffer.insert( aDataBuffer.end(), pArray, pArray + nReadSize ); + } + } + while( nReadSize == nBlockSize ); + + if( aDataBuffer.size() && + ( NULL != ( mpRsvgHandle = rLib.rsvg_handle_new_from_data( reinterpret_cast< sal_uInt8* >( &aDataBuffer[ 0 ] ), + aDataBuffer.size(), NULL ) ) ) && + !rLib.rsvg_handle_close( mpRsvgHandle, NULL ) ) + { + implFreeRsvgHandle(); + } + } + + // get default dimensions of image + mnDefaultWidth = mnDefaultHeight = 0; + + if( mpRsvgHandle ) + { + RsvgDimensionData aDefaultDimension = { 0, 0, 0.0, 0.0 }; + + rLib.rsvg_handle_set_dpi_x_y( mpRsvgHandle, nDPI_X ? nDPI_X: 72, nDPI_Y ? nDPI_Y : 72 ); + rLib.rsvg_handle_get_dimensions( mpRsvgHandle, &aDefaultDimension ); + + mnDefaultWidth = aDefaultDimension.width; + mnDefaultHeight = aDefaultDimension.height; + } + + rDefaultSizePixel.Width = mnDefaultWidth; + rDefaultSizePixel.Height = mnDefaultHeight; + + return( mpRsvgHandle != NULL ); +} + +// ----------------------------------------------------------------------------- + +uno::Reference< graphic::XGraphic > SAL_CALL Rasterizer::rasterize( ::sal_uInt32 nWidth, + ::sal_uInt32 nHeight, + double /*fRotateAngle*/, + double /*fShearAngle_X*/, + double /*ShearAngle_Y*/, + const uno::Sequence< beans::PropertyValue >& + /*rRasterizeProperties*/ ) + throw ( uno::RuntimeException ) +{ + LibraryWrapper& rLib = LibraryWrapper::get(); + uno::Reference< graphic::XGraphic > xRet; + + if( mpRsvgHandle && rLib.isValid() && nWidth && nHeight && mnDefaultWidth && mnDefaultHeight ) + { + cairo_surface_t* pSurface = rLib.image_surface_create( CAIRO_FORMAT_ARGB32, nWidth, nHeight ); + + if( pSurface && ( CAIRO_STATUS_SUCCESS == rLib.surface_status( pSurface ) ) ) + { + cairo_t* pCr = rLib.create( pSurface ); + + if( pCr ) + { + cairo_matrix_t aMatrix; + + rLib.matrix_init_identity( &aMatrix ); + rLib.matrix_scale( &aMatrix, + static_cast< double >( nWidth ) / mnDefaultWidth, + static_cast< double >( nHeight ) / mnDefaultHeight ); + rLib.transform( pCr, &aMatrix ); + + if( rLib.rsvg_handle_render_cairo( mpRsvgHandle, pCr ) ) + { + xRet = implGetXGraphicFromSurface( pSurface ); + } + + rLib.destroy( pCr ); + } + + rLib.surface_destroy( pSurface ); + OSL_ENSURE( xRet.is(), "SVG *not* rendered successfully" ); + } + } + + return( xRet ); +} + +// ----------------------------------------------------------------------------- + +::rtl::OUString SAL_CALL Rasterizer::getImplementationName() + throw( uno::RuntimeException ) +{ + return( Rasterizer_getImplementationName() ); +} + +// ----------------------------------------------------------------------------- + +sal_Bool SAL_CALL Rasterizer::supportsService( const ::rtl::OUString& rServiceName ) + throw( uno::RuntimeException ) +{ + const uno::Sequence< ::rtl::OUString > aServices( Rasterizer_getSupportedServiceNames() ); + + for( sal_Int32 nService = 0; nService < aServices.getLength(); ++nService ) + { + if( rServiceName == aServices[ nService ] ) + return sal_True; + } + + return sal_False; +} + +// ----------------------------------------------------------------------------- + +uno::Sequence< ::rtl::OUString > SAL_CALL Rasterizer::getSupportedServiceNames() + throw( uno::RuntimeException ) +{ + return( Rasterizer_getSupportedServiceNames() ); +} + +// ------------------------------ +// - Uno instantiation function - +// ------------------------------ + +uno::Reference< uno::XInterface > SAL_CALL Rasterizer_createInstance( const uno::Reference< lang::XMultiServiceFactory >& ) +{ + return static_cast< ::cppu::OWeakObject* >( new rsvg::Rasterizer ); +} + +} // namespace rsvg +} // namespace vcl diff --git a/vcl/source/gdi/gdimtf.cxx b/vcl/source/gdi/gdimtf.cxx index 23da138d23a2..1e99c5c3c04f 100644 --- a/vcl/source/gdi/gdimtf.cxx +++ b/vcl/source/gdi/gdimtf.cxx @@ -1449,6 +1449,15 @@ void GDIMetaFile::Rotate( long nAngle10 ) } break; + case( META_RENDERGRAPHIC_ACTION ): + { + OSL_TRACE( "Rotate not supported for RenderGraphic MetaActions yet" ); + + pAction->Duplicate(); + aMtf.AddAction( pAction ); + } + break; + default: { pAction->Execute( &aMapVDev ); @@ -1513,363 +1522,371 @@ Rectangle GDIMetaFile::GetBoundRect( OutputDevice& i_rReference ) switch( nActionType ) { case( META_PIXEL_ACTION ): - { - MetaPixelAction* pAct = (MetaPixelAction*) pAction; - ImplActionBounds( aBound, - Rectangle( aMapVDev.LogicToLogic( pAct->GetPoint(), aMapVDev.GetMapMode(), GetPrefMapMode() ), - aMapVDev.PixelToLogic( Size( 1, 1 ), GetPrefMapMode() ) ), - aClipStack ); - } - break; + { + MetaPixelAction* pAct = (MetaPixelAction*) pAction; + ImplActionBounds( aBound, + Rectangle( aMapVDev.LogicToLogic( pAct->GetPoint(), aMapVDev.GetMapMode(), GetPrefMapMode() ), + aMapVDev.PixelToLogic( Size( 1, 1 ), GetPrefMapMode() ) ), + aClipStack ); + } + break; case( META_POINT_ACTION ): - { - MetaPointAction* pAct = (MetaPointAction*) pAction; - ImplActionBounds( aBound, - Rectangle( aMapVDev.LogicToLogic( pAct->GetPoint(), aMapVDev.GetMapMode(), GetPrefMapMode() ), - aMapVDev.PixelToLogic( Size( 1, 1 ), GetPrefMapMode() ) ), - aClipStack ); - } - break; + { + MetaPointAction* pAct = (MetaPointAction*) pAction; + ImplActionBounds( aBound, + Rectangle( aMapVDev.LogicToLogic( pAct->GetPoint(), aMapVDev.GetMapMode(), GetPrefMapMode() ), + aMapVDev.PixelToLogic( Size( 1, 1 ), GetPrefMapMode() ) ), + aClipStack ); + } + break; case( META_LINE_ACTION ): - { - MetaLineAction* pAct = (MetaLineAction*) pAction; - Point aP1( pAct->GetStartPoint() ), aP2( pAct->GetEndPoint() ); - Rectangle aRect( aP1, aP2 ); - aRect.Justify(); - ImplActionBounds( aBound, aMapVDev.LogicToLogic( aRect, aMapVDev.GetMapMode(), GetPrefMapMode() ), aClipStack ); - } - break; + { + MetaLineAction* pAct = (MetaLineAction*) pAction; + Point aP1( pAct->GetStartPoint() ), aP2( pAct->GetEndPoint() ); + Rectangle aRect( aP1, aP2 ); + aRect.Justify(); + ImplActionBounds( aBound, aMapVDev.LogicToLogic( aRect, aMapVDev.GetMapMode(), GetPrefMapMode() ), aClipStack ); + } + break; case( META_RECT_ACTION ): - { - MetaRectAction* pAct = (MetaRectAction*) pAction; - ImplActionBounds( aBound, aMapVDev.LogicToLogic( pAct->GetRect(), aMapVDev.GetMapMode(), GetPrefMapMode() ), aClipStack ); - } - break; + { + MetaRectAction* pAct = (MetaRectAction*) pAction; + ImplActionBounds( aBound, aMapVDev.LogicToLogic( pAct->GetRect(), aMapVDev.GetMapMode(), GetPrefMapMode() ), aClipStack ); + } + break; case( META_ROUNDRECT_ACTION ): - { - MetaRoundRectAction* pAct = (MetaRoundRectAction*) pAction; - ImplActionBounds( aBound, aMapVDev.LogicToLogic( pAct->GetRect(), aMapVDev.GetMapMode(), GetPrefMapMode() ), aClipStack ); - } - break; + { + MetaRoundRectAction* pAct = (MetaRoundRectAction*) pAction; + ImplActionBounds( aBound, aMapVDev.LogicToLogic( pAct->GetRect(), aMapVDev.GetMapMode(), GetPrefMapMode() ), aClipStack ); + } + break; case( META_ELLIPSE_ACTION ): - { - MetaEllipseAction* pAct = (MetaEllipseAction*) pAction; - ImplActionBounds( aBound, aMapVDev.LogicToLogic( pAct->GetRect(), aMapVDev.GetMapMode(), GetPrefMapMode() ), aClipStack ); - } - break; + { + MetaEllipseAction* pAct = (MetaEllipseAction*) pAction; + ImplActionBounds( aBound, aMapVDev.LogicToLogic( pAct->GetRect(), aMapVDev.GetMapMode(), GetPrefMapMode() ), aClipStack ); + } + break; case( META_ARC_ACTION ): - { - MetaArcAction* pAct = (MetaArcAction*) pAction; - // FIXME: this is imprecise - // e.g. for small arcs the whole rectangle is WAY too large - ImplActionBounds( aBound, aMapVDev.LogicToLogic( pAct->GetRect(), aMapVDev.GetMapMode(), GetPrefMapMode() ), aClipStack ); - } - break; + { + MetaArcAction* pAct = (MetaArcAction*) pAction; + // FIXME: this is imprecise + // e.g. for small arcs the whole rectangle is WAY too large + ImplActionBounds( aBound, aMapVDev.LogicToLogic( pAct->GetRect(), aMapVDev.GetMapMode(), GetPrefMapMode() ), aClipStack ); + } + break; case( META_PIE_ACTION ): - { - MetaPieAction* pAct = (MetaPieAction*) pAction; - // FIXME: this is imprecise - // e.g. for small arcs the whole rectangle is WAY too large - ImplActionBounds( aBound, aMapVDev.LogicToLogic( pAct->GetRect(), aMapVDev.GetMapMode(), GetPrefMapMode() ), aClipStack ); - } - break; + { + MetaPieAction* pAct = (MetaPieAction*) pAction; + // FIXME: this is imprecise + // e.g. for small arcs the whole rectangle is WAY too large + ImplActionBounds( aBound, aMapVDev.LogicToLogic( pAct->GetRect(), aMapVDev.GetMapMode(), GetPrefMapMode() ), aClipStack ); + } + break; case( META_CHORD_ACTION ): - { - MetaChordAction* pAct = (MetaChordAction*) pAction; - // FIXME: this is imprecise - // e.g. for small arcs the whole rectangle is WAY too large - ImplActionBounds( aBound, aMapVDev.LogicToLogic( pAct->GetRect(), aMapVDev.GetMapMode(), GetPrefMapMode() ), aClipStack ); - } - break; + { + MetaChordAction* pAct = (MetaChordAction*) pAction; + // FIXME: this is imprecise + // e.g. for small arcs the whole rectangle is WAY too large + ImplActionBounds( aBound, aMapVDev.LogicToLogic( pAct->GetRect(), aMapVDev.GetMapMode(), GetPrefMapMode() ), aClipStack ); + } + break; case( META_POLYLINE_ACTION ): - { - MetaPolyLineAction* pAct = (MetaPolyLineAction*) pAction; - Rectangle aRect( pAct->GetPolygon().GetBoundRect() ); - ImplActionBounds( aBound, aMapVDev.LogicToLogic( aRect, aMapVDev.GetMapMode(), GetPrefMapMode() ), aClipStack ); - } - break; + { + MetaPolyLineAction* pAct = (MetaPolyLineAction*) pAction; + Rectangle aRect( pAct->GetPolygon().GetBoundRect() ); + ImplActionBounds( aBound, aMapVDev.LogicToLogic( aRect, aMapVDev.GetMapMode(), GetPrefMapMode() ), aClipStack ); + } + break; case( META_POLYGON_ACTION ): - { - MetaPolygonAction* pAct = (MetaPolygonAction*) pAction; - Rectangle aRect( pAct->GetPolygon().GetBoundRect() ); - ImplActionBounds( aBound, aMapVDev.LogicToLogic( aRect, aMapVDev.GetMapMode(), GetPrefMapMode() ), aClipStack ); - } - break; + { + MetaPolygonAction* pAct = (MetaPolygonAction*) pAction; + Rectangle aRect( pAct->GetPolygon().GetBoundRect() ); + ImplActionBounds( aBound, aMapVDev.LogicToLogic( aRect, aMapVDev.GetMapMode(), GetPrefMapMode() ), aClipStack ); + } + break; case( META_POLYPOLYGON_ACTION ): - { - MetaPolyPolygonAction* pAct = (MetaPolyPolygonAction*) pAction; - Rectangle aRect( pAct->GetPolyPolygon().GetBoundRect() ); - ImplActionBounds( aBound, aMapVDev.LogicToLogic( aRect, aMapVDev.GetMapMode(), GetPrefMapMode() ), aClipStack ); - } - break; + { + MetaPolyPolygonAction* pAct = (MetaPolyPolygonAction*) pAction; + Rectangle aRect( pAct->GetPolyPolygon().GetBoundRect() ); + ImplActionBounds( aBound, aMapVDev.LogicToLogic( aRect, aMapVDev.GetMapMode(), GetPrefMapMode() ), aClipStack ); + } + break; case( META_TEXT_ACTION ): - { - MetaTextAction* pAct = (MetaTextAction*) pAction; - Rectangle aRect; - // hdu said base = index - aMapVDev.GetTextBoundRect( aRect, pAct->GetText(), pAct->GetIndex(), pAct->GetIndex(), pAct->GetLen() ); - Point aPt( pAct->GetPoint() ); - aRect.Move( aPt.X(), aPt.Y() ); - ImplActionBounds( aBound, aMapVDev.LogicToLogic( aRect, aMapVDev.GetMapMode(), GetPrefMapMode() ), aClipStack ); - } - break; + { + MetaTextAction* pAct = (MetaTextAction*) pAction; + Rectangle aRect; + // hdu said base = index + aMapVDev.GetTextBoundRect( aRect, pAct->GetText(), pAct->GetIndex(), pAct->GetIndex(), pAct->GetLen() ); + Point aPt( pAct->GetPoint() ); + aRect.Move( aPt.X(), aPt.Y() ); + ImplActionBounds( aBound, aMapVDev.LogicToLogic( aRect, aMapVDev.GetMapMode(), GetPrefMapMode() ), aClipStack ); + } + break; case( META_TEXTARRAY_ACTION ): - { - MetaTextArrayAction* pAct = (MetaTextArrayAction*) pAction; - Rectangle aRect; - // hdu said base = index - aMapVDev.GetTextBoundRect( aRect, pAct->GetText(), pAct->GetIndex(), pAct->GetIndex(), pAct->GetLen(), - 0, pAct->GetDXArray() ); - Point aPt( pAct->GetPoint() ); - aRect.Move( aPt.X(), aPt.Y() ); - ImplActionBounds( aBound, aMapVDev.LogicToLogic( aRect, aMapVDev.GetMapMode(), GetPrefMapMode() ), aClipStack ); - } - break; + { + MetaTextArrayAction* pAct = (MetaTextArrayAction*) pAction; + Rectangle aRect; + // hdu said base = index + aMapVDev.GetTextBoundRect( aRect, pAct->GetText(), pAct->GetIndex(), pAct->GetIndex(), pAct->GetLen(), + 0, pAct->GetDXArray() ); + Point aPt( pAct->GetPoint() ); + aRect.Move( aPt.X(), aPt.Y() ); + ImplActionBounds( aBound, aMapVDev.LogicToLogic( aRect, aMapVDev.GetMapMode(), GetPrefMapMode() ), aClipStack ); + } + break; case( META_STRETCHTEXT_ACTION ): - { - MetaStretchTextAction* pAct = (MetaStretchTextAction*) pAction; - Rectangle aRect; - // hdu said base = index - aMapVDev.GetTextBoundRect( aRect, pAct->GetText(), pAct->GetIndex(), pAct->GetIndex(), pAct->GetLen(), - pAct->GetWidth(), NULL ); - Point aPt( pAct->GetPoint() ); - aRect.Move( aPt.X(), aPt.Y() ); - ImplActionBounds( aBound, aMapVDev.LogicToLogic( aRect, aMapVDev.GetMapMode(), GetPrefMapMode() ), aClipStack ); - } - break; + { + MetaStretchTextAction* pAct = (MetaStretchTextAction*) pAction; + Rectangle aRect; + // hdu said base = index + aMapVDev.GetTextBoundRect( aRect, pAct->GetText(), pAct->GetIndex(), pAct->GetIndex(), pAct->GetLen(), + pAct->GetWidth(), NULL ); + Point aPt( pAct->GetPoint() ); + aRect.Move( aPt.X(), aPt.Y() ); + ImplActionBounds( aBound, aMapVDev.LogicToLogic( aRect, aMapVDev.GetMapMode(), GetPrefMapMode() ), aClipStack ); + } + break; case( META_TEXTLINE_ACTION ): - { - MetaTextLineAction* pAct = (MetaTextLineAction*) pAction; - // measure a test string to get ascend and descent right - static const sal_Unicode pStr[] = { 0xc4, 0x67, 0 }; - String aStr( pStr ); - - Rectangle aRect; - aMapVDev.GetTextBoundRect( aRect, aStr, 0, 0, aStr.Len(), 0, NULL ); - Point aPt( pAct->GetStartPoint() ); - aRect.Move( aPt.X(), aPt.Y() ); - aRect.Right() = aRect.Left() + pAct->GetWidth(); - ImplActionBounds( aBound, aMapVDev.LogicToLogic( aRect, aMapVDev.GetMapMode(), GetPrefMapMode() ), aClipStack ); - } - break; + { + MetaTextLineAction* pAct = (MetaTextLineAction*) pAction; + // measure a test string to get ascend and descent right + static const sal_Unicode pStr[] = { 0xc4, 0x67, 0 }; + String aStr( pStr ); + + Rectangle aRect; + aMapVDev.GetTextBoundRect( aRect, aStr, 0, 0, aStr.Len(), 0, NULL ); + Point aPt( pAct->GetStartPoint() ); + aRect.Move( aPt.X(), aPt.Y() ); + aRect.Right() = aRect.Left() + pAct->GetWidth(); + ImplActionBounds( aBound, aMapVDev.LogicToLogic( aRect, aMapVDev.GetMapMode(), GetPrefMapMode() ), aClipStack ); + } + break; case( META_BMPSCALE_ACTION ): - { - MetaBmpScaleAction* pAct = (MetaBmpScaleAction*) pAction; - Rectangle aRect( pAct->GetPoint(), pAct->GetSize() ); - ImplActionBounds( aBound, aMapVDev.LogicToLogic( aRect, aMapVDev.GetMapMode(), GetPrefMapMode() ), aClipStack ); - } - break; + { + MetaBmpScaleAction* pAct = (MetaBmpScaleAction*) pAction; + Rectangle aRect( pAct->GetPoint(), pAct->GetSize() ); + ImplActionBounds( aBound, aMapVDev.LogicToLogic( aRect, aMapVDev.GetMapMode(), GetPrefMapMode() ), aClipStack ); + } + break; case( META_BMPSCALEPART_ACTION ): - { - MetaBmpScalePartAction* pAct = (MetaBmpScalePartAction*) pAction; - Rectangle aRect( pAct->GetDestPoint(), pAct->GetDestSize() ); - ImplActionBounds( aBound, aMapVDev.LogicToLogic( aRect, aMapVDev.GetMapMode(), GetPrefMapMode() ), aClipStack ); - } - break; + { + MetaBmpScalePartAction* pAct = (MetaBmpScalePartAction*) pAction; + Rectangle aRect( pAct->GetDestPoint(), pAct->GetDestSize() ); + ImplActionBounds( aBound, aMapVDev.LogicToLogic( aRect, aMapVDev.GetMapMode(), GetPrefMapMode() ), aClipStack ); + } + break; case( META_BMPEXSCALE_ACTION ): - { - MetaBmpExScaleAction* pAct = (MetaBmpExScaleAction*) pAction; - Rectangle aRect( pAct->GetPoint(), pAct->GetSize() ); - ImplActionBounds( aBound, aMapVDev.LogicToLogic( aRect, aMapVDev.GetMapMode(), GetPrefMapMode() ), aClipStack ); - } - break; + { + MetaBmpExScaleAction* pAct = (MetaBmpExScaleAction*) pAction; + Rectangle aRect( pAct->GetPoint(), pAct->GetSize() ); + ImplActionBounds( aBound, aMapVDev.LogicToLogic( aRect, aMapVDev.GetMapMode(), GetPrefMapMode() ), aClipStack ); + } + break; case( META_BMPEXSCALEPART_ACTION ): - { - MetaBmpExScalePartAction* pAct = (MetaBmpExScalePartAction*) pAction; - Rectangle aRect( pAct->GetDestPoint(), pAct->GetDestSize() ); - ImplActionBounds( aBound, aMapVDev.LogicToLogic( aRect, aMapVDev.GetMapMode(), GetPrefMapMode() ), aClipStack ); - } - break; + { + MetaBmpExScalePartAction* pAct = (MetaBmpExScalePartAction*) pAction; + Rectangle aRect( pAct->GetDestPoint(), pAct->GetDestSize() ); + ImplActionBounds( aBound, aMapVDev.LogicToLogic( aRect, aMapVDev.GetMapMode(), GetPrefMapMode() ), aClipStack ); + } + break; case( META_GRADIENT_ACTION ): - { - MetaGradientAction* pAct = (MetaGradientAction*) pAction; - Rectangle aRect( pAct->GetRect() ); - ImplActionBounds( aBound, aMapVDev.LogicToLogic( aRect, aMapVDev.GetMapMode(), GetPrefMapMode() ), aClipStack ); - } - break; + { + MetaGradientAction* pAct = (MetaGradientAction*) pAction; + Rectangle aRect( pAct->GetRect() ); + ImplActionBounds( aBound, aMapVDev.LogicToLogic( aRect, aMapVDev.GetMapMode(), GetPrefMapMode() ), aClipStack ); + } + break; case( META_GRADIENTEX_ACTION ): - { - MetaGradientExAction* pAct = (MetaGradientExAction*) pAction; - Rectangle aRect( pAct->GetPolyPolygon().GetBoundRect() ); - ImplActionBounds( aBound, aMapVDev.LogicToLogic( aRect, aMapVDev.GetMapMode(), GetPrefMapMode() ), aClipStack ); - } - break; + { + MetaGradientExAction* pAct = (MetaGradientExAction*) pAction; + Rectangle aRect( pAct->GetPolyPolygon().GetBoundRect() ); + ImplActionBounds( aBound, aMapVDev.LogicToLogic( aRect, aMapVDev.GetMapMode(), GetPrefMapMode() ), aClipStack ); + } + break; case( META_COMMENT_ACTION ): - { - // nothing to do - }; - break; + { + // nothing to do + }; + break; case( META_HATCH_ACTION ): - { - MetaHatchAction* pAct = (MetaHatchAction*) pAction; - Rectangle aRect( pAct->GetPolyPolygon().GetBoundRect() ); - ImplActionBounds( aBound, aMapVDev.LogicToLogic( aRect, aMapVDev.GetMapMode(), GetPrefMapMode() ), aClipStack ); - } - break; + { + MetaHatchAction* pAct = (MetaHatchAction*) pAction; + Rectangle aRect( pAct->GetPolyPolygon().GetBoundRect() ); + ImplActionBounds( aBound, aMapVDev.LogicToLogic( aRect, aMapVDev.GetMapMode(), GetPrefMapMode() ), aClipStack ); + } + break; case( META_TRANSPARENT_ACTION ): - { - MetaTransparentAction* pAct = (MetaTransparentAction*) pAction; - Rectangle aRect( pAct->GetPolyPolygon().GetBoundRect() ); - ImplActionBounds( aBound, aMapVDev.LogicToLogic( aRect, aMapVDev.GetMapMode(), GetPrefMapMode() ), aClipStack ); - } - break; + { + MetaTransparentAction* pAct = (MetaTransparentAction*) pAction; + Rectangle aRect( pAct->GetPolyPolygon().GetBoundRect() ); + ImplActionBounds( aBound, aMapVDev.LogicToLogic( aRect, aMapVDev.GetMapMode(), GetPrefMapMode() ), aClipStack ); + } + break; case( META_FLOATTRANSPARENT_ACTION ): - { - MetaFloatTransparentAction* pAct = (MetaFloatTransparentAction*) pAction; - GDIMetaFile aTransMtf( pAct->GetGDIMetaFile() ); - // get the bound rect of the contained metafile - Rectangle aRect( aTransMtf.GetBoundRect( i_rReference ) ); - // scale the rect now on the assumption that the correct top left of the metafile - // (not its bounds !) is (0,0) - Size aPSize( aTransMtf.GetPrefSize() ); - aPSize = aMapVDev.LogicToLogic( aPSize, aTransMtf.GetPrefMapMode(), aMapVDev.GetMapMode() ); - Size aActSize( pAct->GetSize() ); - double fX = double(aActSize.Width())/double(aPSize.Width()); - double fY = double(aActSize.Height())/double(aPSize.Height()); - aRect.Left() = long(double(aRect.Left())*fX); - aRect.Right() = long(double(aRect.Right())*fX); - aRect.Top() = long(double(aRect.Top())*fY); - aRect.Bottom() = long(double(aRect.Bottom())*fY); - - // transform the rect to current VDev state - aRect = aMapVDev.LogicToLogic( aRect, aTransMtf.GetPrefMapMode(), aMapVDev.GetMapMode() ); - - ImplActionBounds( aBound, aRect, aClipStack ); - } - break; + { + MetaFloatTransparentAction* pAct = (MetaFloatTransparentAction*) pAction; + GDIMetaFile aTransMtf( pAct->GetGDIMetaFile() ); + // get the bound rect of the contained metafile + Rectangle aRect( aTransMtf.GetBoundRect( i_rReference ) ); + // scale the rect now on the assumption that the correct top left of the metafile + // (not its bounds !) is (0,0) + Size aPSize( aTransMtf.GetPrefSize() ); + aPSize = aMapVDev.LogicToLogic( aPSize, aTransMtf.GetPrefMapMode(), aMapVDev.GetMapMode() ); + Size aActSize( pAct->GetSize() ); + double fX = double(aActSize.Width())/double(aPSize.Width()); + double fY = double(aActSize.Height())/double(aPSize.Height()); + aRect.Left() = long(double(aRect.Left())*fX); + aRect.Right() = long(double(aRect.Right())*fX); + aRect.Top() = long(double(aRect.Top())*fY); + aRect.Bottom() = long(double(aRect.Bottom())*fY); + + // transform the rect to current VDev state + aRect = aMapVDev.LogicToLogic( aRect, aTransMtf.GetPrefMapMode(), aMapVDev.GetMapMode() ); + + ImplActionBounds( aBound, aRect, aClipStack ); + } + break; case( META_EPS_ACTION ): - { - MetaEPSAction* pAct = (MetaEPSAction*) pAction; - Rectangle aRect( pAct->GetPoint(), pAct->GetSize() ); - ImplActionBounds( aBound, aMapVDev.LogicToLogic( aRect, aMapVDev.GetMapMode(), GetPrefMapMode() ), aClipStack ); - } - break; + { + MetaEPSAction* pAct = (MetaEPSAction*) pAction; + Rectangle aRect( pAct->GetPoint(), pAct->GetSize() ); + ImplActionBounds( aBound, aMapVDev.LogicToLogic( aRect, aMapVDev.GetMapMode(), GetPrefMapMode() ), aClipStack ); + } + break; case( META_CLIPREGION_ACTION ): - { - MetaClipRegionAction* pAct = (MetaClipRegionAction*) pAction; - if( pAct->IsClipping() ) - aClipStack.back() = aMapVDev.LogicToLogic( pAct->GetRegion().GetBoundRect(), aMapVDev.GetMapMode(), GetPrefMapMode() ); - else - aClipStack.back() = Rectangle(); - } - break; + { + MetaClipRegionAction* pAct = (MetaClipRegionAction*) pAction; + if( pAct->IsClipping() ) + aClipStack.back() = aMapVDev.LogicToLogic( pAct->GetRegion().GetBoundRect(), aMapVDev.GetMapMode(), GetPrefMapMode() ); + else + aClipStack.back() = Rectangle(); + } + break; case( META_ISECTRECTCLIPREGION_ACTION ): - { - MetaISectRectClipRegionAction* pAct = (MetaISectRectClipRegionAction*) pAction; - Rectangle aRect( aMapVDev.LogicToLogic( pAct->GetRect(), aMapVDev.GetMapMode(), GetPrefMapMode() ) ); - if( aClipStack.back().IsEmpty() ) - aClipStack.back() = aRect; - else - aClipStack.back().Intersection( aRect ); - } - break; + { + MetaISectRectClipRegionAction* pAct = (MetaISectRectClipRegionAction*) pAction; + Rectangle aRect( aMapVDev.LogicToLogic( pAct->GetRect(), aMapVDev.GetMapMode(), GetPrefMapMode() ) ); + if( aClipStack.back().IsEmpty() ) + aClipStack.back() = aRect; + else + aClipStack.back().Intersection( aRect ); + } + break; case( META_ISECTREGIONCLIPREGION_ACTION ): - { - MetaISectRegionClipRegionAction* pAct = (MetaISectRegionClipRegionAction*) pAction; - Rectangle aRect( aMapVDev.LogicToLogic( pAct->GetRegion().GetBoundRect(), aMapVDev.GetMapMode(), GetPrefMapMode() ) ); - if( aClipStack.back().IsEmpty() ) - aClipStack.back() = aRect; - else - aClipStack.back().Intersection( aRect ); - } - break; + { + MetaISectRegionClipRegionAction* pAct = (MetaISectRegionClipRegionAction*) pAction; + Rectangle aRect( aMapVDev.LogicToLogic( pAct->GetRegion().GetBoundRect(), aMapVDev.GetMapMode(), GetPrefMapMode() ) ); + if( aClipStack.back().IsEmpty() ) + aClipStack.back() = aRect; + else + aClipStack.back().Intersection( aRect ); + } + break; case( META_BMP_ACTION ): - { - MetaBmpAction* pAct = (MetaBmpAction*) pAction; - Rectangle aRect( pAct->GetPoint(), aMapVDev.PixelToLogic( pAct->GetBitmap().GetSizePixel() ) ); - ImplActionBounds( aBound, aMapVDev.LogicToLogic( aRect, aMapVDev.GetMapMode(), GetPrefMapMode() ), aClipStack ); - } - break; + { + MetaBmpAction* pAct = (MetaBmpAction*) pAction; + Rectangle aRect( pAct->GetPoint(), aMapVDev.PixelToLogic( pAct->GetBitmap().GetSizePixel() ) ); + ImplActionBounds( aBound, aMapVDev.LogicToLogic( aRect, aMapVDev.GetMapMode(), GetPrefMapMode() ), aClipStack ); + } + break; case( META_BMPEX_ACTION ): - { - MetaBmpExAction* pAct = (MetaBmpExAction*) pAction; - Rectangle aRect( pAct->GetPoint(), aMapVDev.PixelToLogic( pAct->GetBitmapEx().GetSizePixel() ) ); - ImplActionBounds( aBound, aMapVDev.LogicToLogic( aRect, aMapVDev.GetMapMode(), GetPrefMapMode() ), aClipStack ); - } - break; + { + MetaBmpExAction* pAct = (MetaBmpExAction*) pAction; + Rectangle aRect( pAct->GetPoint(), aMapVDev.PixelToLogic( pAct->GetBitmapEx().GetSizePixel() ) ); + ImplActionBounds( aBound, aMapVDev.LogicToLogic( aRect, aMapVDev.GetMapMode(), GetPrefMapMode() ), aClipStack ); + } + break; case( META_MASK_ACTION ): - { - MetaMaskAction* pAct = (MetaMaskAction*) pAction; - Rectangle aRect( pAct->GetPoint(), aMapVDev.PixelToLogic( pAct->GetBitmap().GetSizePixel() ) ); - ImplActionBounds( aBound, aMapVDev.LogicToLogic( aRect, aMapVDev.GetMapMode(), GetPrefMapMode() ), aClipStack ); - } - break; + { + MetaMaskAction* pAct = (MetaMaskAction*) pAction; + Rectangle aRect( pAct->GetPoint(), aMapVDev.PixelToLogic( pAct->GetBitmap().GetSizePixel() ) ); + ImplActionBounds( aBound, aMapVDev.LogicToLogic( aRect, aMapVDev.GetMapMode(), GetPrefMapMode() ), aClipStack ); + } + break; case( META_MASKSCALE_ACTION ): - { - MetaMaskScalePartAction* pAct = (MetaMaskScalePartAction*) pAction; - Rectangle aRect( pAct->GetDestPoint(), pAct->GetDestSize() ); - ImplActionBounds( aBound, aMapVDev.LogicToLogic( aRect, aMapVDev.GetMapMode(), GetPrefMapMode() ), aClipStack ); - } - break; + { + MetaMaskScalePartAction* pAct = (MetaMaskScalePartAction*) pAction; + Rectangle aRect( pAct->GetDestPoint(), pAct->GetDestSize() ); + ImplActionBounds( aBound, aMapVDev.LogicToLogic( aRect, aMapVDev.GetMapMode(), GetPrefMapMode() ), aClipStack ); + } + break; case( META_MASKSCALEPART_ACTION ): - { - MetaMaskScalePartAction* pAct = (MetaMaskScalePartAction*) pAction; - Rectangle aRect( pAct->GetDestPoint(), pAct->GetDestSize() ); - ImplActionBounds( aBound, aMapVDev.LogicToLogic( aRect, aMapVDev.GetMapMode(), GetPrefMapMode() ), aClipStack ); - } - break; + { + MetaMaskScalePartAction* pAct = (MetaMaskScalePartAction*) pAction; + Rectangle aRect( pAct->GetDestPoint(), pAct->GetDestSize() ); + ImplActionBounds( aBound, aMapVDev.LogicToLogic( aRect, aMapVDev.GetMapMode(), GetPrefMapMode() ), aClipStack ); + } + break; case( META_WALLPAPER_ACTION ): - { - MetaWallpaperAction* pAct = (MetaWallpaperAction*) pAction; - Rectangle aRect( pAct->GetRect() ); - ImplActionBounds( aBound, aMapVDev.LogicToLogic( aRect, aMapVDev.GetMapMode(), GetPrefMapMode() ), aClipStack ); - } - break; + { + MetaWallpaperAction* pAct = (MetaWallpaperAction*) pAction; + Rectangle aRect( pAct->GetRect() ); + ImplActionBounds( aBound, aMapVDev.LogicToLogic( aRect, aMapVDev.GetMapMode(), GetPrefMapMode() ), aClipStack ); + } + break; case( META_TEXTRECT_ACTION ): - { - MetaTextRectAction* pAct = (MetaTextRectAction*) pAction; - Rectangle aRect( pAct->GetRect() ); - ImplActionBounds( aBound, aMapVDev.LogicToLogic( aRect, aMapVDev.GetMapMode(), GetPrefMapMode() ), aClipStack ); - } - break; + { + MetaTextRectAction* pAct = (MetaTextRectAction*) pAction; + Rectangle aRect( pAct->GetRect() ); + ImplActionBounds( aBound, aMapVDev.LogicToLogic( aRect, aMapVDev.GetMapMode(), GetPrefMapMode() ), aClipStack ); + } + break; case( META_MOVECLIPREGION_ACTION ): + { + MetaMoveClipRegionAction* pAct = (MetaMoveClipRegionAction*) pAction; + if( ! aClipStack.back().IsEmpty() ) { - MetaMoveClipRegionAction* pAct = (MetaMoveClipRegionAction*) pAction; - if( ! aClipStack.back().IsEmpty() ) - { - Size aDelta( pAct->GetHorzMove(), pAct->GetVertMove() ); - aDelta = aMapVDev.LogicToLogic( aDelta, aMapVDev.GetMapMode(), GetPrefMapMode() ); - aClipStack.back().Move( aDelta.Width(), aDelta.Width() ); - } + Size aDelta( pAct->GetHorzMove(), pAct->GetVertMove() ); + aDelta = aMapVDev.LogicToLogic( aDelta, aMapVDev.GetMapMode(), GetPrefMapMode() ); + aClipStack.back().Move( aDelta.Width(), aDelta.Width() ); } - break; + } + break; + + case( META_RENDERGRAPHIC_ACTION ): + { + MetaRenderGraphicAction* pAct = (MetaRenderGraphicAction*) pAction; + Rectangle aRect( pAct->GetPoint(), pAct->GetSize() ); + ImplActionBounds( aBound, aMapVDev.LogicToLogic( aRect, aMapVDev.GetMapMode(), GetPrefMapMode() ), aClipStack ); + } + break; default: { @@ -2269,6 +2286,15 @@ void GDIMetaFile::ImplExchangeColors( ColorExchangeFnc pFncCol, const void* pCol } break; + case( META_RENDERGRAPHIC_ACTION ): + { + OSL_TRACE( "ExchangeColors not supported for RenderGraphic MetaActions yet" ); + + pAction->Duplicate(); + aMtf.Insert( pAction, LIST_APPEND ); + } + break; + default: { pAction->Duplicate(); @@ -2454,11 +2480,13 @@ sal_uLong GDIMetaFile::GetChecksum() const { GDIMetaFile aMtf; SvMemoryStream aMemStm( 65535, 65535 ); - ImplMetaWriteData aWriteData; aWriteData.meActualCharSet = aMemStm.GetStreamCharSet(); + ImplMetaWriteData aWriteData; SVBT16 aBT16; SVBT32 aBT32; sal_uLong nCrc = 0; + aWriteData.meActualCharSet = aMemStm.GetStreamCharSet(); + for( sal_uLong i = 0, nObjCount = GetActionCount(); i < nObjCount; i++ ) { MetaAction* pAction = GetAction( i ); @@ -2715,6 +2743,30 @@ sal_uLong GDIMetaFile::GetChecksum() const } break; + case( META_RENDERGRAPHIC_ACTION ): + { + MetaRenderGraphicAction* pAct = (MetaRenderGraphicAction*) pAction; + const ::vcl::RenderGraphic& rRenderGraphic = pAct->GetRenderGraphic(); + + ShortToSVBT16( pAct->GetType(), aBT16 ); + nCrc = rtl_crc32( nCrc, aBT16, 2 ); + + nCrc = rtl_crc32( nCrc, rRenderGraphic.GetGraphicData().get(), rRenderGraphic.GetGraphicDataLength() ); + + UInt32ToSVBT32( pAct->GetPoint().X(), aBT32 ); + nCrc = rtl_crc32( nCrc, aBT32, 4 ); + + UInt32ToSVBT32( pAct->GetPoint().Y(), aBT32 ); + nCrc = rtl_crc32( nCrc, aBT32, 4 ); + + UInt32ToSVBT32( pAct->GetSize().Width(), aBT32 ); + nCrc = rtl_crc32( nCrc, aBT32, 4 ); + + UInt32ToSVBT32( pAct->GetSize().Height(), aBT32 ); + nCrc = rtl_crc32( nCrc, aBT32, 4 ); + } + break; + default: { pAction->Write( aMemStm, &aWriteData ); @@ -2781,8 +2833,7 @@ sal_uLong GDIMetaFile::GetSizeBytes() const } break; - default: - break; + case( META_RENDERGRAPHIC_ACTION ): nSizeBytes += ( ( (MetaRenderGraphicAction*) pAction )->GetRenderGraphic() ).GetGraphicDataLength(); break; } } @@ -2810,27 +2861,63 @@ SvStream& operator>>( SvStream& rIStm, GDIMetaFile& rGDIMetaFile ) // new format VersionCompat* pCompat; MetaAction* pAction; - sal_uInt32 nStmCompressMode = 0; - sal_uInt32 nCount = 0; + sal_uInt32 nStmCompressMode = 0; + sal_uInt32 nCount = 0; + sal_uInt8 bRenderGraphicReplacements = 0; pCompat = new VersionCompat( rIStm, STREAM_READ ); + { + // version 1 + rIStm >> nStmCompressMode; + rIStm >> rGDIMetaFile.aPrefMapMode; + rIStm >> rGDIMetaFile.aPrefSize; + rIStm >> nCount; - rIStm >> nStmCompressMode; - rIStm >> rGDIMetaFile.aPrefMapMode; - rIStm >> rGDIMetaFile.aPrefSize; - rIStm >> nCount; + if( pCompat->GetVersion() >= 2 ) + { + // version 2 + // ========= + // contains an additional flag to indicate that RenderGraphic + // actions are immediately followed by a replacement image, that + // needs to be skipped in case the flag is set (KA 01/2011) + rIStm >> bRenderGraphicReplacements; + } + } delete pCompat; ImplMetaReadData aReadData; aReadData.meActualCharSet = rIStm.GetStreamCharSet(); - for( sal_uInt32 nAction = 0UL; ( nAction < nCount ) && !rIStm.IsEof(); nAction++ ) + for( sal_uInt32 nAction = 0UL; ( nAction < nCount ) && !rIStm.IsEof(); ++nAction ) { pAction = MetaAction::ReadMetaAction( rIStm, &aReadData ); if( pAction ) + { rGDIMetaFile.AddAction( pAction ); + + // if the MetaFile was written in RenderGraphics replacement mode + // and we just read a RenderGraphic action, skip the following + // META_BMPEXSCALE_ACTION, since this is the replacement image, + // just needed for old implementations; don't forget to increment + // the action read counter! (KA 01/2011) + if( bRenderGraphicReplacements && + ( META_RENDERGRAPHIC_ACTION == pAction->GetType() ) && + ( ++nAction < nCount ) && !rIStm.IsEof() ) + { + sal_uInt16 nFollowingType; + + // dummy read of the next following META_BMPEXSCALE_ACTION + // RenderGraphic replacement action (KA 01/2011) + rIStm >> nFollowingType; + delete ( new VersionCompat( rIStm, STREAM_READ ) ); + + OSL_ENSURE( META_BMPEXSCALE_ACTION == nFollowingType, \ +"META_RENDERGRAPHIC_ACTION read in RenderGraphic replacement mode \ +without following META_BMPEXSCALE_ACTION replacement" ); + } + } } } else @@ -2859,10 +2946,27 @@ SvStream& operator<<( SvStream& rOStm, const GDIMetaFile& rGDIMetaFile ) { if( !rOStm.GetError() ) { - if( rOStm.GetVersion() >= SOFFICE_FILEFORMAT_50 ) - ((GDIMetaFile&) rGDIMetaFile ).Write( rOStm ); + static const char* pEnableSVM1 = getenv( "SAL_ENABLE_SVM1" ); + static const bool bNoSVM1 = (NULL == pEnableSVM1 ) || ( '0' == *pEnableSVM1 ); + + if( bNoSVM1 || rOStm.GetVersion() >= SOFFICE_FILEFORMAT_50 ) + { + const_cast< GDIMetaFile& >( rGDIMetaFile ).Write( rOStm ); + } else - delete( new SVMConverter( rOStm, (GDIMetaFile&) rGDIMetaFile, CONVERT_TO_SVM1 ) ); + { + delete( new SVMConverter( rOStm, const_cast< GDIMetaFile& >( rGDIMetaFile ), CONVERT_TO_SVM1 ) ); + } + +#ifdef DEBUG + if( !bNoSVM1 && rOStm.GetVersion() < SOFFICE_FILEFORMAT_50 ) + { +OSL_TRACE( \ +"GDIMetaFile would normally be written in old SVM1 format by this call. \ +The current implementation always writes in VCLMTF format. \ +Please set environment variable SAL_ENABLE_SVM1 to '1' to reenable old behavior" ); + } +#endif // DEBUG } return rOStm; @@ -2880,32 +2984,90 @@ SvStream& GDIMetaFile::Read( SvStream& rIStm ) // ------------------------------------------------------------------------ -SvStream& GDIMetaFile::Write( SvStream& rOStm ) +SvStream& GDIMetaFile::Write( SvStream& rOStm, GDIMetaFileWriteFlags nWriteFlags ) { VersionCompat* pCompat; const sal_uInt32 nStmCompressMode = rOStm.GetCompressMode(); sal_uInt16 nOldFormat = rOStm.GetNumberFormatInt(); + const sal_uInt8 bRenderGraphicReplacements = + ( ( ( GDIMETAFILE_WRITE_REPLACEMENT_RENDERGRAPHIC & nWriteFlags ) != 0 ) ? 1 : 0 ); + + // With the introduction of the META_RENDERGRAPHIC_ACTION, it is neccessary + // to provide some kind of document backward compatibility: + // + // If the flag GDIMETAFILE_WRITE_REPLACEMENT_RENDERGRAPHIC is set in + // parameter nWriteFlags, each META_RENDERGRAPHIC_ACTION is followed by + // an additional META_BMPEXSCALE_ACTION, that contains a replacement + // image for the new RenderGraphic action. + // + // Old implementations, not knowing anything about META_RENDERGRAPHIC_ACTION, + // will skip this new action and read the META_BMPEXSCALE_ACTION instead + // + // Since the current implementation is able to handle the new action, the + // then following image replacement action needs to be skipped by this + // implementation, if the metafile was written in the RenderGraphic + // replacement mode. + // + // To be able to detect this compatibility mode, the header needs to + // be extended by a corresponding flag, resulting in version 2 of + // the header. The surrounding VersionCompat of the header + // allows to add such new data without any problems (KA 01/2011) rOStm.SetNumberFormatInt( NUMBERFORMAT_INT_LITTLEENDIAN ); rOStm.Write( "VCLMTF", 6 ); - pCompat = new VersionCompat( rOStm, STREAM_WRITE, 1 ); + pCompat = new VersionCompat( rOStm, STREAM_WRITE, 2 ); - rOStm << nStmCompressMode; - rOStm << aPrefMapMode; - rOStm << aPrefSize; - rOStm << (sal_uInt32) GetActionCount(); + { + // version 1 + sal_uInt32 nActionCount = 0; + + // calculate correct action count and watch for + // additional RenderGraphic replacement actions, if the + // GDIMETAFILE_WRITE_REPLACEMENT_RENDERGRAPHIC is set + // and META_RENDERGRAPHIC_ACTION are encountered (KA 01/2011) + for( MetaAction* pAct = static_cast< MetaAction* >( First() ); pAct; pAct = static_cast< MetaAction* >( Next() ) ) + { + nActionCount += ( bRenderGraphicReplacements && ( META_RENDERGRAPHIC_ACTION == pAct->GetType() ) ? 2 : 1 ); + } + + rOStm << nStmCompressMode << aPrefMapMode << aPrefSize << nActionCount; + + { + // version 2 + // ========= + // since version 2, a GDIMETAFILE_WRITE_REPLACEMENT_RENDERGRAPHIC flag + // is written, to indicate that each META_BMPEXSCALE_ACTION following + // a META_RENDERGRAPHIC_ACTION needs to be skipped, in case the flag is + // set (KA 01/2011) + rOStm << bRenderGraphicReplacements; + } + } delete pCompat; ImplMetaWriteData aWriteData; + aWriteData.meActualCharSet = rOStm.GetStreamCharSet(); + aWriteData.mnWriteFlags = nWriteFlags; - MetaAction* pAct = (MetaAction*)First(); - while ( pAct ) + for( MetaAction* pAct = static_cast< MetaAction* >( First() ); pAct; pAct = static_cast< MetaAction* >( Next() ) ) { pAct->Write( rOStm, &aWriteData ); - pAct = (MetaAction*)Next(); + + // write the RenderGraphic replacement image, if the + // GDIMETAFILE_WRITE_REPLACEMENT_RENDERGRAPHIC flag is set + // and if a META_RENDERGRAPHIC_ACTION is encountered (KA 01/2011) + if( bRenderGraphicReplacements && ( META_RENDERGRAPHIC_ACTION == pAct->GetType() ) ) + { + MetaRenderGraphicAction* pRenderAction = static_cast< MetaRenderGraphicAction* >( pAct ); + MetaBmpExScaleAction* pBmpExScaleAction = new MetaBmpExScaleAction( + pRenderAction->GetPoint(), pRenderAction->GetSize(), + pRenderAction->GetRenderGraphic().GetReplacement() ); + + pBmpExScaleAction->Write( rOStm, &aWriteData ); + pBmpExScaleAction->Delete(); + } } rOStm.SetNumberFormatInt( nOldFormat ); diff --git a/vcl/source/gdi/gfxlink.cxx b/vcl/source/gdi/gfxlink.cxx index 1a476f1b5420..c9c997b568e2 100644 --- a/vcl/source/gdi/gfxlink.cxx +++ b/vcl/source/gdi/gfxlink.cxx @@ -258,6 +258,7 @@ sal_Bool GfxLink::LoadNative( Graphic& rGraphic ) case( GFX_LINK_TYPE_NATIVE_WMF ): nCvtType = CVT_WMF; break; case( GFX_LINK_TYPE_NATIVE_MET ): nCvtType = CVT_MET; break; case( GFX_LINK_TYPE_NATIVE_PCT ): nCvtType = CVT_PCT; break; + case( GFX_LINK_TYPE_NATIVE_SVG ): nCvtType = CVT_SVG; break; default: nCvtType = CVT_UNKNOWN; break; } diff --git a/vcl/source/gdi/graph.cxx b/vcl/source/gdi/graph.cxx index 1a8201706212..99f82c5d092b 100644 --- a/vcl/source/gdi/graph.cxx +++ b/vcl/source/gdi/graph.cxx @@ -427,6 +427,27 @@ sal_Bool Graphic::IsAnimated() const // ------------------------------------------------------------------------ +sal_Bool Graphic::IsEPS() const +{ + return mpImpGraphic->ImplIsEPS(); +} + +// ------------------------------------------------------------------------ + +sal_Bool Graphic::IsRenderGraphic() const +{ + return mpImpGraphic->ImplIsRenderGraphic(); +} + +// ------------------------------------------------------------------------ + +sal_Bool Graphic::HasRenderGraphic() const +{ + return mpImpGraphic->ImplHasRenderGraphic(); +} + +// ------------------------------------------------------------------------ + Bitmap Graphic::GetBitmap(const GraphicConversionParameters& rParameters) const { return mpImpGraphic->ImplGetBitmap(rParameters); @@ -455,6 +476,13 @@ const GDIMetaFile& Graphic::GetGDIMetaFile() const // ------------------------------------------------------------------------ +::vcl::RenderGraphic Graphic::GetRenderGraphic() const +{ + return mpImpGraphic->ImplGetRenderGraphic(); +} + +// ------------------------------------------------------------------------ + uno::Reference< graphic::XGraphic > Graphic::GetXGraphic() const { uno::Reference< graphic::XGraphic > xRet; diff --git a/vcl/source/gdi/impgraph.cxx b/vcl/source/gdi/impgraph.cxx index 500ba9549b9e..b4af43cf3556 100644 --- a/vcl/source/gdi/impgraph.cxx +++ b/vcl/source/gdi/impgraph.cxx @@ -480,6 +480,48 @@ sal_Bool ImpGraphic::ImplIsAnimated() const // ------------------------------------------------------------------------ +sal_Bool ImpGraphic::ImplIsEPS() const +{ + return( ( meType == GRAPHIC_GDIMETAFILE ) && + ( maMetaFile.GetActionCount() > 0 ) && + ( maMetaFile.GetAction( 0 )->GetType() == META_EPS_ACTION ) ); +} + +// ------------------------------------------------------------------------ + +sal_Bool ImpGraphic::ImplIsRenderGraphic() const +{ + return( ( GRAPHIC_GDIMETAFILE == meType ) && + ( 1 == maMetaFile.GetActionCount() ) && + ( META_RENDERGRAPHIC_ACTION == maMetaFile.GetAction( 0 )->GetType() ) ); +} + +// ------------------------------------------------------------------------ + +sal_Bool ImpGraphic::ImplHasRenderGraphic() const +{ + sal_Bool bRet = sal_False; + + if( GRAPHIC_GDIMETAFILE == meType ) + { + GDIMetaFile& rMtf = const_cast< ImpGraphic* >( this )->maMetaFile; + + for( MetaAction* pAct = rMtf.FirstAction(); pAct && !bRet; pAct = rMtf.NextAction() ) + { + if( META_RENDERGRAPHIC_ACTION == pAct->GetType() ) + { + bRet = sal_True; + } + } + + rMtf.WindStart(); + } + + return( bRet ); +} + +// ------------------------------------------------------------------------ + Bitmap ImpGraphic::ImplGetBitmap(const GraphicConversionParameters& rParameters) const { Bitmap aRetBmp; @@ -592,6 +634,18 @@ Animation ImpGraphic::ImplGetAnimation() const // ------------------------------------------------------------------------ +::vcl::RenderGraphic ImpGraphic::ImplGetRenderGraphic() const +{ + ::vcl::RenderGraphic aRet; + + if( ImplIsRenderGraphic() ) + aRet = static_cast< MetaRenderGraphicAction* >( maMetaFile.GetAction( 0 ) )->GetRenderGraphic(); + + return( aRet ); +} + +// ------------------------------------------------------------------------ + const GDIMetaFile& ImpGraphic::ImplGetGDIMetaFile() const { return maMetaFile; diff --git a/vcl/source/gdi/makefile.mk b/vcl/source/gdi/makefile.mk index ac2e586a41cb..ec664cf648a6 100755 --- a/vcl/source/gdi/makefile.mk +++ b/vcl/source/gdi/makefile.mk @@ -47,75 +47,77 @@ CDEFS+=-DENABLE_GRAPHITE # --- Files -------------------------------------------------------- -EXCEPTIONSFILES= $(SLO)$/salmisc.obj \ - $(SLO)$/outdev.obj \ - $(SLO)$/outdev3.obj \ - $(SLO)$/outdevnative.obj \ - $(SLO)$/gfxlink.obj \ - $(SLO)$/print.obj \ - $(SLO)$/print2.obj \ - $(SLO)$/print3.obj \ - $(SLO)$/oldprintadaptor.obj \ - $(SLO)$/configsettings.obj \ - $(SLO)$/sallayout.obj \ - $(SLO)$/image.obj \ - $(SLO)$/impimage.obj \ - $(SLO)$/impgraph.obj \ - $(SLO)$/metric.obj \ - $(SLO)$/pdfwriter_impl.obj \ - $(SLO)$/pdfwriter_impl2.obj \ - $(SLO)$/pdffontcache.obj\ - $(SLO)$/bmpconv.obj \ - $(SLO)$/pdfextoutdevdata.obj \ - $(SLO)$/jobset.obj \ - $(SLO)$/impimagetree.obj \ - $(SLO)$/pngread.obj \ - $(SLO)$/pngwrite.obj \ - $(SLO)$/virdev.obj \ - $(SLO)$/gdimtf.obj \ - $(SLO)$/graphictools.obj \ - $(SLO)$/textlayout.obj \ - $(SLO)$/lineinfo.obj +EXCEPTIONSFILES= $(SLO)$/salmisc.obj \ + $(SLO)$/outdev.obj \ + $(SLO)$/outdev3.obj \ + $(SLO)$/outdevnative.obj \ + $(SLO)$/gfxlink.obj \ + $(SLO)$/print.obj \ + $(SLO)$/print2.obj \ + $(SLO)$/print3.obj \ + $(SLO)$/oldprintadaptor.obj \ + $(SLO)$/configsettings.obj \ + $(SLO)$/sallayout.obj \ + $(SLO)$/image.obj \ + $(SLO)$/impimage.obj \ + $(SLO)$/impgraph.obj \ + $(SLO)$/metric.obj \ + $(SLO)$/pdfwriter_impl.obj \ + $(SLO)$/pdfwriter_impl2.obj \ + $(SLO)$/pdffontcache.obj \ + $(SLO)$/bmpconv.obj \ + $(SLO)$/pdfextoutdevdata.obj \ + $(SLO)$/jobset.obj \ + $(SLO)$/impimagetree.obj \ + $(SLO)$/pngread.obj \ + $(SLO)$/pngwrite.obj \ + $(SLO)$/virdev.obj \ + $(SLO)$/gdimtf.obj \ + $(SLO)$/graphictools.obj \ + $(SLO)$/textlayout.obj \ + $(SLO)$/lineinfo.obj \ + $(SLO)$/svgread.obj \ + $(SLO)$/rendergraphic.obj \ + $(SLO)$/rendergraphicrasterizer.obj -SLOFILES= $(EXCEPTIONSFILES) \ +SLOFILES= $(EXCEPTIONSFILES) \ $(SLO)$/animate.obj \ $(SLO)$/impanmvw.obj \ - $(SLO)$/bitmap.obj \ + $(SLO)$/bitmap.obj \ $(SLO)$/bitmap2.obj \ $(SLO)$/bitmap3.obj \ $(SLO)$/bitmap4.obj \ - $(SLO)$/alpha.obj \ + $(SLO)$/alpha.obj \ $(SLO)$/bitmapex.obj \ $(SLO)$/bmpacc.obj \ $(SLO)$/bmpacc2.obj \ $(SLO)$/bmpacc3.obj \ $(SLO)$/bmpfast.obj \ - $(SLO)$/cvtsvm.obj \ - $(SLO)$/cvtgrf.obj \ - $(SLO)$/font.obj \ + $(SLO)$/cvtsvm.obj \ + $(SLO)$/cvtgrf.obj \ + $(SLO)$/font.obj \ $(SLO)$/gradient.obj \ - $(SLO)$/hatch.obj \ - $(SLO)$/graph.obj \ - $(SLO)$/impbmp.obj \ + $(SLO)$/hatch.obj \ + $(SLO)$/graph.obj \ + $(SLO)$/impbmp.obj \ $(SLO)$/imagerepository.obj \ $(SLO)$/impvect.obj \ - $(SLO)$/mapmod.obj \ + $(SLO)$/mapmod.obj \ $(SLO)$/metaact.obj \ - $(SLO)$/octree.obj \ - $(SLO)$/outmap.obj \ + $(SLO)$/octree.obj \ + $(SLO)$/outmap.obj \ $(SLO)$/outdev2.obj \ $(SLO)$/outdev4.obj \ $(SLO)$/outdev5.obj \ $(SLO)$/outdev6.obj \ $(SLO)$/regband.obj \ - $(SLO)$/region.obj \ - $(SLO)$/wall.obj \ - $(SLO)$/base14.obj \ + $(SLO)$/region.obj \ + $(SLO)$/wall.obj \ + $(SLO)$/base14.obj \ $(SLO)$/pdfwriter.obj \ $(SLO)$/salgdilayout.obj \ $(SLO)$/extoutdevdata.obj \ - $(SLO)$/salnativewidgets-none.obj - + $(SLO)$/salnativewidgets-none.obj # --- Targets ------------------------------------------------------ diff --git a/vcl/source/gdi/metaact.cxx b/vcl/source/gdi/metaact.cxx index eab6af8444e5..ad0c9c9d5f95 100644 --- a/vcl/source/gdi/metaact.cxx +++ b/vcl/source/gdi/metaact.cxx @@ -38,6 +38,7 @@ #include <vcl/salbtype.hxx> #include <vcl/metaact.hxx> #include <vcl/graphictools.hxx> +#include <vcl/rendergraphicrasterizer.hxx> // ======================================================================== @@ -235,6 +236,7 @@ MetaAction* MetaAction::ReadMetaAction( SvStream& rIStm, ImplMetaReadData* pData case( META_COMMENT_ACTION ): pAction = new MetaCommentAction; break; case( META_LAYOUTMODE_ACTION ): pAction = new MetaLayoutModeAction; break; case( META_TEXTLANGUAGE_ACTION ): pAction = new MetaTextLanguageAction; break; + case( META_RENDERGRAPHIC_ACTION ): pAction = new MetaRenderGraphicAction; break; default: { @@ -2565,7 +2567,10 @@ MetaGradientExAction::~MetaGradientExAction() void MetaGradientExAction::Execute( OutputDevice* pOut ) { if( pOut->GetConnectMetaFile() ) - pOut->GetConnectMetaFile()->AddAction( Clone() ); + { + Duplicate(); + pOut->GetConnectMetaFile()->AddAction( this ); + } } // ------------------------------------------------------------------------ @@ -4059,7 +4064,10 @@ void MetaCommentAction::ImplInitDynamicData( const sal_uInt8* pData, sal_uInt32 void MetaCommentAction::Execute( OutputDevice* pOut ) { if ( pOut->GetConnectMetaFile() ) - pOut->GetConnectMetaFile()->AddAction( Clone() ); + { + Duplicate(); + pOut->GetConnectMetaFile()->AddAction( this ); + } } // ------------------------------------------------------------------------ @@ -4294,3 +4302,81 @@ void MetaTextLanguageAction::Read( SvStream& rIStm, ImplMetaReadData* ) } // ======================================================================== + +IMPL_META_ACTION( RenderGraphic, META_RENDERGRAPHIC_ACTION ) + +// ------------------------------------------------------------------------ + +MetaRenderGraphicAction::MetaRenderGraphicAction( const Point& rPoint, const Size& rSize, + const vcl::RenderGraphic& rRenderGraphic, + double fRotateAngle, double fShearAngleX, double fShearAngleY ) : + MetaAction( META_RENDERGRAPHIC_ACTION ), + maRenderGraphic( rRenderGraphic ), + maPoint( rPoint ), + maSize( rSize ), + mfRotateAngle( fRotateAngle ), + mfShearAngleX( fShearAngleX ), + mfShearAngleY( fShearAngleY ) +{ +} + +// ------------------------------------------------------------------------ + +void MetaRenderGraphicAction::Execute( OutputDevice* pOut ) +{ + pOut->DrawRenderGraphic( maPoint, maSize, maRenderGraphic ); +} + +// ------------------------------------------------------------------------ + +MetaAction* MetaRenderGraphicAction::Clone() +{ + MetaAction* pClone = (MetaAction*) new MetaRenderGraphicAction( *this ); + pClone->ResetRefCount(); + return pClone; +} + +// ------------------------------------------------------------------------ + +void MetaRenderGraphicAction::Move( long nHorzMove, long nVertMove ) +{ + maPoint.Move( nHorzMove, nVertMove ); +} + +// ------------------------------------------------------------------------ + +void MetaRenderGraphicAction::Scale( double fScaleX, double fScaleY ) +{ + Rectangle aRectangle( maPoint, maSize ); + ImplScaleRect( aRectangle, fScaleX, fScaleY ); + maPoint = aRectangle.TopLeft(); + maSize = aRectangle.GetSize(); +} + +// ------------------------------------------------------------------------ + +sal_Bool MetaRenderGraphicAction::Compare( const MetaAction& rMetaAction ) const +{ + return ( maRenderGraphic.IsEqual( ( (MetaRenderGraphicAction&) rMetaAction).maRenderGraphic ) && + ( maPoint == ( (MetaRenderGraphicAction&) rMetaAction).maPoint ) && + ( maSize == ( (MetaRenderGraphicAction&) rMetaAction).maSize ) && + ( mfRotateAngle == ( (MetaRenderGraphicAction&) rMetaAction).mfRotateAngle ) && + ( mfShearAngleX == ( (MetaRenderGraphicAction&) rMetaAction).mfShearAngleX ) && + ( mfShearAngleY == ( (MetaRenderGraphicAction&) rMetaAction).mfShearAngleY ) ); +} + +// ------------------------------------------------------------------------ + +void MetaRenderGraphicAction::Write( SvStream& rOStm, ImplMetaWriteData* pData ) +{ + WRITE_BASE_COMPAT( rOStm, 1, pData ); + rOStm << maRenderGraphic << maPoint << maSize << mfRotateAngle << mfShearAngleX << mfShearAngleY; +} + +// ------------------------------------------------------------------------ + +void MetaRenderGraphicAction::Read( SvStream& rIStm, ImplMetaReadData* ) +{ + COMPAT( rIStm ); + rIStm >> maRenderGraphic >> maPoint >> maSize >> mfRotateAngle >> mfShearAngleX >> mfShearAngleY; +} diff --git a/vcl/source/gdi/outdev6.cxx b/vcl/source/gdi/outdev6.cxx index eb4b76fb4b41..6f481237ab53 100644 --- a/vcl/source/gdi/outdev6.cxx +++ b/vcl/source/gdi/outdev6.cxx @@ -43,6 +43,7 @@ #include <vcl/wrkwin.hxx> #include <vcl/graph.hxx> #include <vcl/wall2.hxx> +#include <vcl/rendergraphicrasterizer.hxx> #include <com/sun/star/uno/Sequence.hxx> #include <basegfx/vector/b2dvector.hxx> @@ -1143,6 +1144,7 @@ void OutputDevice::Erase() return; sal_Bool bNativeOK = sal_False; + if( meOutDevType == OUTDEV_WINDOW ) { Window* pWindow = static_cast<Window*>(this); @@ -1193,6 +1195,8 @@ void OutputDevice::ImplDraw2ColorFrame( const Rectangle& rRect, bool OutputDevice::DrawEPS( const Point& rPoint, const Size& rSize, const GfxLink& rGfxLink, GDIMetaFile* pSubst ) { + DBG_TRACE( "OutputDevice::DrawEPS()" ); + bool bDrawn(true); if ( mpMetaFile ) @@ -1211,7 +1215,7 @@ bool OutputDevice::DrawEPS( const Point& rPoint, const Size& rSize, if( mbOutputClipped ) return bDrawn; - Rectangle aRect( ImplLogicToDevicePixel( Rectangle( rPoint, rSize ) ) ); + Rectangle aRect( ImplLogicToDevicePixel( Rectangle( rPoint, rSize ) ) ); if( !aRect.IsEmpty() ) { @@ -1245,3 +1249,26 @@ bool OutputDevice::DrawEPS( const Point& rPoint, const Size& rSize, return bDrawn; } + +// ------------------------------------------------------------------ + +void OutputDevice::DrawRenderGraphic( const Point& rPoint, const Size& rSize, + const ::vcl::RenderGraphic& rRenderGraphic ) +{ + DBG_TRACE( "OutputDevice::DrawRenderGraphic()" ); + + if( mpMetaFile ) + mpMetaFile->AddAction( new MetaRenderGraphicAction( rPoint, rSize, rRenderGraphic ) ); + + if( !rRenderGraphic.IsEmpty() ) + { + ::vcl::RenderGraphicRasterizer aRasterizer( rRenderGraphic ); + BitmapEx aBmpEx; + const Size aSizePixel( LogicToPixel( rSize ) ); + GDIMetaFile* pOldMetaFile = mpMetaFile; + + mpMetaFile = NULL; + DrawBitmapEx( rPoint, rSize, aRasterizer.Rasterize( aSizePixel ) ); + mpMetaFile = pOldMetaFile; + } +} diff --git a/vcl/source/gdi/pdfwriter_impl2.cxx b/vcl/source/gdi/pdfwriter_impl2.cxx index 143c55a83ab1..996f320357c8 100644 --- a/vcl/source/gdi/pdfwriter_impl2.cxx +++ b/vcl/source/gdi/pdfwriter_impl2.cxx @@ -36,6 +36,7 @@ #include "vcl/bmpacc.hxx" #include "vcl/graph.hxx" #include "vcl/svdata.hxx" +#include "vcl/rendergraphicrasterizer.hxx" #include "unotools/streamwrap.hxx" #include "unotools/processfactory.hxx" #include "comphelper/processfactory.hxx" @@ -1044,6 +1045,17 @@ void PDFWriterImpl::playMetafile( const GDIMetaFile& i_rMtf, vcl::PDFExtOutDevDa } break; + case( META_RENDERGRAPHIC_ACTION ): + { + const MetaRenderGraphicAction* pA = static_cast< const MetaRenderGraphicAction* >( pAction ); + const ::vcl::RenderGraphicRasterizer aRasterizer( pA->GetRenderGraphic() ); + + implWriteBitmapEx( pA->GetPoint(), pA->GetSize(), + aRasterizer.Rasterize( pDummyVDev->LogicToPixel( pA->GetSize() ) ), + pDummyVDev, i_rContext ); + } + break; + default: // #i24604# Made assertion fire only once per // metafile. The asserted actions here are all diff --git a/vcl/source/gdi/print2.cxx b/vcl/source/gdi/print2.cxx index d86df6e2816b..28fa8670b8e8 100644 --- a/vcl/source/gdi/print2.cxx +++ b/vcl/source/gdi/print2.cxx @@ -45,6 +45,7 @@ #include <vcl/svapp.hxx> #include <vcl/sallayout.hxx> #include <vcl/bmpacc.hxx> +#include <vcl/rendergraphicrasterizer.hxx> #include "pdfwriter_impl.hxx" @@ -111,6 +112,9 @@ static bool ImplIsActionSpecial( const MetaAction& rAct ) case META_BMPEXSCALEPART_ACTION: return static_cast<const MetaBmpExScalePartAction&>(rAct).GetBitmapEx().IsTransparent(); + case META_RENDERGRAPHIC_ACTION: + return true; + default: return false; } @@ -198,6 +202,16 @@ static void ImplConvertTransparentAction( GDIMetaFile& o_rMtf, aBmpEx = static_cast<const MetaBmpExScaleAction&>(rAct).GetBitmapEx(); break; + case META_RENDERGRAPHIC_ACTION: + { + const ::vcl::RenderGraphicRasterizer aRasterizer( static_cast<const MetaRenderGraphicAction&>(rAct). + GetRenderGraphic() ); + + aBmpEx = aRasterizer.Rasterize( rStateOutDev.LogicToPixel( + static_cast<const MetaRenderGraphicAction&>(rAct).GetSize() ) ); + break; + } + case META_TRANSPARENT_ACTION: default: @@ -265,6 +279,11 @@ static void ImplConvertTransparentAction( GDIMetaFile& o_rMtf, static_cast<const MetaBmpExScalePartAction&>(rAct).GetSrcSize(), aBmp )); break; + case META_RENDERGRAPHIC_ACTION: + o_rMtf.AddAction( new MetaBmpScaleAction( + static_cast<const MetaRenderGraphicAction&>(rAct).GetPoint(), + static_cast<const MetaRenderGraphicAction&>(rAct).GetSize(), + aBmp )); default: DBG_ERROR("Unexpected case"); break; @@ -377,6 +396,7 @@ static bool ImplIsNotTransparent( const MetaAction& rAct, const OutputDevice& rO case META_TEXTRECT_ACTION: case META_STRETCHTEXT_ACTION: case META_TEXTLINE_ACTION: + case META_RENDERGRAPHIC_ACTION: // all other actions: generate non-transparent output bRet = true; break; @@ -629,7 +649,14 @@ static Rectangle ImplCalcActionBounds( const MetaAction& rAct, const OutputDevic case META_TEXTLINE_ACTION: DBG_ERROR("META_TEXTLINE_ACTION not supported"); - break; + break; + + case( META_RENDERGRAPHIC_ACTION ): + { + const MetaRenderGraphicAction& rRenderAct = static_cast<const MetaRenderGraphicAction&>(rAct); + aActionBounds = Rectangle( rRenderAct.GetPoint(), rRenderAct.GetSize() ); + } + break; default: break; @@ -656,6 +683,7 @@ static bool ImplIsActionHandlingTransparency( const MetaAction& rAct ) case META_BMPEX_ACTION: case META_BMPEXSCALE_ACTION: case META_BMPEXSCALEPART_ACTION: + case META_RENDERGRAPHIC_ACTION: return true; default: diff --git a/vcl/source/gdi/rendergraphic.cxx b/vcl/source/gdi/rendergraphic.cxx new file mode 100644 index 000000000000..10b6064cc57c --- /dev/null +++ b/vcl/source/gdi/rendergraphic.cxx @@ -0,0 +1,240 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#include <vcl/rendergraphic.hxx> +#include <vcl/rendergraphicrasterizer.hxx> +#include <vcl/mapmod.hxx> +#include <tools/stream.hxx> +#include <tools/vcompat.hxx> + +#include <cstring> +#include <cstdio> + +namespace vcl +{ + +// ----------------- +// - RenderGraphic - +// ----------------- +RenderGraphic::RenderGraphic( ) : + mnGraphicDataLength( 0 ) +{ +} + +// ------------------------------------------------------------------------- + +RenderGraphic::RenderGraphic( const RenderGraphic& rRenderGraphic ) : + maGraphicData( rRenderGraphic.maGraphicData ), + mnGraphicDataLength( rRenderGraphic.mnGraphicDataLength ), + maGraphicDataMimeType( rRenderGraphic.maGraphicDataMimeType ), + mapPrefMapMode( rRenderGraphic.mapPrefMapMode.get() ? new MapMode( *rRenderGraphic.mapPrefMapMode ) : NULL ), + mapPrefSize( rRenderGraphic.mapPrefSize.get() ? new Size( *rRenderGraphic.mapPrefSize ) : NULL ) +{ +} + +// ------------------------------------------------------------------------- + +RenderGraphic::RenderGraphic( const GraphicData& rGraphicData, + sal_uInt32 nGraphicDataLength, + const rtl::OUString& rGraphicDataMimeType ) : + maGraphicData( rGraphicData ), + mnGraphicDataLength( nGraphicDataLength ), + maGraphicDataMimeType( rGraphicDataMimeType ) +{ + ImplCheckData( ); +} + +// ------------------------------------------------------------------------- + +RenderGraphic::RenderGraphic( const rtl::OUString& rGraphicDataMimeType, + sal_uInt32 nGraphicDataLength, + const sal_uInt8* pGraphicData ) : + maGraphicData(), + mnGraphicDataLength( nGraphicDataLength ), + maGraphicDataMimeType( rGraphicDataMimeType ) +{ + if( rGraphicDataMimeType.getLength( ) && nGraphicDataLength ) + { + maGraphicData.reset( new sal_uInt8[ nGraphicDataLength ] ); + + if( pGraphicData ) + { + memcpy( maGraphicData.get(), pGraphicData, nGraphicDataLength ); + } + } + else + { + ImplCheckData( ); + } +} + +// ------------------------------------------------------------------------- + +RenderGraphic::~RenderGraphic( ) +{ +} + +// ------------------------------------------------------------------------- + +RenderGraphic& RenderGraphic::operator=(const RenderGraphic& rRenderGraphic ) +{ + maGraphicData = rRenderGraphic.maGraphicData; + mnGraphicDataLength = rRenderGraphic.mnGraphicDataLength; + maGraphicDataMimeType = rRenderGraphic.maGraphicDataMimeType; + mapPrefMapMode.reset( rRenderGraphic.mapPrefMapMode.get() ? new MapMode( *rRenderGraphic.mapPrefMapMode ) : NULL ); + mapPrefSize.reset( rRenderGraphic.mapPrefSize.get() ? new Size( *rRenderGraphic.mapPrefSize ) : NULL ); + + return( *this ); +} + +// ------------------------------------------------------------------------- + +bool RenderGraphic::operator==(const RenderGraphic& rRenderGraphic ) const +{ + return( ( rRenderGraphic.mnGraphicDataLength == mnGraphicDataLength ) && + ( rRenderGraphic.maGraphicData == maGraphicData ) && + ( rRenderGraphic.maGraphicDataMimeType.equalsIgnoreAsciiCase( maGraphicDataMimeType ) ) ); +} + +// ------------------------------------------------------------------------- + +bool RenderGraphic::operator!() const +{ + return( ( 0 == maGraphicDataMimeType.getLength( ) ) || + ( 0 == mnGraphicDataLength ) || + !maGraphicData.get( ) ); +} + +// ------------------------------------------------------------------------- + +bool RenderGraphic::IsEqual( const RenderGraphic& rRenderGraphic ) const +{ + bool bRet = ( rRenderGraphic.mnGraphicDataLength == mnGraphicDataLength ) && + ( rRenderGraphic.maGraphicDataMimeType.equalsIgnoreAsciiCase( maGraphicDataMimeType ) ); + + if( bRet && mnGraphicDataLength && ( rRenderGraphic.maGraphicData != maGraphicData ) ) + { + bRet = ( 0 == memcmp( rRenderGraphic.maGraphicData.get( ), + maGraphicData.get( ), + mnGraphicDataLength ) ); + } + + return( bRet ); +} + +// ------------------------------------------------------------------------- + +const MapMode& RenderGraphic::GetPrefMapMode() const +{ + ImplGetDefaults(); + return( *mapPrefMapMode ); +} + +// ------------------------------------------------------------------------- + +const Size& RenderGraphic::GetPrefSize() const +{ + ImplGetDefaults(); + return( *mapPrefSize ); +} + +// ------------------------------------------------------------------------- + +BitmapEx RenderGraphic::GetReplacement() const +{ + const RenderGraphicRasterizer aRasterizer( *this ); + + return( aRasterizer.GetReplacement() ); +} + +// ------------------------------------------------------------------------- + +void RenderGraphic::ImplCheckData( ) +{ + if( !( *this ) ) + { + maGraphicData.reset( ); + mnGraphicDataLength = 0; + maGraphicDataMimeType = ::rtl::OUString(); + mapPrefMapMode.reset(); + mapPrefSize.reset(); + } +} + +// ------------------------------------------------------------------------- + +void RenderGraphic::ImplGetDefaults() const +{ + if( !mapPrefMapMode.get() || !mapPrefSize.get() ) + { + const RenderGraphicRasterizer aRasterizer( *this ); + + mapPrefMapMode.reset( new MapMode( aRasterizer.GetPrefMapMode() ) ); + mapPrefSize.reset( new Size( aRasterizer.GetPrefSize() ) ); + } +} + +// ------------------------------------------------------------------------- + +::SvStream& operator>>( ::SvStream& rIStm, RenderGraphic& rRenderGraphic ) +{ + ::VersionCompat aVCompat( rIStm, STREAM_READ ); + String aGraphicDataMimeType; + sal_uInt32 nGraphicDataLength = 0; + + rIStm.ReadByteString( aGraphicDataMimeType, RTL_TEXTENCODING_ASCII_US ); + rIStm >> nGraphicDataLength; + + rRenderGraphic = RenderGraphic( aGraphicDataMimeType, nGraphicDataLength ); + + if( !rRenderGraphic.IsEmpty() ) + { + rIStm.Read( rRenderGraphic.GetGraphicData().get(), nGraphicDataLength ); + } + + return rIStm; +} + +// ------------------------------------------------------------------ + +::SvStream& operator<<( ::SvStream& rOStm, const RenderGraphic& rRenderGraphic ) +{ + ::VersionCompat aVCompat( rOStm, STREAM_WRITE, 1 ); + const sal_uInt32 nGraphicDataLength = rRenderGraphic.GetGraphicDataLength(); + + rOStm.WriteByteString( rRenderGraphic.GetGraphicDataMimeType(), RTL_TEXTENCODING_ASCII_US ); + rOStm << nGraphicDataLength; + + if( nGraphicDataLength ) + { + rOStm.Write( rRenderGraphic.GetGraphicData().get(), nGraphicDataLength ); + } + + return rOStm; +} + +} // VCL diff --git a/vcl/source/gdi/rendergraphicrasterizer.cxx b/vcl/source/gdi/rendergraphicrasterizer.cxx new file mode 100644 index 000000000000..29c9863335b3 --- /dev/null +++ b/vcl/source/gdi/rendergraphicrasterizer.cxx @@ -0,0 +1,400 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#include <vcl/rendergraphicrasterizer.hxx> +#include <vcl/svapp.hxx> +#include <vcl/wrkwin.hxx> +#include <vcl/virdev.hxx> +#include <vcl/unohelp.hxx> +#include <vcl/bmpacc.hxx> +#include <vcl/graph.hxx> +#include <tools/stream.hxx> +#include <comphelper/processfactory.hxx> +#include <unotools/streamwrap.hxx> + +#include <com/sun/star/lang/XMultiServiceFactory.hpp> + +#define VCL_SERVICENAME_RASTERIZER_SVG "com.sun.star.graphic.GraphicRasterizer_RSVG" + +using namespace com::sun::star; + +namespace vcl +{ +// --------------------------------------------------------- +// - maximum extent in pixel for graphics to be rasterized - +// --------------------------------------------------------- + +static const sal_uInt32 nRasterizerDefaultExtent = 4096; + +// --------------------------- +// - RenderGraphicRasterizer - +// --------------------------- + +RenderGraphicRasterizer::RenderGraphicRasterizer( const RenderGraphic& rRenderGraphic ) : + maRenderGraphic( rRenderGraphic ), + mfRotateAngle( 0.0 ), + mfShearAngleX( 0.0 ), + mfShearAngleY( 0.0 ) +{ +} + +// ------------------------------------------------------------------------- + +RenderGraphicRasterizer::RenderGraphicRasterizer( const RenderGraphicRasterizer& rRenderGraphicRasterizer ) : + maRenderGraphic( rRenderGraphicRasterizer.maRenderGraphic ), + mxRasterizer( rRenderGraphicRasterizer.mxRasterizer ), + maBitmapEx( rRenderGraphicRasterizer.maBitmapEx ), + maDefaultSizePixel( rRenderGraphicRasterizer.maDefaultSizePixel ), + mfRotateAngle( rRenderGraphicRasterizer.mfRotateAngle ), + mfShearAngleX( rRenderGraphicRasterizer.mfShearAngleX ), + mfShearAngleY( rRenderGraphicRasterizer.mfShearAngleY ) +{ +} + +// ------------------------------------------------------------------------- + +RenderGraphicRasterizer::~RenderGraphicRasterizer() +{ +} + +// ------------------------------------------------------------------------- + +RenderGraphicRasterizer& RenderGraphicRasterizer::operator=( + const RenderGraphicRasterizer& rRenderGraphicRasterizer ) +{ + maRenderGraphic = rRenderGraphicRasterizer.maRenderGraphic; + maBitmapEx = rRenderGraphicRasterizer.maBitmapEx; + maDefaultSizePixel = rRenderGraphicRasterizer.maDefaultSizePixel; + mfRotateAngle = rRenderGraphicRasterizer.mfRotateAngle; + mfShearAngleX = rRenderGraphicRasterizer.mfShearAngleX; + mfShearAngleY = rRenderGraphicRasterizer.mfShearAngleY; + mxRasterizer = rRenderGraphicRasterizer.mxRasterizer; + + return( *this ); +} + +// ------------------------------------------------------------------------- + +const Size& RenderGraphicRasterizer::GetDefaultSizePixel() const +{ + const_cast< RenderGraphicRasterizer* >( this )->InitializeRasterizer(); + + return( maDefaultSizePixel ); +} + +// ------------------------------------------------------------------------- + +BitmapEx RenderGraphicRasterizer::GetReplacement() const +{ + BitmapEx aRet( Rasterize( GetDefaultSizePixel() ) ); + + aRet.SetPrefSize( GetPrefSize() ); + aRet.SetPrefMapMode( GetPrefMapMode() ); + + return( aRet ); +} + +// ------------------------------------------------------------------------- + +Size RenderGraphicRasterizer::GetPrefSize() const +{ + const Size aSizePixel( GetDefaultSizePixel() ); + std::auto_ptr< VirtualDevice > apCompVDev; + OutputDevice* pCompDev = NULL; + +#ifndef NO_GETAPPWINDOW + pCompDev = Application::GetAppWindow(); +#endif + + if( !pCompDev ) + { + apCompVDev.reset( new VirtualDevice ); + pCompDev = apCompVDev.get(); + } + + return( pCompDev->PixelToLogic( aSizePixel, GetPrefMapMode() ) ); +} + +// ------------------------------------------------------------------------- + +MapMode RenderGraphicRasterizer::GetPrefMapMode() const +{ + return( MapMode( MAP_100TH_MM ) ); +} + +// ------------------------------------------------------------------------- + +const BitmapEx& RenderGraphicRasterizer::Rasterize( const Size& rSizePixel, + double fRotateAngle, + double fShearAngleX, + double fShearAngleY, + sal_uInt32 nMaxExtent ) const +{ + const bool bRasterize = !maRenderGraphic.IsEmpty() && + rSizePixel.Width() && rSizePixel.Height() && + ( maBitmapEx.IsEmpty() || + ( rSizePixel != maBitmapEx.GetSizePixel() ) || + ( fRotateAngle != mfRotateAngle ) || + ( fShearAngleX != mfShearAngleX ) || + ( fShearAngleY != mfShearAngleY ) ); + + if( bRasterize ) + { + const_cast< RenderGraphicRasterizer* >( this )->InitializeRasterizer(); + + if( mxRasterizer.is() ) + { + sal_uInt32 nWidth = labs( rSizePixel.Width() ); + sal_uInt32 nHeight = labs( rSizePixel.Height() ); + + // limiting the extent of the rastered bitmap + if( VCL_RASTERIZER_UNLIMITED_EXTENT != nMaxExtent ) + { + if( VCL_RASTERIZER_DEFAULT_EXTENT == nMaxExtent ) + { + nMaxExtent = nRasterizerDefaultExtent; + } + + if( ( nWidth > nMaxExtent ) || ( nHeight > nMaxExtent ) ) + { + const double fScale = static_cast< double >( nMaxExtent ) / ::std::max( nWidth, nHeight ); + + nWidth = FRound( nWidth * fScale ); + nHeight = FRound( nHeight * fScale ); + } + } + + if( !ImplRasterizeFromCache( const_cast< RenderGraphicRasterizer& >( *this ), + Size( nWidth, nHeight ), fRotateAngle, fShearAngleX, fShearAngleY ) ) + { + try + { + const uno::Sequence< beans::PropertyValue > aPropertySeq; + const Graphic aRasteredGraphic( mxRasterizer->rasterize( nWidth, + nHeight, + fRotateAngle, + fShearAngleX, + fShearAngleY, + aPropertySeq ) ); + + maBitmapEx = aRasteredGraphic.GetBitmapEx(); + mfRotateAngle = fRotateAngle; + mfShearAngleX = fShearAngleX; + mfShearAngleY = fShearAngleY; + + ImplUpdateCache( *this ); + +// OSL_TRACE( "Wanted: %d x %d / Got: %d x %d", rSizePixel.Width(), rSizePixel.Height(), maBitmapEx.GetSizePixel().Width(), maBitmapEx.GetSizePixel().Height() ); + } + catch( ... ) + { + OSL_TRACE( "caught exception during rasterization" ); + } + } + } + } + + return( maBitmapEx ); +} + +// ------------------------------------------------------------------------- + +void RenderGraphicRasterizer::InitializeRasterizer() +{ + if( !mxRasterizer.is() && !ImplInitializeFromCache( *this ) ) + { + uno::Reference< lang::XMultiServiceFactory > xFactory( ::comphelper::getProcessServiceFactory() ); + + maDefaultSizePixel.Width() = maDefaultSizePixel.Height() = 0; + + if( !maRenderGraphic.IsEmpty() ) + { + rtl::OUString aServiceName; + + if( 0 == maRenderGraphic.GetGraphicDataMimeType().compareToAscii( "image/svg+xml" ) ) + { + aServiceName = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( VCL_SERVICENAME_RASTERIZER_SVG ) ); + } + + if( aServiceName.getLength() ) + { + mxRasterizer.set( xFactory->createInstance( aServiceName ), uno::UNO_QUERY ); + + if( mxRasterizer.is() ) + { + std::auto_ptr< VirtualDevice > apCompVDev; + OutputDevice* pCompDev = NULL; + +#ifndef NO_GETAPPWINDOW + pCompDev = Application::GetAppWindow(); +#endif + + if( !pCompDev ) + { + apCompVDev.reset( new VirtualDevice ); + pCompDev = apCompVDev.get(); + } + + const Size aDPI( pCompDev->LogicToPixel( Size( 1, 1 ), MAP_INCH ) ); + awt::Size aSizePixel; + SvMemoryStream aMemStm( maRenderGraphic.GetGraphicData().get(), + maRenderGraphic.GetGraphicDataLength(), + STREAM_READ ); + + uno::Reference< io::XInputStream > xIStm( new utl::OSeekableInputStreamWrapper( aMemStm ) ); + + try + { + if( !xIStm.is() || !mxRasterizer->initializeData( xIStm, aDPI.Width(), aDPI.Height(), aSizePixel ) ) + { + mxRasterizer.clear(); + } + else + { + maDefaultSizePixel.Width() = aSizePixel.Width; + maDefaultSizePixel.Height() = aSizePixel.Height; + } + } + catch( ... ) + { + OSL_TRACE( "caught exception during initialization of SVG rasterizer component" ); + mxRasterizer.clear(); + } + } + } + } + } +} + +// ------------------------------------------------------------------------------ + +RenderGraphicRasterizer::RenderGraphicRasterizerCache& RenderGraphicRasterizer::ImplGetCache() +{ + static RenderGraphicRasterizerCache* pCache = NULL; + + if( !pCache ) + { + pCache = new RenderGraphicRasterizerCache; + } + + return( *pCache ); +} + +// ------------------------------------------------------------------------------ + +bool RenderGraphicRasterizer::ImplInitializeFromCache( RenderGraphicRasterizer& rRasterizer ) +{ + RenderGraphicRasterizerCache& rCache = ImplGetCache(); + bool bRet = false; + + for( sal_uInt32 i = 0; i < rCache.size(); ++i ) + { + const RenderGraphicRasterizer* pCheck = &rCache[ i ]; + + if( pCheck && pCheck->mxRasterizer.is() && ( pCheck->maRenderGraphic == rRasterizer.maRenderGraphic ) ) + { +// OSL_TRACE( "Hit RenderGraphicRasterizer cache for initialization" ); + + rRasterizer.mxRasterizer = pCheck->mxRasterizer; + rRasterizer.maDefaultSizePixel = pCheck->maDefaultSizePixel; + + // put found Rasterizer at begin of deque + const RenderGraphicRasterizer aFound( rCache[ i ] ); + + rCache.erase( rCache.begin() + i ); + rCache.push_front( aFound ); + + + bRet = true; + } + } + + return( bRet ); +} + +// ------------------------------------------------------------------------------ + +bool RenderGraphicRasterizer::ImplRasterizeFromCache( RenderGraphicRasterizer& rRasterizer, + const Size& rSizePixel, + double fRotateAngle, + double fShearAngleX, + double fShearAngleY ) +{ + RenderGraphicRasterizerCache& rCache = ImplGetCache(); + bool bRet = false; + + for( sal_uInt32 i = 0; i < rCache.size(); ++i ) + { + const RenderGraphicRasterizer& rCheck = rCache[ i ]; + + if( rCheck.mxRasterizer.is() && rRasterizer.mxRasterizer.is() && + ( ( rCheck.mxRasterizer == rRasterizer.mxRasterizer ) || + ( rRasterizer.maRenderGraphic == rCheck.maRenderGraphic ) ) && + ( rCheck.maBitmapEx.GetSizePixel() == rSizePixel ) && + ( rCheck.mfRotateAngle == fRotateAngle ) && + ( rCheck.mfShearAngleX == fShearAngleX ) && + ( rCheck.mfShearAngleY == fShearAngleY ) ) + { +// OSL_TRACE( "Hit RenderGraphicRasterizer cache for rasterizing" ); + + rRasterizer.maBitmapEx = rCheck.maBitmapEx; + rRasterizer.mfRotateAngle = fRotateAngle; + rRasterizer.mfShearAngleX = fShearAngleX; + rRasterizer.mfShearAngleY = fShearAngleY; + + // put found Rasterizer at begin of deque + const RenderGraphicRasterizer aFound( rCache[ i ] ); + + rCache.erase( rCache.begin() + i ); + rCache.push_front( aFound ); + + bRet = true; + } + } + + return( bRet ); +} + +// ------------------------------------------------------------------------------ + +void RenderGraphicRasterizer::ImplUpdateCache( const RenderGraphicRasterizer& rRasterizer ) +{ + RenderGraphicRasterizerCache& rCache = ImplGetCache(); + const sal_uInt32 nMaxCacheSize = 8; + + if( rCache.size() < nMaxCacheSize ) + { + rCache.push_front( rRasterizer ); + } + else + { + rCache.pop_back(); + rCache.push_front( rRasterizer ); + } +} + +} // VCL diff --git a/vcl/source/gdi/svgread.cxx b/vcl/source/gdi/svgread.cxx new file mode 100644 index 000000000000..47ef39c37f20 --- /dev/null +++ b/vcl/source/gdi/svgread.cxx @@ -0,0 +1,131 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include <tools/stream.hxx> +#include <vcl/svgread.hxx> +#include <vcl/gdimtf.hxx> +#include <vcl/metaact.hxx> +#include <vcl/rendergraphicrasterizer.hxx> + +// ----------- +// - Defines - +// ----------- + +namespace vcl +{ + // ----------------- + // - SVGReaderImpl - + // ----------------- + + class SVGReaderImpl + { + public: + + SVGReaderImpl( SvStream& rStm ); + ~SVGReaderImpl(); + + GDIMetaFile& ImplRead( GDIMetaFile& rSVGMtf ); + + private: + + SvStream& mrStm; + }; + + // ------------------------------------------------------------------------------ + + SVGReaderImpl::SVGReaderImpl( SvStream& rStm ) : + mrStm( rStm ) + { + } + + // ------------------------------------------------------------------------ + + SVGReaderImpl::~SVGReaderImpl() + { + } + + // ------------------------------------------------------------------------ + + GDIMetaFile& SVGReaderImpl::ImplRead( GDIMetaFile& rSVGMtf ) + { + const sal_uInt32 nStmPos = mrStm.Tell(); + const sal_uInt32 nStmLen = mrStm.Seek( STREAM_SEEK_TO_END ) - nStmPos; + + if( nStmLen ) + { + const vcl::RenderGraphic aSVGGraphic( ::rtl::OUString::createFromAscii( "image/svg+xml" ), nStmLen ); + + mrStm.Seek( nStmPos ); + mrStm.Read( aSVGGraphic.GetGraphicData().get(), nStmLen ); + + if( !mrStm.GetError() ) + { + const vcl::RenderGraphicRasterizer aRasterizer( aSVGGraphic ); + const Size aDefaultSizePixel( aRasterizer.GetDefaultSizePixel() ); + + if( aDefaultSizePixel.Width() && aDefaultSizePixel.Height() ) + { + const Point aPos; + const Size aPrefSize( aRasterizer.GetPrefSize() ); + + rSVGMtf.SetPrefMapMode( aRasterizer.GetPrefMapMode() ); + rSVGMtf.SetPrefSize( aPrefSize ); + rSVGMtf.AddAction( new MetaRenderGraphicAction( aPos, aPrefSize, aSVGGraphic ) ); + rSVGMtf.WindStart(); + } + } + } + + return( rSVGMtf ); + } + + // ------------- + // - SVGReader - + // ------------- + + SVGReader::SVGReader( SvStream& rIStm ) : + mapImpl( new ::vcl::SVGReaderImpl( rIStm ) ) + { + } + + // ------------------------------------------------------------------------ + + SVGReader::~SVGReader() + { + } + + // ------------------------------------------------------------------------ + + GDIMetaFile& SVGReader::Read( GDIMetaFile& rSVGMtf ) + { + rSVGMtf = GDIMetaFile(); + + return( mapImpl.get() ? mapImpl->ImplRead( rSVGMtf ) : rSVGMtf ); + } + +} // namespace vcl diff --git a/vcl/util/makefile.mk b/vcl/util/makefile.mk index 8d1de2ed30f0..75b3f9f527c1 100644 --- a/vcl/util/makefile.mk +++ b/vcl/util/makefile.mk @@ -99,6 +99,8 @@ HXXDEPNLST= $(INC)$/vcl$/accel.hxx \ $(INC)$/vcl$/print.hxx \ $(INC)$/vcl$/prndlg.hxx \ $(INC)$/vcl$/region.hxx \ + $(INC)$/vcl$/rendergraphic.hxx \ + $(INC)$/vcl$/rendergraphicrasterizer.hxx \ $(INC)$/vcl$/salbtype.hxx \ $(INC)$/vcl$/scrbar.hxx \ $(INC)$/vcl$/slider.hxx \ diff --git a/vcl/util/vcl.component b/vcl/util/vcl.component index da20fc916c32..ea14667d17c1 100644 --- a/vcl/util/vcl.component +++ b/vcl/util/vcl.component @@ -46,4 +46,7 @@ <implementation name="vcl::FontIdentificator"> <service name="com.sun.star.awt.FontIdentificator"/> </implementation> + <implementation name="vcl::rsvg::Rasterizer"> + <service name="com.sun.star.graphic.GraphicRasterizer_RSVG"/> + </implementation> </component> diff --git a/vcl/util/vcl.macosx.component b/vcl/util/vcl.macosx.component index 3aabcd8c7050..023f805672bd 100644 --- a/vcl/util/vcl.macosx.component +++ b/vcl/util/vcl.macosx.component @@ -46,4 +46,7 @@ <implementation name="vcl::FontIdentificator"> <service name="com.sun.star.awt.FontIdentificator"/> </implementation> + <implementation name="vcl::rsvg::Rasterizer"> + <service name="com.sun.star.graphic.GraphicRasterizer_RSVG"/> + </implementation> </component> diff --git a/vcl/util/vcl.windows.component b/vcl/util/vcl.windows.component index 72f7ace9f251..df786c4d832b 100644 --- a/vcl/util/vcl.windows.component +++ b/vcl/util/vcl.windows.component @@ -37,4 +37,7 @@ <implementation name="vcl::FontIdentificator"> <service name="com.sun.star.awt.FontIdentificator"/> </implementation> + <implementation name="vcl::rsvg::Rasterizer"> + <service name="com.sun.star.graphic.GraphicRasterizer_RSVG"/> + </implementation> </component> |