diff options
Diffstat (limited to 'canvas/source/vcl/canvashelper.cxx')
-rw-r--r-- | canvas/source/vcl/canvashelper.cxx | 1428 |
1 files changed, 0 insertions, 1428 deletions
diff --git a/canvas/source/vcl/canvashelper.cxx b/canvas/source/vcl/canvashelper.cxx deleted file mode 100644 index 63afce2376..0000000000 --- a/canvas/source/vcl/canvashelper.cxx +++ /dev/null @@ -1,1428 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/************************************************************************* - * - * 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_canvas.hxx" - -#include <canvas/debug.hxx> -#include <tools/diagnose_ex.h> - -#include <rtl/math.hxx> - -#include <com/sun/star/rendering/CompositeOperation.hpp> -#include <com/sun/star/util/Endianness.hpp> -#include <com/sun/star/rendering/TextDirection.hpp> -#include <com/sun/star/rendering/TexturingMode.hpp> -#include <com/sun/star/rendering/PathCapType.hpp> -#include <com/sun/star/rendering/PathJoinType.hpp> - -#include <tools/poly.hxx> -#include <vcl/window.hxx> -#include <vcl/bitmapex.hxx> -#include <vcl/bmpacc.hxx> -#include <vcl/canvastools.hxx> - -#include <basegfx/matrix/b2dhommatrix.hxx> -#include <basegfx/range/b2drectangle.hxx> -#include <basegfx/point/b2dpoint.hxx> -#include <basegfx/vector/b2dsize.hxx> -#include <basegfx/polygon/b2dpolygon.hxx> -#include <basegfx/polygon/b2dpolygontools.hxx> -#include <basegfx/polygon/b2dpolypolygontools.hxx> -#include <basegfx/polygon/b2dlinegeometry.hxx> -#include <basegfx/tools/canvastools.hxx> -#include <basegfx/numeric/ftools.hxx> - -#include <utility> - -#include <comphelper/sequence.hxx> -#include <canvas/canvastools.hxx> - -#include "textlayout.hxx" -#include "canvashelper.hxx" -#include "canvasbitmap.hxx" -#include "impltools.hxx" -#include "canvasfont.hxx" - - -using namespace ::com::sun::star; - -namespace vclcanvas -{ - namespace - { - basegfx::B2DLineJoin b2DJoineFromJoin( sal_Int8 nJoinType ) - { - switch( nJoinType ) - { - case rendering::PathJoinType::NONE: - return basegfx::B2DLINEJOIN_NONE; - - case rendering::PathJoinType::MITER: - return basegfx::B2DLINEJOIN_MITER; - - case rendering::PathJoinType::ROUND: - return basegfx::B2DLINEJOIN_ROUND; - - case rendering::PathJoinType::BEVEL: - return basegfx::B2DLINEJOIN_BEVEL; - - default: - ENSURE_OR_THROW( false, - "b2DJoineFromJoin(): Unexpected join type" ); - } - - return basegfx::B2DLINEJOIN_NONE; - } - } - - CanvasHelper::CanvasHelper() : - mpDevice(), - mpProtectedOutDev(), - mpOutDev(), - mp2ndOutDev(), - mbHaveAlpha( false ) - { - } - - void CanvasHelper::disposing() - { - mpDevice = NULL; - mpProtectedOutDev.reset(); - mpOutDev.reset(); - mp2ndOutDev.reset(); - } - - void CanvasHelper::init( rendering::XGraphicDevice& rDevice, - const OutDevProviderSharedPtr& rOutDev, - bool bProtect, - bool bHaveAlpha ) - { - // cast away const, need to change refcount (as this is - // ~invisible to client code, still logically const) - mpDevice = &rDevice; - mbHaveAlpha = bHaveAlpha; - - setOutDev( rOutDev, bProtect ); - } - - void CanvasHelper::setOutDev( const OutDevProviderSharedPtr& rOutDev, - bool bProtect ) - { - if( bProtect ) - mpProtectedOutDev = rOutDev; - else - mpProtectedOutDev.reset(); - - mpOutDev = rOutDev; - } - - void CanvasHelper::setBackgroundOutDev( const OutDevProviderSharedPtr& rOutDev ) - { - mp2ndOutDev = rOutDev; - mp2ndOutDev->getOutDev().EnableMapMode( sal_False ); - } - - void CanvasHelper::clear() - { - // are we disposed? - if( mpOutDev ) - { - OutputDevice& rOutDev( mpOutDev->getOutDev() ); - tools::OutDevStateKeeper aStateKeeper( mpProtectedOutDev ); - - rOutDev.EnableMapMode( sal_False ); - rOutDev.SetLineColor( COL_TRANSPARENT ); - rOutDev.SetFillColor( COL_TRANSPARENT ); - rOutDev.DrawRect( Rectangle( Point(), - rOutDev.GetOutputSizePixel()) ); - - if( mp2ndOutDev ) - { - OutputDevice& rOutDev2( mp2ndOutDev->getOutDev() ); - - rOutDev2.SetDrawMode( DRAWMODE_DEFAULT ); - rOutDev2.EnableMapMode( sal_False ); - rOutDev2.SetLineColor( COL_TRANSPARENT ); - rOutDev2.SetFillColor( COL_TRANSPARENT ); - rOutDev2.DrawRect( Rectangle( Point(), - rOutDev2.GetOutputSizePixel()) ); - rOutDev2.SetDrawMode( DRAWMODE_BLACKLINE | DRAWMODE_BLACKFILL | DRAWMODE_BLACKTEXT | - DRAWMODE_BLACKGRADIENT | DRAWMODE_BLACKBITMAP ); - } - } - } - - void CanvasHelper::drawPoint( const rendering::XCanvas* , - const geometry::RealPoint2D& aPoint, - const rendering::ViewState& viewState, - const rendering::RenderState& renderState ) - { - // are we disposed? - if( mpOutDev ) - { - // nope, render - tools::OutDevStateKeeper aStateKeeper( mpProtectedOutDev ); - setupOutDevState( viewState, renderState, LINE_COLOR ); - - const Point aOutPoint( tools::mapRealPoint2D( aPoint, - viewState, renderState ) ); - // TODO(F1): alpha - mpOutDev->getOutDev().DrawPixel( aOutPoint ); - - if( mp2ndOutDev ) - mp2ndOutDev->getOutDev().DrawPixel( aOutPoint ); - } - } - - void CanvasHelper::drawLine( const rendering::XCanvas* , - const geometry::RealPoint2D& aStartRealPoint2D, - const geometry::RealPoint2D& aEndRealPoint2D, - const rendering::ViewState& viewState, - const rendering::RenderState& renderState ) - { - // are we disposed? - if( mpOutDev ) - { - // nope, render - tools::OutDevStateKeeper aStateKeeper( mpProtectedOutDev ); - setupOutDevState( viewState, renderState, LINE_COLOR ); - - const Point aStartPoint( tools::mapRealPoint2D( aStartRealPoint2D, - viewState, renderState ) ); - const Point aEndPoint( tools::mapRealPoint2D( aEndRealPoint2D, - viewState, renderState ) ); - // TODO(F2): alpha - mpOutDev->getOutDev().DrawLine( aStartPoint, aEndPoint ); - - if( mp2ndOutDev ) - mp2ndOutDev->getOutDev().DrawLine( aStartPoint, aEndPoint ); - } - } - - void CanvasHelper::drawBezier( const rendering::XCanvas* , - const geometry::RealBezierSegment2D& aBezierSegment, - const geometry::RealPoint2D& _aEndPoint, - const rendering::ViewState& viewState, - const rendering::RenderState& renderState ) - { - if( mpOutDev ) - { - tools::OutDevStateKeeper aStateKeeper( mpProtectedOutDev ); - setupOutDevState( viewState, renderState, LINE_COLOR ); - - const Point& rStartPoint( tools::mapRealPoint2D( geometry::RealPoint2D(aBezierSegment.Px, - aBezierSegment.Py), - viewState, renderState ) ); - const Point& rCtrlPoint1( tools::mapRealPoint2D( geometry::RealPoint2D(aBezierSegment.C1x, - aBezierSegment.C1y), - viewState, renderState ) ); - const Point& rCtrlPoint2( tools::mapRealPoint2D( geometry::RealPoint2D(aBezierSegment.C2x, - aBezierSegment.C2y), - viewState, renderState ) ); - const Point& rEndPoint( tools::mapRealPoint2D( _aEndPoint, - viewState, renderState ) ); - - ::Polygon aPoly(4); - aPoly.SetPoint( rStartPoint, 0 ); - aPoly.SetFlags( 0, POLY_NORMAL ); - aPoly.SetPoint( rCtrlPoint1, 1 ); - aPoly.SetFlags( 1, POLY_CONTROL ); - aPoly.SetPoint( rCtrlPoint2, 2 ); - aPoly.SetFlags( 2, POLY_CONTROL ); - aPoly.SetPoint( rEndPoint, 3 ); - aPoly.SetFlags( 3, POLY_NORMAL ); - - // TODO(F2): alpha - mpOutDev->getOutDev().DrawPolygon( aPoly ); - if( mp2ndOutDev ) - mp2ndOutDev->getOutDev().DrawPolygon( aPoly ); - } - } - - uno::Reference< rendering::XCachedPrimitive > CanvasHelper::drawPolyPolygon( const rendering::XCanvas* , - const uno::Reference< rendering::XPolyPolygon2D >& xPolyPolygon, - const rendering::ViewState& viewState, - const rendering::RenderState& renderState ) - { - ENSURE_ARG_OR_THROW( xPolyPolygon.is(), - "polygon is NULL"); - - if( mpOutDev ) - { - tools::OutDevStateKeeper aStateKeeper( mpProtectedOutDev ); - setupOutDevState( viewState, renderState, LINE_COLOR ); - - const ::basegfx::B2DPolyPolygon& rPolyPoly( - ::basegfx::unotools::b2DPolyPolygonFromXPolyPolygon2D(xPolyPolygon) ); - const PolyPolygon aPolyPoly( tools::mapPolyPolygon( rPolyPoly, viewState, renderState ) ); - - if( rPolyPoly.isClosed() ) - { - mpOutDev->getOutDev().DrawPolyPolygon( aPolyPoly ); - - if( mp2ndOutDev ) - mp2ndOutDev->getOutDev().DrawPolyPolygon( aPolyPoly ); - } - else - { - // mixed open/closed state. Cannot render open polygon - // via DrawPolyPolygon(), since that implicitley - // closed every polygon. OTOH, no need to distinguish - // further and render closed polygons via - // DrawPolygon(), and open ones via DrawPolyLine(): - // closed polygons will simply already contain the - // closing segment. - sal_uInt16 nSize( aPolyPoly.Count() ); - - for( sal_uInt16 i=0; i<nSize; ++i ) - { - mpOutDev->getOutDev().DrawPolyLine( aPolyPoly[i] ); - - if( mp2ndOutDev ) - mp2ndOutDev->getOutDev().DrawPolyLine( aPolyPoly[i] ); - } - } - } - - // TODO(P1): Provide caching here. - return uno::Reference< rendering::XCachedPrimitive >(NULL); - } - - uno::Reference< rendering::XCachedPrimitive > CanvasHelper::strokePolyPolygon( const rendering::XCanvas* , - const uno::Reference< rendering::XPolyPolygon2D >& xPolyPolygon, - const rendering::ViewState& viewState, - const rendering::RenderState& renderState, - const rendering::StrokeAttributes& strokeAttributes ) - { - ENSURE_ARG_OR_THROW( xPolyPolygon.is(), - "polygon is NULL"); - - if( mpOutDev ) - { - tools::OutDevStateKeeper aStateKeeper( mpProtectedOutDev ); - - ::basegfx::B2DHomMatrix aMatrix; - ::canvas::tools::mergeViewAndRenderTransform(aMatrix, viewState, renderState); - - ::basegfx::B2DSize aLinePixelSize(strokeAttributes.StrokeWidth, - strokeAttributes.StrokeWidth); - aLinePixelSize *= aMatrix; - - ::basegfx::B2DPolyPolygon aPolyPoly( - ::basegfx::unotools::b2DPolyPolygonFromXPolyPolygon2D(xPolyPolygon) ); - - if( aPolyPoly.areControlPointsUsed() ) - { - // AW: Not needed for ApplyLineDashing anymore; should be removed - aPolyPoly = ::basegfx::tools::adaptiveSubdivideByAngle(aPolyPoly); - } - - // apply dashing, if any - if( strokeAttributes.DashArray.getLength() ) - { - const ::std::vector<double>& aDashArray( - ::comphelper::sequenceToContainer< ::std::vector<double> >(strokeAttributes.DashArray) ); - - ::basegfx::B2DPolyPolygon aDashedPolyPoly; - - for( sal_uInt32 i=0; i<aPolyPoly.count(); ++i ) - { - // AW: new interface; You may also get gaps in the same run now - basegfx::tools::applyLineDashing(aPolyPoly.getB2DPolygon(i), aDashArray, &aDashedPolyPoly); - //aDashedPolyPoly.append( - // ::basegfx::tools::applyLineDashing( aPolyPoly.getB2DPolygon(i), - // aDashArray ) ); - } - - aPolyPoly = aDashedPolyPoly; - } - - ::basegfx::B2DPolyPolygon aStrokedPolyPoly; - if( aLinePixelSize.getLength() < 1.42 ) - { - // line width < 1.0 in device pixel, thus, output as a - // simple hairline poly-polygon - setupOutDevState( viewState, renderState, LINE_COLOR ); - - aStrokedPolyPoly = aPolyPoly; - } - else - { - // render as a 'thick' line - setupOutDevState( viewState, renderState, FILL_COLOR ); - - for( sal_uInt32 i=0; i<aPolyPoly.count(); ++i ) - { - // TODO(F2): Use MiterLimit from StrokeAttributes, - // need to convert it here to angle. - - // TODO(F2): Also use Cap settings from - // StrokeAttributes, the - // createAreaGeometryForLineStartEnd() method does not - // seem to fit very well here - - // AW: New interface, will create bezier polygons now - aStrokedPolyPoly.append(basegfx::tools::createAreaGeometry( - aPolyPoly.getB2DPolygon(i), strokeAttributes.StrokeWidth*0.5, b2DJoineFromJoin(strokeAttributes.JoinType))); - //aStrokedPolyPoly.append( - // ::basegfx::tools::createAreaGeometryForPolygon( aPolyPoly.getB2DPolygon(i), - // strokeAttributes.StrokeWidth*0.5, - // b2DJoineFromJoin(strokeAttributes.JoinType) ) ); - } - } - - // transform only _now_, all the StrokeAttributes are in - // user coordinates. - aStrokedPolyPoly.transform( aMatrix ); - - const PolyPolygon aVCLPolyPoly( aStrokedPolyPoly ); - - // TODO(F2): When using alpha here, must handle that via - // temporary surface or somesuch. - - // Note: the generated stroke poly-polygon is NOT free of - // self-intersections. Therefore, if we would render it - // via OutDev::DrawPolyPolygon(), on/off fill would - // generate off areas on those self-intersections. - sal_uInt16 nSize( aVCLPolyPoly.Count() ); - - for( sal_uInt16 i=0; i<nSize; ++i ) - { - if( aStrokedPolyPoly.getB2DPolygon( i ).isClosed() ) { - mpOutDev->getOutDev().DrawPolygon( aVCLPolyPoly[i] ); - if( mp2ndOutDev ) - mp2ndOutDev->getOutDev().DrawPolygon( aVCLPolyPoly[i] ); - } else { - const sal_uInt16 nPolySize = aVCLPolyPoly[i].GetSize(); - if( nPolySize ) { - Point rPrevPoint = aVCLPolyPoly[i].GetPoint( 0 ); - Point rPoint; - - for( sal_uInt16 j=1; j<nPolySize; j++ ) { - rPoint = aVCLPolyPoly[i].GetPoint( j ); - mpOutDev->getOutDev().DrawLine( rPrevPoint, rPoint ); - if( mp2ndOutDev ) - mp2ndOutDev->getOutDev().DrawLine( rPrevPoint, rPoint ); - rPrevPoint = rPoint; - } - } - } - } - } - - // TODO(P1): Provide caching here. - return uno::Reference< rendering::XCachedPrimitive >(NULL); - } - - uno::Reference< rendering::XCachedPrimitive > CanvasHelper::strokeTexturedPolyPolygon( const rendering::XCanvas* , - const uno::Reference< rendering::XPolyPolygon2D >& , - const rendering::ViewState& , - const rendering::RenderState& , - const uno::Sequence< rendering::Texture >& , - const rendering::StrokeAttributes& ) - { - return uno::Reference< rendering::XCachedPrimitive >(NULL); - } - - uno::Reference< rendering::XCachedPrimitive > CanvasHelper::strokeTextureMappedPolyPolygon( const rendering::XCanvas* , - const uno::Reference< rendering::XPolyPolygon2D >& , - const rendering::ViewState& , - const rendering::RenderState& , - const uno::Sequence< rendering::Texture >& , - const uno::Reference< geometry::XMapping2D >& , - const rendering::StrokeAttributes& ) - { - return uno::Reference< rendering::XCachedPrimitive >(NULL); - } - - uno::Reference< rendering::XPolyPolygon2D > CanvasHelper::queryStrokeShapes( const rendering::XCanvas* , - const uno::Reference< rendering::XPolyPolygon2D >& , - const rendering::ViewState& , - const rendering::RenderState& , - const rendering::StrokeAttributes& ) - { - return uno::Reference< rendering::XPolyPolygon2D >(NULL); - } - - uno::Reference< rendering::XCachedPrimitive > CanvasHelper::fillPolyPolygon( const rendering::XCanvas* , - const uno::Reference< rendering::XPolyPolygon2D >& xPolyPolygon, - const rendering::ViewState& viewState, - const rendering::RenderState& renderState ) - { - ENSURE_ARG_OR_THROW( xPolyPolygon.is(), - "polygon is NULL"); - - if( mpOutDev ) - { - tools::OutDevStateKeeper aStateKeeper( mpProtectedOutDev ); - - const int nTransparency( setupOutDevState( viewState, renderState, FILL_COLOR ) ); - const int nTransPercent( (nTransparency * 100 + 128) / 255 ); // normal rounding, no truncation here - ::basegfx::B2DPolyPolygon aB2DPolyPoly( - ::basegfx::unotools::b2DPolyPolygonFromXPolyPolygon2D(xPolyPolygon)); - aB2DPolyPoly.setClosed(true); // ensure closed poly, otherwise VCL does not fill - const PolyPolygon aPolyPoly( tools::mapPolyPolygon( - aB2DPolyPoly, - viewState, renderState ) ); - const bool bSourceAlpha( renderState.CompositeOperation == rendering::CompositeOperation::SOURCE ); - if( !nTransparency || bSourceAlpha ) - { - mpOutDev->getOutDev().DrawPolyPolygon( aPolyPoly ); - } - else - { - mpOutDev->getOutDev().DrawTransparent( aPolyPoly, (sal_uInt16)nTransPercent ); - } - - if( mp2ndOutDev ) - { - if( !nTransparency || bSourceAlpha ) - { - // HACK. Normally, CanvasHelper does not care - // about actually what mp2ndOutDev is... - if( bSourceAlpha && nTransparency == 255 ) - { - mp2ndOutDev->getOutDev().SetDrawMode( DRAWMODE_WHITELINE | DRAWMODE_WHITEFILL | DRAWMODE_WHITETEXT | - DRAWMODE_WHITEGRADIENT | DRAWMODE_WHITEBITMAP ); - mp2ndOutDev->getOutDev().SetFillColor( COL_WHITE ); - mp2ndOutDev->getOutDev().DrawPolyPolygon( aPolyPoly ); - mp2ndOutDev->getOutDev().SetDrawMode( DRAWMODE_BLACKLINE | DRAWMODE_BLACKFILL | DRAWMODE_BLACKTEXT | - DRAWMODE_BLACKGRADIENT | DRAWMODE_BLACKBITMAP ); - } - else - { - mp2ndOutDev->getOutDev().DrawPolyPolygon( aPolyPoly ); - } - } - else - { - mp2ndOutDev->getOutDev().DrawTransparent( aPolyPoly, (sal_uInt16)nTransPercent ); - } - } - } - - // TODO(P1): Provide caching here. - return uno::Reference< rendering::XCachedPrimitive >(NULL); - } - - uno::Reference< rendering::XCachedPrimitive > CanvasHelper::fillTextureMappedPolyPolygon( const rendering::XCanvas* , - const uno::Reference< rendering::XPolyPolygon2D >& , - const rendering::ViewState& , - const rendering::RenderState& , - const uno::Sequence< rendering::Texture >& , - const uno::Reference< geometry::XMapping2D >& ) - { - return uno::Reference< rendering::XCachedPrimitive >(NULL); - } - - uno::Reference< rendering::XCanvasFont > CanvasHelper::createFont( const rendering::XCanvas* , - const rendering::FontRequest& fontRequest, - const uno::Sequence< beans::PropertyValue >& extraFontProperties, - const geometry::Matrix2D& fontMatrix ) - { - if( mpOutDev && mpDevice ) - { - // TODO(F2): font properties and font matrix - return uno::Reference< rendering::XCanvasFont >( - new CanvasFont(fontRequest, extraFontProperties, fontMatrix, - *mpDevice, mpOutDev) ); - } - - return uno::Reference< rendering::XCanvasFont >(); - } - - uno::Sequence< rendering::FontInfo > CanvasHelper::queryAvailableFonts( const rendering::XCanvas* , - const rendering::FontInfo& , - const uno::Sequence< beans::PropertyValue >& ) - { - // TODO(F2) - return uno::Sequence< rendering::FontInfo >(); - } - - uno::Reference< rendering::XCachedPrimitive > CanvasHelper::drawText( const rendering::XCanvas* , - const rendering::StringContext& text, - const uno::Reference< rendering::XCanvasFont >& xFont, - const rendering::ViewState& viewState, - const rendering::RenderState& renderState, - sal_Int8 textDirection ) - { - ENSURE_ARG_OR_THROW( xFont.is(), - "font is NULL"); - - if( mpOutDev ) - { - tools::OutDevStateKeeper aStateKeeper( mpProtectedOutDev ); - - ::Point aOutpos; - if( !setupTextOutput( aOutpos, viewState, renderState, xFont ) ) - return uno::Reference< rendering::XCachedPrimitive >(NULL); // no output necessary - - // change text direction and layout mode - sal_uIntPtr nLayoutMode(0); - switch( textDirection ) - { - case rendering::TextDirection::WEAK_LEFT_TO_RIGHT: - nLayoutMode |= TEXT_LAYOUT_BIDI_LTR; - // FALLTHROUGH intended - case rendering::TextDirection::STRONG_LEFT_TO_RIGHT: - nLayoutMode |= TEXT_LAYOUT_BIDI_LTR | TEXT_LAYOUT_BIDI_STRONG; - nLayoutMode |= TEXT_LAYOUT_TEXTORIGIN_LEFT; - break; - - case rendering::TextDirection::WEAK_RIGHT_TO_LEFT: - nLayoutMode |= TEXT_LAYOUT_BIDI_RTL; - // FALLTHROUGH intended - case rendering::TextDirection::STRONG_RIGHT_TO_LEFT: - nLayoutMode |= TEXT_LAYOUT_BIDI_RTL | TEXT_LAYOUT_BIDI_STRONG; - nLayoutMode |= TEXT_LAYOUT_TEXTORIGIN_RIGHT; - break; - } - - // TODO(F2): alpha - mpOutDev->getOutDev().SetLayoutMode( nLayoutMode ); - mpOutDev->getOutDev().DrawText( aOutpos, - text.Text, - ::canvas::tools::numeric_cast<sal_uInt16>(text.StartPosition), - ::canvas::tools::numeric_cast<sal_uInt16>(text.Length) ); - - if( mp2ndOutDev ) - { - mp2ndOutDev->getOutDev().SetLayoutMode( nLayoutMode ); - mp2ndOutDev->getOutDev().DrawText( aOutpos, - text.Text, - ::canvas::tools::numeric_cast<sal_uInt16>(text.StartPosition), - ::canvas::tools::numeric_cast<sal_uInt16>(text.Length) ); - } - } - - return uno::Reference< rendering::XCachedPrimitive >(NULL); - } - - uno::Reference< rendering::XCachedPrimitive > CanvasHelper::drawTextLayout( const rendering::XCanvas* , - const uno::Reference< rendering::XTextLayout >& xLayoutedText, - const rendering::ViewState& viewState, - const rendering::RenderState& renderState ) - { - ENSURE_ARG_OR_THROW( xLayoutedText.is(), - "layout is NULL"); - - TextLayout* pTextLayout = dynamic_cast< TextLayout* >( xLayoutedText.get() ); - - if( pTextLayout ) - { - if( mpOutDev ) - { - tools::OutDevStateKeeper aStateKeeper( mpProtectedOutDev ); - - // TODO(T3): Race condition. We're taking the font - // from xLayoutedText, and then calling draw() at it, - // without exclusive access. Move setupTextOutput(), - // e.g. to impltools? - - ::Point aOutpos; - if( !setupTextOutput( aOutpos, viewState, renderState, xLayoutedText->getFont() ) ) - return uno::Reference< rendering::XCachedPrimitive >(NULL); // no output necessary - - // TODO(F2): What about the offset scalings? - // TODO(F2): alpha - pTextLayout->draw( mpOutDev->getOutDev(), aOutpos, viewState, renderState ); - - if( mp2ndOutDev ) - pTextLayout->draw( mp2ndOutDev->getOutDev(), aOutpos, viewState, renderState ); - } - } - else - { - ENSURE_ARG_OR_THROW( false, - "TextLayout not compatible with this canvas" ); - } - - return uno::Reference< rendering::XCachedPrimitive >(NULL); - } - - uno::Reference< rendering::XCachedPrimitive > CanvasHelper::implDrawBitmap( const rendering::XCanvas* pCanvas, - const uno::Reference< rendering::XBitmap >& xBitmap, - const rendering::ViewState& viewState, - const rendering::RenderState& renderState, - bool bModulateColors ) - { - ENSURE_ARG_OR_THROW( xBitmap.is(), - "bitmap is NULL"); - - ::canvas::tools::verifyInput( renderState, - BOOST_CURRENT_FUNCTION, - mpDevice, - 4, - bModulateColors ? 3 : 0 ); - - if( mpOutDev ) - { - tools::OutDevStateKeeper aStateKeeper( mpProtectedOutDev ); - setupOutDevState( viewState, renderState, IGNORE_COLOR ); - - ::basegfx::B2DHomMatrix aMatrix; - ::canvas::tools::mergeViewAndRenderTransform(aMatrix, viewState, renderState); - - ::basegfx::B2DPoint aOutputPos( 0.0, 0.0 ); - aOutputPos *= aMatrix; - - BitmapEx aBmpEx( tools::bitmapExFromXBitmap(xBitmap) ); - - // TODO(F2): Implement modulation again for other color - // channels (currently, works only for alpha). Note: this - // is already implemented in transformBitmap() - if( bModulateColors && - renderState.DeviceColor.getLength() > 3 ) - { - // optimize away the case where alpha modulation value - // is 1.0 - we then simply switch off modulation at all - bModulateColors = !::rtl::math::approxEqual( - renderState.DeviceColor[3], 1.0); - } - - // check whether we can render bitmap as-is: must not - // modulate colors, matrix must either be the identity - // transform (that's clear), _or_ contain only - // translational components. - if( !bModulateColors && - (aMatrix.isIdentity() || - (::basegfx::fTools::equalZero( aMatrix.get(0,1) ) && - ::basegfx::fTools::equalZero( aMatrix.get(1,0) ) && - ::rtl::math::approxEqual(aMatrix.get(0,0), 1.0) && - ::rtl::math::approxEqual(aMatrix.get(1,1), 1.0)) ) ) - { - // optimized case: identity matrix, or only - // translational components. - mpOutDev->getOutDev().DrawBitmapEx( ::vcl::unotools::pointFromB2DPoint( aOutputPos ), - aBmpEx ); - - if( mp2ndOutDev ) - mp2ndOutDev->getOutDev().DrawBitmapEx( ::vcl::unotools::pointFromB2DPoint( aOutputPos ), - aBmpEx ); - - // Returning a cache object is not useful, the XBitmap - // itself serves this purpose - return uno::Reference< rendering::XCachedPrimitive >(NULL); - } - else - { - // Matrix contains non-trivial transformation (or - // color modulation is requested), decompose to check - // whether GraphicObject suffices - ::basegfx::B2DVector aScale; - double nRotate; - double nShearX; - aMatrix.decompose( aScale, aOutputPos, nRotate, nShearX ); - - GraphicAttr aGrfAttr; - GraphicObjectSharedPtr pGrfObj; - - ::Size aBmpSize( aBmpEx.GetSizePixel() ); - - // setup alpha modulation - if( bModulateColors ) - { - const double nAlphaModulation( renderState.DeviceColor[3] ); - - // TODO(F1): Note that the GraphicManager has a - // subtle difference in how it calculates the - // resulting alpha value: it's using the inverse - // alpha values (i.e. 'transparency'), and - // calculates transOrig + transModulate, instead - // of transOrig + transModulate - - // transOrig*transModulate (which would be - // equivalent to the origAlpha*modulateAlpha the - // DX canvas performs) - aGrfAttr.SetTransparency( - static_cast< sal_uInt8 >( - ::basegfx::fround( 255.0*( 1.0 - nAlphaModulation ) ) ) ); - } - - if( ::basegfx::fTools::equalZero( nShearX ) ) - { - // no shear, GraphicObject is enough (the - // GraphicObject only supports scaling, rotation - // and translation) - - // #i75339# don't apply mirror flags, having - // negative size values is enough to make - // GraphicObject flip the bitmap - - // The angle has to be mapped from radian to tenths of - // degress with the orientation reversed: [0,2Pi) -> - // (3600,0]. Note that the original angle may have - // values outside the [0,2Pi) interval. - const double nAngleInTenthOfDegrees (3600.0 - nRotate * 3600.0 / (2*M_PI)); - aGrfAttr.SetRotation( static_cast< sal_uInt16 >(::basegfx::fround(nAngleInTenthOfDegrees)) ); - - pGrfObj.reset( new GraphicObject( aBmpEx ) ); - } - else - { - // modify output position, to account for the fact - // that transformBitmap() always normalizes its output - // bitmap into the smallest enclosing box. - ::basegfx::B2DRectangle aDestRect; - ::canvas::tools::calcTransformedRectBounds( aDestRect, - ::basegfx::B2DRectangle(0, - 0, - aBmpSize.Width(), - aBmpSize.Height()), - aMatrix ); - - aOutputPos.setX( aDestRect.getMinX() ); - aOutputPos.setY( aDestRect.getMinY() ); - - // complex transformation, use generic affine bitmap - // transformation - aBmpEx = tools::transformBitmap( aBmpEx, - aMatrix, - renderState.DeviceColor, - tools::MODULATE_NONE ); - - pGrfObj.reset( new GraphicObject( aBmpEx ) ); - - // clear scale values, generated bitmap already - // contains scaling - aScale.setX( 1.0 ); aScale.setY( 1.0 ); - - // update bitmap size, bitmap has changed above. - aBmpSize = aBmpEx.GetSizePixel(); - } - - // output GraphicObject - const ::Point aPt( ::vcl::unotools::pointFromB2DPoint( aOutputPos ) ); - const ::Size aSz( ::basegfx::fround( aScale.getX() * aBmpSize.Width() ), - ::basegfx::fround( aScale.getY() * aBmpSize.Height() ) ); - - pGrfObj->Draw( &mpOutDev->getOutDev(), - aPt, - aSz, - &aGrfAttr ); - - if( mp2ndOutDev ) - pGrfObj->Draw( &mp2ndOutDev->getOutDev(), - aPt, - aSz, - &aGrfAttr ); - - // created GraphicObject, which possibly cached - // display bitmap - return cache object, to retain - // that information. - return uno::Reference< rendering::XCachedPrimitive >( - new CachedBitmap( pGrfObj, - aPt, - aSz, - aGrfAttr, - viewState, - renderState, - // cast away const, need to - // change refcount (as this is - // ~invisible to client code, - // still logically const) - const_cast< rendering::XCanvas* >(pCanvas)) ); - } - } - - // Nothing rendered - return uno::Reference< rendering::XCachedPrimitive >(NULL); - } - - uno::Reference< rendering::XCachedPrimitive > CanvasHelper::drawBitmap( const rendering::XCanvas* pCanvas, - const uno::Reference< rendering::XBitmap >& xBitmap, - const rendering::ViewState& viewState, - const rendering::RenderState& renderState ) - { - return implDrawBitmap( pCanvas, - xBitmap, - viewState, - renderState, - false ); - } - - uno::Reference< rendering::XCachedPrimitive > CanvasHelper::drawBitmapModulated( const rendering::XCanvas* pCanvas, - const uno::Reference< rendering::XBitmap >& xBitmap, - const rendering::ViewState& viewState, - const rendering::RenderState& renderState ) - { - return implDrawBitmap( pCanvas, - xBitmap, - viewState, - renderState, - true ); - } - - uno::Reference< rendering::XGraphicDevice > CanvasHelper::getDevice() - { - // cast away const, need to change refcount (as this is - // ~invisible to client code, still logically const) - return uno::Reference< rendering::XGraphicDevice >(mpDevice); - } - - void CanvasHelper::copyRect( const rendering::XCanvas* , - const uno::Reference< rendering::XBitmapCanvas >& , - const geometry::RealRectangle2D& , - const rendering::ViewState& , - const rendering::RenderState& , - const geometry::RealRectangle2D& , - const rendering::ViewState& , - const rendering::RenderState& ) - { - // TODO(F1) - } - - geometry::IntegerSize2D CanvasHelper::getSize() - { - if( !mpOutDev.get() ) - return geometry::IntegerSize2D(); // we're disposed - - return ::vcl::unotools::integerSize2DFromSize( mpOutDev->getOutDev().GetOutputSizePixel() ); - } - - uno::Reference< rendering::XBitmap > CanvasHelper::getScaledBitmap( const geometry::RealSize2D& newSize, - sal_Bool beFast ) - { - if( !mpOutDev.get() || !mpDevice ) - return uno::Reference< rendering::XBitmap >(); // we're disposed - - OutputDevice& rOutDev( mpOutDev->getOutDev() ); - - tools::OutDevStateKeeper aStateKeeper( mpProtectedOutDev ); - rOutDev.EnableMapMode( sal_False ); - - // TODO(F2): Support alpha vdev canvas here - const Point aEmptyPoint(0,0); - const Size aBmpSize( rOutDev.GetOutputSizePixel() ); - - Bitmap aBitmap( rOutDev.GetBitmap(aEmptyPoint, aBmpSize) ); - - aBitmap.Scale( ::vcl::unotools::sizeFromRealSize2D(newSize), - beFast ? BMP_SCALE_FAST : BMP_SCALE_INTERPOLATE ); - - return uno::Reference< rendering::XBitmap >( - new CanvasBitmap( aBitmap, *mpDevice, mpOutDev ) ); - } - - uno::Sequence< sal_Int8 > CanvasHelper::getData( rendering::IntegerBitmapLayout& rLayout, - const geometry::IntegerRectangle2D& rect ) - { - if( !mpOutDev.get() ) - return uno::Sequence< sal_Int8 >(); // we're disposed - - rLayout = getMemoryLayout(); - - // TODO(F2): Support alpha canvas here - const Rectangle aRect( ::vcl::unotools::rectangleFromIntegerRectangle2D(rect) ); - - OutputDevice& rOutDev( mpOutDev->getOutDev() ); - - tools::OutDevStateKeeper aStateKeeper( mpProtectedOutDev ); - rOutDev.EnableMapMode( sal_False ); - - Bitmap aBitmap( rOutDev.GetBitmap(aRect.TopLeft(), - aRect.GetSize()) ); - - Bitmap::ScopedReadAccess pReadAccess( aBitmap ); - - ENSURE_OR_THROW( pReadAccess.get() != NULL, - "Could not acquire read access to OutDev bitmap" ); - - const sal_Int32 nWidth( rect.X2 - rect.X1 ); - const sal_Int32 nHeight( rect.Y2 - rect.Y1 ); - - rLayout.ScanLines = nHeight; - rLayout.ScanLineBytes = nWidth*4; - rLayout.ScanLineStride = rLayout.ScanLineBytes; - - uno::Sequence< sal_Int8 > aRes( 4*nWidth*nHeight ); - sal_Int8* pRes = aRes.getArray(); - - int nCurrPos(0); - for( int y=0; y<nHeight; ++y ) - { - for( int x=0; x<nWidth; ++x ) - { - pRes[ nCurrPos++ ] = pReadAccess->GetColor( y, x ).GetRed(); - pRes[ nCurrPos++ ] = pReadAccess->GetColor( y, x ).GetGreen(); - pRes[ nCurrPos++ ] = pReadAccess->GetColor( y, x ).GetBlue(); - pRes[ nCurrPos++ ] = -1; - } - } - - return aRes; - } - - void CanvasHelper::setData( const uno::Sequence< sal_Int8 >& data, - const rendering::IntegerBitmapLayout& aLayout, - const geometry::IntegerRectangle2D& rect ) - { - if( !mpOutDev.get() ) - return; // we're disposed - - const rendering::IntegerBitmapLayout aRefLayout( getMemoryLayout() ); - ENSURE_ARG_OR_THROW( aRefLayout.PlaneStride != aLayout.PlaneStride || - aRefLayout.ColorSpace != aLayout.ColorSpace || - aRefLayout.Palette != aLayout.Palette || - aRefLayout.IsMsbFirst != aLayout.IsMsbFirst, - "Mismatching memory layout" ); - - OutputDevice& rOutDev( mpOutDev->getOutDev() ); - - tools::OutDevStateKeeper aStateKeeper( mpProtectedOutDev ); - rOutDev.EnableMapMode( sal_False ); - - const Rectangle aRect( ::vcl::unotools::rectangleFromIntegerRectangle2D(rect) ); - const sal_uInt16 nBitCount( ::std::min( (sal_uInt16)24U, - (sal_uInt16)rOutDev.GetBitCount() ) ); - const BitmapPalette* pPalette = NULL; - - if( nBitCount <= 8 ) - { - // TODO(Q1): Extract this to a common place, e.g. GraphicDevice - - // try to determine palette from output device (by - // extracting a 1,1 bitmap, and querying it) - const Point aEmptyPoint; - const Size aSize(1,1); - Bitmap aTmpBitmap( rOutDev.GetBitmap( aEmptyPoint, - aSize ) ); - - Bitmap::ScopedReadAccess pReadAccess( aTmpBitmap ); - - pPalette = &pReadAccess->GetPalette(); - } - - // TODO(F2): Support alpha canvas here - Bitmap aBitmap( aRect.GetSize(), nBitCount, pPalette ); - - bool bCopyBack( false ); // only copy something back, if we - // actually changed some pixel - { - Bitmap::ScopedWriteAccess pWriteAccess( aBitmap ); - - ENSURE_OR_THROW( pWriteAccess.get() != NULL, - "Could not acquire write access to OutDev bitmap" ); - - // for the time being, always read as RGB - const sal_Int32 nWidth( rect.X2 - rect.X1 ); - const sal_Int32 nHeight( rect.Y2 - rect.Y1 ); - int x, y, nCurrPos(0); - for( y=0; y<nHeight; ++y ) - { - switch( pWriteAccess->GetScanlineFormat() ) - { - case BMP_FORMAT_8BIT_PAL: - { - Scanline pScan = pWriteAccess->GetScanline( y ); - - for( x=0; x<nWidth; ++x ) - { - *pScan++ = (sal_uInt8)pWriteAccess->GetBestPaletteIndex( - BitmapColor( data[ nCurrPos ], - data[ nCurrPos+1 ], - data[ nCurrPos+2 ] ) ); - - nCurrPos += 4; - } - } - break; - - case BMP_FORMAT_24BIT_TC_BGR: - { - Scanline pScan = pWriteAccess->GetScanline( y ); - - for( x=0; x<nWidth; ++x ) - { - *pScan++ = data[ nCurrPos+2 ]; - *pScan++ = data[ nCurrPos+1 ]; - *pScan++ = data[ nCurrPos ]; - - nCurrPos += 4; - } - } - break; - - case BMP_FORMAT_24BIT_TC_RGB: - { - Scanline pScan = pWriteAccess->GetScanline( y ); - - for( x=0; x<nWidth; ++x ) - { - *pScan++ = data[ nCurrPos ]; - *pScan++ = data[ nCurrPos+1 ]; - *pScan++ = data[ nCurrPos+2 ]; - - nCurrPos += 4; - } - } - break; - - default: - { - for( x=0; x<nWidth; ++x ) - { - pWriteAccess->SetPixel( y, x, BitmapColor( data[ nCurrPos ], - data[ nCurrPos+1 ], - data[ nCurrPos+2 ] ) ); - nCurrPos += 4; - } - } - break; - } - } - - bCopyBack = true; - } - - // copy back only here, since the BitmapAccessors must be - // destroyed beforehand - if( bCopyBack ) - { - // TODO(F2): Support alpha canvas here - rOutDev.DrawBitmap(aRect.TopLeft(), aBitmap); - } - } - - void CanvasHelper::setPixel( const uno::Sequence< sal_Int8 >& color, - const rendering::IntegerBitmapLayout& rLayout, - const geometry::IntegerPoint2D& pos ) - { - if( !mpOutDev.get() ) - return; // we're disposed - - OutputDevice& rOutDev( mpOutDev->getOutDev() ); - - tools::OutDevStateKeeper aStateKeeper( mpProtectedOutDev ); - rOutDev.EnableMapMode( sal_False ); - - const Size aBmpSize( rOutDev.GetOutputSizePixel() ); - - ENSURE_ARG_OR_THROW( pos.X >= 0 && pos.X < aBmpSize.Width(), - "X coordinate out of bounds" ); - ENSURE_ARG_OR_THROW( pos.Y >= 0 && pos.Y < aBmpSize.Height(), - "Y coordinate out of bounds" ); - ENSURE_ARG_OR_THROW( color.getLength() > 3, - "not enough color components" ); - - const rendering::IntegerBitmapLayout aRefLayout( getMemoryLayout() ); - ENSURE_ARG_OR_THROW( aRefLayout.PlaneStride != rLayout.PlaneStride || - aRefLayout.ColorSpace != rLayout.ColorSpace || - aRefLayout.Palette != rLayout.Palette || - aRefLayout.IsMsbFirst != rLayout.IsMsbFirst, - "Mismatching memory layout" ); - - // TODO(F2): Support alpha canvas here - rOutDev.DrawPixel( ::vcl::unotools::pointFromIntegerPoint2D( pos ), - ::canvas::tools::stdIntSequenceToColor( color )); - } - - uno::Sequence< sal_Int8 > CanvasHelper::getPixel( rendering::IntegerBitmapLayout& rLayout, - const geometry::IntegerPoint2D& pos ) - { - if( !mpOutDev.get() ) - return uno::Sequence< sal_Int8 >(); // we're disposed - - rLayout = getMemoryLayout(); - rLayout.ScanLines = 1; - rLayout.ScanLineBytes = 4; - rLayout.ScanLineStride = rLayout.ScanLineBytes; - - OutputDevice& rOutDev( mpOutDev->getOutDev() ); - - tools::OutDevStateKeeper aStateKeeper( mpProtectedOutDev ); - rOutDev.EnableMapMode( sal_False ); - - const Size aBmpSize( rOutDev.GetOutputSizePixel() ); - - ENSURE_ARG_OR_THROW( pos.X >= 0 && pos.X < aBmpSize.Width(), - "X coordinate out of bounds" ); - ENSURE_ARG_OR_THROW( pos.Y >= 0 && pos.Y < aBmpSize.Height(), - "Y coordinate out of bounds" ); - - // TODO(F2): Support alpha canvas here - return ::canvas::tools::colorToStdIntSequence( - rOutDev.GetPixel( - ::vcl::unotools::pointFromIntegerPoint2D( pos ))); - } - - rendering::IntegerBitmapLayout CanvasHelper::getMemoryLayout() - { - if( !mpOutDev.get() ) - return rendering::IntegerBitmapLayout(); // we're disposed - - return ::canvas::tools::getStdMemoryLayout(getSize()); - } - - int CanvasHelper::setupOutDevState( const rendering::ViewState& viewState, - const rendering::RenderState& renderState, - ColorType eColorType ) const - { - ENSURE_OR_THROW( mpOutDev.get(), - "outdev null. Are we disposed?" ); - - ::canvas::tools::verifyInput( renderState, - BOOST_CURRENT_FUNCTION, - mpDevice, - 2, - eColorType == IGNORE_COLOR ? 0 : 3 ); - - OutputDevice& rOutDev( mpOutDev->getOutDev() ); - OutputDevice* p2ndOutDev = NULL; - - rOutDev.EnableMapMode( sal_False ); - - if( mp2ndOutDev ) - p2ndOutDev = &mp2ndOutDev->getOutDev(); - - int nTransparency(0); - - // TODO(P2): Don't change clipping all the time, maintain current clip - // state and change only when update is necessary - - // accumulate non-empty clips into one region - // ========================================== - - Region aClipRegion( REGION_NULL ); - - if( viewState.Clip.is() ) - { - ::basegfx::B2DPolyPolygon aClipPoly( - ::basegfx::unotools::b2DPolyPolygonFromXPolyPolygon2D(viewState.Clip) ); - - if( aClipPoly.count() ) - { - // setup non-empty clipping - ::basegfx::B2DHomMatrix aMatrix; - aClipPoly.transform( - ::basegfx::unotools::homMatrixFromAffineMatrix( aMatrix, - viewState.AffineTransform ) ); - - aClipRegion = Region::GetRegionFromPolyPolygon( ::PolyPolygon( aClipPoly ) ); - } - else - { - // clip polygon is empty - aClipRegion.SetEmpty(); - } - } - - if( renderState.Clip.is() ) - { - ::basegfx::B2DPolyPolygon aClipPoly( - ::basegfx::unotools::b2DPolyPolygonFromXPolyPolygon2D(renderState.Clip) ); - - ::basegfx::B2DHomMatrix aMatrix; - aClipPoly.transform( - ::canvas::tools::mergeViewAndRenderTransform( aMatrix, - viewState, - renderState ) ); - - if( aClipPoly.count() ) - { - // setup non-empty clipping - Region aRegion = Region::GetRegionFromPolyPolygon( ::PolyPolygon( aClipPoly ) ); - aClipRegion.Intersect( aRegion ); - } - else - { - // clip polygon is empty - aClipRegion.SetEmpty(); - } - } - - // setup accumulated clip region. Note that setting an - // empty clip region denotes "clip everything" on the - // OutputDevice (which is why we translate that into - // SetClipRegion() here). When both view and render clip - // are empty, aClipRegion remains default-constructed, - // i.e. empty, too. - if( aClipRegion.IsNull() ) - { - rOutDev.SetClipRegion(); - - if( p2ndOutDev ) - p2ndOutDev->SetClipRegion(); - } - else - { - rOutDev.SetClipRegion( aClipRegion ); - - if( p2ndOutDev ) - p2ndOutDev->SetClipRegion( aClipRegion ); - } - - if( eColorType != IGNORE_COLOR ) - { - Color aColor( COL_WHITE ); - - if( renderState.DeviceColor.getLength() > 2 ) - { - aColor = ::vcl::unotools::stdColorSpaceSequenceToColor( - renderState.DeviceColor ); - } - - // extract alpha, and make color opaque - // afterwards. Otherwise, OutputDevice won't draw anything - nTransparency = aColor.GetTransparency(); - aColor.SetTransparency(0); - - switch( eColorType ) - { - case LINE_COLOR: - rOutDev.SetLineColor( aColor ); - rOutDev.SetFillColor(); - - if( p2ndOutDev ) - { - p2ndOutDev->SetLineColor( aColor ); - p2ndOutDev->SetFillColor(); - } - break; - - case FILL_COLOR: - rOutDev.SetFillColor( aColor ); - rOutDev.SetLineColor(); - - if( p2ndOutDev ) - { - p2ndOutDev->SetFillColor( aColor ); - p2ndOutDev->SetLineColor(); - } - break; - - case TEXT_COLOR: - rOutDev.SetTextColor( aColor ); - - if( p2ndOutDev ) - p2ndOutDev->SetTextColor( aColor ); - break; - - default: - ENSURE_OR_THROW( false, - "Unexpected color type"); - break; - } - } - - return nTransparency; - } - - bool CanvasHelper::setupTextOutput( ::Point& o_rOutPos, - const rendering::ViewState& viewState, - const rendering::RenderState& renderState, - const uno::Reference< rendering::XCanvasFont >& xFont ) const - { - ENSURE_OR_THROW( mpOutDev.get(), - "outdev null. Are we disposed?" ); - - setupOutDevState( viewState, renderState, TEXT_COLOR ); - - OutputDevice& rOutDev( mpOutDev->getOutDev() ); - - ::Font aVCLFont; - - CanvasFont* pFont = dynamic_cast< CanvasFont* >( xFont.get() ); - - ENSURE_ARG_OR_THROW( pFont, - "Font not compatible with this canvas" ); - - aVCLFont = pFont->getVCLFont(); - - Color aColor( COL_BLACK ); - - if( renderState.DeviceColor.getLength() > 2 ) - { - aColor = ::vcl::unotools::stdColorSpaceSequenceToColor( - renderState.DeviceColor ); - } - - // setup font color - aVCLFont.SetColor( aColor ); - aVCLFont.SetFillColor( aColor ); - - // no need to replicate this for mp2ndOutDev, we're modifying only aVCLFont here. - if( !tools::setupFontTransform( o_rOutPos, aVCLFont, viewState, renderState, rOutDev ) ) - return false; - - rOutDev.SetFont( aVCLFont ); - - if( mp2ndOutDev ) - mp2ndOutDev->getOutDev().SetFont( aVCLFont ); - - return true; - } - - bool CanvasHelper::repaint( const GraphicObjectSharedPtr& rGrf, - const rendering::ViewState& viewState, - const rendering::RenderState& renderState, - const ::Point& rPt, - const ::Size& rSz, - const GraphicAttr& rAttr ) const - { - ENSURE_OR_RETURN_FALSE( rGrf, - "Invalid Graphic" ); - - if( !mpOutDev ) - return false; // disposed - else - { - tools::OutDevStateKeeper aStateKeeper( mpProtectedOutDev ); - setupOutDevState( viewState, renderState, IGNORE_COLOR ); - - if( !rGrf->Draw( &mpOutDev->getOutDev(), rPt, rSz, &rAttr ) ) - return false; - - // #i80779# Redraw also into mask outdev - if( mp2ndOutDev ) - return rGrf->Draw( &mp2ndOutDev->getOutDev(), rPt, rSz, &rAttr ); - - return true; - } - } - - void CanvasHelper::flush() const - { - if( mpOutDev && mpOutDev->getOutDev().GetOutDevType() == OUTDEV_WINDOW ) - { - // TODO(Q3): Evil downcast. And what's more, Window::Flush is - // not even const. Wah. - static_cast<Window&>(mpOutDev->getOutDev()).Flush(); - } - - if( mp2ndOutDev && mp2ndOutDev->getOutDev().GetOutDevType() == OUTDEV_WINDOW ) - { - // TODO(Q3): Evil downcast. And what's more, Window::Flush is - // not even const. Wah. - static_cast<Window&>(mp2ndOutDev->getOutDev()).Flush(); - } - } - -} - -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |