/* -*- 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 <sal/config.h>
#include <com/sun/star/frame/XModel.hpp>
#include <sfx2/objsh.hxx>
#include <comphelper/fileformat.h>
#include <comphelper/servicehelper.hxx>
#include <tools/vcompat.hxx>
#include <tools/helpers.hxx>
#include <vcl/virdev.hxx>
#include <svx/fmmodel.hxx>
#include <svx/fmview.hxx>
#include <svx/fmpage.hxx>
#include <svx/galmisc.hxx>
#include <galobj.hxx>
#include <vcl/dibtools.hxx>
#include <vcl/filter/SvmReader.hxx>
#include <vcl/filter/SvmWriter.hxx>
#include "gallerydrawmodel.hxx"
#include <bitmaps.hlst>
using namespace ::com::sun::star;
SgaObject::SgaObject()
: bIsValid (
false ),
bIsThumbBmp (
true )
{
}
SgaObject::SgaObject(
const SgaObject& aObject)
: aThumbBmp(aObject.aThumbBmp)
, aThumbMtf(aObject.aThumbMtf)
, aURL(aObject.aURL)
, aTitle(aObject.aTitle)
, bIsValid(aObject.bIsValid)
, bIsThumbBmp(aObject.bIsThumbBmp)
{
}
BitmapEx SgaObject::createPreviewBitmapEx(
const Size& rSizePixel)
const
{
BitmapEx aRetval;
if (rSizePixel.Width() && rSizePixel.Height())
{
if (SgaObjKind::Sound == GetObjKind())
{
aRetval = BitmapEx(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(
static_cast <
double >(rSizePixel.Width()) /
static_cast <
double >(aCurr
entSizePixel.Width()));
const double fScaleY(static_cast <double >(rSizePixel.Height()) / static_cast <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)
{
aRetval.Scale(fScale, fScale, BmpScaleFlag::BestQuality);
}
}
}
return aRetval;
}
bool SgaObject::CreateThumb( const Graphic& rGraphic )
{
bool bRet = false ;
if ( rGraphic.GetType() == GraphicType::Bitmap )
{
BitmapEx aBmpEx( rGraphic.GetBitmapEx() );
Size aBmpSize( aBmpEx.GetSizePixel() );
if ( aBmpSize.Width() && aBmpSize.Height() )
{
if ( aBmpEx.GetPrefMapMode().GetMapUnit() != MapUnit::MapPixel &&
aBmpEx.GetPrefSize().Width() > 0 &&
aBmpEx.GetPrefSize().Height() > 0 )
{
Size aLogSize( OutputDevice::LogicToLogic(aBmpEx.GetPrefSize(), aBmpEx.GetPrefMapMode(), MapMode(MapUnit::Map100thMM)) );
if ( !aLogSize.IsEmpty() )
{
double fFactorLog = static_cast < double >( aLogSize.Width() ) / aLogSize.Height();
double fFactorPix = static_cast < double >( aBmpSize.Width() ) / aBmpSize.Height();
if ( fFactorPix > fFactorLog )
aBmpSize.setWidth( basegfx::fround<tools::Long >( aBmpSize.Height() * fFactorLog ) );
else
aBmpSize.setHeight( basegfx::fround<tools::Long >( aBmpSize.Width() / fFactorLog ) );
aBmpEx.Scale(aBmpSize, BmpScaleFlag::BestQuality);
}
}
// take over BitmapEx
aThumbBmp = aBmpEx;
if ( ( aBmpSize.Width() <= S_THUMB ) && ( aBmpSize.Height() <= S_THUMB ) )
{
aThumbBmp.Convert( BmpConversion::N8BitColors );
bRet = true ;
}
else
{
const float fFactor = static_cast <float >(aBmpSize.Width()) / aBmpSize.Height();
const Size aNewSize( std::max( tools::Long (fFactor < 1. ? S_THUMB * fFactor : S_THUMB), tools::Long (8) ),
std::max( tools::Long (fFactor < 1. ? S_THUMB : S_THUMB / fFactor), tools::Long (8) ) );
if (aThumbBmp.Scale(
static_cast <double >(aNewSize.Width()) / aBmpSize.Width(),
static_cast <double >(aNewSize.Height()) / aBmpSize.Height(),
BmpScaleFlag::BestQuality ) )
{
aThumbBmp.Convert( BmpConversion::N8BitColors );
bRet = true ;
}
}
}
}
else if ( rGraphic.GetType() == GraphicType::GdiMetafile )
{
const Size aPrefSize( rGraphic.GetPrefSize() );
const double fFactor = static_cast <double >(aPrefSize.Width()) / static_cast <double >(aPrefSize.Height());
Size aSize( S_THUMB, S_THUMB );
if ( fFactor < 1.0 )
aSize.setWidth( static_cast <sal_Int32>( S_THUMB * fFactor ) );
else
aSize.setHeight( static_cast <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( BmpConversion::N8BitColors );
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( static_cast <sal_uInt16>(GetObjKind()) );
rOut.WriteBool( bIsThumbBmp );
if ( bIsThumbBmp )
{
const SvStreamCompressFlags nOldCompressMode = rOut.GetCompressMode();
const sal_Int32 nOldVersion = rOut.GetVersion();
rOut.SetCompressMode( SvStreamCompressFlags::ZBITMAP );
rOut.SetVersion( SOFFICE_FILEFORMAT_50 );
WriteDIBBitmapEx(aThumbBmp, rOut);
rOut.SetVersion( nOldVersion );
rOut.SetCompressMode( nOldCompressMode );
}
else
{
if (!rOut.GetError())
{
SvmWriter aWriter(rOut);
aWriter.Write(aThumbMtf);
}
}
OUString aURLWithoutDestDir = aURL.GetMainURL( INetURLObject::DecodeMechanism::NONE );
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
{
SvmReader aReader( rIn );
aReader.Read( aThumbMtf );
}
OUString aTmpStr = read_uInt16_lenPrefixed_uInt8s_ToOUString(rIn, RTL_TEXTENCODING_UTF8);
aURL = INetURLObject(aTmpStr);
}
OUString const & SgaObject::GetTitle() const
{
return aTitle;
}
void SgaObject::SetTitle( const OUString& rTitle )
{
aTitle = rTitle;
}
SvStream& WriteSgaObject( SvStream& rOut, const SgaObject& rObj )
{
rObj.WriteData( rOut, u"" _ustr );
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 ( GalleryGraphicImportRet::IMPORT_NONE != GalleryGraphicImport( rURL, aGraphic, aFilter ) )
Init( aGraphic, rURL );
}
SgaObjectBmp::SgaObjectBmp( const Graphic& rGraphic, const INetURLObject& rURL )
{
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 const aDummy[ 10 ] = { 0 };
rOut.WriteBytes(aDummy, 10);
write_uInt16_lenPrefixed_uInt8s_FromOString(rOut, "" ); //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), vcl::PixelFormat::N8_BPP);
bIsValid = true ;
}
else
bIsValid = false ;
}
SgaObjectSound::~SgaObjectSound()
{
}
BitmapEx SgaObjectSound::GetThumbBmp() const
{
OUString sId;
switch ( eSoundType )
{
case SOUND_COMPUTER: sId = RID_SVXBMP_GALLERY_SOUND_1; break ;
case SOUND_MISC: sId = RID_SVXBMP_GALLERY_SOUND_2; break ;
case SOUND_MUSIC: sId = RID_SVXBMP_GALLERY_SOUND_3; break ;
case SOUND_NATURE: sId = RID_SVXBMP_GALLERY_SOUND_4; break ;
case SOUND_SPEECH: sId = RID_SVXBMP_GALLERY_SOUND_5; break ;
case SOUND_TECHNIC: sId = RID_SVXBMP_GALLERY_SOUND_6; break ;
case SOUND_ANIMAL: sId = RID_SVXBMP_GALLERY_SOUND_7; break ;
// standard
default :
sId = RID_SVXBMP_GALLERY_MEDIA;
break ;
}
const BitmapEx aBmpEx(sId);
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 = static_cast <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 )
{
aURL = rURL;
bIsValid = CreateThumb( rGraphic );
}
SgaObjectINet::SgaObjectINet()
{
}
SgaObjectINet::SgaObjectINet( const Graphic& rGraphic, const INetURLObject& rURL ) :
SgaObjectAnim ( rGraphic, rURL )
{
}
SgaObjectSvDraw::SgaObjectSvDraw()
{
}
SgaObjectSvDraw::SgaObjectSvDraw( const FmFormModel& rModel, const INetURLObject& rURL )
{
aURL = rURL;
bIsValid = CreateThumb( rModel );
}
SvxGalleryDrawModel::SvxGalleryDrawModel()
: mpFormModel( nullptr )
{
mxDoc = SfxObjectShell::CreateObjectByFactoryName( u"sdraw" _ustr );
if ( !mxDoc.Is() )
return ;
mxDoc->DoInitNew();
mpFormModel
= dynamic_cast <FmFormModel*>(comphelper::getFromUnoTunnel<SdrModel>(mxDoc->GetModel()));
if (mpFormModel)
{
mpFormModel->InsertPage(mpFormModel->AllocPage(false ).get());
}
}
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 tools::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(true );
aGraphic = Graphic(aThumbBmp);
bRet = SgaObject::CreateThumb(aGraphic);
}
}
}
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: */
Messung V0.5 C=96 H=95 G=95
¤ Dauer der Verarbeitung: 0.5 Sekunden
¤
*© Formatika GbR, Deutschland