/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ /* * This file is part of the LibreOffice project. * * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. * * This file incorporates work covered by the following license notice: * * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed * with this work for additional information regarding copyright * ownership. The ASF licenses this file to you under the Apache * License, Version 2.0 (the "License"); you may not use this file * except in compliance with the License. You may obtain a copy of * the License at http://www.apache.org/licenses/LICENSE-2.0 . */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "gallery.hrc" #include "svx/galmisc.hxx" #include "galobj.hxx" #include #include #include #include "gallerydrawmodel.hxx" #include using namespace ::com::sun::star; SgaObject::SgaObject() : bIsValid ( false ), bIsThumbBmp ( true ) { } BitmapEx SgaObject::createPreviewBitmapEx(const Size& rSizePixel) const { BitmapEx aRetval; if(rSizePixel.Width() && rSizePixel.Height()) { if(SGA_OBJ_SOUND == GetObjKind()) { aRetval = GAL_RES(RID_SVXBMP_GALLERY_MEDIA); } else if(IsThumbBitmap()) { aRetval = GetThumbBmp(); } else { const Graphic aGraphic(GetThumbMtf()); aRetval = aGraphic.GetBitmapEx(); } if(!aRetval.IsEmpty()) { const Size aCurrentSizePixel(aRetval.GetSizePixel()); const double fScaleX((double)rSizePixel.Width() / (double)aCurrentSizePixel.Width()); const double fScaleY((double)rSizePixel.Height() / (double)aCurrentSizePixel.Height()); const double fScale(std::min(fScaleX, fScaleY)); // only scale when need to decrease, no need to make bigger as original. Also // prevent scaling close to 1.0 which is not needed for pixel graphics if(fScale < 1.0 && fabs(1.0 - fScale) > 0.005) { static sal_uInt32 nScaleFlag = BMP_SCALE_BESTQUALITY; aRetval.Scale(fScale, fScale, nScaleFlag); } } } return aRetval; } bool SgaObject::CreateThumb( const Graphic& rGraphic ) { bool bRet = false; if( rGraphic.GetType() == GRAPHIC_BITMAP ) { BitmapEx aBmpEx( rGraphic.GetBitmapEx() ); Size aBmpSize( aBmpEx.GetSizePixel() ); if( aBmpSize.Width() && aBmpSize.Height() ) { if( aBmpEx.GetPrefMapMode().GetMapUnit() != MAP_PIXEL && aBmpEx.GetPrefSize().Width() > 0 && aBmpEx.GetPrefSize().Height() > 0 ) { Size aLogSize( OutputDevice::LogicToLogic( aBmpEx.GetPrefSize(), aBmpEx.GetPrefMapMode(), MAP_100TH_MM ) ); if( aLogSize.Width() > 0 && aLogSize.Height() > 0 ) { double fFactorLog = static_cast< double >( aLogSize.Width() ) / aLogSize.Height(); double fFactorPix = static_cast< double >( aBmpSize.Width() ) / aBmpSize.Height(); if( fFactorPix > fFactorLog ) aBmpSize.Width() = FRound( aBmpSize.Height() * fFactorLog ); else aBmpSize.Height() = FRound( aBmpSize.Width() / fFactorLog ); aBmpEx.SetSizePixel( aBmpSize, BMP_SCALE_BESTQUALITY ); } } // take over BitmapEx aThumbBmp = aBmpEx; if( ( aBmpSize.Width() <= S_THUMB ) && ( aBmpSize.Height() <= S_THUMB ) ) { aThumbBmp.Convert( BMP_CONVERSION_8BIT_COLORS ); bRet = true; } else { const float fFactor = (float) aBmpSize.Width() / aBmpSize.Height(); const Size aNewSize( std::max( (long) (fFactor < 1. ? S_THUMB * fFactor : S_THUMB), 8L ), std::max( (long) (fFactor < 1. ? S_THUMB : S_THUMB / fFactor), 8L ) ); if(aThumbBmp.Scale( (double) aNewSize.Width() / aBmpSize.Width(), (double) aNewSize.Height() / aBmpSize.Height(), BMP_SCALE_BESTQUALITY ) ) { aThumbBmp.Convert( BMP_CONVERSION_8BIT_COLORS ); bRet = true; } } } } else if( rGraphic.GetType() == GRAPHIC_GDIMETAFILE ) { const Size aPrefSize( rGraphic.GetPrefSize() ); const double fFactor = (double)aPrefSize.Width() / (double)aPrefSize.Height(); Size aSize( S_THUMB, S_THUMB ); if ( fFactor < 1.0 ) aSize.Width() = (sal_Int32)( S_THUMB * fFactor ); else aSize.Height() = (sal_Int32)( S_THUMB / fFactor ); const GraphicConversionParameters aParameters(aSize, false, true, true /*TODO: extra ", true" post-#i121194#*/); aThumbBmp = rGraphic.GetBitmapEx(aParameters); if( !aThumbBmp.IsEmpty() ) { aThumbBmp.Convert( BMP_CONVERSION_8BIT_COLORS ); bRet = true; } } return bRet; } void SgaObject::WriteData( SvStream& rOut, const OUString& rDestDir ) const { static const sal_uInt32 nInventor = COMPAT_FORMAT( 'S', 'G', 'A', '3' ); rOut.WriteUInt32( nInventor ).WriteUInt16( 0x0004 ).WriteUInt16( GetVersion() ).WriteUInt16( GetObjKind() ); rOut.WriteBool( bIsThumbBmp ); if( bIsThumbBmp ) { const SvStreamCompressFlags nOldCompressMode = rOut.GetCompressMode(); const sal_uIntPtr nOldVersion = rOut.GetVersion(); rOut.SetCompressMode( SvStreamCompressFlags::ZBITMAP ); rOut.SetVersion( SOFFICE_FILEFORMAT_50 ); WriteDIBBitmapEx(aThumbBmp, rOut); rOut.SetVersion( nOldVersion ); rOut.SetCompressMode( nOldCompressMode ); } else WriteGDIMetaFile( rOut, aThumbMtf ); OUString aURLWithoutDestDir = aURL.GetMainURL( INetURLObject::NO_DECODE ); aURLWithoutDestDir = aURLWithoutDestDir.replaceFirst(rDestDir, ""); write_uInt16_lenPrefixed_uInt8s_FromOUString(rOut, aURLWithoutDestDir, RTL_TEXTENCODING_UTF8); } void SgaObject::ReadData(SvStream& rIn, sal_uInt16& rReadVersion ) { sal_uInt32 nTmp32; sal_uInt16 nTmp16; rIn.ReadUInt32( nTmp32 ).ReadUInt16( nTmp16 ).ReadUInt16( rReadVersion ).ReadUInt16( nTmp16 ).ReadCharAsBool( bIsThumbBmp ); if( bIsThumbBmp ) { ReadDIBBitmapEx(aThumbBmp, rIn); } else { ReadGDIMetaFile( rIn, aThumbMtf ); } OUString aTmpStr = read_uInt16_lenPrefixed_uInt8s_ToOUString(rIn, RTL_TEXTENCODING_UTF8); aURL = INetURLObject(aTmpStr); } const OUString SgaObject::GetTitle() const { OUString aReturnValue( aTitle ); if ( !getenv( "GALLERY_SHOW_PRIVATE_TITLE" ) ) { if ( comphelper::string::getTokenCount(aReturnValue, ':') == 3 ) { OUString aPrivateInd ( aReturnValue.getToken( 0, ':' ) ); OUString aResourceName( aReturnValue.getToken( 1, ':' ) ); sal_Int32 nResId ( aReturnValue.getToken( 2, ':' ).toInt32() ); if ( aPrivateInd == "private" && !aResourceName.isEmpty() && ( nResId > 0 ) && ( nResId < 0x10000 ) ) { OString aMgrName(OUStringToOString(aResourceName, RTL_TEXTENCODING_UTF8)); boost::scoped_ptr pResMgr(ResMgr::CreateResMgr( aMgrName.getStr(), Application::GetSettings().GetUILanguageTag() )); if ( pResMgr ) { ResId aResId( (sal_uInt16)nResId, *pResMgr ); aResId.SetRT( RSC_STRING ); if ( pResMgr->IsAvailable( aResId ) ) { aReturnValue = aResId.toString(); } } } } } return aReturnValue; } void SgaObject::SetTitle( const OUString& rTitle ) { aTitle = rTitle; } SvStream& WriteSgaObject( SvStream& rOut, const SgaObject& rObj ) { rObj.WriteData( rOut, "" ); return rOut; } SvStream& ReadSgaObject( SvStream& rIn, SgaObject& rObj ) { sal_uInt16 nReadVersion; rObj.ReadData( rIn, nReadVersion ); rObj.bIsValid = ( rIn.GetError() == ERRCODE_NONE ); return rIn; } SgaObjectBmp::SgaObjectBmp() { } SgaObjectBmp::SgaObjectBmp( const INetURLObject& rURL ) { Graphic aGraphic; OUString aFilter; if ( SGA_IMPORT_NONE != GalleryGraphicImport( rURL, aGraphic, aFilter ) ) Init( aGraphic, rURL ); } SgaObjectBmp::SgaObjectBmp( const Graphic& rGraphic, const INetURLObject& rURL, const OUString& ) { if( FileExists( rURL ) ) Init( rGraphic, rURL ); } void SgaObjectBmp::Init( const Graphic& rGraphic, const INetURLObject& rURL ) { aURL = rURL; bIsValid = CreateThumb( rGraphic ); } void SgaObjectBmp::WriteData( SvStream& rOut, const OUString& rDestDir ) const { // Set version SgaObject::WriteData( rOut, rDestDir ); char aDummy[ 10 ]; rOut.Write( aDummy, 10 ); write_uInt16_lenPrefixed_uInt8s_FromOString(rOut, OString()); //dummy write_uInt16_lenPrefixed_uInt8s_FromOUString(rOut, aTitle, RTL_TEXTENCODING_UTF8); } void SgaObjectBmp::ReadData( SvStream& rIn, sal_uInt16& rReadVersion ) { SgaObject::ReadData( rIn, rReadVersion ); rIn.SeekRel( 10 ); // 16, 16, 32, 16 read_uInt16_lenPrefixed_uInt8s_ToOString(rIn); //dummy if( rReadVersion >= 5 ) aTitle = read_uInt16_lenPrefixed_uInt8s_ToOUString(rIn, RTL_TEXTENCODING_UTF8); } SgaObjectSound::SgaObjectSound() : eSoundType( SOUND_STANDARD ) { } SgaObjectSound::SgaObjectSound( const INetURLObject& rURL ) : eSoundType( SOUND_STANDARD ) { if( FileExists( rURL ) ) { aURL = rURL; aThumbBmp = Bitmap( Size( 1, 1 ), 1 ); bIsValid = true; } else bIsValid = false; } SgaObjectSound::~SgaObjectSound() { } BitmapEx SgaObjectSound::GetThumbBmp() const { sal_uInt16 nId; switch( eSoundType ) { case( SOUND_COMPUTER ): nId = RID_SVXBMP_GALLERY_SOUND_1; break; case( SOUND_MISC ): nId = RID_SVXBMP_GALLERY_SOUND_2; break; case( SOUND_MUSIC ): nId = RID_SVXBMP_GALLERY_SOUND_3; break; case( SOUND_NATURE ): nId = RID_SVXBMP_GALLERY_SOUND_4; break; case( SOUND_SPEECH ): nId = RID_SVXBMP_GALLERY_SOUND_5; break; case( SOUND_TECHNIC ): nId = RID_SVXBMP_GALLERY_SOUND_6; break; case( SOUND_ANIMAL ): nId = RID_SVXBMP_GALLERY_SOUND_7; break; // standard default: nId = RID_SVXBMP_GALLERY_MEDIA; break; } const BitmapEx aBmpEx( GAL_RES( nId ) ); return aBmpEx; } void SgaObjectSound::WriteData( SvStream& rOut, const OUString& rDestDir ) const { SgaObject::WriteData( rOut, rDestDir ); rOut.WriteUInt16( eSoundType ); write_uInt16_lenPrefixed_uInt8s_FromOUString(rOut, aTitle, RTL_TEXTENCODING_UTF8); } void SgaObjectSound::ReadData( SvStream& rIn, sal_uInt16& rReadVersion ) { SgaObject::ReadData( rIn, rReadVersion ); if( rReadVersion >= 5 ) { sal_uInt16 nTmp16; rIn.ReadUInt16( nTmp16 ); eSoundType = (GalSoundType) nTmp16; if( rReadVersion >= 6 ) aTitle = read_uInt16_lenPrefixed_uInt8s_ToOUString(rIn, RTL_TEXTENCODING_UTF8); } } SgaObjectAnim::SgaObjectAnim() { } SgaObjectAnim::SgaObjectAnim( const Graphic& rGraphic, const INetURLObject& rURL, const OUString& ) { aURL = rURL; bIsValid = CreateThumb( rGraphic ); } SgaObjectINet::SgaObjectINet() { } SgaObjectINet::SgaObjectINet( const Graphic& rGraphic, const INetURLObject& rURL, const OUString& rFormatName ) : SgaObjectAnim ( rGraphic, rURL, rFormatName ) { } SgaObjectSvDraw::SgaObjectSvDraw() { } SgaObjectSvDraw::SgaObjectSvDraw( const FmFormModel& rModel, const INetURLObject& rURL ) { aURL = rURL; bIsValid = CreateThumb( rModel ); } SvxGalleryDrawModel::SvxGalleryDrawModel() : mpFormModel( 0 ) { const OUString sFactoryURL("sdraw"); mxDoc = SfxObjectShell::CreateObjectByFactoryName( sFactoryURL ); if( mxDoc.Is() ) { mxDoc->DoInitNew(0); uno::Reference< lang::XUnoTunnel > xTunnel( mxDoc->GetModel(), uno::UNO_QUERY ); if( xTunnel.is() ) { mpFormModel = dynamic_cast< FmFormModel* >( reinterpret_cast(xTunnel->getSomething(SdrModel::getUnoTunnelImplementationId()))); if( mpFormModel ) { mpFormModel->InsertPage( mpFormModel->AllocPage( false ) ); } } } } SvxGalleryDrawModel::~SvxGalleryDrawModel() { if( mxDoc.Is() ) mxDoc->DoClose(); } SgaObjectSvDraw::SgaObjectSvDraw( SvStream& rIStm, const INetURLObject& rURL ) { SvxGalleryDrawModel aModel; if( aModel.GetModel() ) { if( GallerySvDrawImport( rIStm, *aModel.GetModel() ) ) { aURL = rURL; bIsValid = CreateThumb( *aModel.GetModel() ); } } } bool SgaObjectSvDraw::CreateThumb( const FmFormModel& rModel ) { Graphic aGraphic; ImageMap aImageMap; bool bRet = false; if ( CreateIMapGraphic( rModel, aGraphic, aImageMap ) ) { bRet = SgaObject::CreateThumb( aGraphic ); } else { const FmFormPage* pPage = static_cast< const FmFormPage* >(rModel.GetPage(0)); if(pPage) { const Rectangle aObjRect(pPage->GetAllObjBoundRect()); if(aObjRect.GetWidth() && aObjRect.GetHeight()) { ScopedVclPtrInstance< VirtualDevice > pVDev; FmFormView aView(const_cast< FmFormModel* >(&rModel), pVDev); aView.ShowSdrPage(const_cast< FmFormPage* >(pPage)); aView.MarkAllObj(); aThumbBmp = aView.GetMarkedObjBitmapEx(); const Size aDiscreteSize(aThumbBmp.GetSizePixel()); if(aDiscreteSize.Width() && aDiscreteSize.Height()) { sal_uInt32 nTargetSizeX(S_THUMB); sal_uInt32 nTargetSizeY(S_THUMB); if(aDiscreteSize.Width() > aDiscreteSize.Height()) { nTargetSizeY = (aDiscreteSize.Height() * nTargetSizeX) / aDiscreteSize.Width(); } else { nTargetSizeX = (aDiscreteSize.Width() * nTargetSizeY) / aDiscreteSize.Height(); } if(!!aThumbBmp) { aThumbBmp.Scale(Size(nTargetSizeX, nTargetSizeY), BMP_SCALE_BESTQUALITY); aThumbBmp.Convert(BMP_CONVERSION_8BIT_COLORS); bRet = true; } } } } } return bRet; } void SgaObjectSvDraw::WriteData( SvStream& rOut, const OUString& rDestDir ) const { SgaObject::WriteData( rOut, rDestDir ); write_uInt16_lenPrefixed_uInt8s_FromOUString(rOut, aTitle, RTL_TEXTENCODING_UTF8); } void SgaObjectSvDraw::ReadData( SvStream& rIn, sal_uInt16& rReadVersion ) { SgaObject::ReadData( rIn, rReadVersion ); if( rReadVersion >= 5 ) aTitle = read_uInt16_lenPrefixed_uInt8s_ToOUString(rIn, RTL_TEXTENCODING_UTF8); } /* vim:set shiftwidth=4 softtabstop=4 expandtab: */