diff options
Diffstat (limited to 'slideshow/source/engine/shapes/viewshape.cxx')
-rw-r--r-- | slideshow/source/engine/shapes/viewshape.cxx | 901 |
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: */ |