summaryrefslogtreecommitdiff
path: root/vcl/source/helper
diff options
context:
space:
mode:
Diffstat (limited to 'vcl/source/helper')
-rw-r--r--vcl/source/helper/canvasbitmap.cxx1467
-rw-r--r--vcl/source/helper/canvastools.cxx837
-rw-r--r--vcl/source/helper/evntpost.cxx65
-rw-r--r--vcl/source/helper/lazydelete.cxx125
-rw-r--r--vcl/source/helper/makefile.mk56
-rwxr-xr-xvcl/source/helper/smartid.cxx264
-rw-r--r--vcl/source/helper/strhelper.cxx442
-rw-r--r--vcl/source/helper/threadex.cxx127
-rw-r--r--vcl/source/helper/xconnection.cxx178
9 files changed, 3561 insertions, 0 deletions
diff --git a/vcl/source/helper/canvasbitmap.cxx b/vcl/source/helper/canvasbitmap.cxx
new file mode 100644
index 000000000000..2bc0ab94d272
--- /dev/null
+++ b/vcl/source/helper/canvasbitmap.cxx
@@ -0,0 +1,1467 @@
+/*************************************************************************
+ *
+ * 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 <com/sun/star/util/Endianness.hpp>
+#include <com/sun/star/rendering/ColorComponentTag.hpp>
+#include <com/sun/star/rendering/ColorSpaceType.hpp>
+#include <com/sun/star/rendering/RenderingIntent.hpp>
+
+#include <rtl/instance.hxx>
+#include <vos/mutex.hxx>
+
+#include <tools/diagnose_ex.h>
+#include <vcl/canvasbitmap.hxx>
+#include <vcl/canvastools.hxx>
+#include <vcl/bmpacc.hxx>
+#include <vcl/svapp.hxx>
+
+#include <algorithm>
+
+
+using namespace ::vcl::unotools;
+using namespace ::com::sun::star;
+
+namespace
+{
+ // TODO(Q3): move to o3tl bithacks or somesuch. A similar method is in canvas/canvastools.hxx
+
+ // Good ole HAKMEM tradition. Calc number of 1 bits in 32bit word,
+ // unrolled loop. See e.g. Hackers Delight, p. 66
+ inline sal_Int32 bitcount( sal_uInt32 val )
+ {
+ val = val - ((val >> 1) & 0x55555555);
+ val = (val & 0x33333333) + ((val >> 2) & 0x33333333);
+ val = (val + (val >> 4)) & 0x0F0F0F0F;
+ val = val + (val >> 8);
+ val = val + (val >> 16);
+ return sal_Int32(val & 0x0000003F);
+ }
+}
+
+void VclCanvasBitmap::setComponentInfo( ULONG redShift, ULONG greenShift, ULONG blueShift )
+{
+ // sort channels in increasing order of appearance in the pixel
+ // (starting with the least significant bits)
+ sal_Int8 redPos(0);
+ sal_Int8 greenPos(1);
+ sal_Int8 bluePos(2);
+
+ if( redShift > greenShift )
+ {
+ std::swap(redPos,greenPos);
+ if( redShift > blueShift )
+ {
+ std::swap(redPos,bluePos);
+ if( greenShift > blueShift )
+ std::swap(greenPos,bluePos);
+ }
+ }
+ else
+ {
+ if( greenShift > blueShift )
+ {
+ std::swap(greenPos,bluePos);
+ if( redShift > blueShift )
+ std::swap(redPos,bluePos);
+ }
+ }
+
+ m_aComponentTags.realloc(3);
+ sal_Int8* pTags = m_aComponentTags.getArray();
+ pTags[redPos] = rendering::ColorComponentTag::RGB_RED;
+ pTags[greenPos] = rendering::ColorComponentTag::RGB_GREEN;
+ pTags[bluePos] = rendering::ColorComponentTag::RGB_BLUE;
+
+ m_aComponentBitCounts.realloc(3);
+ sal_Int32* pCounts = m_aComponentBitCounts.getArray();
+ pCounts[redPos] = bitcount(sal::static_int_cast<sal_uInt32>(redShift));
+ pCounts[greenPos] = bitcount(sal::static_int_cast<sal_uInt32>(greenShift));
+ pCounts[bluePos] = bitcount(sal::static_int_cast<sal_uInt32>(blueShift));
+}
+
+VclCanvasBitmap::VclCanvasBitmap( const BitmapEx& rBitmap ) :
+ m_aBmpEx( rBitmap ),
+ m_aBitmap( rBitmap.GetBitmap() ),
+ m_aAlpha(),
+ m_pBmpAcc( m_aBitmap.AcquireReadAccess() ),
+ m_pAlphaAcc( NULL ),
+ m_aComponentTags(),
+ m_aComponentBitCounts(),
+ m_aLayout(),
+ m_nBitsPerInputPixel(0),
+ m_nBitsPerOutputPixel(0),
+ m_nRedIndex(-1),
+ m_nGreenIndex(-1),
+ m_nBlueIndex(-1),
+ m_nAlphaIndex(-1),
+ m_nIndexIndex(-1),
+ m_nEndianness(0),
+ m_bSwap(false),
+ m_bPalette(false)
+{
+ if( m_aBmpEx.IsTransparent() )
+ {
+ m_aAlpha = m_aBmpEx.IsAlpha() ? m_aBmpEx.GetAlpha().GetBitmap() : m_aBmpEx.GetMask();
+ m_pAlphaAcc = m_aAlpha.AcquireReadAccess();
+ }
+
+ m_aLayout.ScanLines = 0;
+ m_aLayout.ScanLineBytes = 0;
+ m_aLayout.ScanLineStride = 0;
+ m_aLayout.PlaneStride = 0;
+ m_aLayout.ColorSpace.clear();
+ m_aLayout.Palette.clear();
+ m_aLayout.IsMsbFirst = sal_False;
+
+ if( m_pBmpAcc )
+ {
+ m_aLayout.ScanLines = m_pBmpAcc->Height();
+ m_aLayout.ScanLineBytes = (m_pBmpAcc->GetBitCount()*m_pBmpAcc->Width() + 7) / 8;
+ m_aLayout.ScanLineStride = m_pBmpAcc->GetScanlineSize();
+ m_aLayout.PlaneStride = 0;
+
+ switch( m_pBmpAcc->GetScanlineFormat() )
+ {
+ case BMP_FORMAT_1BIT_MSB_PAL:
+ m_bPalette = true;
+ m_nBitsPerInputPixel = 1;
+ m_nEndianness = util::Endianness::LITTLE; // doesn't matter
+ m_aLayout.IsMsbFirst = sal_True;
+ break;
+
+ case BMP_FORMAT_1BIT_LSB_PAL:
+ m_bPalette = true;
+ m_nBitsPerInputPixel = 1;
+ m_nEndianness = util::Endianness::LITTLE; // doesn't matter
+ m_aLayout.IsMsbFirst = sal_False;
+ break;
+
+ case BMP_FORMAT_4BIT_MSN_PAL:
+ m_bPalette = true;
+ m_nBitsPerInputPixel = 4;
+ m_nEndianness = util::Endianness::LITTLE; // doesn't matter
+ m_aLayout.IsMsbFirst = sal_True;
+ break;
+
+ case BMP_FORMAT_4BIT_LSN_PAL:
+ m_bPalette = true;
+ m_nBitsPerInputPixel = 4;
+ m_nEndianness = util::Endianness::LITTLE; // doesn't matter
+ m_aLayout.IsMsbFirst = sal_False;
+ break;
+
+ case BMP_FORMAT_8BIT_PAL:
+ m_bPalette = true;
+ m_nBitsPerInputPixel = 8;
+ m_nEndianness = util::Endianness::LITTLE; // doesn't matter
+ m_aLayout.IsMsbFirst = sal_False; // doesn't matter
+ break;
+
+ case BMP_FORMAT_8BIT_TC_MASK:
+ m_bPalette = false;
+ m_nBitsPerInputPixel = 8;
+ m_nEndianness = util::Endianness::LITTLE; // doesn't matter
+ m_aLayout.IsMsbFirst = sal_False; // doesn't matter
+ setComponentInfo( m_pBmpAcc->GetColorMask().GetRedMask(),
+ m_pBmpAcc->GetColorMask().GetGreenMask(),
+ m_pBmpAcc->GetColorMask().GetBlueMask() );
+ break;
+
+ case BMP_FORMAT_16BIT_TC_MSB_MASK:
+ m_bPalette = false;
+ m_nBitsPerInputPixel = 16;
+ m_nEndianness = util::Endianness::BIG;
+ m_aLayout.IsMsbFirst = sal_False; // doesn't matter
+ setComponentInfo( m_pBmpAcc->GetColorMask().GetRedMask(),
+ m_pBmpAcc->GetColorMask().GetGreenMask(),
+ m_pBmpAcc->GetColorMask().GetBlueMask() );
+ break;
+
+ case BMP_FORMAT_16BIT_TC_LSB_MASK:
+ m_bPalette = false;
+ m_nBitsPerInputPixel = 16;
+ m_nEndianness = util::Endianness::LITTLE;
+ m_aLayout.IsMsbFirst = sal_False; // doesn't matter
+ setComponentInfo( m_pBmpAcc->GetColorMask().GetRedMask(),
+ m_pBmpAcc->GetColorMask().GetGreenMask(),
+ m_pBmpAcc->GetColorMask().GetBlueMask() );
+ break;
+
+ case BMP_FORMAT_24BIT_TC_BGR:
+ m_bPalette = false;
+ m_nBitsPerInputPixel = 24;
+ m_nEndianness = util::Endianness::LITTLE;
+ m_aLayout.IsMsbFirst = sal_False; // doesn't matter
+ setComponentInfo( 0xff0000LL,
+ 0x00ff00LL,
+ 0x0000ffLL );
+ break;
+
+ case BMP_FORMAT_24BIT_TC_RGB:
+ m_bPalette = false;
+ m_nBitsPerInputPixel = 24;
+ m_nEndianness = util::Endianness::LITTLE;
+ m_aLayout.IsMsbFirst = sal_False; // doesn't matter
+ setComponentInfo( 0x0000ffLL,
+ 0x00ff00LL,
+ 0xff0000LL );
+ break;
+
+ case BMP_FORMAT_24BIT_TC_MASK:
+ m_bPalette = false;
+ m_nBitsPerInputPixel = 24;
+ m_nEndianness = util::Endianness::LITTLE;
+ m_aLayout.IsMsbFirst = sal_False; // doesn't matter
+ setComponentInfo( m_pBmpAcc->GetColorMask().GetRedMask(),
+ m_pBmpAcc->GetColorMask().GetGreenMask(),
+ m_pBmpAcc->GetColorMask().GetBlueMask() );
+ break;
+
+ case BMP_FORMAT_32BIT_TC_ABGR:
+ {
+ m_bPalette = false;
+ m_nBitsPerInputPixel = 32;
+ m_nEndianness = util::Endianness::LITTLE;
+ m_aLayout.IsMsbFirst = sal_False; // doesn't matter
+
+ m_aComponentTags.realloc(4);
+ sal_Int8* pTags = m_aComponentTags.getArray();
+ pTags[0] = rendering::ColorComponentTag::ALPHA;
+ pTags[1] = rendering::ColorComponentTag::RGB_BLUE;
+ pTags[2] = rendering::ColorComponentTag::RGB_GREEN;
+ pTags[3] = rendering::ColorComponentTag::RGB_RED;
+
+ m_aComponentBitCounts.realloc(4);
+ sal_Int32* pCounts = m_aComponentBitCounts.getArray();
+ pCounts[0] = 8;
+ pCounts[1] = 8;
+ pCounts[2] = 8;
+ pCounts[3] = 8;
+
+ m_nRedIndex = 3;
+ m_nGreenIndex = 2;
+ m_nBlueIndex = 1;
+ m_nAlphaIndex = 0;
+ }
+ break;
+
+ case BMP_FORMAT_32BIT_TC_ARGB:
+ {
+ m_bPalette = false;
+ m_nBitsPerInputPixel = 32;
+ m_nEndianness = util::Endianness::LITTLE;
+ m_aLayout.IsMsbFirst = sal_False; // doesn't matter
+
+ m_aComponentTags.realloc(4);
+ sal_Int8* pTags = m_aComponentTags.getArray();
+ pTags[0] = rendering::ColorComponentTag::ALPHA;
+ pTags[1] = rendering::ColorComponentTag::RGB_RED;
+ pTags[2] = rendering::ColorComponentTag::RGB_GREEN;
+ pTags[3] = rendering::ColorComponentTag::RGB_BLUE;
+
+ m_aComponentBitCounts.realloc(4);
+ sal_Int32* pCounts = m_aComponentBitCounts.getArray();
+ pCounts[0] = 8;
+ pCounts[1] = 8;
+ pCounts[2] = 8;
+ pCounts[3] = 8;
+
+ m_nRedIndex = 1;
+ m_nGreenIndex = 2;
+ m_nBlueIndex = 3;
+ m_nAlphaIndex = 0;
+ }
+ break;
+
+ case BMP_FORMAT_32BIT_TC_BGRA:
+ {
+ m_bPalette = false;
+ m_nBitsPerInputPixel = 32;
+ m_nEndianness = util::Endianness::LITTLE;
+ m_aLayout.IsMsbFirst = sal_False; // doesn't matter
+
+ m_aComponentTags.realloc(4);
+ sal_Int8* pTags = m_aComponentTags.getArray();
+ pTags[0] = rendering::ColorComponentTag::RGB_BLUE;
+ pTags[1] = rendering::ColorComponentTag::RGB_GREEN;
+ pTags[2] = rendering::ColorComponentTag::RGB_RED;
+ pTags[3] = rendering::ColorComponentTag::ALPHA;
+
+ m_aComponentBitCounts.realloc(4);
+ sal_Int32* pCounts = m_aComponentBitCounts.getArray();
+ pCounts[0] = 8;
+ pCounts[1] = 8;
+ pCounts[2] = 8;
+ pCounts[3] = 8;
+
+ m_nRedIndex = 2;
+ m_nGreenIndex = 1;
+ m_nBlueIndex = 0;
+ m_nAlphaIndex = 3;
+ }
+ break;
+
+ case BMP_FORMAT_32BIT_TC_RGBA:
+ {
+ m_bPalette = false;
+ m_nBitsPerInputPixel = 32;
+ m_nEndianness = util::Endianness::LITTLE;
+ m_aLayout.IsMsbFirst = sal_False; // doesn't matter
+
+ m_aComponentTags.realloc(4);
+ sal_Int8* pTags = m_aComponentTags.getArray();
+ pTags[0] = rendering::ColorComponentTag::RGB_RED;
+ pTags[1] = rendering::ColorComponentTag::RGB_GREEN;
+ pTags[2] = rendering::ColorComponentTag::RGB_BLUE;
+ pTags[3] = rendering::ColorComponentTag::ALPHA;
+
+ m_aComponentBitCounts.realloc(4);
+ sal_Int32* pCounts = m_aComponentBitCounts.getArray();
+ pCounts[0] = 8;
+ pCounts[1] = 8;
+ pCounts[2] = 8;
+ pCounts[3] = 8;
+
+ m_nRedIndex = 0;
+ m_nGreenIndex = 1;
+ m_nBlueIndex = 2;
+ m_nAlphaIndex = 3;
+ }
+ break;
+
+ case BMP_FORMAT_32BIT_TC_MASK:
+ m_bPalette = false;
+ m_nBitsPerInputPixel = 32;
+ m_nEndianness = util::Endianness::LITTLE;
+ m_aLayout.IsMsbFirst = sal_False; // doesn't matter
+ setComponentInfo( m_pBmpAcc->GetColorMask().GetRedMask(),
+ m_pBmpAcc->GetColorMask().GetGreenMask(),
+ m_pBmpAcc->GetColorMask().GetBlueMask() );
+ break;
+
+ default:
+ DBG_ERROR( "unsupported bitmap format" );
+ break;
+ }
+
+ if( m_bPalette )
+ {
+ m_aComponentTags.realloc(1);
+ m_aComponentTags[0] = rendering::ColorComponentTag::INDEX;
+
+ m_aComponentBitCounts.realloc(1);
+ m_aComponentBitCounts[0] = m_nBitsPerInputPixel;
+
+ m_nIndexIndex = 0;
+ }
+
+ m_nBitsPerOutputPixel = m_nBitsPerInputPixel;
+ if( m_aBmpEx.IsTransparent() )
+ {
+ // TODO(P1): need to interleave alpha with bitmap data -
+ // won't fuss with less-than-8 bit for now
+ m_nBitsPerOutputPixel = std::max(sal_Int32(8),m_nBitsPerInputPixel);
+
+ // check whether alpha goes in front or behind the
+ // bitcount sequence. If pixel format is little endian,
+ // put it behind all the other channels. If it's big
+ // endian, put it in front (because later, the actual data
+ // always gets written after the pixel data)
+
+ // TODO(Q1): slight catch - in the case of the
+ // BMP_FORMAT_32BIT_XX_ARGB formats, duplicate alpha
+ // channels might happen!
+ m_aComponentTags.realloc(m_aComponentTags.getLength()+1);
+ m_aComponentTags[m_aComponentTags.getLength()-1] = rendering::ColorComponentTag::ALPHA;
+
+ m_aComponentBitCounts.realloc(m_aComponentBitCounts.getLength()+1);
+ m_aComponentBitCounts[m_aComponentBitCounts.getLength()-1] = m_aBmpEx.IsAlpha() ? 8 : 1;
+
+ if( m_nEndianness == util::Endianness::BIG )
+ {
+ // put alpha in front of all the color channels
+ sal_Int8* pTags =m_aComponentTags.getArray();
+ sal_Int32* pCounts=m_aComponentBitCounts.getArray();
+ std::rotate(pTags,
+ pTags+m_aComponentTags.getLength()-1,
+ pTags+m_aComponentTags.getLength());
+ std::rotate(pCounts,
+ pCounts+m_aComponentBitCounts.getLength()-1,
+ pCounts+m_aComponentBitCounts.getLength());
+ ++m_nRedIndex;
+ ++m_nGreenIndex;
+ ++m_nBlueIndex;
+ ++m_nIndexIndex;
+ m_nAlphaIndex=0;
+ }
+
+ // always add a full byte to the pixel size, otherwise
+ // pixel packing hell breaks loose.
+ m_nBitsPerOutputPixel += 8;
+
+ // adapt scanline parameters
+ const Size aSize = m_aBitmap.GetSizePixel();
+ m_aLayout.ScanLineBytes =
+ m_aLayout.ScanLineStride = (aSize.Width()*m_nBitsPerOutputPixel + 7)/8;
+ }
+ }
+}
+
+VclCanvasBitmap::~VclCanvasBitmap()
+{
+ if( m_pAlphaAcc )
+ m_aAlpha.ReleaseAccess(m_pAlphaAcc);
+ if( m_pBmpAcc )
+ m_aBitmap.ReleaseAccess(m_pBmpAcc);
+}
+
+// XBitmap
+geometry::IntegerSize2D SAL_CALL VclCanvasBitmap::getSize() throw (uno::RuntimeException)
+{
+ vos::OGuard aGuard( Application::GetSolarMutex() );
+ return integerSize2DFromSize( m_aBitmap.GetSizePixel() );
+}
+
+::sal_Bool SAL_CALL VclCanvasBitmap::hasAlpha() throw (uno::RuntimeException)
+{
+ vos::OGuard aGuard( Application::GetSolarMutex() );
+ return m_aBmpEx.IsTransparent();
+}
+
+uno::Reference< rendering::XBitmap > SAL_CALL VclCanvasBitmap::getScaledBitmap( const geometry::RealSize2D& newSize,
+ sal_Bool beFast ) throw (uno::RuntimeException)
+{
+ vos::OGuard aGuard( Application::GetSolarMutex() );
+
+ BitmapEx aNewBmp( m_aBitmap );
+ aNewBmp.Scale( sizeFromRealSize2D( newSize ), beFast ? BMP_SCALE_FAST : BMP_SCALE_INTERPOLATE );
+ return uno::Reference<rendering::XBitmap>( new VclCanvasBitmap( aNewBmp ) );
+}
+
+// XIntegerReadOnlyBitmap
+uno::Sequence< sal_Int8 > SAL_CALL VclCanvasBitmap::getData( rendering::IntegerBitmapLayout& bitmapLayout,
+ const geometry::IntegerRectangle2D& rect ) throw( lang::IndexOutOfBoundsException,
+ rendering::VolatileContentDestroyedException,
+ uno::RuntimeException)
+{
+ vos::OGuard aGuard( Application::GetSolarMutex() );
+
+ bitmapLayout = getMemoryLayout();
+
+ const ::Rectangle aRequestedArea( vcl::unotools::rectangleFromIntegerRectangle2D(rect) );
+ if( aRequestedArea.IsEmpty() )
+ return uno::Sequence< sal_Int8 >();
+
+ // Invalid/empty bitmap: no data available
+ if( !m_pBmpAcc )
+ throw lang::IndexOutOfBoundsException();
+ if( m_aBmpEx.IsTransparent() && !m_pAlphaAcc )
+ throw lang::IndexOutOfBoundsException();
+
+ if( aRequestedArea.Left() < 0 || aRequestedArea.Top() < 0 ||
+ aRequestedArea.Right() > m_pBmpAcc->Width() ||
+ aRequestedArea.Bottom() > m_pBmpAcc->Height() )
+ {
+ throw lang::IndexOutOfBoundsException();
+ }
+
+ uno::Sequence< sal_Int8 > aRet;
+ Rectangle aRequestedBytes( aRequestedArea );
+
+ // adapt to byte boundaries
+ aRequestedBytes.Left() = aRequestedArea.Left()*m_nBitsPerOutputPixel/8;
+ aRequestedBytes.Right() = (aRequestedArea.Right()*m_nBitsPerOutputPixel + 7)/8;
+
+ // copy stuff to output sequence
+ aRet.realloc(aRequestedBytes.getWidth()*aRequestedBytes.getHeight());
+ sal_Int8* pOutBuf = aRet.getArray();
+
+ bitmapLayout.ScanLines = aRequestedBytes.getHeight();
+ bitmapLayout.ScanLineBytes =
+ bitmapLayout.ScanLineStride= aRequestedBytes.getWidth();
+
+ sal_Int32 nScanlineStride=bitmapLayout.ScanLineStride;
+ if( !(m_pBmpAcc->GetScanlineFormat() & BMP_FORMAT_TOP_DOWN) )
+ {
+ pOutBuf += bitmapLayout.ScanLineStride*(aRequestedBytes.getHeight()-1);
+ nScanlineStride *= -1;
+ }
+
+ if( !m_aBmpEx.IsTransparent() )
+ {
+ OSL_ENSURE(m_pBmpAcc,"Invalid bmp read access");
+
+ // can return bitmap data as-is
+ for( long y=aRequestedBytes.Top(); y<aRequestedBytes.Bottom(); ++y )
+ {
+ Scanline pScan = m_pBmpAcc->GetScanline(y);
+ rtl_copyMemory(pOutBuf, pScan+aRequestedBytes.Left(), aRequestedBytes.getWidth());
+ pOutBuf += nScanlineStride;
+ }
+ }
+ else
+ {
+ OSL_ENSURE(m_pBmpAcc,"Invalid bmp read access");
+ OSL_ENSURE(m_pAlphaAcc,"Invalid alpha read access");
+
+ // interleave alpha with bitmap data - note, bitcount is
+ // always integer multiple of 8
+ OSL_ENSURE((m_nBitsPerOutputPixel & 0x07) == 0,
+ "Transparent bitmap bitcount not integer multiple of 8" );
+
+ for( long y=aRequestedArea.Top(); y<aRequestedArea.Bottom(); ++y )
+ {
+ sal_Int8* pOutScan = pOutBuf;
+
+ if( m_nBitsPerInputPixel < 8 )
+ {
+ // input less than a byte - copy via GetPixel()
+ for( long x=aRequestedArea.Left(); x<aRequestedArea.Right(); ++x )
+ {
+ *pOutScan++ = m_pBmpAcc->GetPixel(y,x);
+ *pOutScan++ = m_pAlphaAcc->GetPixel(y,x);
+ }
+ }
+ else
+ {
+ const long nNonAlphaBytes( m_nBitsPerInputPixel/8 );
+ const long nScanlineOffsetLeft(aRequestedArea.Left()*nNonAlphaBytes);
+ Scanline pScan = m_pBmpAcc->GetScanline(y) + nScanlineOffsetLeft;
+
+ // input integer multiple of byte - copy directly
+ for( long x=aRequestedArea.Left(); x<aRequestedArea.Right(); ++x )
+ {
+ for( long i=0; i<nNonAlphaBytes; ++i )
+ *pOutScan++ = *pScan++;
+ *pOutScan++ = m_pAlphaAcc->GetPixel(y,x);
+ }
+ }
+
+ pOutBuf += nScanlineStride;
+ }
+ }
+
+ return aRet;
+}
+
+uno::Sequence< sal_Int8 > SAL_CALL VclCanvasBitmap::getPixel( rendering::IntegerBitmapLayout& bitmapLayout,
+ const geometry::IntegerPoint2D& pos ) throw (lang::IndexOutOfBoundsException,
+ rendering::VolatileContentDestroyedException,
+ uno::RuntimeException)
+{
+ vos::OGuard aGuard( Application::GetSolarMutex() );
+
+ bitmapLayout = getMemoryLayout();
+
+ // Invalid/empty bitmap: no data available
+ if( !m_pBmpAcc )
+ throw lang::IndexOutOfBoundsException();
+ if( m_aBmpEx.IsTransparent() && !m_pAlphaAcc )
+ throw lang::IndexOutOfBoundsException();
+
+ if( pos.X < 0 || pos.Y < 0 ||
+ pos.X > m_pBmpAcc->Width() || pos.Y > m_pBmpAcc->Height() )
+ {
+ throw lang::IndexOutOfBoundsException();
+ }
+
+ uno::Sequence< sal_Int8 > aRet((m_nBitsPerOutputPixel + 7)/8);
+ sal_Int8* pOutBuf = aRet.getArray();
+
+ // copy stuff to output sequence
+ bitmapLayout.ScanLines = 1;
+ bitmapLayout.ScanLineBytes =
+ bitmapLayout.ScanLineStride= aRet.getLength();
+
+ const long nScanlineLeftOffset( pos.X*m_nBitsPerInputPixel/8 );
+ if( !m_aBmpEx.IsTransparent() )
+ {
+ OSL_ENSURE(m_pBmpAcc,"Invalid bmp read access");
+
+ // can return bitmap data as-is
+ Scanline pScan = m_pBmpAcc->GetScanline(pos.Y);
+ rtl_copyMemory(pOutBuf, pScan+nScanlineLeftOffset, aRet.getLength() );
+ }
+ else
+ {
+ OSL_ENSURE(m_pBmpAcc,"Invalid bmp read access");
+ OSL_ENSURE(m_pAlphaAcc,"Invalid alpha read access");
+
+ // interleave alpha with bitmap data - note, bitcount is
+ // always integer multiple of 8
+ OSL_ENSURE((m_nBitsPerOutputPixel & 0x07) == 0,
+ "Transparent bitmap bitcount not integer multiple of 8" );
+
+ if( m_nBitsPerInputPixel < 8 )
+ {
+ // input less than a byte - copy via GetPixel()
+ *pOutBuf++ = m_pBmpAcc->GetPixel(pos.Y,pos.X);
+ *pOutBuf = m_pAlphaAcc->GetPixel(pos.Y,pos.X);
+ }
+ else
+ {
+ const long nNonAlphaBytes( m_nBitsPerInputPixel/8 );
+ Scanline pScan = m_pBmpAcc->GetScanline(pos.Y);
+
+ // input integer multiple of byte - copy directly
+ rtl_copyMemory(pOutBuf, pScan+nScanlineLeftOffset, nNonAlphaBytes );
+ pOutBuf += nNonAlphaBytes;
+ *pOutBuf++ = m_pAlphaAcc->GetPixel(pos.Y,pos.X);
+ }
+ }
+
+ return aRet;
+}
+
+uno::Reference< rendering::XBitmapPalette > SAL_CALL VclCanvasBitmap::getPalette() throw (uno::RuntimeException)
+{
+ vos::OGuard aGuard( Application::GetSolarMutex() );
+
+ uno::Reference< XBitmapPalette > aRet;
+ if( m_bPalette )
+ aRet.set(this);
+
+ return aRet;
+}
+
+rendering::IntegerBitmapLayout SAL_CALL VclCanvasBitmap::getMemoryLayout() throw (uno::RuntimeException)
+{
+ vos::OGuard aGuard( Application::GetSolarMutex() );
+
+ rendering::IntegerBitmapLayout aLayout( m_aLayout );
+
+ // only set references to self on separate copy of
+ // IntegerBitmapLayout - if we'd set that on m_aLayout, we'd have
+ // a circular reference!
+ if( m_bPalette )
+ aLayout.Palette.set( this );
+
+ aLayout.ColorSpace.set( this );
+
+ return aLayout;
+}
+
+sal_Int32 SAL_CALL VclCanvasBitmap::getNumberOfEntries() throw (uno::RuntimeException)
+{
+ vos::OGuard aGuard( Application::GetSolarMutex() );
+
+ if( !m_pBmpAcc )
+ return 0;
+
+ return m_pBmpAcc->HasPalette() ? m_pBmpAcc->GetPaletteEntryCount() : 0 ;
+}
+
+sal_Bool SAL_CALL VclCanvasBitmap::getIndex( uno::Sequence< double >& o_entry, sal_Int32 nIndex ) throw (lang::IndexOutOfBoundsException, uno::RuntimeException)
+{
+ vos::OGuard aGuard( Application::GetSolarMutex() );
+
+ const USHORT nCount( m_pBmpAcc ?
+ (m_pBmpAcc->HasPalette() ? m_pBmpAcc->GetPaletteEntryCount() : 0 ) : 0 );
+ OSL_ENSURE(nIndex >= 0 && nIndex < nCount,"Palette index out of range");
+ if( nIndex < 0 || nIndex >= nCount )
+ throw lang::IndexOutOfBoundsException(::rtl::OUString::createFromAscii("Palette index out of range"),
+ static_cast<rendering::XBitmapPalette*>(this));
+
+ const BitmapColor aCol = m_pBmpAcc->GetPaletteColor(sal::static_int_cast<USHORT>(nIndex));
+ o_entry.realloc(3);
+ double* pColor=o_entry.getArray();
+ pColor[0] = aCol.GetRed();
+ pColor[1] = aCol.GetGreen();
+ pColor[2] = aCol.GetBlue();
+
+ return sal_True; // no palette transparency here.
+}
+
+sal_Bool SAL_CALL VclCanvasBitmap::setIndex( const uno::Sequence< double >&, sal_Bool, sal_Int32 nIndex ) throw (lang::IndexOutOfBoundsException, lang::IllegalArgumentException, uno::RuntimeException)
+{
+ vos::OGuard aGuard( Application::GetSolarMutex() );
+
+ const USHORT nCount( m_pBmpAcc ?
+ (m_pBmpAcc->HasPalette() ? m_pBmpAcc->GetPaletteEntryCount() : 0 ) : 0 );
+
+ OSL_ENSURE(nIndex >= 0 && nIndex < nCount,"Palette index out of range");
+ if( nIndex < 0 || nIndex >= nCount )
+ throw lang::IndexOutOfBoundsException(::rtl::OUString::createFromAscii("Palette index out of range"),
+ static_cast<rendering::XBitmapPalette*>(this));
+
+ return sal_False; // read-only implementation
+}
+
+namespace
+{
+ struct PaletteColorSpaceHolder: public rtl::StaticWithInit<uno::Reference<rendering::XColorSpace>,
+ PaletteColorSpaceHolder>
+ {
+ uno::Reference<rendering::XColorSpace> operator()()
+ {
+ return vcl::unotools::createStandardColorSpace();
+ }
+ };
+}
+
+uno::Reference< rendering::XColorSpace > SAL_CALL VclCanvasBitmap::getColorSpace( ) throw (uno::RuntimeException)
+{
+ // this is the method from XBitmapPalette. Return palette color
+ // space here
+ return PaletteColorSpaceHolder::get();
+}
+
+sal_Int8 SAL_CALL VclCanvasBitmap::getType( ) throw (uno::RuntimeException)
+{
+ return rendering::ColorSpaceType::RGB;
+}
+
+uno::Sequence< ::sal_Int8 > SAL_CALL VclCanvasBitmap::getComponentTags( ) throw (uno::RuntimeException)
+{
+ vos::OGuard aGuard( Application::GetSolarMutex() );
+ return m_aComponentTags;
+}
+
+sal_Int8 SAL_CALL VclCanvasBitmap::getRenderingIntent( ) throw (uno::RuntimeException)
+{
+ return rendering::RenderingIntent::PERCEPTUAL;
+}
+
+uno::Sequence< ::beans::PropertyValue > SAL_CALL VclCanvasBitmap::getProperties( ) throw (uno::RuntimeException)
+{
+ return uno::Sequence< ::beans::PropertyValue >();
+}
+
+uno::Sequence< double > SAL_CALL VclCanvasBitmap::convertColorSpace( const uno::Sequence< double >& deviceColor,
+ const uno::Reference< ::rendering::XColorSpace >& targetColorSpace ) throw (uno::RuntimeException)
+{
+ // TODO(P3): if we know anything about target
+ // colorspace, this can be greatly sped up
+ uno::Sequence<rendering::ARGBColor> aIntermediate(
+ convertToARGB(deviceColor));
+ return targetColorSpace->convertFromARGB(aIntermediate);
+}
+
+uno::Sequence<rendering::RGBColor> SAL_CALL VclCanvasBitmap::convertToRGB( const uno::Sequence< double >& deviceColor ) throw (lang::IllegalArgumentException,uno::RuntimeException)
+{
+ vos::OGuard aGuard( Application::GetSolarMutex() );
+
+ const sal_Size nLen( deviceColor.getLength() );
+ const sal_Int32 nComponentsPerPixel(m_aComponentTags.getLength());
+ ENSURE_ARG_OR_THROW2(nLen%nComponentsPerPixel==0,
+ "number of channels no multiple of pixel element count",
+ static_cast<rendering::XBitmapPalette*>(this), 01);
+
+ uno::Sequence< rendering::RGBColor > aRes(nLen/nComponentsPerPixel);
+ rendering::RGBColor* pOut( aRes.getArray() );
+
+ if( m_bPalette )
+ {
+ OSL_ENSURE(m_nIndexIndex != -1,
+ "Invalid color channel indices");
+ ENSURE_OR_THROW(m_pBmpAcc,
+ "Unable to get BitmapAccess");
+
+ for( sal_Size i=0; i<nLen; i+=nComponentsPerPixel )
+ {
+ const BitmapColor aCol = m_pBmpAcc->GetPaletteColor(
+ sal::static_int_cast<USHORT>(deviceColor[i+m_nIndexIndex]));
+
+ // TODO(F3): Convert result to sRGB color space
+ *pOut++ = rendering::RGBColor(toDoubleColor(aCol.GetRed()),
+ toDoubleColor(aCol.GetGreen()),
+ toDoubleColor(aCol.GetBlue()));
+ }
+ }
+ else
+ {
+ OSL_ENSURE(m_nRedIndex != -1 && m_nGreenIndex != -1 && m_nBlueIndex != -1,
+ "Invalid color channel indices");
+
+ for( sal_Size i=0; i<nLen; i+=nComponentsPerPixel )
+ {
+ // TODO(F3): Convert result to sRGB color space
+ *pOut++ = rendering::RGBColor(
+ deviceColor[i+m_nRedIndex],
+ deviceColor[i+m_nGreenIndex],
+ deviceColor[i+m_nBlueIndex]);
+ }
+ }
+
+ return aRes;
+}
+
+uno::Sequence<rendering::ARGBColor> SAL_CALL VclCanvasBitmap::convertToARGB( const uno::Sequence< double >& deviceColor ) throw (lang::IllegalArgumentException,uno::RuntimeException)
+{
+ vos::OGuard aGuard( Application::GetSolarMutex() );
+
+ const sal_Size nLen( deviceColor.getLength() );
+ const sal_Int32 nComponentsPerPixel(m_aComponentTags.getLength());
+ ENSURE_ARG_OR_THROW2(nLen%nComponentsPerPixel==0,
+ "number of channels no multiple of pixel element count",
+ static_cast<rendering::XBitmapPalette*>(this), 01);
+
+ uno::Sequence< rendering::ARGBColor > aRes(nLen/nComponentsPerPixel);
+ rendering::ARGBColor* pOut( aRes.getArray() );
+
+ if( m_bPalette )
+ {
+ OSL_ENSURE(m_nIndexIndex != -1,
+ "Invalid color channel indices");
+ ENSURE_OR_THROW(m_pBmpAcc,
+ "Unable to get BitmapAccess");
+
+ for( sal_Size i=0; i<nLen; i+=nComponentsPerPixel )
+ {
+ const BitmapColor aCol = m_pBmpAcc->GetPaletteColor(
+ sal::static_int_cast<USHORT>(deviceColor[i+m_nIndexIndex]));
+
+ // TODO(F3): Convert result to sRGB color space
+ const double nAlpha( m_nAlphaIndex != -1 ? 1.0 - deviceColor[i+m_nAlphaIndex] : 1.0 );
+ *pOut++ = rendering::ARGBColor(nAlpha,
+ toDoubleColor(aCol.GetRed()),
+ toDoubleColor(aCol.GetGreen()),
+ toDoubleColor(aCol.GetBlue()));
+ }
+ }
+ else
+ {
+ OSL_ENSURE(m_nRedIndex != -1 && m_nGreenIndex != -1 && m_nBlueIndex != -1,
+ "Invalid color channel indices");
+
+ for( sal_Size i=0; i<nLen; i+=nComponentsPerPixel )
+ {
+ // TODO(F3): Convert result to sRGB color space
+ const double nAlpha( m_nAlphaIndex != -1 ? 1.0 - deviceColor[i+m_nAlphaIndex] : 1.0 );
+ *pOut++ = rendering::ARGBColor(
+ nAlpha,
+ deviceColor[i+m_nRedIndex],
+ deviceColor[i+m_nGreenIndex],
+ deviceColor[i+m_nBlueIndex]);
+ }
+ }
+
+ return aRes;
+}
+
+uno::Sequence<rendering::ARGBColor> SAL_CALL VclCanvasBitmap::convertToPARGB( const uno::Sequence< double >& deviceColor ) throw (lang::IllegalArgumentException,uno::RuntimeException)
+{
+ vos::OGuard aGuard( Application::GetSolarMutex() );
+
+ const sal_Size nLen( deviceColor.getLength() );
+ const sal_Int32 nComponentsPerPixel(m_aComponentTags.getLength());
+ ENSURE_ARG_OR_THROW2(nLen%nComponentsPerPixel==0,
+ "number of channels no multiple of pixel element count",
+ static_cast<rendering::XBitmapPalette*>(this), 01);
+
+ uno::Sequence< rendering::ARGBColor > aRes(nLen/nComponentsPerPixel);
+ rendering::ARGBColor* pOut( aRes.getArray() );
+
+ if( m_bPalette )
+ {
+ OSL_ENSURE(m_nIndexIndex != -1,
+ "Invalid color channel indices");
+ ENSURE_OR_THROW(m_pBmpAcc,
+ "Unable to get BitmapAccess");
+
+ for( sal_Size i=0; i<nLen; i+=nComponentsPerPixel )
+ {
+ const BitmapColor aCol = m_pBmpAcc->GetPaletteColor(
+ sal::static_int_cast<USHORT>(deviceColor[i+m_nIndexIndex]));
+
+ // TODO(F3): Convert result to sRGB color space
+ const double nAlpha( m_nAlphaIndex != -1 ? 1.0 - deviceColor[i+m_nAlphaIndex] : 1.0 );
+ *pOut++ = rendering::ARGBColor(nAlpha,
+ nAlpha*toDoubleColor(aCol.GetRed()),
+ nAlpha*toDoubleColor(aCol.GetGreen()),
+ nAlpha*toDoubleColor(aCol.GetBlue()));
+ }
+ }
+ else
+ {
+ OSL_ENSURE(m_nRedIndex != -1 && m_nGreenIndex != -1 && m_nBlueIndex != -1,
+ "Invalid color channel indices");
+
+ for( sal_Size i=0; i<nLen; i+=nComponentsPerPixel )
+ {
+ // TODO(F3): Convert result to sRGB color space
+ const double nAlpha( m_nAlphaIndex != -1 ? 1.0 - deviceColor[i+m_nAlphaIndex] : 1.0 );
+ *pOut++ = rendering::ARGBColor(
+ nAlpha,
+ nAlpha*deviceColor[i+m_nRedIndex],
+ nAlpha*deviceColor[i+m_nGreenIndex],
+ nAlpha*deviceColor[i+m_nBlueIndex]);
+ }
+ }
+
+ return aRes;
+}
+
+uno::Sequence< double > SAL_CALL VclCanvasBitmap::convertFromRGB( const uno::Sequence<rendering::RGBColor>& rgbColor ) throw (lang::IllegalArgumentException,uno::RuntimeException)
+{
+ vos::OGuard aGuard( Application::GetSolarMutex() );
+
+ const sal_Size nLen( rgbColor.getLength() );
+ const sal_Int32 nComponentsPerPixel(m_aComponentTags.getLength());
+
+ uno::Sequence< double > aRes(nLen*nComponentsPerPixel);
+ double* pColors=aRes.getArray();
+
+ if( m_bPalette )
+ {
+ for( sal_Size i=0; i<nLen; ++i )
+ {
+ pColors[m_nIndexIndex] = m_pBmpAcc->GetBestPaletteIndex(
+ BitmapColor(toByteColor(rgbColor[i].Red),
+ toByteColor(rgbColor[i].Green),
+ toByteColor(rgbColor[i].Blue)));
+ if( m_nAlphaIndex != -1 )
+ pColors[m_nAlphaIndex] = 1.0;
+
+ pColors += nComponentsPerPixel;
+ }
+ }
+ else
+ {
+ for( sal_Size i=0; i<nLen; ++i )
+ {
+ pColors[m_nRedIndex] = rgbColor[i].Red;
+ pColors[m_nGreenIndex] = rgbColor[i].Green;
+ pColors[m_nBlueIndex] = rgbColor[i].Blue;
+ if( m_nAlphaIndex != -1 )
+ pColors[m_nAlphaIndex] = 1.0;
+
+ pColors += nComponentsPerPixel;
+ }
+ }
+ return aRes;
+}
+
+uno::Sequence< double > SAL_CALL VclCanvasBitmap::convertFromARGB( const uno::Sequence<rendering::ARGBColor>& rgbColor ) throw (lang::IllegalArgumentException,uno::RuntimeException)
+{
+ vos::OGuard aGuard( Application::GetSolarMutex() );
+
+ const sal_Size nLen( rgbColor.getLength() );
+ const sal_Int32 nComponentsPerPixel(m_aComponentTags.getLength());
+
+ uno::Sequence< double > aRes(nLen*nComponentsPerPixel);
+ double* pColors=aRes.getArray();
+
+ if( m_bPalette )
+ {
+ for( sal_Size i=0; i<nLen; ++i )
+ {
+ pColors[m_nIndexIndex] = m_pBmpAcc->GetBestPaletteIndex(
+ BitmapColor(toByteColor(rgbColor[i].Red),
+ toByteColor(rgbColor[i].Green),
+ toByteColor(rgbColor[i].Blue)));
+ if( m_nAlphaIndex != -1 )
+ pColors[m_nAlphaIndex] = rgbColor[i].Alpha;
+
+ pColors += nComponentsPerPixel;
+ }
+ }
+ else
+ {
+ for( sal_Size i=0; i<nLen; ++i )
+ {
+ pColors[m_nRedIndex] = rgbColor[i].Red;
+ pColors[m_nGreenIndex] = rgbColor[i].Green;
+ pColors[m_nBlueIndex] = rgbColor[i].Blue;
+ if( m_nAlphaIndex != -1 )
+ pColors[m_nAlphaIndex] = rgbColor[i].Alpha;
+
+ pColors += nComponentsPerPixel;
+ }
+ }
+ return aRes;
+}
+
+uno::Sequence< double > SAL_CALL VclCanvasBitmap::convertFromPARGB( const uno::Sequence<rendering::ARGBColor>& rgbColor ) throw (lang::IllegalArgumentException,uno::RuntimeException)
+{
+ vos::OGuard aGuard( Application::GetSolarMutex() );
+
+ const sal_Size nLen( rgbColor.getLength() );
+ const sal_Int32 nComponentsPerPixel(m_aComponentTags.getLength());
+
+ uno::Sequence< double > aRes(nLen*nComponentsPerPixel);
+ double* pColors=aRes.getArray();
+
+ if( m_bPalette )
+ {
+ for( sal_Size i=0; i<nLen; ++i )
+ {
+ const double nAlpha( rgbColor[i].Alpha );
+ pColors[m_nIndexIndex] = m_pBmpAcc->GetBestPaletteIndex(
+ BitmapColor(toByteColor(rgbColor[i].Red / nAlpha),
+ toByteColor(rgbColor[i].Green / nAlpha),
+ toByteColor(rgbColor[i].Blue / nAlpha)));
+ if( m_nAlphaIndex != -1 )
+ pColors[m_nAlphaIndex] = nAlpha;
+
+ pColors += nComponentsPerPixel;
+ }
+ }
+ else
+ {
+ for( sal_Size i=0; i<nLen; ++i )
+ {
+ const double nAlpha( rgbColor[i].Alpha );
+ pColors[m_nRedIndex] = rgbColor[i].Red / nAlpha;
+ pColors[m_nGreenIndex] = rgbColor[i].Green / nAlpha;
+ pColors[m_nBlueIndex] = rgbColor[i].Blue / nAlpha;
+ if( m_nAlphaIndex != -1 )
+ pColors[m_nAlphaIndex] = nAlpha;
+
+ pColors += nComponentsPerPixel;
+ }
+ }
+ return aRes;
+}
+
+sal_Int32 SAL_CALL VclCanvasBitmap::getBitsPerPixel( ) throw (uno::RuntimeException)
+{
+ vos::OGuard aGuard( Application::GetSolarMutex() );
+ return m_nBitsPerOutputPixel;
+}
+
+uno::Sequence< ::sal_Int32 > SAL_CALL VclCanvasBitmap::getComponentBitCounts( ) throw (uno::RuntimeException)
+{
+ vos::OGuard aGuard( Application::GetSolarMutex() );
+ return m_aComponentBitCounts;
+}
+
+sal_Int8 SAL_CALL VclCanvasBitmap::getEndianness( ) throw (uno::RuntimeException)
+{
+ vos::OGuard aGuard( Application::GetSolarMutex() );
+ return m_nEndianness;
+}
+
+uno::Sequence<double> SAL_CALL VclCanvasBitmap::convertFromIntegerColorSpace( const uno::Sequence< ::sal_Int8 >& deviceColor,
+ const uno::Reference< ::rendering::XColorSpace >& targetColorSpace ) throw (lang::IllegalArgumentException,uno::RuntimeException)
+{
+ if( dynamic_cast<VclCanvasBitmap*>(targetColorSpace.get()) )
+ {
+ vos::OGuard aGuard( Application::GetSolarMutex() );
+
+ const sal_Size nLen( deviceColor.getLength() );
+ const sal_Int32 nComponentsPerPixel(m_aComponentTags.getLength());
+ ENSURE_ARG_OR_THROW2(nLen%nComponentsPerPixel==0,
+ "number of channels no multiple of pixel element count",
+ static_cast<rendering::XBitmapPalette*>(this), 01);
+
+ uno::Sequence<double> aRes(nLen);
+ double* pOut( aRes.getArray() );
+
+ if( m_bPalette )
+ {
+ OSL_ENSURE(m_nIndexIndex != -1,
+ "Invalid color channel indices");
+ ENSURE_OR_THROW(m_pBmpAcc,
+ "Unable to get BitmapAccess");
+
+ for( sal_Size i=0; i<nLen; i+=nComponentsPerPixel )
+ {
+ const BitmapColor aCol = m_pBmpAcc->GetPaletteColor(
+ sal::static_int_cast<USHORT>(deviceColor[i+m_nIndexIndex]));
+
+ // TODO(F3): Convert result to sRGB color space
+ const double nAlpha( m_nAlphaIndex != -1 ? 1.0 - deviceColor[i+m_nAlphaIndex] : 1.0 );
+ *pOut++ = toDoubleColor(aCol.GetRed());
+ *pOut++ = toDoubleColor(aCol.GetGreen());
+ *pOut++ = toDoubleColor(aCol.GetBlue());
+ *pOut++ = nAlpha;
+ }
+ }
+ else
+ {
+ OSL_ENSURE(m_nRedIndex != -1 && m_nGreenIndex != -1 && m_nBlueIndex != -1,
+ "Invalid color channel indices");
+
+ for( sal_Size i=0; i<nLen; i+=nComponentsPerPixel )
+ {
+ // TODO(F3): Convert result to sRGB color space
+ const double nAlpha( m_nAlphaIndex != -1 ? 1.0 - deviceColor[i+m_nAlphaIndex] : 1.0 );
+ *pOut++ = deviceColor[i+m_nRedIndex];
+ *pOut++ = deviceColor[i+m_nGreenIndex];
+ *pOut++ = deviceColor[i+m_nBlueIndex];
+ *pOut++ = nAlpha;
+ }
+ }
+
+ return aRes;
+ }
+ else
+ {
+ // TODO(P3): if we know anything about target
+ // colorspace, this can be greatly sped up
+ uno::Sequence<rendering::ARGBColor> aIntermediate(
+ convertIntegerToARGB(deviceColor));
+ return targetColorSpace->convertFromARGB(aIntermediate);
+ }
+}
+
+uno::Sequence< ::sal_Int8 > SAL_CALL VclCanvasBitmap::convertToIntegerColorSpace( const uno::Sequence< ::sal_Int8 >& deviceColor,
+ const uno::Reference< ::rendering::XIntegerBitmapColorSpace >& targetColorSpace ) throw (lang::IllegalArgumentException,uno::RuntimeException)
+{
+ if( dynamic_cast<VclCanvasBitmap*>(targetColorSpace.get()) )
+ {
+ // it's us, so simply pass-through the data
+ return deviceColor;
+ }
+ else
+ {
+ // TODO(P3): if we know anything about target
+ // colorspace, this can be greatly sped up
+ uno::Sequence<rendering::ARGBColor> aIntermediate(
+ convertIntegerToARGB(deviceColor));
+ return targetColorSpace->convertIntegerFromARGB(aIntermediate);
+ }
+}
+
+uno::Sequence<rendering::RGBColor> SAL_CALL VclCanvasBitmap::convertIntegerToRGB( const uno::Sequence< ::sal_Int8 >& deviceColor ) throw (lang::IllegalArgumentException,uno::RuntimeException)
+{
+ vos::OGuard aGuard( Application::GetSolarMutex() );
+
+ const BYTE* pIn( reinterpret_cast<const BYTE*>(deviceColor.getConstArray()) );
+ const sal_Size nLen( deviceColor.getLength() );
+ const sal_Int32 nNumColors((nLen*8 + m_nBitsPerOutputPixel-1)/m_nBitsPerOutputPixel);
+
+ uno::Sequence< rendering::RGBColor > aRes(nNumColors);
+ rendering::RGBColor* pOut( aRes.getArray() );
+
+ ENSURE_OR_THROW(m_pBmpAcc,
+ "Unable to get BitmapAccess");
+
+ if( m_aBmpEx.IsTransparent() )
+ {
+ const sal_Int32 nBytesPerPixel((m_nBitsPerOutputPixel+7)/8);
+ for( sal_Size i=0; i<nLen; i+=nBytesPerPixel )
+ {
+ // if palette, index is guaranteed to be 8 bit
+ const BitmapColor aCol =
+ m_bPalette ?
+ m_pBmpAcc->GetPaletteColor(*pIn) :
+ m_pBmpAcc->GetPixelFromData(pIn,0);
+
+ // TODO(F3): Convert result to sRGB color space
+ *pOut++ = rendering::RGBColor(toDoubleColor(aCol.GetRed()),
+ toDoubleColor(aCol.GetGreen()),
+ toDoubleColor(aCol.GetBlue()));
+ // skips alpha
+ pIn += nBytesPerPixel;
+ }
+ }
+ else
+ {
+ for( sal_Int32 i=0; i<nNumColors; ++i )
+ {
+ const BitmapColor aCol =
+ m_bPalette ?
+ m_pBmpAcc->GetPaletteColor(
+ sal::static_int_cast<USHORT>(
+ m_pBmpAcc->GetPixelFromData(
+ pIn, i ))) :
+ m_pBmpAcc->GetPixelFromData(pIn, i);
+
+ // TODO(F3): Convert result to sRGB color space
+ *pOut++ = rendering::RGBColor(toDoubleColor(aCol.GetRed()),
+ toDoubleColor(aCol.GetGreen()),
+ toDoubleColor(aCol.GetBlue()));
+ }
+ }
+
+ return aRes;
+}
+
+uno::Sequence<rendering::ARGBColor> SAL_CALL VclCanvasBitmap::convertIntegerToARGB( const uno::Sequence< ::sal_Int8 >& deviceColor ) throw (lang::IllegalArgumentException,uno::RuntimeException)
+{
+ vos::OGuard aGuard( Application::GetSolarMutex() );
+
+ const BYTE* pIn( reinterpret_cast<const BYTE*>(deviceColor.getConstArray()) );
+ const sal_Size nLen( deviceColor.getLength() );
+ const sal_Int32 nNumColors((nLen*8 + m_nBitsPerOutputPixel-1)/m_nBitsPerOutputPixel);
+
+ uno::Sequence< rendering::ARGBColor > aRes(nNumColors);
+ rendering::ARGBColor* pOut( aRes.getArray() );
+
+ ENSURE_OR_THROW(m_pBmpAcc,
+ "Unable to get BitmapAccess");
+
+ if( m_aBmpEx.IsTransparent() )
+ {
+ const long nNonAlphaBytes( (m_nBitsPerInputPixel+7)/8 );
+ const sal_Int32 nBytesPerPixel((m_nBitsPerOutputPixel+7)/8);
+ const sal_uInt8 nAlphaFactor( m_aBmpEx.IsAlpha() ? 1 : 255 );
+ for( sal_Size i=0; i<nLen; i+=nBytesPerPixel )
+ {
+ // if palette, index is guaranteed to be 8 bit
+ const BitmapColor aCol =
+ m_bPalette ?
+ m_pBmpAcc->GetPaletteColor(*pIn) :
+ m_pBmpAcc->GetPixelFromData(pIn,0);
+
+ // TODO(F3): Convert result to sRGB color space
+ *pOut++ = rendering::ARGBColor(1.0 - toDoubleColor(nAlphaFactor*pIn[nNonAlphaBytes]),
+ toDoubleColor(aCol.GetRed()),
+ toDoubleColor(aCol.GetGreen()),
+ toDoubleColor(aCol.GetBlue()));
+ pIn += nBytesPerPixel;
+ }
+ }
+ else
+ {
+ for( sal_Int32 i=0; i<nNumColors; ++i )
+ {
+ const BitmapColor aCol =
+ m_bPalette ?
+ m_pBmpAcc->GetPaletteColor(
+ sal::static_int_cast<USHORT>(
+ m_pBmpAcc->GetPixelFromData(
+ pIn, i ))) :
+ m_pBmpAcc->GetPixelFromData(pIn, i);
+
+ // TODO(F3): Convert result to sRGB color space
+ *pOut++ = rendering::ARGBColor(1.0,
+ toDoubleColor(aCol.GetRed()),
+ toDoubleColor(aCol.GetGreen()),
+ toDoubleColor(aCol.GetBlue()));
+ }
+ }
+
+ return aRes;
+}
+
+uno::Sequence<rendering::ARGBColor> SAL_CALL VclCanvasBitmap::convertIntegerToPARGB( const uno::Sequence< ::sal_Int8 >& deviceColor ) throw (lang::IllegalArgumentException,uno::RuntimeException)
+{
+ vos::OGuard aGuard( Application::GetSolarMutex() );
+
+ const BYTE* pIn( reinterpret_cast<const BYTE*>(deviceColor.getConstArray()) );
+ const sal_Size nLen( deviceColor.getLength() );
+ const sal_Int32 nNumColors((nLen*8 + m_nBitsPerOutputPixel-1)/m_nBitsPerOutputPixel);
+
+ uno::Sequence< rendering::ARGBColor > aRes(nNumColors);
+ rendering::ARGBColor* pOut( aRes.getArray() );
+
+ ENSURE_OR_THROW(m_pBmpAcc,
+ "Unable to get BitmapAccess");
+
+ if( m_aBmpEx.IsTransparent() )
+ {
+ const long nNonAlphaBytes( (m_nBitsPerInputPixel+7)/8 );
+ const sal_Int32 nBytesPerPixel((m_nBitsPerOutputPixel+7)/8);
+ const sal_uInt8 nAlphaFactor( m_aBmpEx.IsAlpha() ? 1 : 255 );
+ for( sal_Size i=0; i<nLen; i+=nBytesPerPixel )
+ {
+ // if palette, index is guaranteed to be 8 bit
+ const BitmapColor aCol =
+ m_bPalette ?
+ m_pBmpAcc->GetPaletteColor(*pIn) :
+ m_pBmpAcc->GetPixelFromData(pIn,0);
+
+ // TODO(F3): Convert result to sRGB color space
+ const double nAlpha( 1.0 - toDoubleColor(nAlphaFactor*pIn[nNonAlphaBytes]) );
+ *pOut++ = rendering::ARGBColor(nAlpha,
+ nAlpha*toDoubleColor(aCol.GetRed()),
+ nAlpha*toDoubleColor(aCol.GetGreen()),
+ nAlpha*toDoubleColor(aCol.GetBlue()));
+ pIn += nBytesPerPixel;
+ }
+ }
+ else
+ {
+ for( sal_Int32 i=0; i<nNumColors; ++i )
+ {
+ const BitmapColor aCol =
+ m_bPalette ?
+ m_pBmpAcc->GetPaletteColor(
+ sal::static_int_cast<USHORT>(
+ m_pBmpAcc->GetPixelFromData(
+ pIn, i ))) :
+ m_pBmpAcc->GetPixelFromData(pIn, i);
+
+ // TODO(F3): Convert result to sRGB color space
+ *pOut++ = rendering::ARGBColor(1.0,
+ toDoubleColor(aCol.GetRed()),
+ toDoubleColor(aCol.GetGreen()),
+ toDoubleColor(aCol.GetBlue()));
+ }
+ }
+
+ return aRes;
+}
+
+uno::Sequence< ::sal_Int8 > SAL_CALL VclCanvasBitmap::convertIntegerFromRGB( const uno::Sequence<rendering::RGBColor>& rgbColor ) throw (lang::IllegalArgumentException,uno::RuntimeException)
+{
+ vos::OGuard aGuard( Application::GetSolarMutex() );
+
+ const sal_Size nLen( rgbColor.getLength() );
+ const sal_Int32 nNumBytes((nLen*m_nBitsPerOutputPixel+7)/8);
+
+ uno::Sequence< sal_Int8 > aRes(nNumBytes);
+ BYTE* pColors=reinterpret_cast<BYTE*>(aRes.getArray());
+
+ if( m_aBmpEx.IsTransparent() )
+ {
+ const long nNonAlphaBytes( (m_nBitsPerInputPixel+7)/8 );
+ for( sal_Size i=0; i<nLen; ++i )
+ {
+ const BitmapColor aCol(toByteColor(rgbColor[i].Red),
+ toByteColor(rgbColor[i].Green),
+ toByteColor(rgbColor[i].Blue));
+ const BitmapColor aCol2 =
+ m_bPalette ?
+ BitmapColor(
+ sal::static_int_cast<BYTE>(m_pBmpAcc->GetBestPaletteIndex( aCol ))) :
+ aCol;
+
+ m_pBmpAcc->SetPixelOnData(pColors,0,aCol2);
+ pColors += nNonAlphaBytes;
+ *pColors++ = BYTE(255);
+ }
+ }
+ else
+ {
+ for( sal_Size i=0; i<nLen; ++i )
+ {
+ const BitmapColor aCol(toByteColor(rgbColor[i].Red),
+ toByteColor(rgbColor[i].Green),
+ toByteColor(rgbColor[i].Blue));
+ const BitmapColor aCol2 =
+ m_bPalette ?
+ BitmapColor(
+ sal::static_int_cast<BYTE>(m_pBmpAcc->GetBestPaletteIndex( aCol ))) :
+ aCol;
+
+ m_pBmpAcc->SetPixelOnData(pColors,i,aCol2);
+ }
+ }
+
+ return aRes;
+}
+
+uno::Sequence< ::sal_Int8 > SAL_CALL VclCanvasBitmap::convertIntegerFromARGB( const uno::Sequence<rendering::ARGBColor>& rgbColor ) throw (lang::IllegalArgumentException,uno::RuntimeException)
+{
+ vos::OGuard aGuard( Application::GetSolarMutex() );
+
+ const sal_Size nLen( rgbColor.getLength() );
+ const sal_Int32 nNumBytes((nLen*m_nBitsPerOutputPixel+7)/8);
+
+ uno::Sequence< sal_Int8 > aRes(nNumBytes);
+ BYTE* pColors=reinterpret_cast<BYTE*>(aRes.getArray());
+
+ if( m_aBmpEx.IsTransparent() )
+ {
+ const long nNonAlphaBytes( (m_nBitsPerInputPixel+7)/8 );
+ for( sal_Size i=0; i<nLen; ++i )
+ {
+ const BitmapColor aCol(toByteColor(rgbColor[i].Red),
+ toByteColor(rgbColor[i].Green),
+ toByteColor(rgbColor[i].Blue));
+ const BitmapColor aCol2 =
+ m_bPalette ?
+ BitmapColor(
+ sal::static_int_cast<BYTE>(m_pBmpAcc->GetBestPaletteIndex( aCol ))) :
+ aCol;
+
+ m_pBmpAcc->SetPixelOnData(pColors,0,aCol2);
+ pColors += nNonAlphaBytes;
+ *pColors++ = 255 - toByteColor(rgbColor[i].Alpha);
+ }
+ }
+ else
+ {
+ for( sal_Size i=0; i<nLen; ++i )
+ {
+ const BitmapColor aCol(toByteColor(rgbColor[i].Red),
+ toByteColor(rgbColor[i].Green),
+ toByteColor(rgbColor[i].Blue));
+ const BitmapColor aCol2 =
+ m_bPalette ?
+ BitmapColor(
+ sal::static_int_cast<BYTE>(m_pBmpAcc->GetBestPaletteIndex( aCol ))) :
+ aCol;
+
+ m_pBmpAcc->SetPixelOnData(pColors,i,aCol2);
+ }
+ }
+
+ return aRes;
+}
+
+uno::Sequence< ::sal_Int8 > SAL_CALL VclCanvasBitmap::convertIntegerFromPARGB( const uno::Sequence<rendering::ARGBColor>& rgbColor ) throw (lang::IllegalArgumentException,uno::RuntimeException)
+{
+ vos::OGuard aGuard( Application::GetSolarMutex() );
+
+ const sal_Size nLen( rgbColor.getLength() );
+ const sal_Int32 nNumBytes((nLen*m_nBitsPerOutputPixel+7)/8);
+
+ uno::Sequence< sal_Int8 > aRes(nNumBytes);
+ BYTE* pColors=reinterpret_cast<BYTE*>(aRes.getArray());
+
+ if( m_aBmpEx.IsTransparent() )
+ {
+ const long nNonAlphaBytes( (m_nBitsPerInputPixel+7)/8 );
+ for( sal_Size i=0; i<nLen; ++i )
+ {
+ const double nAlpha( rgbColor[i].Alpha );
+ const BitmapColor aCol(toByteColor(rgbColor[i].Red / nAlpha),
+ toByteColor(rgbColor[i].Green / nAlpha),
+ toByteColor(rgbColor[i].Blue / nAlpha));
+ const BitmapColor aCol2 =
+ m_bPalette ?
+ BitmapColor(
+ sal::static_int_cast<BYTE>(m_pBmpAcc->GetBestPaletteIndex( aCol ))) :
+ aCol;
+
+ m_pBmpAcc->SetPixelOnData(pColors,0,aCol2);
+ pColors += nNonAlphaBytes;
+ *pColors++ = 255 - toByteColor(nAlpha);
+ }
+ }
+ else
+ {
+ for( sal_Size i=0; i<nLen; ++i )
+ {
+ const BitmapColor aCol(toByteColor(rgbColor[i].Red),
+ toByteColor(rgbColor[i].Green),
+ toByteColor(rgbColor[i].Blue));
+ const BitmapColor aCol2 =
+ m_bPalette ?
+ BitmapColor(
+ sal::static_int_cast<BYTE>(m_pBmpAcc->GetBestPaletteIndex( aCol ))) :
+ aCol;
+
+ m_pBmpAcc->SetPixelOnData(pColors,i,aCol2);
+ }
+ }
+
+ return aRes;
+}
+
+BitmapEx VclCanvasBitmap::getBitmapEx() const
+{
+ return m_aBmpEx;
+}
diff --git a/vcl/source/helper/canvastools.cxx b/vcl/source/helper/canvastools.cxx
new file mode 100644
index 000000000000..71c306ff9bbb
--- /dev/null
+++ b/vcl/source/helper/canvastools.cxx
@@ -0,0 +1,837 @@
+/*************************************************************************
+ *
+ * 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/logfile.hxx>
+#include <cppuhelper/compbase1.hxx>
+
+#include <com/sun/star/geometry/RealSize2D.hpp>
+#include <com/sun/star/geometry/RealPoint2D.hpp>
+#include <com/sun/star/geometry/RealRectangle2D.hpp>
+#include <com/sun/star/geometry/IntegerSize2D.hpp>
+#include <com/sun/star/geometry/IntegerPoint2D.hpp>
+#include <com/sun/star/geometry/IntegerRectangle2D.hpp>
+#include <com/sun/star/geometry/RealBezierSegment2D.hpp>
+
+#include <com/sun/star/rendering/ColorSpaceType.hpp>
+#include <com/sun/star/rendering/RenderingIntent.hpp>
+#include <com/sun/star/rendering/XGraphicDevice.hpp>
+#include <com/sun/star/rendering/XBitmap.hpp>
+#include <com/sun/star/rendering/XPolyPolygon2D.hpp>
+#include <com/sun/star/rendering/IntegerBitmapLayout.hpp>
+#include <com/sun/star/rendering/XIntegerBitmap.hpp>
+#include <com/sun/star/rendering/ColorComponentTag.hpp>
+
+#include <basegfx/matrix/b2dhommatrix.hxx>
+#include <basegfx/vector/b2dsize.hxx>
+#include <basegfx/point/b2dpoint.hxx>
+#include <basegfx/range/b2drectangle.hxx>
+#include <basegfx/vector/b2isize.hxx>
+#include <basegfx/point/b2ipoint.hxx>
+#include <basegfx/range/b2irectangle.hxx>
+
+// #i79917#
+#include <basegfx/polygon/b2dpolygon.hxx>
+#include <basegfx/tools/canvastools.hxx>
+#include <basegfx/polygon/b2dpolypolygon.hxx>
+
+#include <tools/poly.hxx>
+#include <tools/diagnose_ex.h>
+#include <rtl/uuid.h>
+
+#include <vcl/salbtype.hxx>
+#include <vcl/bmpacc.hxx>
+#include <vcl/bitmapex.hxx>
+
+#include <vcl/canvasbitmap.hxx>
+#include <vcl/canvastools.hxx>
+#include <hash_map>
+
+
+using namespace ::com::sun::star;
+
+namespace vcl
+{
+ namespace unotools
+ {
+ // #i79917# removed helpers bezierSequenceFromPolygon and
+ // pointSequenceFromPolygon here
+ // Also all helpers using tools Polygon and PolyPolygon will get mapped to the
+ // B2DPolygon helpers for these cases, see comments with the same TaskID below.
+ // TODO: Remove those wrapped methods
+
+ //---------------------------------------------------------------------------------------
+
+ uno::Reference< rendering::XPolyPolygon2D > xPolyPolygonFromPolygon( const uno::Reference< rendering::XGraphicDevice >& xGraphicDevice,
+ const ::Polygon& inputPolygon )
+ {
+ RTL_LOGFILE_CONTEXT( aLog, "::vcl::unotools::xPolyPolygonFromPolygon()" );
+
+ // #i79917# map to basegfx
+ const basegfx::B2DPolygon aB2DPolygon(inputPolygon.getB2DPolygon());
+ return basegfx::unotools::xPolyPolygonFromB2DPolygon(xGraphicDevice, aB2DPolygon);
+ }
+
+ //---------------------------------------------------------------------------------------
+
+ uno::Reference< rendering::XPolyPolygon2D > xPolyPolygonFromPolyPolygon( const uno::Reference< rendering::XGraphicDevice >& xGraphicDevice,
+ const ::PolyPolygon& inputPolyPolygon )
+ {
+ RTL_LOGFILE_CONTEXT( aLog, "::vcl::unotools::xPolyPolygonFromPolyPolygon()" );
+
+ // #i79917# map to basegfx
+ const basegfx::B2DPolyPolygon aB2DPolyPolygon(inputPolyPolygon.getB2DPolyPolygon());
+ return basegfx::unotools::xPolyPolygonFromB2DPolyPolygon(xGraphicDevice, aB2DPolyPolygon);
+ }
+
+ //---------------------------------------------------------------------------------------
+
+ ::Polygon polygonFromPoint2DSequence( const uno::Sequence< geometry::RealPoint2D >& points )
+ {
+ RTL_LOGFILE_CONTEXT( aLog, "::vcl::unotools::polygonFromPoint2DSequence()" );
+
+ const USHORT nCurrSize( sal::static_int_cast<USHORT>(points.getLength()) );
+
+ ::Polygon aPoly( nCurrSize );
+
+ USHORT nCurrPoint;
+ for( nCurrPoint=0; nCurrPoint<nCurrSize; ++nCurrPoint )
+ aPoly[nCurrPoint] = pointFromRealPoint2D( points[nCurrPoint] );
+
+ return aPoly;
+ }
+
+ //---------------------------------------------------------------------------------------
+
+ ::PolyPolygon polyPolygonFromPoint2DSequenceSequence( const uno::Sequence< uno::Sequence< geometry::RealPoint2D > >& points )
+ {
+ RTL_LOGFILE_CONTEXT( aLog, "::vcl::unotools::polyPolygonFromPoint2DSequenceSequence()" );
+
+ ::PolyPolygon aRes;
+
+ int nCurrPoly;
+ for( nCurrPoly=0; nCurrPoly<points.getLength(); ++nCurrPoly )
+ {
+ aRes.Insert( polygonFromPoint2DSequence( points[nCurrPoly] ) );
+ }
+
+ return aRes;
+ }
+
+ //---------------------------------------------------------------------------------------
+
+ ::Polygon polygonFromBezier2DSequence( const uno::Sequence< geometry::RealBezierSegment2D >& curves )
+ {
+ // #i79917# map to basegfx
+ const basegfx::B2DPolygon aB2DPolygon(basegfx::unotools::polygonFromBezier2DSequence(curves));
+ return ::Polygon(aB2DPolygon);
+ }
+
+ //---------------------------------------------------------------------------------------
+
+ ::PolyPolygon polyPolygonFromBezier2DSequenceSequence( const uno::Sequence< uno::Sequence< geometry::RealBezierSegment2D > >& curves )
+ {
+ // #i79917# map to basegfx
+ const basegfx::B2DPolyPolygon aB2DPolyPolygon(basegfx::unotools::polyPolygonFromBezier2DSequenceSequence(curves));
+ return ::PolyPolygon(aB2DPolyPolygon);
+ }
+
+ //---------------------------------------------------------------------------------------
+
+ uno::Reference< rendering::XBitmap > xBitmapFromBitmap( const uno::Reference< rendering::XGraphicDevice >& /*xGraphicDevice*/,
+ const ::Bitmap& inputBitmap )
+ {
+ RTL_LOGFILE_CONTEXT( aLog, "::vcl::unotools::xBitmapFromBitmap()" );
+
+ return new vcl::unotools::VclCanvasBitmap( BitmapEx( inputBitmap ) );
+ }
+
+ //---------------------------------------------------------------------------------------
+
+ uno::Reference< rendering::XBitmap > xBitmapFromBitmapEx( const uno::Reference< rendering::XGraphicDevice >& /*xGraphicDevice*/,
+ const ::BitmapEx& inputBitmap )
+ {
+ RTL_LOGFILE_CONTEXT( aLog, "::vcl::unotools::xBitmapFromBitmapEx()" );
+
+ return new vcl::unotools::VclCanvasBitmap( inputBitmap );
+ }
+
+ //---------------------------------------------------------------------------------------
+
+ const uno::Sequence< sal_Int8 > getTunnelIdentifier( TunnelIdentifierType eType )
+ {
+ static std::hash_map< int, uno::Sequence< sal_Int8 > > aIds;
+ std::hash_map< int, uno::Sequence< sal_Int8 > >::iterator it =
+ aIds.find( eType );
+ if( it == aIds.end() )
+ {
+ uno::Sequence< sal_Int8 > aNewId( 16 );
+ rtl_createUuid( (sal_uInt8*)aNewId.getArray(), NULL, sal_True );
+ aIds[ eType ] = aNewId;
+ it = aIds.find( eType );
+ }
+ return it->second;
+ }
+
+ //---------------------------------------------------------------------------------------
+
+ namespace
+ {
+ inline bool operator==( const rendering::IntegerBitmapLayout& rLHS,
+ const rendering::IntegerBitmapLayout& rRHS )
+ {
+ return
+ rLHS.ScanLineBytes == rRHS.ScanLineBytes &&
+ rLHS.ScanLineStride == rRHS.ScanLineStride &&
+ rLHS.PlaneStride == rRHS.PlaneStride &&
+ rLHS.ColorSpace == rRHS.ColorSpace &&
+ rLHS.Palette == rRHS.Palette &&
+ rLHS.IsMsbFirst == rRHS.IsMsbFirst;
+ }
+
+ bool readBmp( sal_Int32 nWidth,
+ sal_Int32 nHeight,
+ const rendering::IntegerBitmapLayout& rLayout,
+ const uno::Reference< rendering::XIntegerReadOnlyBitmap >& xInputBitmap,
+ ScopedBitmapWriteAccess& rWriteAcc,
+ ScopedBitmapWriteAccess& rAlphaAcc )
+ {
+ rendering::IntegerBitmapLayout aCurrLayout;
+ geometry::IntegerRectangle2D aRect;
+ uno::Sequence<sal_Int8> aPixelData;
+ uno::Sequence<rendering::RGBColor> aRGBColors;
+ uno::Sequence<rendering::ARGBColor> aARGBColors;
+
+ for( aRect.Y1=0; aRect.Y1<nHeight; ++aRect.Y1 )
+ {
+ aRect.X1 = 0; aRect.X2 = nWidth; aRect.Y2 = aRect.Y1+1;
+ try
+ {
+ aPixelData = xInputBitmap->getData(aCurrLayout,aRect);
+ }
+ catch( rendering::VolatileContentDestroyedException& )
+ {
+ // re-read bmp from the start
+ return false;
+ }
+ if( !(aCurrLayout == rLayout) )
+ return false; // re-read bmp from the start
+
+ if( rAlphaAcc.get() )
+ {
+ // read ARGB color
+ aARGBColors = rLayout.ColorSpace->convertIntegerToARGB(aPixelData);
+
+ if( rWriteAcc->HasPalette() )
+ {
+ for( sal_Int32 x=0; x<nWidth; ++x )
+ {
+ const rendering::ARGBColor& rColor=aARGBColors[x];
+ rWriteAcc->SetPixel( aRect.Y1, x,
+ (BYTE)rWriteAcc->GetBestPaletteIndex(
+ BitmapColor( toByteColor(rColor.Red),
+ toByteColor(rColor.Green),
+ toByteColor(rColor.Blue))) );
+ rAlphaAcc->SetPixel( aRect.Y1, x,
+ BitmapColor( 255 - toByteColor(rColor.Alpha) ));
+ }
+ }
+ else
+ {
+ for( sal_Int32 x=0; x<nWidth; ++x )
+ {
+ const rendering::ARGBColor& rColor=aARGBColors[x];
+ rWriteAcc->SetPixel( aRect.Y1, x,
+ BitmapColor( toByteColor(rColor.Red),
+ toByteColor(rColor.Green),
+ toByteColor(rColor.Blue) ));
+ rAlphaAcc->SetPixel( aRect.Y1, x,
+ BitmapColor( 255 - toByteColor(rColor.Alpha) ));
+ }
+ }
+ }
+ else
+ {
+ // read RGB color
+ aRGBColors = rLayout.ColorSpace->convertIntegerToRGB(aPixelData);
+ if( rWriteAcc->HasPalette() )
+ {
+ for( sal_Int32 x=0; x<nWidth; ++x )
+ {
+ const rendering::RGBColor& rColor=aRGBColors[x];
+ rWriteAcc->SetPixel( aRect.Y1, x,
+ (BYTE)rWriteAcc->GetBestPaletteIndex(
+ BitmapColor( toByteColor(rColor.Red),
+ toByteColor(rColor.Green),
+ toByteColor(rColor.Blue))) );
+ }
+ }
+ else
+ {
+ for( sal_Int32 x=0; x<nWidth; ++x )
+ {
+ const rendering::RGBColor& rColor=aRGBColors[x];
+ rWriteAcc->SetPixel( aRect.Y1, x,
+ BitmapColor( toByteColor(rColor.Red),
+ toByteColor(rColor.Green),
+ toByteColor(rColor.Blue) ));
+ }
+ }
+ }
+ }
+
+ return true;
+ }
+ }
+
+ ::BitmapEx VCL_DLLPUBLIC bitmapExFromXBitmap( const uno::Reference< rendering::XIntegerReadOnlyBitmap >& xInputBitmap )
+ {
+ RTL_LOGFILE_CONTEXT( aLog, "::vcl::unotools::bitmapExFromXBitmap()" );
+
+ if( !xInputBitmap.is() )
+ return ::BitmapEx();
+
+ // tunnel directly for known implementation
+ // ----------------------------------------------------------------
+ VclCanvasBitmap* pImplBitmap = dynamic_cast<VclCanvasBitmap*>(xInputBitmap.get());
+ if( pImplBitmap )
+ return pImplBitmap->getBitmapEx();
+
+ // retrieve data via UNO interface
+ // ----------------------------------------------------------------
+
+ // volatile bitmaps are a bit more complicated to read
+ // from..
+ uno::Reference<rendering::XVolatileBitmap> xVolatileBitmap(
+ xInputBitmap, uno::UNO_QUERY);
+
+ // loop a few times, until successfully read (for XVolatileBitmap)
+ for( int i=0; i<10; ++i )
+ {
+ sal_Int32 nDepth=0;
+ sal_Int32 nAlphaDepth=0;
+ const rendering::IntegerBitmapLayout aLayout(
+ xInputBitmap->getMemoryLayout());
+
+ OSL_ENSURE(aLayout.ColorSpace.is(),
+ "Cannot convert image without color space!");
+ if( !aLayout.ColorSpace.is() )
+ return ::BitmapEx();
+
+ nDepth = aLayout.ColorSpace->getBitsPerPixel();
+
+ if( xInputBitmap->hasAlpha() )
+ {
+ // determine alpha channel depth
+ const uno::Sequence<sal_Int8> aTags(
+ aLayout.ColorSpace->getComponentTags() );
+ const uno::Sequence<sal_Int32> aDepths(
+ aLayout.ColorSpace->getComponentBitCounts() );
+ const sal_Int8* pStart(aTags.getConstArray());
+ const sal_Size nLen(aTags.getLength());
+ const sal_Int8* pEnd(pStart+nLen);
+
+ const std::ptrdiff_t nAlphaIndex =
+ std::find(pStart,pEnd,
+ rendering::ColorComponentTag::ALPHA) - pStart;
+
+ if( nAlphaIndex < sal::static_int_cast<std::ptrdiff_t>(nLen) )
+ {
+ nAlphaDepth = aLayout.ColorSpace->getComponentBitCounts()[nAlphaIndex] > 1 ? 8 : 1;
+ nDepth -= nAlphaDepth;
+ }
+ }
+
+ BitmapPalette aPalette;
+ if( aLayout.Palette.is() )
+ {
+ uno::Reference< rendering::XColorSpace > xPaletteColorSpace(
+ aLayout.Palette->getColorSpace());
+ ENSURE_OR_THROW(xPaletteColorSpace.is(),
+ "Palette without color space");
+
+ const sal_Int32 nEntryCount( aLayout.Palette->getNumberOfEntries() );
+ if( nEntryCount <= 256 )
+ {
+ if( nEntryCount <= 2 )
+ nDepth = 1;
+ else
+ nDepth = 8;
+
+ const USHORT nPaletteEntries(
+ sal::static_int_cast<USHORT>(
+ std::min(sal_Int32(255), nEntryCount)));
+
+ // copy palette entries
+ aPalette.SetEntryCount(nPaletteEntries);
+ uno::Reference<rendering::XBitmapPalette> xPalette( aLayout.Palette );
+ uno::Reference<rendering::XColorSpace> xPalColorSpace( xPalette->getColorSpace() );
+
+ uno::Sequence<double> aPaletteEntry;
+ for( USHORT j=0; j<nPaletteEntries; ++j )
+ {
+ if( !xPalette->getIndex(aPaletteEntry,j) &&
+ nAlphaDepth == 0 )
+ {
+ nAlphaDepth = 1;
+ }
+ uno::Sequence<rendering::RGBColor> aColors=xPalColorSpace->convertToRGB(aPaletteEntry);
+ ENSURE_OR_THROW(aColors.getLength() == 1,
+ "Palette returned more or less than one entry");
+ const rendering::RGBColor& rColor=aColors[0];
+ aPalette[j] = BitmapColor(toByteColor(rColor.Red),
+ toByteColor(rColor.Green),
+ toByteColor(rColor.Blue));
+ }
+ }
+ }
+
+ const ::Size aPixelSize(
+ sizeFromIntegerSize2D(xInputBitmap->getSize()));
+
+ // normalize bitcount
+ nDepth =
+ ( nDepth <= 1 ) ? 1 :
+ ( nDepth <= 4 ) ? 4 :
+ ( nDepth <= 8 ) ? 8 : 24;
+
+ ::Bitmap aBitmap( aPixelSize,
+ sal::static_int_cast<USHORT>(nDepth),
+ aLayout.Palette.is() ? &aPalette : NULL );
+ ::Bitmap aAlpha;
+ if( nAlphaDepth )
+ aAlpha = ::Bitmap( aPixelSize,
+ sal::static_int_cast<USHORT>(nAlphaDepth),
+ &::Bitmap::GetGreyPalette(
+ sal::static_int_cast<USHORT>(1L << nAlphaDepth)) );
+
+ { // limit scoped access
+ ScopedBitmapWriteAccess pWriteAccess( aBitmap.AcquireWriteAccess(),
+ aBitmap );
+ ScopedBitmapWriteAccess pAlphaWriteAccess( nAlphaDepth ? aAlpha.AcquireWriteAccess() : NULL,
+ aAlpha );
+
+ ENSURE_OR_THROW(pWriteAccess.get() != NULL,
+ "Cannot get write access to bitmap");
+
+ const sal_Int32 nWidth(aPixelSize.Width());
+ const sal_Int32 nHeight(aPixelSize.Height());
+
+ if( !readBmp(nWidth,nHeight,aLayout,xInputBitmap,
+ pWriteAccess,pAlphaWriteAccess) )
+ continue;
+ } // limit scoped access
+
+ if( nAlphaDepth )
+ return ::BitmapEx( aBitmap,
+ AlphaMask( aAlpha ) );
+ else
+ return ::BitmapEx( aBitmap );
+ }
+
+ // failed to read data 10 times - bail out
+ return ::BitmapEx();
+ }
+
+ //---------------------------------------------------------------------------------------
+
+ geometry::RealSize2D size2DFromSize( const Size& rSize )
+ {
+ return geometry::RealSize2D( rSize.Width(),
+ rSize.Height() );
+ }
+
+ geometry::RealPoint2D point2DFromPoint( const Point& rPoint )
+ {
+ return geometry::RealPoint2D( rPoint.X(),
+ rPoint.Y() );
+ }
+
+ geometry::RealRectangle2D rectangle2DFromRectangle( const Rectangle& rRect )
+ {
+ return geometry::RealRectangle2D( rRect.Left(), rRect.Top(),
+ rRect.Right(), rRect.Bottom() );
+ }
+
+ Size sizeFromRealSize2D( const geometry::RealSize2D& rSize )
+ {
+ return Size( static_cast<long>(rSize.Width + .5),
+ static_cast<long>(rSize.Height + .5) );
+ }
+
+ Point pointFromRealPoint2D( const geometry::RealPoint2D& rPoint )
+ {
+ return Point( static_cast<long>(rPoint.X + .5),
+ static_cast<long>(rPoint.Y + .5) );
+ }
+
+ Rectangle rectangleFromRealRectangle2D( const geometry::RealRectangle2D& rRect )
+ {
+ return Rectangle( static_cast<long>(rRect.X1 + .5),
+ static_cast<long>(rRect.Y1 + .5),
+ static_cast<long>(rRect.X2 + .5),
+ static_cast<long>(rRect.Y2 + .5) );
+ }
+
+ ::Size sizeFromB2DSize( const ::basegfx::B2DVector& rVec )
+ {
+ return ::Size( FRound( rVec.getX() ),
+ FRound( rVec.getY() ) );
+ }
+
+ ::Point pointFromB2DPoint( const ::basegfx::B2DPoint& rPoint )
+ {
+ return ::Point( FRound( rPoint.getX() ),
+ FRound( rPoint.getY() ) );
+ }
+
+ ::Rectangle rectangleFromB2DRectangle( const ::basegfx::B2DRange& rRect )
+ {
+ return ::Rectangle( FRound( rRect.getMinX() ),
+ FRound( rRect.getMinY() ),
+ FRound( rRect.getMaxX() ),
+ FRound( rRect.getMaxY() ) );
+ }
+
+ Size sizeFromB2ISize( const ::basegfx::B2IVector& rVec )
+ {
+ return ::Size( rVec.getX(),
+ rVec.getY() );
+ }
+
+ Point pointFromB2IPoint( const ::basegfx::B2IPoint& rPoint )
+ {
+ return ::Point( rPoint.getX(),
+ rPoint.getY() );
+ }
+
+ Rectangle rectangleFromB2IRectangle( const ::basegfx::B2IRange& rRect )
+ {
+ return ::Rectangle( rRect.getMinX(),
+ rRect.getMinY(),
+ rRect.getMaxX(),
+ rRect.getMaxY() );
+ }
+
+ ::basegfx::B2DVector b2DSizeFromSize( const ::Size& rSize )
+ {
+ return ::basegfx::B2DVector( rSize.Width(),
+ rSize.Height() );
+ }
+
+ ::basegfx::B2DPoint b2DPointFromPoint( const ::Point& rPoint )
+ {
+ return ::basegfx::B2DPoint( rPoint.X(),
+ rPoint.Y() );
+ }
+
+ ::basegfx::B2DRange b2DRectangleFromRectangle( const ::Rectangle& rRect )
+ {
+ return ::basegfx::B2DRange( rRect.Left(),
+ rRect.Top(),
+ rRect.Right(),
+ rRect.Bottom() );
+ }
+
+ basegfx::B2IVector b2ISizeFromSize( const Size& rSize )
+ {
+ return ::basegfx::B2IVector( rSize.Width(),
+ rSize.Height() );
+ }
+
+ basegfx::B2IPoint b2IPointFromPoint( const Point& rPoint )
+ {
+ return ::basegfx::B2IPoint( rPoint.X(),
+ rPoint.Y() );
+ }
+
+ basegfx::B2IRange b2IRectangleFromRectangle( const Rectangle& rRect )
+ {
+ return ::basegfx::B2IRange( rRect.Left(),
+ rRect.Top(),
+ rRect.Right(),
+ rRect.Bottom() );
+ }
+
+ geometry::IntegerSize2D integerSize2DFromSize( const Size& rSize )
+ {
+ return geometry::IntegerSize2D( rSize.Width(),
+ rSize.Height() );
+ }
+
+ geometry::IntegerPoint2D integerPoint2DFromPoint( const Point& rPoint )
+ {
+ return geometry::IntegerPoint2D( rPoint.X(),
+ rPoint.Y() );
+ }
+
+ geometry::IntegerRectangle2D integerRectangle2DFromRectangle( const Rectangle& rRectangle )
+ {
+ return geometry::IntegerRectangle2D( rRectangle.Left(), rRectangle.Top(),
+ rRectangle.Right(), rRectangle.Bottom() );
+ }
+
+ Size sizeFromIntegerSize2D( const geometry::IntegerSize2D& rSize )
+ {
+ return Size( rSize.Width,
+ rSize.Height );
+ }
+
+ Point pointFromIntegerPoint2D( const geometry::IntegerPoint2D& rPoint )
+ {
+ return Point( rPoint.X,
+ rPoint.Y );
+ }
+
+ Rectangle rectangleFromIntegerRectangle2D( const geometry::IntegerRectangle2D& rRectangle )
+ {
+ return Rectangle( rRectangle.X1, rRectangle.Y1,
+ rRectangle.X2, rRectangle.Y2 );
+ }
+
+ namespace
+ {
+ class StandardColorSpace : public cppu::WeakImplHelper1< com::sun::star::rendering::XColorSpace >
+ {
+ private:
+ uno::Sequence< sal_Int8 > m_aComponentTags;
+
+ virtual ::sal_Int8 SAL_CALL getType( ) throw (uno::RuntimeException)
+ {
+ return rendering::ColorSpaceType::RGB;
+ }
+ virtual uno::Sequence< ::sal_Int8 > SAL_CALL getComponentTags( ) throw (uno::RuntimeException)
+ {
+ return m_aComponentTags;
+ }
+ virtual ::sal_Int8 SAL_CALL getRenderingIntent( ) throw (uno::RuntimeException)
+ {
+ return rendering::RenderingIntent::PERCEPTUAL;
+ }
+ virtual uno::Sequence< beans::PropertyValue > SAL_CALL getProperties( ) throw (uno::RuntimeException)
+ {
+ return uno::Sequence< beans::PropertyValue >();
+ }
+ virtual uno::Sequence< double > SAL_CALL convertColorSpace( const uno::Sequence< double >& deviceColor,
+ const uno::Reference< rendering::XColorSpace >& targetColorSpace ) throw (lang::IllegalArgumentException,
+ uno::RuntimeException)
+ {
+ // TODO(P3): if we know anything about target
+ // colorspace, this can be greatly sped up
+ uno::Sequence<rendering::ARGBColor> aIntermediate(
+ convertToARGB(deviceColor));
+ return targetColorSpace->convertFromARGB(aIntermediate);
+ }
+ virtual uno::Sequence< rendering::RGBColor > SAL_CALL convertToRGB( const uno::Sequence< double >& deviceColor ) throw (lang::IllegalArgumentException, uno::RuntimeException)
+ {
+ const double* pIn( deviceColor.getConstArray() );
+ const sal_Size nLen( deviceColor.getLength() );
+ ENSURE_ARG_OR_THROW2(nLen%4==0,
+ "number of channels no multiple of 4",
+ static_cast<rendering::XColorSpace*>(this), 0);
+
+ uno::Sequence< rendering::RGBColor > aRes(nLen/4);
+ rendering::RGBColor* pOut( aRes.getArray() );
+ for( sal_Size i=0; i<nLen; i+=4 )
+ {
+ *pOut++ = rendering::RGBColor(pIn[0],pIn[1],pIn[2]);
+ pIn += 4;
+ }
+ return aRes;
+ }
+ virtual uno::Sequence< rendering::ARGBColor > SAL_CALL convertToARGB( const uno::Sequence< double >& deviceColor ) throw (lang::IllegalArgumentException, uno::RuntimeException)
+ {
+ const double* pIn( deviceColor.getConstArray() );
+ const sal_Size nLen( deviceColor.getLength() );
+ ENSURE_ARG_OR_THROW2(nLen%4==0,
+ "number of channels no multiple of 4",
+ static_cast<rendering::XColorSpace*>(this), 0);
+
+ uno::Sequence< rendering::ARGBColor > aRes(nLen/4);
+ rendering::ARGBColor* pOut( aRes.getArray() );
+ for( sal_Size i=0; i<nLen; i+=4 )
+ {
+ *pOut++ = rendering::ARGBColor(pIn[3],pIn[0],pIn[1],pIn[2]);
+ pIn += 4;
+ }
+ return aRes;
+ }
+ virtual uno::Sequence< rendering::ARGBColor > SAL_CALL convertToPARGB( const uno::Sequence< double >& deviceColor ) throw (lang::IllegalArgumentException, uno::RuntimeException)
+ {
+ const double* pIn( deviceColor.getConstArray() );
+ const sal_Size nLen( deviceColor.getLength() );
+ ENSURE_ARG_OR_THROW2(nLen%4==0,
+ "number of channels no multiple of 4",
+ static_cast<rendering::XColorSpace*>(this), 0);
+
+ uno::Sequence< rendering::ARGBColor > aRes(nLen/4);
+ rendering::ARGBColor* pOut( aRes.getArray() );
+ for( sal_Size i=0; i<nLen; i+=4 )
+ {
+ *pOut++ = rendering::ARGBColor(pIn[3],pIn[3]*pIn[0],pIn[3]*pIn[1],pIn[3]*pIn[2]);
+ pIn += 4;
+ }
+ return aRes;
+ }
+ virtual uno::Sequence< double > SAL_CALL convertFromRGB( const uno::Sequence< rendering::RGBColor >& rgbColor ) throw (lang::IllegalArgumentException, uno::RuntimeException)
+ {
+ const rendering::RGBColor* pIn( rgbColor.getConstArray() );
+ const sal_Size nLen( rgbColor.getLength() );
+
+ uno::Sequence< double > aRes(nLen*4);
+ double* pColors=aRes.getArray();
+ for( sal_Size i=0; i<nLen; ++i )
+ {
+ *pColors++ = pIn->Red;
+ *pColors++ = pIn->Green;
+ *pColors++ = pIn->Blue;
+ *pColors++ = 1.0;
+ ++pIn;
+ }
+ return aRes;
+ }
+ virtual uno::Sequence< double > SAL_CALL convertFromARGB( const uno::Sequence< rendering::ARGBColor >& rgbColor ) throw (lang::IllegalArgumentException, uno::RuntimeException)
+ {
+ const rendering::ARGBColor* pIn( rgbColor.getConstArray() );
+ const sal_Size nLen( rgbColor.getLength() );
+
+ uno::Sequence< double > aRes(nLen*4);
+ double* pColors=aRes.getArray();
+ for( sal_Size i=0; i<nLen; ++i )
+ {
+ *pColors++ = pIn->Red;
+ *pColors++ = pIn->Green;
+ *pColors++ = pIn->Blue;
+ *pColors++ = pIn->Alpha;
+ ++pIn;
+ }
+ return aRes;
+ }
+ virtual uno::Sequence< double > SAL_CALL convertFromPARGB( const uno::Sequence< rendering::ARGBColor >& rgbColor ) throw (lang::IllegalArgumentException, uno::RuntimeException)
+ {
+ const rendering::ARGBColor* pIn( rgbColor.getConstArray() );
+ const sal_Size nLen( rgbColor.getLength() );
+
+ uno::Sequence< double > aRes(nLen*4);
+ double* pColors=aRes.getArray();
+ for( sal_Size i=0; i<nLen; ++i )
+ {
+ *pColors++ = pIn->Red/pIn->Alpha;
+ *pColors++ = pIn->Green/pIn->Alpha;
+ *pColors++ = pIn->Blue/pIn->Alpha;
+ *pColors++ = pIn->Alpha;
+ ++pIn;
+ }
+ return aRes;
+ }
+
+ public:
+ StandardColorSpace() : m_aComponentTags(4)
+ {
+ sal_Int8* pTags = m_aComponentTags.getArray();
+ pTags[0] = rendering::ColorComponentTag::RGB_RED;
+ pTags[1] = rendering::ColorComponentTag::RGB_GREEN;
+ pTags[2] = rendering::ColorComponentTag::RGB_BLUE;
+ pTags[3] = rendering::ColorComponentTag::ALPHA;
+ }
+ };
+ }
+
+ uno::Reference<rendering::XColorSpace> VCL_DLLPUBLIC createStandardColorSpace()
+ {
+ return new StandardColorSpace();
+ }
+
+ //---------------------------------------------------------------------------------------
+
+ uno::Sequence< double > colorToStdColorSpaceSequence( const Color& rColor )
+ {
+ uno::Sequence< double > aRet(4);
+ double* pRet = aRet.getArray();
+
+ pRet[0] = toDoubleColor(rColor.GetRed());
+ pRet[1] = toDoubleColor(rColor.GetGreen());
+ pRet[2] = toDoubleColor(rColor.GetBlue());
+
+ // VCL's notion of alpha is different from the rest of the world's
+ pRet[3] = 1.0 - toDoubleColor(rColor.GetTransparency());
+
+ return aRet;
+ }
+
+ Color stdColorSpaceSequenceToColor( const uno::Sequence< double >& rColor )
+ {
+ ENSURE_ARG_OR_THROW( rColor.getLength() == 4,
+ "color must have 4 channels" );
+
+ Color aColor;
+
+ aColor.SetRed ( toByteColor(rColor[0]) );
+ aColor.SetGreen( toByteColor(rColor[1]) );
+ aColor.SetBlue ( toByteColor(rColor[2]) );
+ // VCL's notion of alpha is different from the rest of the world's
+ aColor.SetTransparency( 255 - toByteColor(rColor[3]) );
+
+ return aColor;
+ }
+
+ uno::Sequence< double > VCL_DLLPUBLIC colorToDoubleSequence(
+ const Color& rColor,
+ const uno::Reference< rendering::XColorSpace >& xColorSpace )
+ {
+ uno::Sequence<rendering::ARGBColor> aSeq(1);
+ aSeq[0] = rendering::ARGBColor(
+ 1.0-toDoubleColor(rColor.GetTransparency()),
+ toDoubleColor(rColor.GetRed()),
+ toDoubleColor(rColor.GetGreen()),
+ toDoubleColor(rColor.GetBlue()) );
+
+ return xColorSpace->convertFromARGB(aSeq);
+ }
+
+ Color VCL_DLLPUBLIC doubleSequenceToColor(
+ const uno::Sequence< double > rColor,
+ const uno::Reference< rendering::XColorSpace >& xColorSpace )
+ {
+ const rendering::ARGBColor& rARGBColor(
+ xColorSpace->convertToARGB(rColor)[0]);
+
+ return Color( 255-toByteColor(rARGBColor.Alpha),
+ toByteColor(rARGBColor.Red),
+ toByteColor(rARGBColor.Green),
+ toByteColor(rARGBColor.Blue) );
+ }
+
+ //---------------------------------------------------------------------------------------
+
+ } // namespace vcltools
+
+} // namespace canvas
+
+// eof
diff --git a/vcl/source/helper/evntpost.cxx b/vcl/source/helper/evntpost.cxx
new file mode 100644
index 000000000000..9e200a3136c3
--- /dev/null
+++ b/vcl/source/helper/evntpost.cxx
@@ -0,0 +1,65 @@
+/*************************************************************************
+ *
+ * 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 <vcl/evntpost.hxx>
+#include <vcl/svapp.hxx>
+
+namespace vcl
+{
+
+EventPoster::EventPoster( const Link& rLink )
+ : m_aLink(rLink)
+{
+ m_nId = 0;
+}
+
+EventPoster::~EventPoster()
+{
+ if ( m_nId )
+ GetpApp()->RemoveUserEvent( m_nId );
+}
+
+void EventPoster::Post( UserEvent* pEvent )
+
+{
+ m_nId = GetpApp()->PostUserEvent( ( LINK( this, EventPoster, DoEvent_Impl ) ), pEvent );
+}
+
+IMPL_LINK_INLINE_START( EventPoster, DoEvent_Impl, UserEvent*, pEvent )
+{
+ m_nId = 0;
+ m_aLink.Call( pEvent );
+ return 0;
+}
+IMPL_LINK_INLINE_END( EventPoster, DoEvent_Impl, UserEvent*, pEvent )
+
+}
diff --git a/vcl/source/helper/lazydelete.cxx b/vcl/source/helper/lazydelete.cxx
new file mode 100644
index 000000000000..7b244781c3c7
--- /dev/null
+++ b/vcl/source/helper/lazydelete.cxx
@@ -0,0 +1,125 @@
+/*************************************************************************
+ *
+ * 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"
+
+#ifndef LAZYDELETE_CXX
+#define LAZYDELETE_CXX
+
+#include "vcl/window.hxx"
+#include "vcl/menu.hxx"
+#include "vcl/lazydelete.hxx"
+#include "vcl/svdata.hxx"
+
+namespace vcl {
+
+LazyDeletorBase::LazyDeletorBase()
+{
+}
+
+LazyDeletorBase::~LazyDeletorBase()
+{
+}
+
+// instantiate instance pointers for LazyDeletor<Window,Menu>
+template<> LazyDeletor<Window>* LazyDeletor<Window>::s_pOneInstance = NULL;
+template<> LazyDeletor<Menu>* LazyDeletor<Menu>::s_pOneInstance = NULL;
+
+// a list for all LazyeDeletor<T> singletons
+static std::vector< LazyDeletorBase* > lcl_aDeletors;
+
+void LazyDelete::addDeletor( LazyDeletorBase* i_pDel )
+{
+ lcl_aDeletors.push_back( i_pDel );
+}
+
+void LazyDelete::flush()
+{
+ unsigned int nCount = lcl_aDeletors.size();
+ for( unsigned int i = 0; i < nCount; i++ )
+ delete lcl_aDeletors[i];
+ lcl_aDeletors.clear();
+}
+
+// specialized is_less function for Window
+template<> bool LazyDeletor<Window>::is_less( Window* left, Window* right )
+{
+ return (left != right && right->IsChild( left, TRUE )) ? true : false;
+}
+
+// specialized is_less function for Menu
+template<> bool LazyDeletor<Menu>::is_less( Menu* left, Menu* right )
+{
+ while( left && left != right )
+ left = left->ImplGetStartedFrom();
+ return left != NULL;
+}
+
+DeleteOnDeinitBase::~DeleteOnDeinitBase()
+{
+ ImplSVData* pSVData = ImplGetSVData();
+ if( pSVData && pSVData->mpDeinitDeleteList != NULL )
+ pSVData->mpDeinitDeleteList->remove( this );
+}
+
+void DeleteOnDeinitBase::addDeinitContainer( DeleteOnDeinitBase* i_pContainer )
+{
+ ImplSVData* pSVData = ImplGetSVData();
+ if( ! pSVData )
+ {
+ ImplInitSVData();
+ pSVData = ImplGetSVData();
+ }
+
+ DBG_ASSERT( ! pSVData->mbDeInit, "DeleteOnDeinit added after DeiInitVCL !" );
+ if( pSVData->mbDeInit )
+ return;
+
+ if( pSVData->mpDeinitDeleteList == NULL )
+ pSVData->mpDeinitDeleteList = new std::list< DeleteOnDeinitBase* >();
+ pSVData->mpDeinitDeleteList->push_back( i_pContainer );
+}
+
+void DeleteOnDeinitBase::ImplDeleteOnDeInit()
+{
+ ImplSVData* pSVData = ImplGetSVData();
+ if( pSVData->mpDeinitDeleteList )
+ {
+ for( std::list< vcl::DeleteOnDeinitBase* >::iterator it = pSVData->mpDeinitDeleteList->begin();
+ it != pSVData->mpDeinitDeleteList->end(); ++it )
+ {
+ (*it)->doCleanup();
+ }
+ delete pSVData->mpDeinitDeleteList;
+ pSVData->mpDeinitDeleteList = NULL;
+ }
+}
+
+} // namespace vcl
+
+#endif
+
diff --git a/vcl/source/helper/makefile.mk b/vcl/source/helper/makefile.mk
new file mode 100644
index 000000000000..e708bdec9eaa
--- /dev/null
+++ b/vcl/source/helper/makefile.mk
@@ -0,0 +1,56 @@
+#*************************************************************************
+#
+# 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.
+#
+#*************************************************************************
+
+PRJ=..$/..
+
+ENABLE_EXCEPTIONS=TRUE
+PRJNAME=vcl
+TARGET=helper
+.INCLUDE : $(PRJ)$/util$/makefile.pmk
+
+# --- Settings -----------------------------------------------------
+
+.INCLUDE : settings.mk
+.INCLUDE : $(PRJ)$/util$/makefile2.pmk
+
+# --- Files --------------------------------------------------------
+
+SLOFILES=\
+ $(SLO)$/strhelper.obj \
+ $(SLO)$/evntpost.obj \
+ $(SLO)$/canvasbitmap.obj \
+ $(SLO)$/canvastools.obj \
+ $(SLO)$/xconnection.obj \
+ $(SLO)$/threadex.obj \
+ $(SLO)$/smartid.obj \
+ $(SLO)$/lazydelete.obj
+
+# --- Targets ------------------------------------------------------
+
+.INCLUDE : target.mk
+
+.INCLUDE : $(PRJ)$/util$/target.pmk
diff --git a/vcl/source/helper/smartid.cxx b/vcl/source/helper/smartid.cxx
new file mode 100755
index 000000000000..c367aeb2bce5
--- /dev/null
+++ b/vcl/source/helper/smartid.cxx
@@ -0,0 +1,264 @@
+/*************************************************************************
+ *
+ * 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 <vcl/smartid.hxx>
+
+struct ImplSmartIdData
+{
+ String aUId;
+ ULONG nUId;
+ BOOL bHasStringId;
+ BOOL bHasNumericId;
+};
+
+
+ImplSmartIdData* SmartId::GetSmartIdData()
+{
+ if ( !mpData )
+ {
+ mpData = new ImplSmartIdData;
+// mpData->aUId = "";
+ mpData->nUId = 0;
+ mpData->bHasStringId = FALSE;
+ mpData->bHasNumericId = FALSE;
+ }
+ return mpData;
+}
+
+
+SmartId::SmartId( const String& rId )
+: mpData( NULL )
+{
+ GetSmartIdData()->aUId = rId;
+ GetSmartIdData()->bHasStringId = TRUE;
+}
+
+SmartId::SmartId( ULONG nId )
+: mpData( NULL )
+{
+ GetSmartIdData()->nUId = nId;
+ GetSmartIdData()->bHasNumericId = TRUE;
+}
+
+SmartId::SmartId( const String& rId, ULONG nId )
+: mpData( NULL )
+{
+ GetSmartIdData()->aUId = rId;
+ GetSmartIdData()->bHasStringId = TRUE;
+ GetSmartIdData()->nUId = nId;
+ GetSmartIdData()->bHasNumericId = TRUE;
+}
+
+SmartId::SmartId()
+: mpData( NULL )
+{}
+
+SmartId::SmartId( const SmartId& rId )
+: mpData( NULL )
+{
+ if ( rId.mpData )
+ {
+ GetSmartIdData();
+ mpData->aUId = rId.mpData->aUId;
+ mpData->bHasStringId = rId.mpData->bHasStringId;
+ mpData->nUId = rId.mpData->nUId;
+ mpData->bHasNumericId = rId.mpData->bHasNumericId;
+ }
+}
+
+SmartId& SmartId::operator = ( const SmartId& rId )
+{
+ if ( rId.mpData )
+ GetSmartIdData();
+ else
+ {
+ delete mpData;
+ mpData = NULL;
+ }
+ if ( mpData && rId.mpData )
+ {
+ mpData->aUId = rId.mpData->aUId;
+ mpData->bHasStringId = rId.mpData->bHasStringId;
+ mpData->nUId = rId.mpData->nUId;
+ mpData->bHasNumericId = rId.mpData->bHasNumericId;
+ }
+ return *this;
+}
+
+SmartId::~SmartId()
+{
+ if ( mpData )
+ delete mpData;
+#ifdef DBG_UTIL
+ if ( mpData )
+ mpData = (ImplSmartIdData*)0xDeadBeef;
+#endif
+}
+
+void SmartId::UpdateId( const SmartId& rId, SmartIdUpdateMode aMode )
+{
+ // Check if ImplData is needed
+ if ( aMode != SMART_SET_SMART || ( rId.HasString() || rId.HasNumeric() ) )
+ GetSmartIdData();
+
+ if ( aMode == SMART_SET_STR || aMode == SMART_SET_ALL || ( aMode == SMART_SET_SMART && rId.HasString() ) )
+ {
+ GetSmartIdData()->aUId = rId.GetStr();
+ GetSmartIdData()->bHasStringId = rId.HasString();
+ }
+ if ( aMode == SMART_SET_NUM || aMode == SMART_SET_ALL || ( aMode == SMART_SET_SMART && rId.HasNumeric() ) )
+ {
+ GetSmartIdData()->nUId = rId.GetNum();
+ GetSmartIdData()->bHasNumericId = rId.HasNumeric();
+ }
+
+ // remove ImplData when no IDs are set. This is Important because Implementation of Equals() Matches and HasAny relies on it
+ if ( mpData && !mpData->bHasStringId && !mpData->bHasNumericId )
+ {
+ delete mpData;
+ mpData = NULL;
+ }
+}
+
+BOOL SmartId::HasNumeric() const
+{
+ if ( !mpData )
+ return FALSE;
+ else
+ return mpData->bHasNumericId;
+}
+
+BOOL SmartId::HasString() const
+{
+ if ( !mpData )
+ return FALSE;
+ else
+ return mpData->bHasStringId;
+}
+
+BOOL SmartId::HasAny() const
+{
+ return mpData != NULL;
+}
+
+ULONG SmartId::GetNum() const
+{
+ if ( !mpData )
+ return 0;
+ else
+ return mpData->nUId;
+}
+
+String SmartId::GetStr() const
+{
+ if ( !mpData )
+ return String();
+ else
+ return mpData->aUId;
+}
+
+
+String SmartId::GetText() const // return String for UI usage
+{
+ String aRes;
+ if ( HasNumeric() )
+ aRes = String::CreateFromInt64( GetNum() );
+ if ( HasString() )
+ {
+ if ( HasNumeric() )
+ aRes.AppendAscii( "/" );
+ aRes.Append( GetStr() );
+ }
+ return aRes;
+}
+
+BOOL SmartId::Matches( const String &rId )const
+{
+ if ( HasString() )
+ return GetStr().EqualsIgnoreCaseAscii( rId );
+ else
+ return FALSE;
+}
+
+BOOL SmartId::Matches( const ULONG nId ) const
+{
+ if ( HasNumeric() )
+ return GetNum() == nId;
+ else
+ return FALSE;
+}
+
+/******************************************************************************
+If Both Ids have nither Strings nor Numbers they don't match
+If both Ids have Strings the result of Matching these is returned.
+Numbers are then Ignored.
+Else Matching Numbers is attempted.
+******************************************************************************/
+BOOL SmartId::Matches( const SmartId &rId ) const
+{
+ if ( !mpData || !rId.mpData )
+ return FALSE;
+ else if ( HasString() && rId.HasString() )
+ return Matches( rId.GetStr() );
+ else
+ return rId.HasNumeric() && Matches( rId.GetNum() );
+}
+
+BOOL SmartId::Equals( const SmartId &rId ) const
+{
+ if ( mpData && rId.mpData )
+ return mpData->aUId.EqualsIgnoreCaseAscii( rId.mpData->aUId )
+ && mpData->bHasStringId == rId.mpData->bHasStringId
+ && mpData->nUId == rId.mpData->nUId
+ && mpData->bHasNumericId == rId.mpData->bHasNumericId;
+ else if ( !mpData && !rId.mpData )
+ return TRUE;
+ else
+ return FALSE;
+}
+
+BOOL SmartId::operator == ( const SmartId& rRight ) const
+{
+ return Equals( rRight );
+}
+
+BOOL SmartId::operator < ( const SmartId& rRight ) const
+{
+ if ( HasString() && rRight.HasString() && GetStr() != rRight.GetStr() )
+ return GetStr() < rRight.GetStr();
+ else if ( HasNumeric() && rRight.HasNumeric() && GetNum() != rRight.GetNum() )
+ return GetNum() < rRight.GetNum();
+ else
+ { // Sort Strings to Front
+ if ( HasString() )
+ return rRight.HasString() && rRight.HasNumeric();
+ else
+ return rRight.HasString() || (!HasNumeric() && rRight.HasNumeric());
+ }
+}
diff --git a/vcl/source/helper/strhelper.cxx b/vcl/source/helper/strhelper.cxx
new file mode 100644
index 000000000000..db622073cea9
--- /dev/null
+++ b/vcl/source/helper/strhelper.cxx
@@ -0,0 +1,442 @@
+/*************************************************************************
+ *
+ * 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 "vcl/strhelper.hxx"
+#include "sal/alloca.h"
+
+namespace psp {
+
+inline int isSpace( char cChar )
+{
+ return
+ cChar == ' ' || cChar == '\t' ||
+ cChar == '\r' || cChar == '\n' ||
+ cChar == 0x0c || cChar == 0x0b;
+}
+
+inline int isSpace( sal_Unicode cChar )
+{
+ return
+ cChar == ' ' || cChar == '\t' ||
+ cChar == '\r' || cChar == '\n' ||
+ cChar == 0x0c || cChar == 0x0b;
+}
+
+inline int isProtect( char cChar )
+{
+ return cChar == '`' || cChar == '\'' || cChar == '"';
+}
+
+inline int isProtect( sal_Unicode cChar )
+{
+ return cChar == '`' || cChar == '\'' || cChar == '"';
+}
+
+inline void CopyUntil( char*& pTo, const char*& pFrom, char cUntil, int bIncludeUntil = 0 )
+{
+ do
+ {
+ if( *pFrom == '\\' )
+ {
+ pFrom++;
+ if( *pFrom )
+ {
+ *pTo = *pFrom;
+ pTo++;
+ }
+ }
+ else if( bIncludeUntil || ! isProtect( *pFrom ) )
+ {
+ *pTo = *pFrom;
+ pTo++;
+ }
+ pFrom++;
+ } while( *pFrom && *pFrom != cUntil );
+ // copy the terminating character unless zero or protector
+ if( ! isProtect( *pFrom ) || bIncludeUntil )
+ {
+ *pTo = *pFrom;
+ if( *pTo )
+ pTo++;
+ }
+ if( *pFrom )
+ pFrom++;
+}
+
+inline void CopyUntil( sal_Unicode*& pTo, const sal_Unicode*& pFrom, sal_Unicode cUntil, int bIncludeUntil = 0 )
+{
+ do
+ {
+ if( *pFrom == '\\' )
+ {
+ pFrom++;
+ if( *pFrom )
+ {
+ *pTo = *pFrom;
+ pTo++;
+ }
+ }
+ else if( bIncludeUntil || ! isProtect( *pFrom ) )
+ {
+ *pTo = *pFrom;
+ pTo++;
+ }
+ pFrom++;
+ } while( *pFrom && *pFrom != cUntil );
+ // copy the terminating character unless zero or protector
+ if( ! isProtect( *pFrom ) || bIncludeUntil )
+ {
+ *pTo = *pFrom;
+ if( *pTo )
+ pTo++;
+ }
+ if( *pFrom )
+ pFrom++;
+}
+
+String GetCommandLineToken( int nToken, const String& rLine )
+{
+ int nLen = rLine.Len();
+ if( ! nLen )
+ return String();
+
+ int nActualToken = 0;
+ sal_Unicode* pBuffer = (sal_Unicode*)alloca( sizeof(sal_Unicode)*( nLen + 1 ) );
+ const sal_Unicode* pRun = rLine.GetBuffer();
+ sal_Unicode* pLeap = NULL;
+
+ while( *pRun && nActualToken <= nToken )
+ {
+ while( *pRun && isSpace( *pRun ) )
+ pRun++;
+ pLeap = pBuffer;
+ while( *pRun && ! isSpace( *pRun ) )
+ {
+ if( *pRun == '\\' )
+ {
+ // escapement
+ pRun++;
+ *pLeap = *pRun;
+ pLeap++;
+ if( *pRun )
+ pRun++;
+ }
+ else if( *pRun == '`' )
+ CopyUntil( pLeap, pRun, '`' );
+ else if( *pRun == '\'' )
+ CopyUntil( pLeap, pRun, '\'' );
+ else if( *pRun == '"' )
+ CopyUntil( pLeap, pRun, '"' );
+ else
+ {
+ *pLeap = *pRun;
+ pLeap++;
+ pRun++;
+ }
+ }
+ if( nActualToken != nToken )
+ pBuffer[0] = 0;
+ nActualToken++;
+ }
+
+ *pLeap = 0;
+
+ String aRet( pBuffer );
+ return aRet;
+}
+
+ByteString GetCommandLineToken( int nToken, const ByteString& rLine )
+{
+ int nLen = rLine.Len();
+ if( ! nLen )
+ return ByteString();
+
+ int nActualToken = 0;
+ char* pBuffer = (char*)alloca( nLen + 1 );
+ const char* pRun = rLine.GetBuffer();
+ char* pLeap = NULL;
+
+ while( *pRun && nActualToken <= nToken )
+ {
+ while( *pRun && isSpace( *pRun ) )
+ pRun++;
+ pLeap = pBuffer;
+ while( *pRun && ! isSpace( *pRun ) )
+ {
+ if( *pRun == '\\' )
+ {
+ // escapement
+ pRun++;
+ *pLeap = *pRun;
+ pLeap++;
+ if( *pRun )
+ pRun++;
+ }
+ else if( *pRun == '`' )
+ CopyUntil( pLeap, pRun, '`' );
+ else if( *pRun == '\'' )
+ CopyUntil( pLeap, pRun, '\'' );
+ else if( *pRun == '"' )
+ CopyUntil( pLeap, pRun, '"' );
+ else
+ {
+ *pLeap = *pRun;
+ pLeap++;
+ pRun++;
+ }
+ }
+ if( nActualToken != nToken )
+ pBuffer[0] = 0;
+ nActualToken++;
+ }
+
+ *pLeap = 0;
+
+ ByteString aRet( pBuffer );
+ return aRet;
+}
+
+int GetCommandLineTokenCount( const String& rLine )
+{
+ if( ! rLine.Len() )
+ return 0;
+
+ int nTokenCount = 0;
+ const sal_Unicode *pRun = rLine.GetBuffer();
+
+
+ while( *pRun )
+ {
+ while( *pRun && isSpace( *pRun ) )
+ pRun++;
+ if( ! *pRun )
+ break;
+ while( *pRun && ! isSpace( *pRun ) )
+ {
+ if( *pRun == '\\' )
+ {
+ // escapement
+ pRun++;
+ if( *pRun )
+ pRun++;
+ }
+ else if( *pRun == '`' )
+ {
+ do pRun++; while( *pRun && *pRun != '`' );
+ if( *pRun )
+ pRun++;
+ }
+ else if( *pRun == '\'' )
+ {
+ do pRun++; while( *pRun && *pRun != '\'' );
+ if( *pRun )
+ pRun++;
+ }
+ else if( *pRun == '"' )
+ {
+ do pRun++; while( *pRun && *pRun != '"' );
+ if( *pRun )
+ pRun++;
+ }
+ else
+ pRun++;
+ }
+ nTokenCount++;
+ }
+
+ return nTokenCount;
+}
+
+int GetCommandLineTokenCount( const ByteString& rLine )
+{
+ if( ! rLine.Len() )
+ return 0;
+
+ int nTokenCount = 0;
+ const char *pRun = rLine.GetBuffer();
+
+
+ while( *pRun )
+ {
+ while( *pRun && isSpace( *pRun ) )
+ pRun++;
+ if( ! *pRun )
+ break;
+ while( *pRun && ! isSpace( *pRun ) )
+ {
+ if( *pRun == '\\' )
+ {
+ // escapement
+ pRun++;
+ if( *pRun )
+ pRun++;
+ }
+ else if( *pRun == '`' )
+ {
+ do pRun++; while( *pRun && *pRun != '`' );
+ if( *pRun )
+ pRun++;
+ }
+ else if( *pRun == '\'' )
+ {
+ do pRun++; while( *pRun && *pRun != '\'' );
+ if( *pRun )
+ pRun++;
+ }
+ else if( *pRun == '"' )
+ {
+ do pRun++; while( *pRun && *pRun != '"' );
+ if( *pRun )
+ pRun++;
+ }
+ else
+ pRun++;
+ }
+ nTokenCount++;
+ }
+
+ return nTokenCount;
+}
+
+String WhitespaceToSpace( const String& rLine, BOOL bProtect )
+{
+ int nLen = rLine.Len();
+ if( ! nLen )
+ return String();
+
+ sal_Unicode *pBuffer = (sal_Unicode*)alloca( sizeof(sal_Unicode)*(nLen + 1) );
+ const sal_Unicode *pRun = rLine.GetBuffer();
+ sal_Unicode *pLeap = pBuffer;
+
+ while( *pRun )
+ {
+ if( *pRun && isSpace( *pRun ) )
+ {
+ *pLeap = ' ';
+ pLeap++;
+ pRun++;
+ }
+ while( *pRun && isSpace( *pRun ) )
+ pRun++;
+ while( *pRun && ! isSpace( *pRun ) )
+ {
+ if( *pRun == '\\' )
+ {
+ // escapement
+ pRun++;
+ *pLeap = *pRun;
+ pLeap++;
+ if( *pRun )
+ pRun++;
+ }
+ else if( bProtect && *pRun == '`' )
+ CopyUntil( pLeap, pRun, '`', TRUE );
+ else if( bProtect && *pRun == '\'' )
+ CopyUntil( pLeap, pRun, '\'', TRUE );
+ else if( bProtect && *pRun == '"' )
+ CopyUntil( pLeap, pRun, '"', TRUE );
+ else
+ {
+ *pLeap = *pRun;
+ *pLeap++;
+ *pRun++;
+ }
+ }
+ }
+
+ *pLeap = 0;
+
+ // there might be a space at beginning or end
+ pLeap--;
+ if( *pLeap == ' ' )
+ *pLeap = 0;
+
+ String aRet( *pBuffer == ' ' ? pBuffer+1 : pBuffer );
+ return aRet;
+}
+
+ByteString WhitespaceToSpace( const ByteString& rLine, BOOL bProtect )
+{
+ int nLen = rLine.Len();
+ if( ! nLen )
+ return ByteString();
+
+ char *pBuffer = (char*)alloca( nLen + 1 );
+ const char *pRun = rLine.GetBuffer();
+ char *pLeap = pBuffer;
+
+ while( *pRun )
+ {
+ if( *pRun && isSpace( *pRun ) )
+ {
+ *pLeap = ' ';
+ pLeap++;
+ pRun++;
+ }
+ while( *pRun && isSpace( *pRun ) )
+ pRun++;
+ while( *pRun && ! isSpace( *pRun ) )
+ {
+ if( *pRun == '\\' )
+ {
+ // escapement
+ pRun++;
+ *pLeap = *pRun;
+ pLeap++;
+ if( *pRun )
+ pRun++;
+ }
+ else if( bProtect && *pRun == '`' )
+ CopyUntil( pLeap, pRun, '`', TRUE );
+ else if( bProtect && *pRun == '\'' )
+ CopyUntil( pLeap, pRun, '\'', TRUE );
+ else if( bProtect && *pRun == '"' )
+ CopyUntil( pLeap, pRun, '"', TRUE );
+ else
+ {
+ *pLeap = *pRun;
+ *pLeap++;
+ *pRun++;
+ }
+ }
+ }
+
+ *pLeap = 0;
+
+ // there might be a space at beginning or end
+ pLeap--;
+ if( *pLeap == ' ' )
+ *pLeap = 0;
+
+ ByteString aRet( *pBuffer == ' ' ? pBuffer+1 : pBuffer );
+ return aRet;
+}
+
+} // namespace
diff --git a/vcl/source/helper/threadex.cxx b/vcl/source/helper/threadex.cxx
new file mode 100644
index 000000000000..133b19aa0538
--- /dev/null
+++ b/vcl/source/helper/threadex.cxx
@@ -0,0 +1,127 @@
+/*************************************************************************
+ *
+ * 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"
+
+#define THREADEX_IMPLEMENTATION
+#include <vcl/threadex.hxx>
+#include <vcl/svapp.hxx>
+
+using namespace vcl;
+
+ThreadExecutor::ThreadExecutor()
+{
+ m_aFinish = osl_createCondition();
+ m_aThread = NULL;
+}
+
+ThreadExecutor::~ThreadExecutor()
+{
+ osl_destroyCondition( m_aFinish );
+ if( m_aThread )
+ osl_destroyThread( m_aThread );
+}
+
+extern "C"
+{
+ static void call_worker( void* pInstance )
+ {
+ ThreadExecutor::worker( pInstance );
+ }
+}
+
+void ThreadExecutor::worker( void* pInstance )
+{
+ ThreadExecutor* pThis = ((ThreadExecutor*)pInstance);
+ pThis->m_nReturn = pThis->doIt();
+ osl_setCondition( pThis->m_aFinish );
+}
+
+long ThreadExecutor::execute()
+{
+ osl_resetCondition( m_aFinish );
+ if( m_aThread )
+ osl_destroyThread( m_aThread ), m_aThread = NULL;
+ m_aThread = osl_createThread( call_worker, this );
+ while( ! osl_checkCondition( m_aFinish ) )
+ Application::Reschedule();
+ return m_nReturn;
+}
+
+
+SolarThreadExecutor::SolarThreadExecutor()
+ :m_nReturn( 0 )
+ ,m_bTimeout( false )
+{
+ m_aStart = osl_createCondition();
+ m_aFinish = osl_createCondition();
+}
+
+SolarThreadExecutor::~SolarThreadExecutor()
+{
+ osl_destroyCondition( m_aStart );
+ osl_destroyCondition( m_aFinish );
+}
+
+IMPL_LINK( SolarThreadExecutor, worker, void*, EMPTYARG )
+{
+ if ( !m_bTimeout )
+ {
+ osl_setCondition( m_aStart );
+ m_nReturn = doIt();
+ osl_setCondition( m_aFinish );
+ }
+ return m_nReturn;
+}
+
+long SolarThreadExecutor::impl_execute( const TimeValue* _pTimeout )
+{
+ if( ::vos::OThread::getCurrentIdentifier() == Application::GetMainThreadIdentifier() )
+ {
+ osl_setCondition( m_aStart );
+ m_nReturn = doIt();
+ osl_setCondition( m_aFinish );
+ }
+ else
+ {
+ osl_resetCondition( m_aStart );
+ osl_resetCondition( m_aFinish );
+ ULONG nSolarMutexCount = Application::ReleaseSolarMutex();
+ ULONG nEvent = Application::PostUserEvent( LINK( this, SolarThreadExecutor, worker ) );
+ if ( osl_cond_result_timeout == osl_waitCondition( m_aStart, _pTimeout ) )
+ {
+ m_bTimeout = true;
+ Application::RemoveUserEvent( nEvent );
+ }
+ else
+ osl_waitCondition( m_aFinish, NULL );
+ if( nSolarMutexCount )
+ Application::AcquireSolarMutex( nSolarMutexCount );
+ }
+ return m_nReturn;
+}
diff --git a/vcl/source/helper/xconnection.cxx b/vcl/source/helper/xconnection.cxx
new file mode 100644
index 000000000000..caf7ee237d67
--- /dev/null
+++ b/vcl/source/helper/xconnection.cxx
@@ -0,0 +1,178 @@
+/*************************************************************************
+ *
+ * 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 "svsys.h"
+#include "vcl/xconnection.hxx"
+#include "vcl/svdata.hxx"
+#include "vcl/salinst.hxx"
+#include "vcl/svapp.hxx"
+
+namespace vcl
+{
+ class SolarMutexReleaser
+ {
+ ULONG mnReleased;
+ public:
+ SolarMutexReleaser()
+ {
+ mnReleased = Application::ReleaseSolarMutex();
+ }
+
+ ~SolarMutexReleaser()
+ {
+ if( mnReleased )
+ Application::AcquireSolarMutex( mnReleased );
+ }
+ };
+}
+
+using namespace rtl;
+using namespace osl;
+using namespace vcl;
+using namespace com::sun::star::uno;
+using namespace com::sun::star::awt;
+
+
+DisplayConnection::DisplayConnection()
+{
+ ImplSVData* pSVData = ImplGetSVData();
+ pSVData->mpDefInst->SetEventCallback( this, dispatchEvent );
+ pSVData->mpDefInst->SetErrorEventCallback( this, dispatchErrorEvent );
+
+ SalInstance::ConnectionIdentifierType eType;
+ int nBytes;
+ void* pBytes = pSVData->mpDefInst->GetConnectionIdentifier( eType, nBytes );
+ switch( eType )
+ {
+ case SalInstance::AsciiCString:
+ m_aAny <<= OUString::createFromAscii( (sal_Char*)pBytes );
+ break;
+ case SalInstance::Blob:
+ m_aAny <<= Sequence< sal_Int8 >( (sal_Int8*)pBytes, nBytes );
+ break;
+ }
+}
+
+DisplayConnection::~DisplayConnection()
+{
+ ImplSVData* pSVData = ImplGetSVData();
+
+ if( pSVData )
+ {
+ pSVData->mpDefInst->SetEventCallback( NULL, NULL );
+ pSVData->mpDefInst->SetErrorEventCallback( NULL, NULL );
+ }
+}
+
+
+void SAL_CALL DisplayConnection::addEventHandler( const Any& /*window*/, const Reference< XEventHandler >& handler, sal_Int32 /*eventMask*/ ) throw()
+{
+ MutexGuard aGuard( m_aMutex );
+
+ m_aHandlers.push_back( handler );
+}
+
+void SAL_CALL DisplayConnection::removeEventHandler( const Any& /*window*/, const Reference< XEventHandler >& handler ) throw()
+{
+ MutexGuard aGuard( m_aMutex );
+
+ m_aHandlers.remove( handler );
+}
+
+void SAL_CALL DisplayConnection::addErrorHandler( const Reference< XEventHandler >& handler ) throw()
+{
+ MutexGuard aGuard( m_aMutex );
+
+ m_aErrorHandlers.push_back( handler );
+}
+
+void SAL_CALL DisplayConnection::removeErrorHandler( const Reference< XEventHandler >& handler ) throw()
+{
+ MutexGuard aGuard( m_aMutex );
+
+ m_aErrorHandlers.remove( handler );
+}
+
+Any SAL_CALL DisplayConnection::getIdentifier() throw()
+{
+ return m_aAny;
+}
+
+void DisplayConnection::dispatchDowningEvent()
+{
+ SolarMutexReleaser aRel;
+
+ MutexGuard aGuard( m_aMutex );
+ Any aEvent;
+ std::list< Reference< XEventHandler > > aLocalList( m_aHandlers );
+ for( ::std::list< Reference< XEventHandler > >::const_iterator it = aLocalList.begin(); it != aLocalList.end(); ++it )
+ (*it)->handleEvent( aEvent );
+}
+
+bool DisplayConnection::dispatchEvent( void* pThis, void* pData, int nBytes )
+{
+ SolarMutexReleaser aRel;
+
+ DisplayConnection* This = (DisplayConnection*)pThis;
+
+ Sequence< sal_Int8 > aSeq( (sal_Int8*)pData, nBytes );
+ Any aEvent;
+ aEvent <<= aSeq;
+ ::std::list< Reference< XEventHandler > > handlers;
+ {
+ MutexGuard aGuard( This->m_aMutex );
+ handlers = This->m_aHandlers;
+ }
+ for( ::std::list< Reference< XEventHandler > >::const_iterator it = handlers.begin(); it != handlers.end(); ++it )
+ if( (*it)->handleEvent( aEvent ) )
+ return true;
+ return false;
+}
+
+bool DisplayConnection::dispatchErrorEvent( void* pThis, void* pData, int nBytes )
+{
+ SolarMutexReleaser aRel;
+
+ DisplayConnection* This = (DisplayConnection*)pThis;
+
+ Sequence< sal_Int8 > aSeq( (sal_Int8*)pData, nBytes );
+ Any aEvent;
+ aEvent <<= aSeq;
+ ::std::list< Reference< XEventHandler > > handlers;
+ {
+ MutexGuard aGuard( This->m_aMutex );
+ handlers = This->m_aErrorHandlers;
+ }
+ for( ::std::list< Reference< XEventHandler > >::const_iterator it = handlers.begin(); it != handlers.end(); ++it )
+ if( (*it)->handleEvent( aEvent ) )
+ return true;
+
+ return false;
+}