Files
libreoffice/vcl/source/gdi/salmisc.cxx
Jan Holesovsky 83380a7805 Merge commit 'ooo/DEV300_m106' into libreoffice-3-4
Conflicts:
	cppcanvas/source/mtfrenderer/transparencygroupaction.cxx
	l10ntools/scripts/localize.pl
	l10ntools/source/directory.cxx
	l10ntools/source/srciter.cxx
	padmin/Executable_spadmin.bin.mk
	padmin/Library_spa.mk
	svtools/inc/svtools/filter.hxx
	svtools/inc/svtools/grfmgr.hxx
	svtools/source/filter/filter.cxx
	svtools/source/filter/filter2.cxx
	svtools/source/filter/wmf/emfwr.cxx
	svtools/source/filter/wmf/enhwmf.cxx
	svtools/source/filter/wmf/winmtf.cxx
	svtools/source/filter/wmf/winmtf.hxx
	svtools/source/filter/wmf/winwmf.cxx
	svtools/source/filter/wmf/wmfwr.cxx
	svtools/source/graphic/grfmgr.cxx
	svtools/source/graphic/grfmgr2.cxx
	toolkit/source/controls/controlmodelcontainerbase.cxx
	toolkit/source/controls/unocontrol.cxx
	toolkit/source/helper/formpdfexport.cxx
	toolkit/source/helper/unowrapper.cxx
	vcl/Package_osx.mk
	vcl/aqua/source/app/salinst.cxx
	vcl/aqua/source/app/salsys.cxx
	vcl/aqua/source/dtrans/aqua_service.cxx
	vcl/aqua/source/dtrans/test_aquacb.cxx
	vcl/aqua/source/res/makefile.mk
	vcl/aqua/source/window/salframe.cxx
	vcl/aqua/source/window/salframeview.mm
	vcl/inc/aqua/salgdi.h
	vcl/inc/aqua/salinst.h
	vcl/inc/graphite_adaptors.hxx
	vcl/inc/graphite_cache.hxx
	vcl/inc/graphite_serverfont.hxx
	vcl/inc/impprn.hxx
	vcl/inc/svdata.hxx
	vcl/inc/unx/i18n_status.hxx
	vcl/inc/unx/saldata.hxx
	vcl/inc/unx/salfont.h
	vcl/inc/unx/salinst.h
	vcl/inc/unx/salprn.h
	vcl/inc/unx/salsys.h
	vcl/inc/unx/sm.hxx
	vcl/inc/vcl/gdimtf.hxx
	vcl/inc/vcl/graph.hxx
	vcl/inc/vcl/outdev.hxx
	vcl/inc/vcl/polyscan.hxx
	vcl/inc/vcl/svcompat.hxx
	vcl/inc/vcl/svgread.hxx
	vcl/inc/vcl/unobrok.hxx
	vcl/inc/win/salgdi.h
	vcl/inc/win/wincomp.hxx
	vcl/prj/d.lst
	vcl/source/app/dbggui.cxx
	vcl/source/app/idlemgr.cxx
	vcl/source/app/makefile.mk
	vcl/source/app/settings.cxx
	vcl/source/app/sound.cxx
	vcl/source/app/stdtext.cxx
	vcl/source/app/svapp.cxx
	vcl/source/app/svdata.cxx
	vcl/source/app/svmain.cxx
	vcl/source/app/timer.cxx
	vcl/source/app/unohelp.cxx
	vcl/source/components/dtranscomp.cxx
	vcl/source/control/button.cxx
	vcl/source/control/combobox.cxx
	vcl/source/control/ctrl.cxx
	vcl/source/control/edit.cxx
	vcl/source/control/field2.cxx
	vcl/source/control/ilstbox.cxx
	vcl/source/gdi/bitmap.cxx
	vcl/source/gdi/bitmapex.cxx
	vcl/source/gdi/cvtgrf.cxx
	vcl/source/gdi/font.cxx
	vcl/source/gdi/image.cxx
	vcl/source/gdi/imagerepository.cxx
	vcl/source/gdi/impbmp.cxx
	vcl/source/gdi/impgraph.cxx
	vcl/source/gdi/impimagetree.cxx
	vcl/source/gdi/jobset.cxx
	vcl/source/gdi/makefile.mk
	vcl/source/gdi/metaact.cxx
	vcl/source/gdi/outdev.cxx
	vcl/source/gdi/outdev2.cxx
	vcl/source/gdi/outdev5.cxx
	vcl/source/gdi/outdev6.cxx
	vcl/source/gdi/outmap.cxx
	vcl/source/gdi/polyscan.cxx
	vcl/source/gdi/print.cxx
	vcl/source/gdi/print2.cxx
	vcl/source/gdi/region.cxx
	vcl/source/gdi/salgdilayout.cxx
	vcl/source/gdi/sallayout.cxx
	vcl/source/gdi/svcompat.cxx
	vcl/source/gdi/virdev.cxx
	vcl/source/glyphs/gcach_ftyp.cxx
	vcl/source/glyphs/gcach_vdev.cxx
	vcl/source/glyphs/gcach_vdev.hxx
	vcl/source/glyphs/graphite_adaptors.cxx
	vcl/source/glyphs/graphite_cache.cxx
	vcl/source/glyphs/graphite_layout.cxx
	vcl/source/glyphs/graphite_serverfont.cxx
	vcl/source/glyphs/graphite_textsrc.hxx
	vcl/source/glyphs/makefile.mk
	vcl/source/src/makefile.mk
	vcl/source/window/accel.cxx
	vcl/source/window/brdwin.cxx
	vcl/source/window/btndlg.cxx
	vcl/source/window/dialog.cxx
	vcl/source/window/dndevdis.cxx
	vcl/source/window/dockmgr.cxx
	vcl/source/window/dockwin.cxx
	vcl/source/window/floatwin.cxx
	vcl/source/window/introwin.cxx
	vcl/source/window/keycod.cxx
	vcl/source/window/menu.cxx
	vcl/source/window/msgbox.cxx
	vcl/source/window/scrwnd.cxx
	vcl/source/window/split.cxx
	vcl/source/window/splitwin.cxx
	vcl/source/window/status.cxx
	vcl/source/window/syswin.cxx
	vcl/source/window/tabpage.cxx
	vcl/source/window/toolbox.cxx
	vcl/source/window/toolbox2.cxx
	vcl/source/window/window.cxx
	vcl/source/window/window2.cxx
	vcl/source/window/winproc.cxx
	vcl/source/window/wrkwin.cxx
	vcl/unx/generic/app/i18n_cb.cxx
	vcl/unx/generic/app/i18n_ic.cxx
	vcl/unx/generic/app/saldata.cxx
	vcl/unx/generic/app/saldisp.cxx
	vcl/unx/generic/app/salinst.cxx
	vcl/unx/generic/app/wmadaptor.cxx
	vcl/unx/generic/fontmanager/afm_hash.cpp
	vcl/unx/generic/gdi/salbmp.cxx
	vcl/unx/generic/gdi/salgdi3.cxx
	vcl/unx/generic/gdi/xrender_peer.cxx
	vcl/unx/generic/window/salframe.cxx
	vcl/unx/generic/window/salobj.cxx
	vcl/unx/gtk/a11y/makefile.mk
	vcl/unx/gtk/app/gtksys.cxx
	vcl/unx/gtk/app/makefile.mk
	vcl/unx/gtk/window/gtkframe.cxx
	vcl/unx/gtk/window/gtkobject.cxx
	vcl/unx/headless/svpinst.cxx
	vcl/unx/headless/svpinst.hxx
	vcl/unx/headless/svpprn.hxx
	vcl/unx/kde/kdedata.cxx
	vcl/unx/kde/salnativewidgets-kde.cxx
	vcl/unx/kde4/KDESalDisplay.hxx
	vcl/unx/kde4/KDEXLib.cxx
	vcl/unx/kde4/KDEXLib.hxx
	vcl/unx/kde4/VCLKDEApplication.cxx
	vcl/unx/kde4/makefile.mk
	vcl/unx/source/app/makefile.mk
	vcl/unx/source/fontmanager/makefile.mk
	vcl/unx/source/gdi/makefile.mk
	vcl/unx/source/inc/salcursors.h
	vcl/util/linksvp/makefile.mk
	vcl/win/source/app/saldata.cxx
	vcl/win/source/app/salinst.cxx
	vcl/win/source/app/salshl.cxx
	vcl/win/source/gdi/makefile.mk
	vcl/win/source/gdi/salbmp.cxx
	vcl/win/source/gdi/salgdi.cxx
	vcl/win/source/gdi/salgdi2.cxx
	vcl/win/source/gdi/salgdi3.cxx
	vcl/win/source/gdi/salgdi_gdiplus.cxx
	vcl/win/source/gdi/salprn.cxx
	vcl/win/source/gdi/salvd.cxx
	vcl/win/source/gdi/winlayout.cxx
	vcl/win/source/window/salframe.cxx
	vcl/win/source/window/salmenu.cxx
	vcl/win/source/window/salobj.cxx
2011-04-22 15:09:06 +02:00

520 lines
19 KiB
C++

/* -*- 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_vcl.hxx"
#include <rtl/memory.h>
#include <vcl/bmpacc.hxx>
#include <vcl/salbtype.hxx>
#include <bmpfast.hxx>
// -----------
// - Defines -
// -----------
#define IMPL_CASE_GET_FORMAT( Format ) \
case( BMP_FORMAT##Format ): \
pFncGetPixel = BitmapReadAccess::GetPixelFor##Format; \
break
// -----------------------------------------------------------------------------
#define IMPL_CASE_SET_FORMAT( Format, BitCount ) \
case( BMP_FORMAT##Format ): \
{ \
pFncSetPixel = BitmapReadAccess::SetPixelFor##Format; \
pDstBuffer->mnBitCount = BitCount; \
} \
break
// -----------------------------------------------------------------------------
#define DOUBLE_SCANLINES() \
while( ( nActY < nHeight1 ) && ( pMapY[ nActY + 1 ] == nMapY ) ) \
{ \
memcpy( pDstScanMap[ nActY + 1L ], pDstScan, rDstBuffer.mnScanlineSize ); \
nActY++; \
}
// -----------
// - Inlines -
// -----------
#define TC_TO_PAL_COLORS 4096
static long ImplIndexFromColor( const BitmapColor& rCol )
{
#if TC_TO_PAL_COLORS == 4096
return( ( ( (long) rCol.GetBlue() >> 4L) << 8L ) |
( ( (long) rCol.GetGreen() >> 4L ) << 4L ) |
( (long) rCol.GetRed() >> 4L ) );
#elif TC_TO_PAL_COLORS == 32768
return( ( ( (long) rCol.GetBlue() >> 3L) << 10L ) |
( ( (long) rCol.GetGreen() >> 3L ) << 5L ) |
( (long) rCol.GetRed() >> 3L ) );
#endif
}
#define COLOR_TO_INDEX( _def_rCol )
// ------------------------
// - conversion functions -
// ------------------------
static void ImplPALToPAL( const BitmapBuffer& rSrcBuffer, BitmapBuffer& rDstBuffer,
FncGetPixel pFncGetPixel, FncSetPixel pFncSetPixel,
Scanline* pSrcScanMap, Scanline* pDstScanMap, long* pMapX, long* pMapY )
{
const long nWidth = rDstBuffer.mnWidth, nHeight = rDstBuffer.mnHeight, nHeight1 = nHeight - 1;
const ColorMask& rSrcMask = rSrcBuffer.maColorMask;
const ColorMask& rDstMask = rDstBuffer.maColorMask;
BitmapPalette aColMap( rSrcBuffer.maPalette.GetEntryCount() );
BitmapColor* pColMapBuf = aColMap.ImplGetColorBuffer();
BitmapColor aIndex( 0 );
for( sal_uInt16 i = 0, nSrcCount = aColMap.GetEntryCount(), nDstCount = rDstBuffer.maPalette.GetEntryCount(); i < nSrcCount; i++ )
{
if( ( i < nDstCount ) && ( rSrcBuffer.maPalette[ i ] == rDstBuffer.maPalette[ i ] ) )
aIndex.SetIndex( sal::static_int_cast<sal_uInt8>(i) );
else
aIndex.SetIndex( sal::static_int_cast<sal_uInt8>(rDstBuffer.maPalette.GetBestIndex( rSrcBuffer.maPalette[ i ] )) );
pColMapBuf[ i ] = aIndex;
}
for( long nActY = 0, nMapY; nActY < nHeight; nActY++ )
{
Scanline pSrcScan( pSrcScanMap[ nMapY = pMapY[ nActY ] ] ), pDstScan( pDstScanMap[ nActY ] );
for( long nX = 0L; nX < nWidth; nX++ )
pFncSetPixel( pDstScan, nX, pColMapBuf[ pFncGetPixel( pSrcScan, pMapX[ nX ], rSrcMask ).GetIndex() ], rDstMask );
DOUBLE_SCANLINES();
}
}
// -----------------------------------------------------------------------------
static void ImplPALToTC( const BitmapBuffer& rSrcBuffer, BitmapBuffer& rDstBuffer,
FncGetPixel pFncGetPixel, FncSetPixel pFncSetPixel,
Scanline* pSrcScanMap, Scanline* pDstScanMap, long* pMapX, long* pMapY )
{
const long nWidth = rDstBuffer.mnWidth, nHeight = rDstBuffer.mnHeight, nHeight1 = nHeight - 1;
const ColorMask& rSrcMask = rSrcBuffer.maColorMask;
const ColorMask& rDstMask = rDstBuffer.maColorMask;
const BitmapColor* pColBuf = rSrcBuffer.maPalette.ImplGetColorBuffer();
if( BMP_SCANLINE_FORMAT( rSrcBuffer.mnFormat ) == BMP_FORMAT_1BIT_MSB_PAL )
{
const BitmapColor aCol0( pColBuf[ 0 ] );
const BitmapColor aCol1( pColBuf[ 1 ] );
long nMapX;
for( long nActY = 0, nMapY; nActY < nHeight; nActY++ )
{
Scanline pSrcScan( pSrcScanMap[ nMapY = pMapY[ nActY ] ] ), pDstScan( pDstScanMap[ nActY ] );
for( long nX = 0L; nX < nWidth; )
{
nMapX = pMapX[ nX ];
pFncSetPixel( pDstScan, nX++,
pSrcScan[ nMapX >> 3 ] & ( 1 << ( 7 - ( nMapX & 7 ) ) ) ? aCol1 : aCol0,
rDstMask );
}
DOUBLE_SCANLINES();
}
}
else if( BMP_SCANLINE_FORMAT( rSrcBuffer.mnFormat ) == BMP_FORMAT_4BIT_MSN_PAL )
{
long nMapX;
for( long nActY = 0, nMapY; nActY < nHeight; nActY++ )
{
Scanline pSrcScan( pSrcScanMap[ nMapY = pMapY[ nActY ] ] ), pDstScan( pDstScanMap[ nActY ] );
for( long nX = 0L; nX < nWidth; )
{
nMapX = pMapX[ nX ];
pFncSetPixel( pDstScan, nX++,
pColBuf[ ( pSrcScan[ nMapX >> 1 ] >> ( nMapX & 1 ? 0 : 4 ) ) & 0x0f ],
rDstMask );
}
DOUBLE_SCANLINES();
}
}
else if( BMP_SCANLINE_FORMAT( rSrcBuffer.mnFormat ) == BMP_FORMAT_8BIT_PAL )
{
for( long nActY = 0, nMapY; nActY < nHeight; nActY++ )
{
Scanline pSrcScan( pSrcScanMap[ nMapY = pMapY[ nActY ] ] ), pDstScan( pDstScanMap[ nActY ] );
for( long nX = 0L; nX < nWidth; nX++ )
pFncSetPixel( pDstScan, nX, pColBuf[ pSrcScan[ pMapX[ nX ] ] ], rDstMask );
DOUBLE_SCANLINES();
}
}
else
{
for( long nActY = 0, nMapY; nActY < nHeight; nActY++ )
{
Scanline pSrcScan( pSrcScanMap[ nMapY = pMapY[ nActY ] ] ), pDstScan( pDstScanMap[ nActY ] );
for( long nX = 0L; nX < nWidth; nX++ )
pFncSetPixel( pDstScan, nX, pColBuf[ pFncGetPixel( pSrcScan, pMapX[ nX ], rSrcMask ).GetIndex() ], rDstMask );
DOUBLE_SCANLINES();
}
}
}
// -----------------------------------------------------------------------------
static void ImplTCToTC( const BitmapBuffer& rSrcBuffer, BitmapBuffer& rDstBuffer,
FncGetPixel pFncGetPixel, FncSetPixel pFncSetPixel,
Scanline* pSrcScanMap, Scanline* pDstScanMap, long* pMapX, long* pMapY )
{
const long nWidth = rDstBuffer.mnWidth, nHeight = rDstBuffer.mnHeight, nHeight1 = nHeight - 1;
const ColorMask& rSrcMask = rSrcBuffer.maColorMask;
const ColorMask& rDstMask = rDstBuffer.maColorMask;
if( BMP_SCANLINE_FORMAT( rSrcBuffer.mnFormat ) == BMP_FORMAT_24BIT_TC_BGR )
{
BitmapColor aCol;
sal_uInt8* pPixel = NULL;
for( long nActY = 0, nMapY; nActY < nHeight; nActY++ )
{
Scanline pSrcScan( pSrcScanMap[ nMapY = pMapY[ nActY ] ] ), pDstScan( pDstScanMap[ nActY ] );
for( long nX = 0L; nX < nWidth; nX++ )
{
aCol.SetBlue( *( pPixel = ( pSrcScan + pMapX[ nX ] * 3 ) )++ );
aCol.SetGreen( *pPixel++ );
aCol.SetRed( *pPixel );
pFncSetPixel( pDstScan, nX, aCol, rDstMask );
}
DOUBLE_SCANLINES()
}
}
else
{
for( long nActY = 0, nMapY; nActY < nHeight; nActY++ )
{
Scanline pSrcScan( pSrcScanMap[ nMapY = pMapY[ nActY ] ] ), pDstScan( pDstScanMap[ nActY ] );
for( long nX = 0L; nX < nWidth; nX++ )
pFncSetPixel( pDstScan, nX, pFncGetPixel( pSrcScan, pMapX[ nX ], rSrcMask ), rDstMask );
DOUBLE_SCANLINES();
}
}
}
// -----------------------------------------------------------------------------
static void ImplTCToPAL( const BitmapBuffer& rSrcBuffer, BitmapBuffer& rDstBuffer,
FncGetPixel pFncGetPixel, FncSetPixel pFncSetPixel,
Scanline* pSrcScanMap, Scanline* pDstScanMap, long* pMapX, long* pMapY )
{
const long nWidth = rDstBuffer.mnWidth, nHeight = rDstBuffer.mnHeight, nHeight1 = nHeight - 1;
const ColorMask& rSrcMask = rSrcBuffer.maColorMask;
const ColorMask& rDstMask = rDstBuffer.maColorMask;
BitmapPalette aColMap( rSrcBuffer.maPalette.GetEntryCount() );
sal_uInt8* pColToPalMap = new sal_uInt8[ TC_TO_PAL_COLORS ];
BitmapColor aIndex( 0 );
for( long nR = 0; nR < 16; nR++ )
{
for( long nG = 0; nG < 16; nG++ )
{
for( long nB = 0; nB < 16; nB++ )
{
BitmapColor aCol( sal::static_int_cast<sal_uInt8>(nR << 4),
sal::static_int_cast<sal_uInt8>(nG << 4),
sal::static_int_cast<sal_uInt8>(nB << 4) );
pColToPalMap[ ImplIndexFromColor( aCol ) ] = (sal_uInt8) rDstBuffer.maPalette.GetBestIndex( aCol );
}
}
}
for( long nActY = 0, nMapY; nActY < nHeight; nActY++ )
{
Scanline pSrcScan( pSrcScanMap[ nMapY = pMapY[ nActY ] ] ), pDstScan( pDstScanMap[ nActY ] );
for( long nX = 0L; nX < nWidth; nX++ )
{
aIndex.SetIndex( pColToPalMap[ ImplIndexFromColor( pFncGetPixel( pSrcScan, pMapX[ nX ], rSrcMask ) ) ] );
pFncSetPixel( pDstScan, nX, aIndex, rDstMask );
}
DOUBLE_SCANLINES();
}
delete[] pColToPalMap;
}
// -----------------------------------------------------------------------------
// ---------------------
// - StretchAndConvert -
// ---------------------
BitmapBuffer* StretchAndConvert( const BitmapBuffer& rSrcBuffer, const SalTwoRect& rTwoRect,
sal_uLong nDstBitmapFormat, BitmapPalette* pDstPal, ColorMask* pDstMask )
{
FncGetPixel pFncGetPixel;
FncSetPixel pFncSetPixel;
BitmapBuffer* pDstBuffer = new BitmapBuffer;
long i;
// set function for getting pixels
switch( BMP_SCANLINE_FORMAT( rSrcBuffer.mnFormat ) )
{
IMPL_CASE_GET_FORMAT( _1BIT_MSB_PAL );
IMPL_CASE_GET_FORMAT( _1BIT_LSB_PAL );
IMPL_CASE_GET_FORMAT( _4BIT_MSN_PAL );
IMPL_CASE_GET_FORMAT( _4BIT_LSN_PAL );
IMPL_CASE_GET_FORMAT( _8BIT_PAL );
IMPL_CASE_GET_FORMAT( _8BIT_TC_MASK );
IMPL_CASE_GET_FORMAT( _16BIT_TC_MSB_MASK );
IMPL_CASE_GET_FORMAT( _16BIT_TC_LSB_MASK );
IMPL_CASE_GET_FORMAT( _24BIT_TC_BGR );
IMPL_CASE_GET_FORMAT( _24BIT_TC_RGB );
IMPL_CASE_GET_FORMAT( _24BIT_TC_MASK );
IMPL_CASE_GET_FORMAT( _32BIT_TC_ABGR );
IMPL_CASE_GET_FORMAT( _32BIT_TC_ARGB );
IMPL_CASE_GET_FORMAT( _32BIT_TC_BGRA );
IMPL_CASE_GET_FORMAT( _32BIT_TC_RGBA );
IMPL_CASE_GET_FORMAT( _32BIT_TC_MASK );
default:
// should never come here
// initialize pFncGetPixel to something valid that is
// least likely to crash
pFncGetPixel = BitmapReadAccess::GetPixelFor_1BIT_MSB_PAL;
OSL_FAIL( "unknown read format" );
break;
}
// set function for setting pixels
const sal_uLong nDstScanlineFormat = BMP_SCANLINE_FORMAT( nDstBitmapFormat );
switch( nDstScanlineFormat )
{
IMPL_CASE_SET_FORMAT( _1BIT_MSB_PAL, 1 );
IMPL_CASE_SET_FORMAT( _1BIT_LSB_PAL, 1 );
IMPL_CASE_SET_FORMAT( _4BIT_MSN_PAL, 1 );
IMPL_CASE_SET_FORMAT( _4BIT_LSN_PAL, 4 );
IMPL_CASE_SET_FORMAT( _8BIT_PAL, 8 );
IMPL_CASE_SET_FORMAT( _8BIT_TC_MASK, 8 );
IMPL_CASE_SET_FORMAT( _16BIT_TC_MSB_MASK, 16 );
IMPL_CASE_SET_FORMAT( _16BIT_TC_LSB_MASK, 16 );
IMPL_CASE_SET_FORMAT( _24BIT_TC_BGR, 24 );
IMPL_CASE_SET_FORMAT( _24BIT_TC_RGB, 24 );
IMPL_CASE_SET_FORMAT( _24BIT_TC_MASK, 24 );
IMPL_CASE_SET_FORMAT( _32BIT_TC_ABGR, 32 );
IMPL_CASE_SET_FORMAT( _32BIT_TC_ARGB, 32 );
IMPL_CASE_SET_FORMAT( _32BIT_TC_BGRA, 32 );
IMPL_CASE_SET_FORMAT( _32BIT_TC_RGBA, 32 );
IMPL_CASE_SET_FORMAT( _32BIT_TC_MASK, 32 );
default:
// should never come here
// initialize pFncSetPixel to something valid that is
// least likely to crash
pFncSetPixel = BitmapReadAccess::SetPixelFor_1BIT_MSB_PAL;
pDstBuffer->mnBitCount = 1;
OSL_FAIL( "unknown write format" );
break;
}
// fill destination buffer
pDstBuffer->mnFormat = nDstBitmapFormat;
pDstBuffer->mnWidth = rTwoRect.mnDestWidth;
pDstBuffer->mnHeight = rTwoRect.mnDestHeight;
pDstBuffer->mnScanlineSize = AlignedWidth4Bytes( pDstBuffer->mnBitCount * pDstBuffer->mnWidth );
try
{
pDstBuffer->mpBits = new sal_uInt8[ pDstBuffer->mnScanlineSize * pDstBuffer->mnHeight ];
}
catch( const std::bad_alloc& )
{
// memory exception, clean up
pDstBuffer->mpBits = NULL;
delete pDstBuffer;
return NULL;
}
// do we need a destination palette or color mask?
if( ( nDstScanlineFormat == BMP_FORMAT_1BIT_MSB_PAL ) ||
( nDstScanlineFormat == BMP_FORMAT_1BIT_LSB_PAL ) ||
( nDstScanlineFormat == BMP_FORMAT_4BIT_MSN_PAL ) ||
( nDstScanlineFormat == BMP_FORMAT_4BIT_LSN_PAL ) ||
( nDstScanlineFormat == BMP_FORMAT_8BIT_PAL ) )
{
DBG_ASSERT( pDstPal, "destination buffer requires palette" );
pDstBuffer->maPalette = *pDstPal;
}
else if( ( nDstScanlineFormat == BMP_FORMAT_8BIT_TC_MASK ) ||
( nDstScanlineFormat == BMP_FORMAT_16BIT_TC_MSB_MASK ) ||
( nDstScanlineFormat == BMP_FORMAT_16BIT_TC_LSB_MASK ) ||
( nDstScanlineFormat == BMP_FORMAT_24BIT_TC_MASK ) ||
( nDstScanlineFormat == BMP_FORMAT_32BIT_TC_MASK ) )
{
DBG_ASSERT( pDstMask, "destination buffer requires color mask" );
pDstBuffer->maColorMask = *pDstMask;
}
// short circuit the most important conversions
bool bFastConvert = ImplFastBitmapConversion( *pDstBuffer, rSrcBuffer, rTwoRect );
if( bFastConvert )
return pDstBuffer;
const long nSrcX = rTwoRect.mnSrcX, nSrcY = rTwoRect.mnSrcY;
const long nSrcDX = rTwoRect.mnSrcWidth, nSrcDY = rTwoRect.mnSrcHeight;
const long nDstDX = rTwoRect.mnDestWidth, nDstDY = rTwoRect.mnDestHeight;
Scanline* pSrcScan = NULL;
Scanline* pDstScan = NULL;
long* pMapX = NULL;
long* pMapY = NULL;
long nTmp, nOffset;
try
{
pSrcScan = new Scanline[ rSrcBuffer.mnHeight ];
pDstScan = new Scanline[ nDstDY ];
pMapX = new long[ nDstDX ];
pMapY = new long[ nDstDY ];
}
catch( const std::bad_alloc& )
{
// memory exception, clean up
// remark: the buffer ptr causing the exception
// is still NULL here
delete[] pSrcScan;
delete[] pDstScan;
delete[] pMapX;
delete[] pMapY;
delete pDstBuffer;
return NULL;
}
// horizontal mapping table
if( nDstDX != nSrcDX )
{
const double fFactorX = ( nDstDX > 1 ) ? (double) ( nSrcDX - 1 ) / ( nDstDX - 1 ) : 0.0;
for( i = 0L; i < nDstDX; i++ )
pMapX[ i ] = nSrcX + FRound( i * fFactorX );
}
else
{
for( i = 0L, nTmp = nSrcX; i < nDstDX; i++ )
pMapX[ i ] = nTmp++;
}
// vertical mapping table
if( nDstDY != nSrcDY )
{
const double fFactorY = ( nDstDY > 1 ) ? (double) ( nSrcDY - 1 ) / ( nDstDY - 1 ) : 0.0;
for( i = 0L; i < nDstDY; i++ )
pMapY[ i ] = nSrcY + FRound( i * fFactorY );
}
else
{
for( i = 0L, nTmp = nSrcY; i < nDstDY; i++ )
pMapY[ i ] = nTmp++;
}
// source scanline buffer
Scanline pTmpScan;
if( BMP_SCANLINE_ADJUSTMENT( rSrcBuffer.mnFormat ) == BMP_FORMAT_TOP_DOWN )
pTmpScan = rSrcBuffer.mpBits, nOffset = rSrcBuffer.mnScanlineSize;
else
{
pTmpScan = rSrcBuffer.mpBits + ( rSrcBuffer.mnHeight - 1 ) * rSrcBuffer.mnScanlineSize;
nOffset = -rSrcBuffer.mnScanlineSize;
}
for( i = 0L; i < rSrcBuffer.mnHeight; i++, pTmpScan += nOffset )
pSrcScan[ i ] = pTmpScan;
// destination scanline buffer
if( BMP_SCANLINE_ADJUSTMENT( pDstBuffer->mnFormat ) == BMP_FORMAT_TOP_DOWN )
pTmpScan = pDstBuffer->mpBits, nOffset = pDstBuffer->mnScanlineSize;
else
{
pTmpScan = pDstBuffer->mpBits + ( nDstDY - 1 ) * pDstBuffer->mnScanlineSize;
nOffset = -pDstBuffer->mnScanlineSize;
}
for( i = 0L; i < nDstDY; i++, pTmpScan += nOffset )
pDstScan[ i ] = pTmpScan;
// do buffer scaling and conversion
if( rSrcBuffer.mnBitCount <= 8 && pDstBuffer->mnBitCount <= 8 )
{
ImplPALToPAL( rSrcBuffer, *pDstBuffer, pFncGetPixel, pFncSetPixel,
pSrcScan, pDstScan, pMapX, pMapY );
}
else if( rSrcBuffer.mnBitCount <= 8 && pDstBuffer->mnBitCount > 8 )
{
ImplPALToTC( rSrcBuffer, *pDstBuffer, pFncGetPixel, pFncSetPixel,
pSrcScan, pDstScan, pMapX, pMapY );
}
else if( rSrcBuffer.mnBitCount > 8 && pDstBuffer->mnBitCount > 8 )
{
ImplTCToTC( rSrcBuffer, *pDstBuffer, pFncGetPixel, pFncSetPixel,
pSrcScan, pDstScan, pMapX, pMapY );
}
else
{
ImplTCToPAL( rSrcBuffer, *pDstBuffer, pFncGetPixel, pFncSetPixel,
pSrcScan, pDstScan, pMapX, pMapY );
}
// cleanup
delete[] pSrcScan;
delete[] pDstScan;
delete[] pMapX;
delete[] pMapY;
return pDstBuffer;
}
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */