summaryrefslogtreecommitdiff
path: root/goodies/source/filter.vcl/icgm/bitmap.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'goodies/source/filter.vcl/icgm/bitmap.cxx')
-rw-r--r--goodies/source/filter.vcl/icgm/bitmap.cxx449
1 files changed, 449 insertions, 0 deletions
diff --git a/goodies/source/filter.vcl/icgm/bitmap.cxx b/goodies/source/filter.vcl/icgm/bitmap.cxx
new file mode 100644
index 000000000000..c89cdb8c4e3c
--- /dev/null
+++ b/goodies/source/filter.vcl/icgm/bitmap.cxx
@@ -0,0 +1,449 @@
+/*************************************************************************
+ *
+ * $RCSfile: bitmap.cxx,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 16:30:13 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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 for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#include "main.hxx"
+
+// ---------------------------------------------------------------
+
+CGMBitmap::CGMBitmap( CGM& rCGM ) :
+ mpCGM ( &rCGM ),
+ pCGMBitmapDescriptor ( new CGMBitmapDescriptor )
+{
+ ImplGetBitmap( *pCGMBitmapDescriptor );
+};
+
+// ---------------------------------------------------------------
+
+CGMBitmap::~CGMBitmap()
+{
+ delete pCGMBitmapDescriptor;
+}
+
+// ---------------------------------------------------------------
+
+void CGMBitmap::ImplGetBitmap( CGMBitmapDescriptor& rDesc )
+{
+ rDesc.mbStatus = sal_True;
+ long nx, ny, nxC, nxCount, nyCount;
+
+ if ( ImplGetDimensions( rDesc ) && rDesc.mpBuf )
+ {
+ if ( ( rDesc.mpBitmap = new Bitmap( Size( rDesc.mnX, rDesc.mnY ), (sal_uInt16)rDesc.mnDstBitsPerPixel ) ) != NULL )
+ {
+ if ( ( rDesc.mpAcc = rDesc.mpBitmap->AcquireWriteAccess() ) != NULL )
+ {
+
+ // the picture may either be read from left to right or right to left, from top to bottom ...
+
+ nxCount = rDesc.mnX + 1; // +1 because we are using prefix decreasing
+ nyCount = rDesc.mnY + 1;
+
+ switch ( rDesc.mnDstBitsPerPixel )
+ {
+ case 1 :
+ {
+ if ( rDesc.mnLocalColorPrecision == 1 )
+ ImplSetCurrentPalette( rDesc );
+ else
+ {
+ rDesc.mpAcc->SetPaletteEntryCount( 2 );
+ rDesc.mpAcc->SetPaletteColor( 0, BMCOL( mpCGM->pElement->nBackGroundColor ) );
+ rDesc.mpAcc->SetPaletteColor( 1,
+ ( mpCGM->pElement->nAspectSourceFlags & ASF_FILLINTERIORSTYLE )
+ ? BMCOL( mpCGM->pElement->pFillBundle->GetColor() )
+ : BMCOL( mpCGM->pElement->aFillBundle.GetColor() ) ) ;
+ }
+ for ( ny = 0; --nyCount ; ny++, rDesc.mpBuf += rDesc.mnScanSize )
+ {
+ nxC = nxCount;
+ for ( nx = 0; --nxC; nx++ )
+ { // this is not fast, but a one bit/pixel format is rarely used
+ rDesc.mpAcc->SetPixel( ny, nx, (sal_Int8)( (*( rDesc.mpBuf + ( nx >> 3 ) ) >> ( ( nx & 7 ) ^ 7 ) ) ) & 1 );
+ }
+ }
+ }
+ break;
+
+ case 2 :
+ {
+ ImplSetCurrentPalette( rDesc );
+ for ( ny = 0; --nyCount; ny++, rDesc.mpBuf += rDesc.mnScanSize )
+ {
+ nxC = nxCount;
+ for ( nx = 0; --nxC; nx++ )
+ { // this is not fast, but a two bits/pixel format is rarely used
+ rDesc.mpAcc->SetPixel( ny, nx, (sal_Int8)( (*( rDesc.mpBuf + ( nx >> 2 ) ) >> ( ( ( nx & 3 ) ^ 3 ) << 1 ) ) ) & 3 );
+ }
+ }
+ }
+ break;
+
+ case 4 :
+ {
+ ImplSetCurrentPalette( rDesc );
+ for ( ny = 0; --nyCount; ny++, rDesc.mpBuf += rDesc.mnScanSize )
+ {
+ nxC = nxCount;
+ sal_Int8 nDat;
+ sal_uInt8* pTemp = rDesc.mpBuf;
+ for ( nx = 0; --nxC; nx++ )
+ {
+ nDat = *pTemp++;
+ rDesc.mpAcc->SetPixel( ny, nx, (sal_Int8)( nDat >> 4 ) );
+ if ( --nxC )
+ {
+ nx ++;
+ rDesc.mpAcc->SetPixel( ny, nx, (sal_Int8)( nDat & 15 ) );
+ }
+ else
+ break;
+ }
+ }
+ }
+ break;
+
+ case 8 :
+ {
+ ImplSetCurrentPalette( rDesc );
+ for ( ny = 0; --nyCount; ny++, rDesc.mpBuf += rDesc.mnScanSize )
+ {
+ sal_uInt8* pTemp = rDesc.mpBuf;
+ nxC = nxCount;
+ for ( nx = 0; --nxC; nx++ )
+ {
+ rDesc.mpAcc->SetPixel( ny, nx, (sal_Int8)( *pTemp++ ) );
+ }
+ }
+ }
+ break;
+
+ case 24 :
+ {
+ {
+ BitmapColor aBitmapColor;
+ for ( ny = 0; --nyCount; ny++, rDesc.mpBuf += rDesc.mnScanSize )
+ {
+ sal_uInt8* pTemp = rDesc.mpBuf;
+ nxC = nxCount;
+ for ( nx = 0; --nxC; nx++ )
+ {
+ aBitmapColor.SetRed( (sal_Int8)*pTemp++ );
+ aBitmapColor.SetGreen( (sal_Int8)*pTemp++ );
+ aBitmapColor.SetBlue( (sal_Int8)*pTemp++ );
+ rDesc.mpAcc->SetPixel( ny, nx, aBitmapColor );
+ }
+ }
+ }
+ }
+ break;
+ };
+ double nX = rDesc.mnR.X - rDesc.mnQ.X;
+ double nY = rDesc.mnR.Y - rDesc.mnQ.Y;
+
+ rDesc.mndy = sqrt( nX * nX + nY * nY );
+
+ nX = rDesc.mnR.X - rDesc.mnP.X;
+ nY = rDesc.mnR.Y - rDesc.mnP.Y;
+
+ rDesc.mndx = sqrt( nX * nX + nY * nY );
+
+ nX = rDesc.mnR.X - rDesc.mnP.X;
+ nY = rDesc.mnR.Y - rDesc.mnP.Y;
+
+ rDesc.mnOrientation = acos( nX / sqrt( nX * nX + nY * nY ) ) * 57.29577951308;
+ if ( nY > 0 )
+ rDesc.mnOrientation = 360 - rDesc.mnOrientation;
+
+ nX = rDesc.mnQ.X - rDesc.mnR.X;
+ nY = rDesc.mnQ.Y - rDesc.mnR.Y;
+
+ double fAngle = 0.01745329251994 * ( 360 - rDesc.mnOrientation );
+ double fSin = sin(fAngle);
+ double fCos = cos(fAngle);
+ nX = fCos * nX + fSin * nY;
+ nY = -( fSin * nX - fCos * nY );
+
+ fAngle = acos( nX / sqrt( nX * nX + nY * nY ) ) * 57.29577951308;
+ if ( nY > 0 )
+ fAngle = 360 - fAngle;
+
+ if ( fAngle > 180 ) // wird das bild nach oben oder unten aufgebaut ?
+ {
+ rDesc.mnOrigin = rDesc.mnP;
+ }
+ else
+ {
+ rDesc.mbVMirror = sal_True;
+ rDesc.mnOrigin = rDesc.mnP;
+ rDesc.mnOrigin.X += rDesc.mnQ.X - rDesc.mnR.X;
+ rDesc.mnOrigin.Y += rDesc.mnQ.Y - rDesc.mnR.Y;
+ }
+ }
+ else
+ rDesc.mbStatus = sal_False;
+ }
+ else
+ rDesc.mbStatus = sal_False;
+ }
+ else
+ rDesc.mbStatus = sal_False;
+
+ if ( rDesc.mpAcc )
+ {
+ rDesc.mpBitmap->ReleaseAccess( rDesc.mpAcc );
+ rDesc.mpAcc = NULL;
+ }
+ if ( rDesc.mbStatus == sal_False )
+ {
+ if ( rDesc.mpBitmap )
+ {
+ delete rDesc.mpBitmap;
+ rDesc.mpBitmap = NULL;
+ }
+ }
+}
+
+// ---------------------------------------------------------------
+
+void CGMBitmap::ImplSetCurrentPalette( CGMBitmapDescriptor& rDesc )
+{
+ sal_uInt16 nColors = 1 << rDesc.mnDstBitsPerPixel;
+ rDesc.mpAcc->SetPaletteEntryCount( nColors );
+ for ( sal_uInt16 i = 0; i < nColors; i++ )
+ {
+ rDesc.mpAcc->SetPaletteColor( i, BMCOL( mpCGM->pElement->aLatestColorTable[ i ] ) );
+ }
+}
+
+// ---------------------------------------------------------------
+
+sal_Bool CGMBitmap::ImplGetDimensions( CGMBitmapDescriptor& rDesc )
+{
+ mpCGM->ImplGetPoint( rDesc.mnP ); // parallelogram p < - > r
+ mpCGM->ImplGetPoint( rDesc.mnQ ); // |
+ mpCGM->ImplGetPoint( rDesc.mnR ); // q
+ sal_uInt32 nPrecision = mpCGM->pElement->nIntegerPrecision;
+ rDesc.mnX = mpCGM->ImplGetUI( nPrecision );
+ rDesc.mnY = mpCGM->ImplGetUI( nPrecision );
+ rDesc.mnLocalColorPrecision = mpCGM->ImplGetI( nPrecision );
+ rDesc.mnScanSize = 0;
+ switch( rDesc.mnLocalColorPrecision )
+ {
+ case 0x80000001 : // monochrome ( bit = 0->backgroundcolor )
+ case 0 : // bit = 1->fillcolor
+ rDesc.mnDstBitsPerPixel = 1;
+ break;
+ case 1 : // 2 color indexed ( monochrome )
+ case -1 :
+ rDesc.mnDstBitsPerPixel = 1;
+ break;
+ case 2 : // 4 color indexed
+ case -2 :
+ rDesc.mnDstBitsPerPixel = 2;
+ break;
+ case 4 : // 16 color indexed
+ case -4 :
+ rDesc.mnDstBitsPerPixel = 4;
+ break;
+ case 8 : // 256 color indexed
+ case -8 :
+ rDesc.mnDstBitsPerPixel = 8;
+ rDesc.mnScanSize = rDesc.mnX;
+ break;
+ case 16 : // NS
+ case -16 :
+ rDesc.mbStatus = sal_False;
+ break;
+ case 24 : // 24 bit directColor ( 8 bits each component )
+ case -24 :
+ rDesc.mnDstBitsPerPixel = 24;
+ break;
+ case 32 : // NS
+ case -32 :
+ rDesc.mbStatus = sal_False;
+ break;
+
+ }
+ // mnCompressionMode == 0 : CCOMP_RUNLENGTH
+ // == 1 : CCOMP_PACKED ( no compression. each row starts on a 4 byte boundary )
+ if ( ( rDesc.mnCompressionMode = mpCGM->ImplGetUI16() ) != 1 )
+ rDesc.mbStatus = sal_False;
+
+ if ( ( rDesc.mnX || rDesc.mnY ) == 0 )
+ rDesc.mbStatus = sal_False;
+
+ sal_uInt32 nHeaderSize = 2 + 3 * nPrecision + 3 * mpCGM->ImplGetPointSize();
+ rDesc.mnScanSize = ( ( rDesc.mnX * rDesc.mnDstBitsPerPixel + 7 ) >> 3 );
+
+ if ( ( mpCGM->mnMode & CGM_IMPORT_IM ) && ( rDesc.mnLocalColorPrecision & 0x8000 ) )
+ { // if (sal_uInt16)precision is negative the color cell
+ rDesc.mnScanSize = ( rDesc.mnScanSize + 3 ) &~3; // array doesn't include data - instead it is just
+ rDesc.mpBuf = (sal_uInt8*)mpCGM->ImplGetUI( 4 ); // a 4 Byte pointer to the data
+ mpCGM->mnElementSize = mpCGM->mnParaSize;
+ }
+ else
+ {
+ sal_uInt32 nScanSize;
+ nScanSize = rDesc.mnScanSize;
+ if ( ( nScanSize * rDesc.mnY + nHeaderSize ) != mpCGM->mnElementSize ) // try a scansize without dw alignment
+ {
+ nScanSize = ( rDesc.mnScanSize + 1 ) & ~1;
+ if ( ( nScanSize * rDesc.mnY + nHeaderSize ) != mpCGM->mnElementSize ) // then we'll try word alignment
+ {
+ nScanSize = ( rDesc.mnScanSize + 3 ) & ~3;
+ if ( ( nScanSize * rDesc.mnY + nHeaderSize ) != mpCGM->mnElementSize ) // and last we'll try dword alignment
+ {
+ nScanSize = ( rDesc.mnScanSize + 1 ) & ~1; // and LAST BUT NOT LEAST we'll try word alignment without aligning the last line
+ if ( ( nScanSize * ( rDesc.mnY - 1 ) + rDesc.mnScanSize + nHeaderSize ) != mpCGM->mnElementSize )
+ {
+ nScanSize = ( rDesc.mnScanSize + 3 ) & ~3;
+ if ( ( nScanSize * ( rDesc.mnY - 1 ) + rDesc.mnScanSize + nHeaderSize ) != mpCGM->mnElementSize )
+ {
+ mpCGM->mnParaSize = 0; // this format is corrupt
+ rDesc.mbStatus = sal_False;
+ }
+ }
+ }
+ }
+ }
+ rDesc.mnScanSize = nScanSize;
+ if ( rDesc.mbStatus )
+ {
+ rDesc.mpBuf = mpCGM->mpSource + mpCGM->mnParaSize; // mpBuf now points to the first scanline
+ mpCGM->mnParaSize += rDesc.mnScanSize * rDesc.mnY;
+ }
+ }
+ return rDesc.mbStatus;
+}
+
+// ---------------------------------------------------------------
+
+void CGMBitmap::ImplInsert( CGMBitmapDescriptor& rSource, CGMBitmapDescriptor& rDest )
+{
+ if ( ( rSource.mnR.Y == rDest.mnQ.Y ) && ( rSource.mnR.X == rDest.mnQ.X ) )
+ { // Insert on Bottom
+ if ( mpCGM->mnVDCYmul == -1 )
+ rDest.mnOrigin = rSource.mnOrigin; // neuer origin
+ rDest.mpBitmap->Expand( 0, rSource.mnY );
+ rDest.mpBitmap->CopyPixel( Rectangle( Point( 0, rDest.mnY ), Size( rSource.mnX, rSource.mnY ) ),
+ Rectangle( Point( 0, 0 ), Size( rSource.mnX, rSource.mnY ) ), rSource.mpBitmap );
+ FloatPoint aFloatPoint;
+ aFloatPoint.X = rSource.mnQ.X - rSource.mnR.X;
+ aFloatPoint.Y = rSource.mnQ.Y - rSource.mnR.Y;
+ rDest.mnQ.X += aFloatPoint.X;
+ rDest.mnQ.Y += aFloatPoint.Y;
+ rDest.mnP = rSource.mnP;
+ rDest.mnR = rSource.mnR;
+ }
+ else
+ { // Insert on Top
+ if ( mpCGM->mnVDCYmul == 1 )
+ rDest.mnOrigin = rSource.mnOrigin; // neuer origin
+ rDest.mpBitmap->Expand( 0, rSource.mnY );
+ rDest.mpBitmap->CopyPixel( Rectangle( Point( 0, rDest.mnY ), Size( rSource.mnX, rSource.mnY ) ),
+ Rectangle( Point( 0, 0 ), Size( rSource.mnX, rSource.mnY ) ), rSource.mpBitmap );
+ rDest.mnP = rSource.mnP;
+ rDest.mnR = rSource.mnR;
+ }
+ rDest.mnY += rSource.mnY;
+ rDest.mndy += rSource.mndy;
+};
+
+// ---------------------------------------------------------------
+
+CGMBitmap* CGMBitmap::GetNext()
+{
+ if ( pCGMBitmapDescriptor->mpBitmap && pCGMBitmapDescriptor->mbStatus )
+ {
+ CGMBitmap* pCGMTempBitmap = new CGMBitmap( *mpCGM );
+ if ( pCGMTempBitmap )
+ {
+ if ( ( (long)pCGMTempBitmap->pCGMBitmapDescriptor->mnOrientation == (long)pCGMBitmapDescriptor->mnOrientation ) &&
+ ( ( ( pCGMTempBitmap->pCGMBitmapDescriptor->mnR.X == pCGMBitmapDescriptor->mnQ.X ) &&
+ ( pCGMTempBitmap->pCGMBitmapDescriptor->mnR.Y == pCGMBitmapDescriptor->mnQ.Y ) ) ||
+ ( ( pCGMTempBitmap->pCGMBitmapDescriptor->mnQ.X == pCGMBitmapDescriptor->mnR.X ) &&
+ ( pCGMTempBitmap->pCGMBitmapDescriptor->mnQ.Y == pCGMBitmapDescriptor->mnR.Y ) ) ) )
+ {
+ ImplInsert( *(pCGMTempBitmap->pCGMBitmapDescriptor), *(pCGMBitmapDescriptor) );
+ delete pCGMTempBitmap;
+ return NULL;
+ }
+ else // we'll replace the pointers and return the old one
+ {
+ CGMBitmapDescriptor* pTempBD = pCGMBitmapDescriptor;
+ pCGMBitmapDescriptor = pCGMTempBitmap->pCGMBitmapDescriptor;
+ pCGMTempBitmap->pCGMBitmapDescriptor = pTempBD;
+ return pCGMTempBitmap;
+ }
+ }
+ return NULL;
+ }
+ else
+ return NULL;
+}
+
+// ---------------------------------------------------------------
+
+CGMBitmapDescriptor* CGMBitmap::GetBitmap()
+{
+ return pCGMBitmapDescriptor;
+}
+