summaryrefslogtreecommitdiff
path: root/slideshow/source/engine/shapes/viewshape.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'slideshow/source/engine/shapes/viewshape.cxx')
-rw-r--r--slideshow/source/engine/shapes/viewshape.cxx901
1 files changed, 0 insertions, 901 deletions
diff --git a/slideshow/source/engine/shapes/viewshape.cxx b/slideshow/source/engine/shapes/viewshape.cxx
deleted file mode 100644
index 7f4d3dc5f..000000000
--- a/slideshow/source/engine/shapes/viewshape.cxx
+++ /dev/null
@@ -1,901 +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_slideshow.hxx"
-
-// must be first
-#include <canvas/debug.hxx>
-#include <tools/diagnose_ex.h>
-
-#include <math.h>
-
-#include <rtl/logfile.hxx>
-#include <rtl/math.hxx>
-
-#include <com/sun/star/rendering/XCanvas.hpp>
-#include <com/sun/star/rendering/XIntegerBitmap.hpp>
-#include <com/sun/star/rendering/PanoseLetterForm.hpp>
-#include <com/sun/star/awt/FontSlant.hpp>
-
-#include <cppuhelper/exc_hlp.hxx>
-#include <comphelper/anytostring.hxx>
-
-#include <basegfx/polygon/b2dpolygontools.hxx>
-#include <basegfx/numeric/ftools.hxx>
-#include <basegfx/matrix/b2dhommatrix.hxx>
-#include <basegfx/matrix/b2dhommatrixtools.hxx>
-
-#include <canvas/verbosetrace.hxx>
-#include <canvas/canvastools.hxx>
-#include <cppcanvas/vclfactory.hxx>
-#include <cppcanvas/basegfxfactory.hxx>
-
-#include "viewshape.hxx"
-#include "tools.hxx"
-
-#include <boost/bind.hpp>
-
-
-using namespace ::com::sun::star;
-
-namespace slideshow
-{
- namespace internal
- {
-
- // TODO(F2): Provide sensible setup for mtf-related attributes (fill mode,
- // char rotation etc.). Do that via mtf argument at this object
-
- bool ViewShape::prefetch( RendererCacheEntry& io_rCacheEntry,
- const ::cppcanvas::CanvasSharedPtr& rDestinationCanvas,
- const GDIMetaFileSharedPtr& rMtf,
- const ShapeAttributeLayerSharedPtr& rAttr ) const
- {
- RTL_LOGFILE_CONTEXT( aLog, "::presentation::internal::ViewShape::prefetch()" );
- ENSURE_OR_RETURN_FALSE( rMtf,
- "ViewShape::prefetch(): no valid metafile!" );
-
- if( rMtf != io_rCacheEntry.mpMtf ||
- rDestinationCanvas != io_rCacheEntry.getDestinationCanvas() )
- {
- // buffered renderer invalid, re-create
- ::cppcanvas::Renderer::Parameters aParms;
-
- // rendering attribute override parameter struct. For
- // every valid attribute, the corresponding struct
- // member is filled, which in the metafile renderer
- // forces rendering with the given attribute.
- if( rAttr )
- {
- if( rAttr->isFillColorValid() )
- {
- // convert RGBColor to RGBA32 integer. Note
- // that getIntegerColor() also truncates
- // out-of-range values appropriately
- aParms.maFillColor =
- rAttr->getFillColor().getIntegerColor();
- }
- if( rAttr->isLineColorValid() )
- {
- // convert RGBColor to RGBA32 integer. Note
- // that getIntegerColor() also truncates
- // out-of-range values appropriately
- aParms.maLineColor =
- rAttr->getLineColor().getIntegerColor();
- }
- if( rAttr->isCharColorValid() )
- {
- // convert RGBColor to RGBA32 integer. Note
- // that getIntegerColor() also truncates
- // out-of-range values appropriately
- aParms.maTextColor =
- rAttr->getCharColor().getIntegerColor();
- }
- if( rAttr->isDimColorValid() )
- {
- // convert RGBColor to RGBA32 integer. Note
- // that getIntegerColor() also truncates
- // out-of-range values appropriately
-
- // dim color overrides all other colors
- aParms.maFillColor =
- aParms.maLineColor =
- aParms.maTextColor =
- rAttr->getDimColor().getIntegerColor();
- }
- if( rAttr->isFontFamilyValid() )
- {
- aParms.maFontName =
- rAttr->getFontFamily();
- }
- if( rAttr->isCharScaleValid() )
- {
- ::basegfx::B2DHomMatrix aMatrix;
-
- // enlarge text by given scale factor. Do that
- // with the middle of the shape as the center
- // of scaling.
- aMatrix.translate( -0.5, -0.5 );
- aMatrix.scale( rAttr->getCharScale(),
- rAttr->getCharScale() );
- aMatrix.translate( 0.5, 0.5 );
-
- aParms.maTextTransformation = aMatrix;
- }
- if( rAttr->isCharWeightValid() )
- {
- aParms.maFontWeight =
- static_cast< sal_Int8 >(
- ::basegfx::fround(
- ::std::max( 0.0,
- ::std::min( 11.0,
- rAttr->getCharWeight() / 20.0 ) ) ) );
- }
- if( rAttr->isCharPostureValid() )
- {
- aParms.maFontLetterForm =
- rAttr->getCharPosture() == awt::FontSlant_NONE ?
- rendering::PanoseLetterForm::ANYTHING :
- rendering::PanoseLetterForm::OBLIQUE_CONTACT;
- }
- if( rAttr->isUnderlineModeValid() )
- {
- aParms.maFontUnderline =
- rAttr->getUnderlineMode();
- }
- }
-
- io_rCacheEntry.mpRenderer = ::cppcanvas::VCLFactory::getInstance().createRenderer( rDestinationCanvas,
- *rMtf.get(),
- aParms );
-
- io_rCacheEntry.mpMtf = rMtf;
- io_rCacheEntry.mpDestinationCanvas = rDestinationCanvas;
-
- // also invalidate alpha compositing bitmap (created
- // new renderer, which possibly generates different
- // output). Do NOT invalidate, if we're incidentally
- // rendering INTO it.
- if( rDestinationCanvas != io_rCacheEntry.mpLastBitmapCanvas )
- {
- io_rCacheEntry.mpLastBitmapCanvas.reset();
- io_rCacheEntry.mpLastBitmap.reset();
- }
- }
-
- return io_rCacheEntry.mpRenderer;
- }
-
- bool ViewShape::draw( const ::cppcanvas::CanvasSharedPtr& rDestinationCanvas,
- const GDIMetaFileSharedPtr& rMtf,
- const ShapeAttributeLayerSharedPtr& rAttr,
- const ::basegfx::B2DHomMatrix& rTransform,
- const ::basegfx::B2DPolyPolygon* pClip,
- const VectorOfDocTreeNodes& rSubsets ) const
- {
- RTL_LOGFILE_CONTEXT( aLog, "::presentation::internal::ViewShape::draw()" );
-
- ::cppcanvas::RendererSharedPtr pRenderer(
- getRenderer( rDestinationCanvas, rMtf, rAttr ) );
-
- ENSURE_OR_RETURN_FALSE( pRenderer, "ViewShape::draw(): Invalid renderer" );
-
- pRenderer->setTransformation( rTransform );
-#if defined(VERBOSE) && OSL_DEBUG_LEVEL > 0
- rendering::RenderState aRenderState;
- ::canvas::tools::initRenderState(aRenderState);
- ::canvas::tools::setRenderStateTransform(aRenderState,
- rTransform);
- aRenderState.DeviceColor.realloc(4);
- aRenderState.DeviceColor[0] = 1.0;
- aRenderState.DeviceColor[1] = 0.0;
- aRenderState.DeviceColor[2] = 0.0;
- aRenderState.DeviceColor[3] = 1.0;
-
- try
- {
- rDestinationCanvas->getUNOCanvas()->drawLine( geometry::RealPoint2D(0.0,0.0),
- geometry::RealPoint2D(1.0,1.0),
- rDestinationCanvas->getViewState(),
- aRenderState );
- rDestinationCanvas->getUNOCanvas()->drawLine( geometry::RealPoint2D(1.0,0.0),
- geometry::RealPoint2D(0.0,1.0),
- rDestinationCanvas->getViewState(),
- aRenderState );
- }
- catch( uno::Exception& )
- {
- DBG_UNHANDLED_EXCEPTION();
- }
-#endif
- if( pClip )
- pRenderer->setClip( *pClip );
- else
- pRenderer->setClip();
-
- if( rSubsets.empty() )
- {
- return pRenderer->draw();
- }
- else
- {
- // render subsets of whole metafile
- // --------------------------------
-
- bool bRet(true);
- VectorOfDocTreeNodes::const_iterator aIter( rSubsets.begin() );
- const VectorOfDocTreeNodes::const_iterator aEnd ( rSubsets.end() );
- while( aIter != aEnd )
- {
- if( !pRenderer->drawSubset( aIter->getStartIndex(),
- aIter->getEndIndex() ) )
- bRet = false;
-
- ++aIter;
- }
-
- return bRet;
- }
- }
-
- namespace
- {
- /// Convert untransformed shape update area to device pixel.
- ::basegfx::B2DRectangle shapeArea2AreaPixel( const ::basegfx::B2DHomMatrix& rCanvasTransformation,
- const ::basegfx::B2DRectangle& rUntransformedArea )
- {
- // convert area to pixel, and add anti-aliasing border
-
- // TODO(P1): Should the view transform some
- // day contain rotation/shear, transforming
- // the original bounds with the total
- // transformation might result in smaller
- // overall bounds.
-
- ::basegfx::B2DRectangle aBoundsPixel;
- ::canvas::tools::calcTransformedRectBounds( aBoundsPixel,
- rUntransformedArea,
- rCanvasTransformation );
-
- // add antialiasing border around the shape (AA
- // touches pixel _outside_ the nominal bound rect)
- aBoundsPixel.grow( ::cppcanvas::Canvas::ANTIALIASING_EXTRA_SIZE );
-
- return aBoundsPixel;
- }
-
- /// Convert shape unit rect to device pixel.
- ::basegfx::B2DRectangle calcUpdateAreaPixel( const ::basegfx::B2DRectangle& rUnitBounds,
- const ::basegfx::B2DHomMatrix& rShapeTransformation,
- const ::basegfx::B2DHomMatrix& rCanvasTransformation,
- const ShapeAttributeLayerSharedPtr& pAttr )
- {
- // calc update area for whole shape (including
- // character scaling)
- return shapeArea2AreaPixel( rCanvasTransformation,
- getShapeUpdateArea( rUnitBounds,
- rShapeTransformation,
- pAttr ) );
- }
- }
-
- bool ViewShape::renderSprite( const ViewLayerSharedPtr& rViewLayer,
- const GDIMetaFileSharedPtr& rMtf,
- const ::basegfx::B2DRectangle& rOrigBounds,
- const ::basegfx::B2DRectangle& rBounds,
- const ::basegfx::B2DRectangle& rUnitBounds,
- int nUpdateFlags,
- const ShapeAttributeLayerSharedPtr& pAttr,
- const VectorOfDocTreeNodes& rSubsets,
- double nPrio,
- bool bIsVisible ) const
- {
- RTL_LOGFILE_CONTEXT( aLog, "::presentation::internal::ViewShape::renderSprite()" );
-
- // TODO(P1): For multiple views, it might pay off to reorg Shape and ViewShape,
- // in that all the common setup steps here are refactored to Shape (would then
- // have to be performed only _once_ per Shape paint).
-
- if( !bIsVisible ||
- rUnitBounds.isEmpty() ||
- rOrigBounds.isEmpty() ||
- rBounds.isEmpty() )
- {
- // shape is invisible or has zero size, no need to
- // update anything.
- if( mpSprite )
- mpSprite->hide();
-
- return true;
- }
-
-
- // calc sprite position, size and content transformation
- // =====================================================
-
- // the shape transformation for a sprite is always a
- // simple scale-up to the nominal shape size. Everything
- // else is handled via the sprite transformation
- ::basegfx::B2DHomMatrix aNonTranslationalShapeTransformation;
- aNonTranslationalShapeTransformation.scale( rOrigBounds.getWidth(),
- rOrigBounds.getHeight() );
- ::basegfx::B2DHomMatrix aShapeTransformation( aNonTranslationalShapeTransformation );
- aShapeTransformation.translate( rOrigBounds.getMinX(),
- rOrigBounds.getMinY() );
-
- const ::basegfx::B2DHomMatrix& rCanvasTransform(
- rViewLayer->getSpriteTransformation() );
-
- // area actually needed for the sprite
- const ::basegfx::B2DRectangle& rSpriteBoundsPixel(
- calcUpdateAreaPixel( rUnitBounds,
- aShapeTransformation,
- rCanvasTransform,
- pAttr ) );
-
- // actual area for the shape (without subsetting, but
- // including char scaling)
- const ::basegfx::B2DRectangle& rShapeBoundsPixel(
- calcUpdateAreaPixel( ::basegfx::B2DRectangle(0.0,0.0,1.0,1.0),
- aShapeTransformation,
- rCanvasTransform,
- pAttr ) );
-
- // nominal area for the shape (without subsetting, without
- // char scaling). NOTE: to cancel the shape translation,
- // contained in rSpriteBoundsPixel, this is _without_ any
- // translational component.
- ::basegfx::B2DRectangle aLogShapeBounds;
- const ::basegfx::B2DRectangle& rNominalShapeBoundsPixel(
- shapeArea2AreaPixel( rCanvasTransform,
- ::canvas::tools::calcTransformedRectBounds(
- aLogShapeBounds,
- ::basegfx::B2DRectangle(0.0,0.0,1.0,1.0),
- aNonTranslationalShapeTransformation ) ) );
-
- // create (or resize) sprite with sprite's pixel size, if
- // not done already
- const ::basegfx::B2DSize& rSpriteSizePixel(rSpriteBoundsPixel.getRange());
- if( !mpSprite )
- {
- mpSprite.reset(
- new AnimatedSprite( mpViewLayer,
- rSpriteSizePixel,
- nPrio ));
- }
- else
- {
- // TODO(F2): when the sprite _actually_ gets resized,
- // content needs a repaint!
- mpSprite->resize( rSpriteSizePixel );
- }
-
- ENSURE_OR_RETURN_FALSE( mpSprite, "ViewShape::renderSprite(): No sprite" );
-
- VERBOSE_TRACE( "ViewShape::renderSprite(): Rendering sprite 0x%X",
- mpSprite.get() );
-
-
- // always show the sprite (might have been hidden before)
- mpSprite->show();
-
- // determine center of sprite output position in pixel
- // (assumption here: all shape transformations have the
- // shape center as the pivot point). From that, subtract
- // distance of rSpriteBoundsPixel's left, top edge from
- // rShapeBoundsPixel's center. This moves the sprite at
- // the appropriate output position within the virtual
- // rShapeBoundsPixel area.
- ::basegfx::B2DPoint aSpritePosPixel( rBounds.getCenter() );
- aSpritePosPixel *= rCanvasTransform;
- aSpritePosPixel -= rShapeBoundsPixel.getCenter() - rSpriteBoundsPixel.getMinimum();
-
- // the difference between rShapeBoundsPixel and
- // rSpriteBoundsPixel upper, left corner is: the offset we
- // have to move sprite output to the right, top (to make
- // the desired subset content visible at all)
- const ::basegfx::B2DSize& rSpriteCorrectionOffset(
- rSpriteBoundsPixel.getMinimum() - rNominalShapeBoundsPixel.getMinimum() );
-
- // offset added top, left for anti-aliasing (otherwise,
- // shapes fully filling the sprite will have anti-aliased
- // pixel cut off)
- const ::basegfx::B2DSize aAAOffset(
- ::cppcanvas::Canvas::ANTIALIASING_EXTRA_SIZE,
- ::cppcanvas::Canvas::ANTIALIASING_EXTRA_SIZE );
-
- // set pixel output offset to sprite: we always leave
- // ANTIALIASING_EXTRA_SIZE room atop and to the left, and,
- // what's more, for subsetted shapes, we _have_ to cancel
- // the effect of the shape renderer outputting the subset
- // at its absolute position inside the shape, instead of
- // at the origin.
- // NOTE: As for now, sprites are always positioned on
- // integer pixel positions on screen, have to round to
- // nearest integer here, too
- mpSprite->setPixelOffset(
- aAAOffset - ::basegfx::B2DSize(
- ::basegfx::fround( rSpriteCorrectionOffset.getX() ),
- ::basegfx::fround( rSpriteCorrectionOffset.getY() ) ) );
-
- // always set sprite position and transformation, since
- // they do not relate directly to the update flags
- // (e.g. sprite position changes when sprite size changes)
- mpSprite->movePixel( aSpritePosPixel );
- mpSprite->transform( getSpriteTransformation( rSpriteSizePixel,
- rOrigBounds.getRange(),
- pAttr ) );
-
-
- // process flags
- // =============
-
- bool bRedrawRequired( mbForceUpdate || (nUpdateFlags & FORCE) );
-
- if( mbForceUpdate || (nUpdateFlags & ALPHA) )
- {
- mpSprite->setAlpha( (pAttr && pAttr->isAlphaValid()) ?
- ::basegfx::clamp(pAttr->getAlpha(),
- 0.0,
- 1.0) :
- 1.0 );
- }
- if( mbForceUpdate || (nUpdateFlags & CLIP) )
- {
- if( pAttr && pAttr->isClipValid() )
- {
- ::basegfx::B2DPolyPolygon aClipPoly( pAttr->getClip() );
-
- // extract linear part of canvas view transformation
- // (linear means: without translational components)
- ::basegfx::B2DHomMatrix aViewTransform(
- mpViewLayer->getTransformation() );
- aViewTransform.set( 0, 2, 0.0 );
- aViewTransform.set( 1, 2, 0.0 );
-
- // make the clip 2*ANTIALIASING_EXTRA_SIZE larger
- // such that it's again centered over the sprite.
- aViewTransform.scale(rSpriteSizePixel.getX()/
- (rSpriteSizePixel.getX()-2*::cppcanvas::Canvas::ANTIALIASING_EXTRA_SIZE),
- rSpriteSizePixel.getY()/
- (rSpriteSizePixel.getY()-2*::cppcanvas::Canvas::ANTIALIASING_EXTRA_SIZE));
-
- // transform clip polygon from view to device
- // coordinate space
- aClipPoly.transform( aViewTransform );
-
- mpSprite->clip( aClipPoly );
- }
- else
- mpSprite->clip();
- }
- if( mbForceUpdate || (nUpdateFlags & CONTENT) )
- {
- bRedrawRequired = true;
-
- // TODO(P1): maybe provide some appearance change methods at
- // the Renderer interface
-
- // force the renderer to be regenerated below, for the
- // different attributes to take effect
- invalidateRenderer();
- }
-
- mbForceUpdate = false;
-
- if( !bRedrawRequired )
- return true;
-
-
- // sprite needs repaint - output to sprite canvas
- // ==============================================
-
- ::cppcanvas::CanvasSharedPtr pContentCanvas( mpSprite->getContentCanvas() );
-
- return draw( pContentCanvas,
- rMtf,
- pAttr,
- aShapeTransformation,
- NULL, // clipping is done via Sprite::clip()
- rSubsets );
- }
-
- bool ViewShape::render( const ::cppcanvas::CanvasSharedPtr& rDestinationCanvas,
- const GDIMetaFileSharedPtr& rMtf,
- const ::basegfx::B2DRectangle& rBounds,
- const ::basegfx::B2DRectangle& rUpdateBounds,
- int nUpdateFlags,
- const ShapeAttributeLayerSharedPtr& pAttr,
- const VectorOfDocTreeNodes& rSubsets,
- bool bIsVisible ) const
- {
- RTL_LOGFILE_CONTEXT( aLog, "::presentation::internal::ViewShape::render()" );
-
- // TODO(P1): For multiple views, it might pay off to reorg Shape and ViewShape,
- // in that all the common setup steps here are refactored to Shape (would then
- // have to be performed only _once_ per Shape paint).
-
- if( !bIsVisible )
- {
- VERBOSE_TRACE( "ViewShape::render(): skipping shape %X", this );
-
- // shape is invisible, no need to update anything.
- return true;
- }
-
- // since we have no sprite here, _any_ update request
- // translates into a required redraw.
- bool bRedrawRequired( mbForceUpdate || nUpdateFlags != 0 );
-
- if( (nUpdateFlags & CONTENT) )
- {
- // TODO(P1): maybe provide some appearance change methods at
- // the Renderer interface
-
- // force the renderer to be regenerated below, for the
- // different attributes to take effect
- invalidateRenderer();
- }
-
- mbForceUpdate = false;
-
- if( !bRedrawRequired )
- return true;
-
- VERBOSE_TRACE( "ViewShape::render(): rendering shape %X at position (%f,%f)",
- this,
- rBounds.getMinX(),
- rBounds.getMinY() );
-
-
- // shape needs repaint - setup all that's needed
- // ---------------------------------------------
-
- boost::optional<basegfx::B2DPolyPolygon> aClip;
-
- if( pAttr )
- {
- // setup clip poly
- if( pAttr->isClipValid() )
- aClip.reset( pAttr->getClip() );
-
- // emulate global shape alpha by first rendering into
- // a temp bitmap, and then to screen (this would have
- // been much easier if we'd be currently a sprite -
- // see above)
- if( pAttr->isAlphaValid() )
- {
- const double nAlpha( pAttr->getAlpha() );
-
- if( !::basegfx::fTools::equalZero( nAlpha ) &&
- !::rtl::math::approxEqual(nAlpha, 1.0) )
- {
- // render with global alpha - have to prepare
- // a bitmap, and render that with modulated
- // alpha
- // -------------------------------------------
-
- const ::basegfx::B2DHomMatrix aTransform(
- getShapeTransformation( rBounds,
- pAttr ) );
-
- // TODO(P1): Should the view transform some
- // day contain rotation/shear, transforming
- // the original bounds with the total
- // transformation might result in smaller
- // overall bounds.
-
- // determine output rect of _shape update
- // area_ in device pixel
- const ::basegfx::B2DHomMatrix aCanvasTransform(
- rDestinationCanvas->getTransformation() );
- ::basegfx::B2DRectangle aTmpRect;
- ::canvas::tools::calcTransformedRectBounds( aTmpRect,
- rUpdateBounds,
- aCanvasTransform );
-
- // pixel size of cache bitmap: round up to
- // nearest int
- const ::basegfx::B2ISize aBmpSize( static_cast<sal_Int32>( aTmpRect.getWidth() )+1,
- static_cast<sal_Int32>( aTmpRect.getHeight() )+1 );
-
- // try to fetch temporary surface for alpha
- // compositing (to achieve the global alpha
- // blend effect, have to first render shape as
- // a whole, then blit that surface with global
- // alpha to the destination)
- const RendererCacheVector::iterator aCompositingSurface(
- getCacheEntry( rDestinationCanvas ) );
-
- if( !aCompositingSurface->mpLastBitmapCanvas ||
- aCompositingSurface->mpLastBitmapCanvas->getSize() != aBmpSize )
- {
- // create a bitmap of appropriate size
- ::cppcanvas::BitmapSharedPtr pBitmap(
- ::cppcanvas::BaseGfxFactory::getInstance().createAlphaBitmap(
- rDestinationCanvas,
- aBmpSize ) );
-
- ENSURE_OR_THROW(pBitmap,
- "ViewShape::render(): Could not create compositing surface");
-
- aCompositingSurface->mpDestinationCanvas = rDestinationCanvas;
- aCompositingSurface->mpLastBitmap = pBitmap;
- aCompositingSurface->mpLastBitmapCanvas = pBitmap->getBitmapCanvas();
- }
-
- // buffer aCompositingSurface iterator content
- // - said one might get invalidated during
- // draw() below.
- ::cppcanvas::BitmapCanvasSharedPtr pBitmapCanvas(
- aCompositingSurface->mpLastBitmapCanvas );
-
- ::cppcanvas::BitmapSharedPtr pBitmap(
- aCompositingSurface->mpLastBitmap);
-
- // setup bitmap canvas transformation -
- // which happens to be the destination
- // canvas transformation without any
- // translational components.
- //
- // But then, the render transformation as
- // calculated by getShapeTransformation()
- // above outputs the shape at its real
- // destination position. Thus, we have to
- // offset the output back to the origin,
- // for which we simply plug in the
- // negative position of the left, top edge
- // of the shape's bound rect in device
- // pixel into aLinearTransform below.
- ::basegfx::B2DHomMatrix aAdjustedCanvasTransform( aCanvasTransform );
- aAdjustedCanvasTransform.translate( -aTmpRect.getMinX(),
- -aTmpRect.getMinY() );
-
- pBitmapCanvas->setTransformation( aAdjustedCanvasTransform );
-
- // TODO(P2): If no update flags, or only
- // alpha_update is set, we can save us the
- // rendering into the bitmap (uh, it's not
- // _that_ easy - for a forced redraw,
- // e.g. when ending an animation, we always
- // get UPDATE_FORCE here).
-
- // render into this bitmap
- if( !draw( pBitmapCanvas,
- rMtf,
- pAttr,
- aTransform,
- !aClip ? NULL : &(*aClip),
- rSubsets ) )
- {
- return false;
- }
-
- // render bitmap to screen, with given global
- // alpha. Since the bitmap already contains
- // pixel-equivalent output, we have to use the
- // inverse view transformation, adjusted with
- // the final shape output position (note:
- // cannot simply change the view
- // transformation here, as that would affect a
- // possibly set clip!)
- ::basegfx::B2DHomMatrix aBitmapTransform( aCanvasTransform );
- OSL_ENSURE( aBitmapTransform.isInvertible(),
- "ViewShape::render(): View transformation is singular!" );
-
- aBitmapTransform.invert();
-
- const basegfx::B2DHomMatrix aTranslation(basegfx::tools::createTranslateB2DHomMatrix(
- aTmpRect.getMinX(), aTmpRect.getMinY()));
-
- aBitmapTransform = aBitmapTransform * aTranslation;
- pBitmap->setTransformation( aBitmapTransform );
-
- // finally, render bitmap alpha-modulated
- pBitmap->drawAlphaModulated( nAlpha );
-
- return true;
- }
- }
- }
-
- // retrieve shape transformation, _with_ shape translation
- // to actual page position.
- const ::basegfx::B2DHomMatrix aTransform(
- getShapeTransformation( rBounds,
- pAttr ) );
-
- return draw( rDestinationCanvas,
- rMtf,
- pAttr,
- aTransform,
- !aClip ? NULL : &(*aClip),
- rSubsets );
- }
-
-
- // -------------------------------------------------------------------------------------
-
- ViewShape::ViewShape( const ViewLayerSharedPtr& rViewLayer ) :
- mpViewLayer( rViewLayer ),
- maRenderers(),
- mpSprite(),
- mbAnimationMode( false ),
- mbForceUpdate( true )
- {
- ENSURE_OR_THROW( mpViewLayer, "ViewShape::ViewShape(): Invalid View" );
- }
-
- ViewLayerSharedPtr ViewShape::getViewLayer() const
- {
- return mpViewLayer;
- }
-
- ViewShape::RendererCacheVector::iterator ViewShape::getCacheEntry( const ::cppcanvas::CanvasSharedPtr& rDestinationCanvas ) const
- {
- // lookup destination canvas - is there already a renderer
- // created for that target?
- RendererCacheVector::iterator aIter;
- const RendererCacheVector::iterator aEnd( maRenderers.end() );
-
- // already there?
- if( (aIter=::std::find_if( maRenderers.begin(),
- aEnd,
- ::boost::bind(
- ::std::equal_to< ::cppcanvas::CanvasSharedPtr >(),
- ::boost::cref( rDestinationCanvas ),
- ::boost::bind(
- &RendererCacheEntry::getDestinationCanvas,
- _1 ) ) ) ) == aEnd )
- {
- if( maRenderers.size() >= MAX_RENDER_CACHE_ENTRIES )
- {
- // cache size exceeded - prune entries. For now,
- // simply remove the first one, which of course
- // breaks for more complex access schemes. But in
- // general, this leads to most recently used
- // entries to reside at the end of the vector.
- maRenderers.erase( maRenderers.begin() );
-
- // ATTENTION: after this, both aIter and aEnd are
- // invalid!
- }
-
- // not yet in cache - add default-constructed cache
- // entry, to have something to return
- maRenderers.push_back( RendererCacheEntry() );
- aIter = maRenderers.end()-1;
- }
-
- return aIter;
- }
-
- ::cppcanvas::RendererSharedPtr ViewShape::getRenderer( const ::cppcanvas::CanvasSharedPtr& rDestinationCanvas,
- const GDIMetaFileSharedPtr& rMtf,
- const ShapeAttributeLayerSharedPtr& rAttr ) const
- {
- // lookup destination canvas - is there already a renderer
- // created for that target?
- const RendererCacheVector::iterator aIter(
- getCacheEntry( rDestinationCanvas ) );
-
- // now we have a valid entry, either way. call prefetch()
- // on it, nevertheless - maybe the metafile changed, and
- // the renderer still needs an update (prefetch() will
- // detect that)
- if( prefetch( *aIter,
- rDestinationCanvas,
- rMtf,
- rAttr ) )
- {
- return aIter->mpRenderer;
- }
- else
- {
- // prefetch failed - renderer is invalid
- return ::cppcanvas::RendererSharedPtr();
- }
- }
-
- void ViewShape::invalidateRenderer() const
- {
- // simply clear the cache. Subsequent getRenderer() calls
- // will regenerate the Renderers.
- maRenderers.clear();
- }
-
- ::basegfx::B2DSize ViewShape::getAntialiasingBorder() const
- {
- ENSURE_OR_THROW( mpViewLayer->getCanvas(),
- "ViewShape::getAntialiasingBorder(): Invalid ViewLayer canvas" );
-
- const ::basegfx::B2DHomMatrix& rViewTransform(
- mpViewLayer->getTransformation() );
-
- // TODO(F1): As a quick shortcut (did not want to invert
- // whole matrix here), taking only scale components of
- // view transformation matrix. This will be wrong when
- // e.g. shearing is involved.
- const double nXBorder( ::cppcanvas::Canvas::ANTIALIASING_EXTRA_SIZE / rViewTransform.get(0,0) );
- const double nYBorder( ::cppcanvas::Canvas::ANTIALIASING_EXTRA_SIZE / rViewTransform.get(1,1) );
-
- return ::basegfx::B2DSize( nXBorder,
- nYBorder );
- }
-
- bool ViewShape::enterAnimationMode()
- {
- mbForceUpdate = true;
- mbAnimationMode = true;
-
- return true;
- }
-
- void ViewShape::leaveAnimationMode()
- {
- mpSprite.reset();
- mbAnimationMode = false;
- mbForceUpdate = true;
- }
-
- bool ViewShape::update( const GDIMetaFileSharedPtr& rMtf,
- const RenderArgs& rArgs,
- int nUpdateFlags,
- bool bIsVisible ) const
- {
- RTL_LOGFILE_CONTEXT( aLog, "::presentation::internal::ViewShape::update()" );
- ENSURE_OR_RETURN_FALSE( mpViewLayer->getCanvas(), "ViewShape::update(): Invalid layer canvas" );
-
- // Shall we render to a sprite, or to a plain canvas?
- if( isBackgroundDetached() )
- return renderSprite( mpViewLayer,
- rMtf,
- rArgs.maOrigBounds,
- rArgs.maBounds,
- rArgs.maUnitBounds,
- nUpdateFlags,
- rArgs.mrAttr,
- rArgs.mrSubsets,
- rArgs.mnShapePriority,
- bIsVisible );
- else
- return render( mpViewLayer->getCanvas(),
- rMtf,
- rArgs.maBounds,
- rArgs.maUpdateBounds,
- nUpdateFlags,
- rArgs.mrAttr,
- rArgs.mrSubsets,
- bIsVisible );
- }
-
- }
-}
-
-/* vim:set shiftwidth=4 softtabstop=4 expandtab: */