summaryrefslogtreecommitdiff
path: root/canvas/source/vcl/impltools.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'canvas/source/vcl/impltools.cxx')
-rw-r--r--canvas/source/vcl/impltools.cxx414
1 files changed, 414 insertions, 0 deletions
diff --git a/canvas/source/vcl/impltools.cxx b/canvas/source/vcl/impltools.cxx
new file mode 100644
index 000000000000..75a492665a74
--- /dev/null
+++ b/canvas/source/vcl/impltools.cxx
@@ -0,0 +1,414 @@
+/*************************************************************************
+ *
+ * $RCSfile: impltools.cxx,v $
+ *
+ * $Revision: 1.2 $
+ *
+ * last change: $Author: thb $ $Date: 2004-03-18 10:38:41 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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 for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#ifndef _DRAFTS_COM_SUN_STAR_GEOMETRY_REALSIZE2D_HPP__
+#include <drafts/com/sun/star/geometry/RealSize2D.hpp>
+#endif
+#ifndef _DRAFTS_COM_SUN_STAR_GEOMETRY_REALPOINT2D_HPP__
+#include <drafts/com/sun/star/geometry/RealPoint2D.hpp>
+#endif
+#ifndef _DRAFTS_COM_SUN_STAR_GEOMETRY_REALRECTANGLE2D_HPP__
+#include <drafts/com/sun/star/geometry/RealRectangle2D.hpp>
+#endif
+
+#ifndef _DRAFTS_COM_SUN_STAR_RENDERING_RENDERSTATE_HPP__
+#include <drafts/com/sun/star/rendering/RenderState.hpp>
+#endif
+#ifndef _DRAFTS_COM_SUN_STAR_RENDERING_XCANVAS_HPP__
+#include <drafts/com/sun/star/rendering/XCanvas.hpp>
+#endif
+#ifndef _DRAFTS_COM_SUN_STAR_RENDERING_XBITMAP_HPP__
+#include <drafts/com/sun/star/rendering/XBitmap.hpp>
+#endif
+#ifndef _DRAFTS_COM_SUN_STAR_RENDERING_XPOLYPOLYGON2D_HPP__
+#include <drafts/com/sun/star/rendering/XPolyPolygon2D.hpp>
+#endif
+#ifndef _DRAFTS_COM_SUN_STAR_GEOMETRY_REALBEZIERSEGMENT2D_HPP__
+#include <drafts/com/sun/star/geometry/RealBezierSegment2D.hpp>
+#endif
+#ifndef _DRAFTS_COM_SUN_STAR_RENDERING_XINTEGERBITMAP_HPP__
+#include <drafts/com/sun/star/rendering/XIntegerBitmap.hpp>
+#endif
+
+#ifndef _TL_POLY_HXX
+#include <tools/poly.hxx>
+#endif
+#ifndef _SV_SALBTYPE_HXX
+#include <vcl/salbtype.hxx>
+#endif
+#ifndef _SV_BMPACC_HXX
+#include <vcl/bmpacc.hxx>
+#endif
+#ifndef _SV_BITMAPEX_HXX
+#include <vcl/bitmapex.hxx>
+#endif
+#ifndef _SV_METRIC_HXX
+#include <vcl/metric.hxx>
+#endif
+#ifndef _VCL_CANVASTOOLS_HXX
+#include <vcl/canvastools.hxx>
+#endif
+
+#ifndef _BGFX_TUPLE_B2DTUPLE_HXX
+#include <basegfx/tuple/b2dtuple.hxx>
+#endif
+#ifndef _BGFX_MATRIX_B2DHOMMATRIX_HXX
+#include <basegfx/matrix/b2dhommatrix.hxx>
+#endif
+#ifndef _BGFX_TOOLS_CANVASTOOLS_HXX
+#include <basegfx/tools/canvastools.hxx>
+#endif
+
+#ifndef INCLUDED_RTL_MATH_HXX
+#include <rtl/math.hxx>
+#endif
+
+#include <cmath> // for fmod
+
+#include <canvas/canvastools.hxx>
+
+#include "impltools.hxx"
+#include "linepolypolygon.hxx"
+#include "canvasbitmap.hxx"
+
+
+using namespace ::com::sun::star;
+using namespace ::drafts::com::sun::star;
+
+namespace vclcanvas
+{
+ namespace tools
+ {
+ ::PolyPolygon polyPolygonFromXPolyPolygon2D( const uno::Reference< rendering::XPolyPolygon2D >& xPoly )
+ {
+ uno::Reference< lang::XServiceInfo > xRef( xPoly,
+ uno::UNO_QUERY );
+
+ if( xRef.is() &&
+ xRef->getImplementationName().equals( ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(LINEPOLYPOLYGON_IMPLEMENTATION_NAME))) )
+ {
+ // TODO: Maybe use dynamic_cast here
+
+ // TODO: Provide true beziers here!
+ return static_cast<LinePolyPolygon*>(xPoly.get())->getVCLPolyPolygon();
+ }
+ else
+ {
+ // TODO: extract points from polygon interface
+ }
+
+ return ::PolyPolygon();
+ }
+
+ ::BitmapEx bitmapExFromXBitmap( const uno::Reference< rendering::XBitmap >& xBitmap )
+ {
+ uno::Reference< lang::XServiceInfo > xRef( xBitmap,
+ uno::UNO_QUERY );
+
+ if( xRef.is() &&
+ xRef->getImplementationName().equals( ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(CANVASBITMAP_IMPLEMENTATION_NAME))) )
+ {
+ // TODO: Maybe use dynamic_cast here
+ VirtualDevice& rVDev( static_cast<CanvasBitmap*>(xBitmap.get())->getVirDev() );
+ const Point aEmptyPoint(0,0);
+ const Size aBmpSize(rVDev.GetOutputSizePixel());
+
+ // TODO: handle alpha vDev here
+ return rVDev.GetBitmap(aEmptyPoint, aBmpSize);
+ }
+ else
+ {
+ // TODO: extract points from polygon interface
+ }
+
+ return ::BitmapEx();
+ }
+
+ ::Point setupFontTransform( ::Font& aVCLFont,
+ const rendering::ViewState& rViewState,
+ const rendering::RenderState& rRenderState,
+ OutputDevice& rOutDev )
+ {
+ ::basegfx::B2DHomMatrix aMatrix;
+
+ ::canvas::tools::mergeViewAndRenderTransform(aMatrix,
+ rViewState,
+ rRenderState);
+
+ ::basegfx::B2DTuple aScale;
+ ::basegfx::B2DTuple aTranslate;
+ double nRotate, nShearX;
+
+ aMatrix.decompose( aScale, aTranslate, nRotate, nShearX );
+
+ // query font metric _before_ tampering with width and height
+ if( !::rtl::math::approxEqual(aScale.getX(), aScale.getY()) )
+ {
+ // retrieve true font width
+ const int aFontWidth( rOutDev.GetFontMetric( aVCLFont ).GetWidth() );
+
+ aVCLFont.SetWidth( static_cast<long>(aFontWidth * aScale.getX() + .5) );
+ }
+
+ if( !::rtl::math::approxEqual(aScale.getY(), 1.0) )
+ {
+ const int nFontHeight( aVCLFont.GetHeight() );
+ aVCLFont.SetHeight( static_cast<long>(nFontHeight * aScale.getY() + .5) );
+ }
+
+ aVCLFont.SetOrientation( static_cast< short >(-fmod(nRotate, 2*F_PI)*(1800.0/F_PI) + .5) );
+
+ // TODO: Missing functionality in VCL: shearing
+ return ::Point( static_cast<long>(aTranslate.getX() + .5),
+ static_cast<long>(aTranslate.getY() + .5) );
+ }
+
+ // VCL-Canvas related
+ //---------------------------------------------------------------------
+
+ ::Point mapRealPoint2D( const geometry::RealPoint2D& rPoint,
+ const rendering::ViewState& rViewState,
+ const rendering::RenderState& rRenderState )
+ {
+ ::basegfx::B2DPoint aPoint( ::basegfx::unotools::b2DPointFromRealPoint2D(rPoint) );
+
+ ::basegfx::B2DHomMatrix aMatrix;
+ aPoint *= ::canvas::tools::mergeViewAndRenderTransform(aMatrix,
+ rViewState,
+ rRenderState);
+
+ return ::vcl::unotools::pointFromB2DPoint( aPoint );
+ }
+
+ ::PolyPolygon mapPolyPolygon( const ::PolyPolygon& rPoly,
+ const rendering::ViewState& rViewState,
+ const rendering::RenderState& rRenderState )
+ {
+ PolyPolygon aRes;
+ ::basegfx::B2DHomMatrix aMatrix;
+ ::canvas::tools::mergeViewAndRenderTransform(aMatrix,
+ rViewState,
+ rRenderState);
+
+ int nCurrPoly, nCurrPoint;
+ for( nCurrPoly=0; nCurrPoly<rPoly.Count(); ++nCurrPoly )
+ {
+ Polygon aDest(rPoly[nCurrPoly].GetSize());
+
+ for( nCurrPoint=0; nCurrPoint<aDest.GetSize(); ++nCurrPoint )
+ {
+ ::basegfx::B2DPoint aPoint( ::vcl::unotools::b2DPointFromPoint( rPoly[nCurrPoly][nCurrPoint] ) );
+
+ aPoint *= aMatrix;
+
+ aDest[nCurrPoint] = ::vcl::unotools::pointFromB2DPoint( aPoint );
+ }
+
+ aRes.Insert(aDest);
+ }
+
+ return aRes;
+ }
+
+ ::BitmapEx transformBitmap( const BitmapEx& rBitmap,
+ const rendering::ViewState& rViewState,
+ const rendering::RenderState& rRenderState )
+ {
+ // calc transformation and size of bitmap to be
+ // generated. Note, that the translational components are
+ // deleted from the transformation; this can be handled by
+ // an offset when painting the bitmap
+ ::basegfx::B2DHomMatrix aTransform;
+ ::canvas::tools::mergeViewAndRenderTransform(aTransform,
+ rViewState,
+ rRenderState);
+ aTransform.set(0,2,0.0);
+ aTransform.set(1,2,0.0);
+
+ const Size aBmpSize( rBitmap.GetSizePixel() );
+ ::basegfx::B2DRectangle aDestRect;
+
+ bool bCopyBack( false );
+
+ ::canvas::tools::calcTransformedRectBounds( aDestRect,
+ ::basegfx::B2DRectangle(0,
+ 0,
+ aBmpSize.Width(),
+ aBmpSize.Height()),
+ aTransform );
+
+ Bitmap aSrcBitmap( rBitmap.GetBitmap() );
+ Bitmap aSrcAlpha;
+
+ // differentiate mask and alpha channel (on-off
+ // vs. multi-level transparency)
+ if( rBitmap.IsTransparent() )
+ {
+ if( rBitmap.IsAlpha() )
+ aSrcAlpha = rBitmap.GetAlpha().GetBitmap();
+ else
+ aSrcAlpha = rBitmap.GetMask();
+ }
+
+ Bitmap aDstBitmap( aSrcBitmap );
+ Bitmap aDstAlpha( rBitmap.IsTransparent() ? aSrcAlpha : Bitmap( Size(1,1), 8) );
+ aDstBitmap.SetSizePixel( Size( FRound( aDestRect.getMaxX() ),
+ FRound( aDestRect.getMaxY() ) ) );
+ aDstAlpha.SetSizePixel( Size(FRound( aDestRect.getMaxX() ),
+ FRound( aDestRect.getMaxY() ) ) );
+ {
+ // just to be on the safe side: let the
+ // ScopedAccessors get destructed before
+ // copy-constructing the resulting bitmap. This will
+ // rule out the possibility that cached accessor data
+ // is not yet written back.
+ ScopedBitmapReadAccess pReadAccess( aSrcBitmap.AcquireReadAccess(),
+ aSrcBitmap );
+ ScopedBitmapReadAccess pAlphaReadAccess( rBitmap.IsTransparent() ? aSrcAlpha.AcquireReadAccess() : NULL,
+ aSrcAlpha );
+
+ ScopedBitmapWriteAccess pWriteAccess( aDstBitmap.AcquireWriteAccess(),
+ aDstBitmap );
+ ScopedBitmapWriteAccess pAlphaWriteAccess( aDstAlpha.AcquireWriteAccess(),
+ aDstAlpha );
+
+
+ if( pReadAccess.get() != NULL &&
+ (pAlphaReadAccess.get() != NULL || !rBitmap.IsTransparent()) &&
+ pWriteAccess.get() != NULL &&
+ pAlphaWriteAccess.get() != NULL &&
+ aTransform.isInvertible() )
+ {
+ // we're doing inverse mapping here, i.e. mapping
+ // points from the destination bitmap back to the
+ // source
+ aTransform.invert();
+
+ const Size aDestBmpSize( aDstBitmap.GetSizePixel() );
+
+ // for the time being, always read as ARGB
+ for( int y=0; y<aDestBmpSize.Height(); ++y )
+ {
+ // differentiate mask and alpha channel (on-off
+ // vs. multi-level transparency)
+ if( rBitmap.IsTransparent() )
+ {
+ // Handling alpha and mask just the same...
+ for( int x=0; x<aDestBmpSize.Width(); ++x )
+ {
+ ::basegfx::B2DPoint aPoint(x,y);
+ aPoint *= aTransform;
+
+ const int nSrcX( FRound( aPoint.getX() + .5 ) );
+ const int nSrcY( FRound( aPoint.getY() + .5 ) );
+ if( nSrcX < 0 || nSrcX >= aBmpSize.Width() ||
+ nSrcY < 0 || nSrcX >= aBmpSize.Height() )
+ {
+ pAlphaWriteAccess->SetPixel( y, x, BitmapColor(255) );
+ }
+ else
+ {
+ pAlphaWriteAccess->SetPixel( y, x, pAlphaReadAccess->GetPixel( nSrcY,
+ nSrcX ) );
+ pWriteAccess->SetPixel( y, x, pReadAccess->GetPixel( nSrcY,
+ nSrcX ) );
+ }
+ }
+ }
+ else
+ {
+ for( int x=0; x<aDestBmpSize.Width(); ++x )
+ {
+ ::basegfx::B2DPoint aPoint(x,y);
+ aPoint *= aTransform;
+
+ const int nSrcX( FRound( aPoint.getX() + .5 ) );
+ const int nSrcY( FRound( aPoint.getY() + .5 ) );
+ if( nSrcX < 0 || nSrcX >= aBmpSize.Width() ||
+ nSrcY < 0 || nSrcX >= aBmpSize.Height() )
+ {
+ pAlphaWriteAccess->SetPixel( y, x, BitmapColor(255) );
+ }
+ else
+ {
+ pAlphaWriteAccess->SetPixel( y, x, BitmapColor(0) );
+ pWriteAccess->SetPixel( y, x, pReadAccess->GetPixel( nSrcY,
+ nSrcX ) );
+ }
+ }
+ }
+ }
+
+ bCopyBack = true;
+ }
+ else
+ {
+ // TODO: Error handling!
+ }
+ }
+
+ if( bCopyBack )
+ return BitmapEx( aDstBitmap, AlphaMask( aDstAlpha ) );
+ else
+ return BitmapEx();
+ }
+ }
+}