diff options
Diffstat (limited to 'slideshow/source/engine/shapes/gdimtftools.cxx')
-rw-r--r-- | slideshow/source/engine/shapes/gdimtftools.cxx | 551 |
1 files changed, 0 insertions, 551 deletions
diff --git a/slideshow/source/engine/shapes/gdimtftools.cxx b/slideshow/source/engine/shapes/gdimtftools.cxx deleted file mode 100644 index 5265926f5..000000000 --- a/slideshow/source/engine/shapes/gdimtftools.cxx +++ /dev/null @@ -1,551 +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 <gdimtftools.hxx> - -#include <com/sun/star/document/XExporter.hpp> -#include <com/sun/star/document/XFilter.hpp> -#include <com/sun/star/graphic/XGraphic.hpp> -#include <com/sun/star/graphic/XGraphicRenderer.hpp> -#include <com/sun/star/drawing/XShape.hpp> - -#include <cppuhelper/basemutex.hxx> -#include <cppuhelper/compbase1.hxx> - -#include <comphelper/uno3.hxx> -#include <cppuhelper/implbase1.hxx> - -#include <tools/stream.hxx> -#include <vcl/svapp.hxx> -#include <vcl/canvastools.hxx> -#include <vcl/metaact.hxx> -#include <vcl/virdev.hxx> -#include <vcl/gdimtf.hxx> -#include <vcl/metaact.hxx> -#include <vcl/animate.hxx> -#include <vcl/graph.hxx> - -#include <unotools/streamwrap.hxx> - -#include "tools.hxx" - -using namespace ::com::sun::star; - - -// free support functions -// ====================== - -namespace slideshow -{ -namespace internal -{ -// TODO(E2): Detect the case when svx/drawing layer is not -// in-process, or even not on the same machine, and -// fallback to metafile streaming! - -// For fixing #i48102#, have to be a _lot_ more selective -// on which metafiles to convert to bitmaps. The problem -// here is that we _always_ get the shape content as a -// metafile, even if we have a bitmap graphic shape. Thus, -// calling GetBitmapEx on such a Graphic (see below) will -// result in one poorly scaled bitmap into another, -// somewhat arbitrarily sized bitmap. -bool hasUnsupportedActions( const GDIMetaFile& rMtf ) -{ - // search metafile for RasterOp action - MetaAction* pCurrAct; - - // TODO(Q3): avoid const-cast - for( pCurrAct = const_cast<GDIMetaFile&>(rMtf).FirstAction(); - pCurrAct; - pCurrAct = const_cast<GDIMetaFile&>(rMtf).NextAction() ) - { - switch( pCurrAct->GetType() ) - { - case META_RASTEROP_ACTION: - // overpaint is okay - that's the default, anyway - if( ROP_OVERPAINT == - static_cast<MetaRasterOpAction*>(pCurrAct)->GetRasterOp() ) - { - break; - } - // FALLTHROUGH intended - case META_MOVECLIPREGION_ACTION: - // FALLTHROUGH intended - case META_REFPOINT_ACTION: - // FALLTHROUGH intended - case META_WALLPAPER_ACTION: - return true; // at least one unsupported - // action encountered - } - } - - return false; // no unsupported action found -} - -namespace { - -typedef ::cppu::WeakComponentImplHelper1< graphic::XGraphicRenderer > DummyRenderer_Base; - -class DummyRenderer : - public DummyRenderer_Base, - public cppu::BaseMutex -{ -public: - DummyRenderer() : - DummyRenderer_Base( m_aMutex ), - mxGraphic() - { - } - - //--- XGraphicRenderer ----------------------------------- - virtual void SAL_CALL render( const uno::Reference< graphic::XGraphic >& rGraphic ) throw (uno::RuntimeException) - { - ::osl::MutexGuard aGuard( m_aMutex ); - mxGraphic = rGraphic; - } - - /** Retrieve GDIMetaFile from renderer - - @param bForeignSource - When true, the source of the metafile might be a - foreign application. The metafile is checked - against unsupported content, and, if necessary, - returned as a pre-rendererd bitmap. - */ - GDIMetaFile getMtf( bool bForeignSource ) const - { - ::osl::MutexGuard aGuard( m_aMutex ); - - Graphic aGraphic( mxGraphic ); - - if( aGraphic.GetType() == GRAPHIC_BITMAP || - (bForeignSource && - hasUnsupportedActions(aGraphic.GetGDIMetaFile()) ) ) - { - // wrap bitmap into GDIMetafile - GDIMetaFile aMtf; - ::Point aEmptyPoint; - - ::BitmapEx aBmpEx( aGraphic.GetBitmapEx() ); - - aMtf.AddAction( new MetaBmpExAction( aEmptyPoint, - aBmpEx ) ); - aMtf.SetPrefSize( aBmpEx.GetPrefSize() ); - aMtf.SetPrefMapMode( aBmpEx.GetPrefMapMode() ); - - return aMtf; - } - else - { - return aGraphic.GetGDIMetaFile(); - } - } - -private: - uno::Reference< graphic::XGraphic > mxGraphic; -}; - -} // anon namespace - -// Quick'n'dirty way: tunnel Graphic (only works for -// in-process slideshow, of course) -bool getMetaFile( const uno::Reference< lang::XComponent >& xSource, - const uno::Reference< drawing::XDrawPage >& xContainingPage, - GDIMetaFile& rMtf, - int mtfLoadFlags, - const uno::Reference< uno::XComponentContext >& rxContext ) -{ - ENSURE_OR_RETURN_FALSE( rxContext.is(), - "getMetaFile(): Invalid context" ); - - // create dummy XGraphicRenderer, which receives the - // generated XGraphic from the GraphicExporter - - // TODO(P3): Move creation of DummyRenderer out of the - // loop! Either by making it static, or transforming - // the whole thing here into a class. - DummyRenderer* pRenderer( new DummyRenderer() ); - uno::Reference< graphic::XGraphicRenderer > xRenderer( pRenderer ); - - // -> stuff that into UnoGraphicExporter. - uno::Reference<lang::XMultiComponentFactory> xFactory( - rxContext->getServiceManager() ); - - OSL_ENSURE( xFactory.is(), "### no UNO?!" ); - if( !xFactory.is() ) - return false; - - // creating the graphic exporter - uno::Reference< document::XExporter > xExporter( - xFactory->createInstanceWithContext( - OUSTR("com.sun.star.drawing.GraphicExportFilter"), - rxContext), - uno::UNO_QUERY ); - uno::Reference< document::XFilter > xFilter( xExporter, uno::UNO_QUERY ); - - OSL_ENSURE( xExporter.is() && xFilter.is(), "### no graphic exporter?!" ); - if( !xExporter.is() || !xFilter.is() ) - return false; - - uno::Sequence< beans::PropertyValue > aProps(3); - aProps[0].Name = OUSTR("FilterName"); - aProps[0].Value <<= OUSTR("SVM"); - - aProps[1].Name = OUSTR("GraphicRenderer"); - aProps[1].Value <<= xRenderer; - - uno::Sequence< beans::PropertyValue > aFilterData(5); - aFilterData[0].Name = OUSTR("VerboseComments"); - aFilterData[0].Value <<= ((mtfLoadFlags & MTF_LOAD_VERBOSE_COMMENTS) != 0); - - aFilterData[1].Name = OUSTR("ScrollText"); - aFilterData[1].Value <<= ((mtfLoadFlags & MTF_LOAD_SCROLL_TEXT_MTF) != 0); - - aFilterData[2].Name = OUSTR("ExportOnlyBackground"); - aFilterData[2].Value <<= ((mtfLoadFlags & MTF_LOAD_BACKGROUND_ONLY) != 0); - - aFilterData[3].Name = OUSTR("Version"); - aFilterData[3].Value <<= static_cast<sal_Int32>( SOFFICE_FILEFORMAT_50 ); - - aFilterData[4].Name = OUSTR("CurrentPage"); - aFilterData[4].Value <<= uno::Reference< uno::XInterface >( xContainingPage, - uno::UNO_QUERY_THROW ); - - aProps[2].Name = OUSTR("FilterData"); - aProps[2].Value <<= aFilterData; - - xExporter->setSourceDocument( xSource ); - if( !xFilter->filter( aProps ) ) - return false; - - rMtf = pRenderer->getMtf( (mtfLoadFlags & MTF_LOAD_FOREIGN_SOURCE) != 0 ); - - // pRenderer is automatically destroyed when xRenderer - // goes out of scope - - // TODO(E3): Error handling. Exporter might have - // generated nothing, a bitmap, threw an exception, - // whatever. - return true; -} - -void removeTextActions( GDIMetaFile& rMtf ) -{ - // search metafile for text output - MetaAction* pCurrAct; - - int nActionIndex(0); - pCurrAct = rMtf.FirstAction(); - while( pCurrAct ) - { - switch( pCurrAct->GetType() ) - { - case META_TEXTCOLOR_ACTION: - case META_TEXTFILLCOLOR_ACTION: - case META_TEXTLINECOLOR_ACTION: - case META_TEXTALIGN_ACTION: - case META_FONT_ACTION: - case META_LAYOUTMODE_ACTION: - case META_TEXT_ACTION: - case META_TEXTARRAY_ACTION: - case META_TEXTRECT_ACTION: - case META_STRETCHTEXT_ACTION: - case META_TEXTLINE_ACTION: - { - // remove every text-related actions - pCurrAct = rMtf.NextAction(); - - rMtf.RemoveAction( nActionIndex ); - break; - } - - default: - pCurrAct = rMtf.NextAction(); - ++nActionIndex; - break; - } - } -} - -sal_Int32 getNextActionOffset( MetaAction * pCurrAct ) -{ - // Special handling for actions that represent - // more than one indexable action - // =========================================== - - switch (pCurrAct->GetType()) { - case META_TEXT_ACTION: { - MetaTextAction * pAct = static_cast<MetaTextAction *>(pCurrAct); - return (pAct->GetLen() == (sal_uInt16)STRING_LEN - ? pAct->GetText().Len() - pAct->GetIndex() : pAct->GetLen()); - } - case META_TEXTARRAY_ACTION: { - MetaTextArrayAction * pAct = - static_cast<MetaTextArrayAction *>(pCurrAct); - return (pAct->GetLen() == (sal_uInt16)STRING_LEN - ? pAct->GetText().Len() - pAct->GetIndex() : pAct->GetLen()); - } - case META_STRETCHTEXT_ACTION: { - MetaStretchTextAction * pAct = - static_cast<MetaStretchTextAction *>(pCurrAct); - return (pAct->GetLen() == (sal_uInt16)STRING_LEN - ? pAct->GetText().Len() - pAct->GetIndex() : pAct->GetLen()); - } - case META_FLOATTRANSPARENT_ACTION: { - MetaFloatTransparentAction * pAct = - static_cast<MetaFloatTransparentAction*>(pCurrAct); - // TODO(F2): Recurse into action metafile - // (though this is currently not used from the - // DrawingLayer - shape transparency gradients - // don't affect shape text) - return pAct->GetGDIMetaFile().GetActionSize(); - } - default: - return 1; - } -} - -bool getAnimationFromGraphic( VectorOfMtfAnimationFrames& o_rFrames, - ::std::size_t& o_rLoopCount, - CycleMode& o_eCycleMode, - const Graphic& rGraphic ) -{ - o_rFrames.clear(); - - if( !rGraphic.IsAnimated() ) - return false; - - // some loop invariants - Animation aAnimation( rGraphic.GetAnimation() ); - const Point aEmptyPoint; - const Size aAnimSize( aAnimation.GetDisplaySizePixel() ); - - // setup VDev, into which all bitmaps are painted (want to - // normalize animations to n bitmaps of same size. An Animation, - // though, can contain bitmaps of varying sizes and different - // update modes) - VirtualDevice aVDev; - aVDev.SetOutputSizePixel( aAnimSize ); - aVDev.EnableMapMode( sal_False ); - - // setup mask VDev (alpha VDev is currently rather slow) - VirtualDevice aVDevMask; - aVDevMask.SetOutputSizePixel( aAnimSize ); - aVDevMask.EnableMapMode( sal_False ); - - switch( aAnimation.GetCycleMode() ) - { - case CYCLE_NOT: - o_rLoopCount = 1; - o_eCycleMode = CYCLE_LOOP; - break; - - case CYCLE_FALLBACK: - // FALLTHROUGH intended - case CYCLE_NORMAL: - o_rLoopCount = aAnimation.GetLoopCount(); - o_eCycleMode = CYCLE_LOOP; - break; - - case CYCLE_REVERS: - // FALLTHROUGH intended - case CYCLE_REVERS_FALLBACK: - o_rLoopCount = aAnimation.GetLoopCount(); - o_eCycleMode = CYCLE_PINGPONGLOOP; - break; - - default: - ENSURE_OR_RETURN_FALSE(false, - "getAnimationFromGraphic(): Unexpected case" ); - break; - } - - for( sal_uInt16 i=0, nCount=aAnimation.Count(); i<nCount; ++i ) - { - const AnimationBitmap& rAnimBmp( aAnimation.Get(i) ); - switch(rAnimBmp.eDisposal) - { - case DISPOSE_NOT: - { - aVDev.DrawBitmapEx(rAnimBmp.aPosPix, - rAnimBmp.aBmpEx); - Bitmap aMask = rAnimBmp.aBmpEx.GetMask(); - - if( aMask.IsEmpty() ) - { - const Point aEmpty; - const Rectangle aRect(aEmptyPoint, - aVDevMask.GetOutputSizePixel()); - const Wallpaper aWallpaper(COL_BLACK); - aVDevMask.DrawWallpaper(aRect, - aWallpaper); - } - else - { - BitmapEx aTmpMask = BitmapEx(aMask, - aMask); - aVDevMask.DrawBitmapEx(rAnimBmp.aPosPix, - aTmpMask ); - } - break; - } - - case DISPOSE_BACK: - { - // #i70772# react on no mask - const Bitmap aMask(rAnimBmp.aBmpEx.GetMask()); - const Bitmap aContent(rAnimBmp.aBmpEx.GetBitmap()); - - aVDevMask.Erase(); - aVDev.DrawBitmap(rAnimBmp.aPosPix, aContent); - - if(aMask.IsEmpty()) - { - const Rectangle aRect(rAnimBmp.aPosPix, aContent.GetSizePixel()); - aVDevMask.SetFillColor(COL_BLACK); - aVDevMask.SetLineColor(); - aVDevMask.DrawRect(aRect); - } - else - { - aVDevMask.DrawBitmap(rAnimBmp.aPosPix, aMask); - } - break; - } - - case DISPOSE_FULL: - { - aVDev.DrawBitmapEx(rAnimBmp.aPosPix, - rAnimBmp.aBmpEx); - break; - } - - case DISPOSE_PREVIOUS : - { - aVDev.DrawBitmapEx(rAnimBmp.aPosPix, - rAnimBmp.aBmpEx); - aVDevMask.DrawBitmap(rAnimBmp.aPosPix, - rAnimBmp.aBmpEx.GetMask()); - break; - } - } - - // extract current aVDev content into a new animation - // frame - GDIMetaFileSharedPtr pMtf( new GDIMetaFile() ); - pMtf->AddAction( - new MetaBmpExAction( aEmptyPoint, - BitmapEx( - aVDev.GetBitmap( - aEmptyPoint, - aAnimSize ), - aVDevMask.GetBitmap( - aEmptyPoint, - aAnimSize )))); - - // setup mtf dimensions and pref map mode (for - // simplicity, keep it all in pixel. the metafile - // renderer scales it down to (1, 1) box anyway) - pMtf->SetPrefMapMode( MapMode() ); - pMtf->SetPrefSize( aAnimSize ); - - // Take care of special value for MultiPage TIFFs. ATM these shall just - // show their first page for _quite_ some time. - sal_Int32 nWaitTime100thSeconds( rAnimBmp.nWait ); - if( ANIMATION_TIMEOUT_ON_CLICK == nWaitTime100thSeconds ) - { - // ATM the huge value would block the timer, so use a long - // time to show first page (whole day) - nWaitTime100thSeconds = 100 * 60 * 60 * 24; - } - - // There are animated GIFs with no WaitTime set. Take 0.1 sec, the - // same duration that is used by the edit view. - if( nWaitTime100thSeconds == 0 ) - nWaitTime100thSeconds = 10; - - o_rFrames.push_back( MtfAnimationFrame( pMtf, - nWaitTime100thSeconds / 100.0 ) ); - } - - return !o_rFrames.empty(); -} - -bool getRectanglesFromScrollMtf( ::basegfx::B2DRectangle& o_rScrollRect, - ::basegfx::B2DRectangle& o_rPaintRect, - const GDIMetaFileSharedPtr& rMtf ) -{ - // extract bounds: scroll rect, paint rect - bool bScrollRectSet(false); - bool bPaintRectSet(false); - - for ( MetaAction * pCurrAct = rMtf->FirstAction(); - pCurrAct != 0; pCurrAct = rMtf->NextAction() ) - { - if (pCurrAct->GetType() == META_COMMENT_ACTION) - { - MetaCommentAction * pAct = - static_cast<MetaCommentAction *>(pCurrAct); - // skip comment if not a special XTEXT comment - if (pAct->GetComment().CompareIgnoreCaseToAscii( - RTL_CONSTASCII_STRINGPARAM("XTEXT") ) == COMPARE_EQUAL) - { - if (pAct->GetComment().CompareIgnoreCaseToAscii( - "XTEXT_SCROLLRECT" ) == COMPARE_EQUAL) { - o_rScrollRect = ::vcl::unotools::b2DRectangleFromRectangle( - *reinterpret_cast<Rectangle const *>( - pAct->GetData() ) ); - - bScrollRectSet = true; - } - else if (pAct->GetComment().CompareIgnoreCaseToAscii( - "XTEXT_PAINTRECT" ) == COMPARE_EQUAL) { - o_rPaintRect = ::vcl::unotools::b2DRectangleFromRectangle( - *reinterpret_cast<Rectangle const *>( - pAct->GetData() ) ); - - bPaintRectSet = true; - } - } - } - } - - return bScrollRectSet && bPaintRectSet; -} - -} -} - -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |