summaryrefslogtreecommitdiff
path: root/svtools/source/filter/wmf/enhwmf.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'svtools/source/filter/wmf/enhwmf.cxx')
-rw-r--r--svtools/source/filter/wmf/enhwmf.cxx199
1 files changed, 195 insertions, 4 deletions
diff --git a/svtools/source/filter/wmf/enhwmf.cxx b/svtools/source/filter/wmf/enhwmf.cxx
index ec7fec9fdb1e..23990473aa60 100644
--- a/svtools/source/filter/wmf/enhwmf.cxx
+++ b/svtools/source/filter/wmf/enhwmf.cxx
@@ -1,3 +1,4 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*************************************************************************
*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
@@ -158,6 +159,8 @@
#define EMR_SETLINKEDUFIS 119
#define EMR_SETTEXTJUSTIFICATION 120
+#define EMFP_DEBUG(x)
+//#define EMFP_DEBUG(x) x
//-----------------------------------------------------------------------------------
@@ -176,7 +179,7 @@ SvStream& operator>>( SvStream& rIn, XForm& rXForm )
{
if ( sizeof( float ) != 4 )
{
- DBG_ERROR( "EnhWMFReader::sizeof( float ) != 4" );
+ OSL_FAIL( "EnhWMFReader::sizeof( float ) != 4" );
rXForm = XForm();
}
else
@@ -229,6 +232,106 @@ static sal_Bool ImplReadRegion( PolyPolygon& rPolyPoly, SvStream& rSt, sal_uInt3
return bOk;
}
+EMFP_DEBUG(void dumpWords( SvStream& s, int i )
+{
+ sal_uInt32 pos = s.Tell();
+ sal_Int16 data;
+ for( ; i > 0; i -- ) {
+ s >> data;
+ EMFP_DEBUG(printf ("\t\t\tdata: %04hx\n", data));
+ }
+ s.Seek (pos);
+});
+
+void EnhWMFReader::ReadEMFPlusComment(sal_uInt32 length, sal_Bool& bHaveDC)
+{
+ if (!bEMFPlus) {
+ pOut->PassEMFPlusHeaderInfo();
+
+ // debug code - write the stream to debug file /tmp/emf-stream.emf
+ EMFP_DEBUG(int pos = pWMF->Tell();
+ pWMF->Seek(0);
+ SvFileStream file( UniString::CreateFromAscii( "/tmp/emf-stream.emf" ), STREAM_WRITE | STREAM_TRUNC );
+
+ *pWMF >> file;
+ file.Flush();
+ file.Close();
+
+ pWMF->Seek( pos );)
+ }
+ bEMFPlus = true;
+
+ void *buffer = malloc( length );
+
+ int pos = pWMF->Tell();
+ pOut->PassEMFPlus( buffer, pWMF->Read( buffer, length ) );
+ pWMF->Seek( pos );
+
+ bHaveDC = false;
+
+ length -= 4;
+
+ while (length > 0) {
+ sal_uInt16 type, flags;
+ sal_uInt32 size, dataSize;
+ sal_uInt32 next;
+
+ *pWMF >> type >> flags >> size >> dataSize;
+
+ EMFP_DEBUG(printf ("\t\tEMF+ record type: %d\n", type));
+
+ // GetDC
+ if( type == 16388 ) {
+ bHaveDC = true;
+ EMFP_DEBUG(printf ("\t\tEMF+ lock DC (device context)\n", type));
+ }
+
+ next = pWMF->Tell() + ( size - 12 );
+
+ length -= size;
+
+ pWMF->Seek( next );
+ }
+
+ free( buffer );
+}
+
+void EnhWMFReader::ReadGDIComment()
+{
+ sal_uInt32 type;
+
+ *pWMF >> type;
+
+ switch( type ) {
+ case 2: {
+ sal_Int32 x, y, r, b;
+
+ EMFP_DEBUG(printf ("\t\tBEGINGROUP\n"));
+
+ *pWMF >> x >> y >> r >> b;
+ EMFP_DEBUG(printf ("\t\tbounding rectangle: %d,%d x %d,%d\n", x, y, r, b));
+
+ sal_uInt32 l;
+
+ *pWMF >> l;
+ EMFP_DEBUG(printf ("\t\tdescription length: %d\n", l));
+
+ break;
+ }
+ case 3: {
+ EMFP_DEBUG(printf ("\t\tENDGROUP\n"));
+ break;
+ }
+ case 0x40000004: {
+ EMFP_DEBUG(printf ("\t\tMULTIFORMATS\n"));
+ break;
+ }
+ default:
+ EMFP_DEBUG(printf ("\t\tunknown GDIComment\n"));
+ EMFP_DEBUG(dumpWords (*pWMF, 16));
+ }
+}
+
sal_Bool EnhWMFReader::ReadEnhWMF()
{
sal_uInt32 nStretchBltMode = 0;
@@ -239,6 +342,14 @@ sal_Bool EnhWMFReader::ReadEnhWMF()
sal_Int16 nX16, nY16;
sal_Bool bFlag, bStatus = ReadHeader();
+ sal_Bool bHaveDC = false;
+
+#ifdef UNX
+ static sal_Bool bEnableEMFPlus = ( getenv( "EMF_PLUS_DISABLE" ) == NULL );
+#else
+ // TODO: make it possible to disable emf+ on windows
+ static sal_Bool bEnableEMFPlus = sal_False;
+#endif
while( bStatus && nRecordCount-- )
{
@@ -263,6 +374,34 @@ sal_Bool EnhWMFReader::ReadEnhWMF()
bFlag = sal_False;
+ EMFP_DEBUG(printf ("0x%04x-0x%04x record type: %d size: %d\n", nNextPos - nRecSize, nNextPos, nRecType, nRecSize));
+
+ if( bEnableEMFPlus && nRecType == EMR_GDICOMMENT ) {
+ sal_uInt32 length;
+
+ *pWMF >> length;
+
+ EMFP_DEBUG(printf ("\tGDI comment\n\t\tlength: %d\n", length));
+
+ if( length >= 4 ) {
+ sal_uInt32 id;
+
+ *pWMF >> id;
+
+ EMFP_DEBUG(printf ("\t\tbegin %c%c%c%c id: 0x%x\n", (char)(id & 0xff), (char)((id & 0xff00) >> 8), (char)((id & 0xff0000) >> 16), (char)((id & 0xff000000) >> 24), id));
+
+ // EMF+ comment (fixme: BE?)
+ if( id == 0x2B464D45 && nRecSize >= 12 )
+ ReadEMFPlusComment( length, bHaveDC );
+ // GDIC comment, doesn't do anything useful yet => enabled only for debug
+ else if( id == 0x43494447 && nRecSize >= 12 ) {
+ EMFP_DEBUG(ReadGDIComment());
+ } else {
+ EMFP_DEBUG(printf ("\t\tunknown id: 0x%x\n", id));
+ }
+ }
+ } else if( !bEMFPlus || bHaveDC || nRecType == EMR_EOF )
+
switch( nRecType )
{
case EMR_POLYBEZIERTO :
@@ -867,7 +1006,10 @@ sal_Bool EnhWMFReader::ReadEnhWMF()
Rectangle aCropRect( Point( xSrc, ySrc ), Size( cxSrc, cySrc ) );
aBitmap.Crop( aCropRect );
}
- aBmpSaveList.Insert( new BSaveStruct( aBitmap, aRect, dwRop ), LIST_APPEND );
+ /* Pseudocomment to add more context so that make patch.unapply
+ * works better. Ha!
+ */
+ aBmpSaveList.Insert( new BSaveStruct( aBitmap, aRect, dwRop, pOut->GetFillStyle () ), LIST_APPEND );
}
}
}
@@ -921,7 +1063,8 @@ sal_Bool EnhWMFReader::ReadEnhWMF()
Rectangle aCropRect( Point( xSrc, ySrc ), Size( cxSrc, cySrc ) );
aBitmap.Crop( aCropRect );
}
- aBmpSaveList.Insert( new BSaveStruct( aBitmap, aRect, dwRop ), LIST_APPEND );
+ /* Another pseudocomment to make make patch.unapply work better */
+ aBmpSaveList.Insert( new BSaveStruct( aBitmap, aRect, dwRop, pOut->GetFillStyle () ), LIST_APPEND );
}
}
}
@@ -1192,6 +1335,53 @@ sal_Bool EnhWMFReader::ReadEnhWMF()
}
break;
+ case EMR_CREATEDIBPATTERNBRUSHPT :
+ {
+ sal_uInt32 nStart = pWMF->Tell() - 8;
+ Bitmap aBitmap;
+
+ *pWMF >> nIndex;
+
+ if ( ( nIndex & ENHMETA_STOCK_OBJECT ) == 0 )
+ {
+ sal_uInt32 usage, offBmi, cbBmi, offBits, cbBits;
+
+ *pWMF >> usage;
+ *pWMF >> offBmi;
+ *pWMF >> cbBmi;
+ *pWMF >> offBits;
+ *pWMF >> cbBits;
+
+ if ( (cbBits > (SAL_MAX_UINT32 - 14)) || ((SAL_MAX_UINT32 - 14) - cbBits < cbBmi) )
+ bStatus = sal_False;
+ else if ( offBmi )
+ {
+ sal_uInt32 nSize = cbBmi + cbBits + 14;
+ if ( nSize <= ( nEndPos - nStartPos ) )
+ {
+ char* pBuf = new char[ nSize ];
+
+ SvMemoryStream aTmp( pBuf, nSize, STREAM_READ | STREAM_WRITE );
+ aTmp.ObjectOwnsMemory( sal_True );
+ aTmp << (sal_uInt8)'B'
+ << (sal_uInt8)'M'
+ << (sal_uInt32)cbBits
+ << (sal_uInt16)0
+ << (sal_uInt16)0
+ << (sal_uInt32)cbBmi + 14;
+ pWMF->Seek( nStart + offBmi );
+ pWMF->Read( pBuf + 14, cbBmi );
+ pWMF->Seek( nStart + offBits );
+ pWMF->Read( pBuf + 14 + cbBmi, cbBits );
+ aTmp.Seek( 0 );
+ aBitmap.Read( aTmp, sal_True );
+ }
+ }
+ }
+
+ pOut->CreateObject( nIndex, GDI_BRUSH, new WinMtfFillStyle( aBitmap ) );
+ }
+ break;
#ifdef WIN_MTF_ASSERT
default : WinMtfAssertHandler( "Unknown Meta Action" ); break;
@@ -1211,7 +1401,6 @@ sal_Bool EnhWMFReader::ReadEnhWMF()
case EMR_ANGLEARC : WinMtfAssertHandler( "AngleArc" ); break;
case EMR_SETCOLORADJUSTMENT : WinMtfAssertHandler( "SetColorAdjustment" ); break;
case EMR_POLYDRAW16 : WinMtfAssertHandler( "PolyDraw16" ); break;
- case EMR_CREATEDIBPATTERNBRUSHPT : WinMtfAssertHandler( "CreateDibPatternBrushPt" ); break;
case EMR_POLYTEXTOUTA : WinMtfAssertHandler( "PolyTextOutA" ); break;
case EMR_POLYTEXTOUTW : WinMtfAssertHandler( "PolyTextOutW" ); break;
case EMR_CREATECOLORSPACE : WinMtfAssertHandler( "CreateColorSpace" ); break;
@@ -1340,3 +1529,5 @@ EnhWMFReader::~EnhWMFReader()
{
};
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */