diff options
Diffstat (limited to 'canvas/source/vcl/impltools.cxx')
-rw-r--r-- | canvas/source/vcl/impltools.cxx | 414 |
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(); + } + } +} |