diff options
author | Radek Doulik <rodo@novell.com> | 2010-09-15 11:12:11 +0200 |
---|---|---|
committer | Radek Doulik <rodo@novell.com> | 2010-09-15 17:54:14 +0200 |
commit | 33bf550d54f0a9f98edd2e7aec1ece5ba11a1def (patch) | |
tree | e507bbdbe0df41a263d6d4426f4c06113cb82402 /svtools | |
parent | ac58ef65487c17d91e1dd6d10adc9666c434e88b (diff) |
emf+-svtools.diff: emf+ import - parse emf+, pass it along in comments
Diffstat (limited to 'svtools')
-rw-r--r-- | svtools/source/filter.vcl/wmf/enhwmf.cxx | 141 | ||||
-rw-r--r-- | svtools/source/filter.vcl/wmf/winmtf.cxx | 36 | ||||
-rw-r--r-- | svtools/source/filter.vcl/wmf/winmtf.hxx | 9 |
3 files changed, 185 insertions, 1 deletions
diff --git a/svtools/source/filter.vcl/wmf/enhwmf.cxx b/svtools/source/filter.vcl/wmf/enhwmf.cxx index 1e49e0d61446..a11c739022e5 100644 --- a/svtools/source/filter.vcl/wmf/enhwmf.cxx +++ b/svtools/source/filter.vcl/wmf/enhwmf.cxx @@ -158,6 +158,8 @@ #define EMR_SETLINKEDUFIS 119 #define EMR_SETTEXTJUSTIFICATION 120 +#define EMFP_DEBUG(x) +//#define EMFP_DEBUG(x) x //----------------------------------------------------------------------------------- @@ -229,6 +231,110 @@ 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(); + 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 count = 0, next, pos = pWMF->Tell(); + pOut->PassEMFPlus( buffer, pWMF->Read( buffer, length ) ); + pWMF->Seek( pos ); + + bHaveDC = false; + + length -= 4; + + while (length > 0) { + UINT16 type, flags; + 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: { + sal_uInt32 x, y, w, h; + + EMFP_DEBUG(printf ("\t\tENDGROUP\n")); + break; + } + case 0x40000004: { + sal_uInt32 x, y, w, h; + + EMFP_DEBUG(printf ("\t\tMULTIFORMATS\n")); + break; + } + default: + EMFP_DEBUG(printf ("\t\tunknown GDIComment\n")); + EMFP_DEBUG(dumpWords (*pWMF, 16)); + } +} + BOOL EnhWMFReader::ReadEnhWMF() { sal_uInt32 nStretchBltMode = 0; @@ -239,6 +345,14 @@ 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_True; +#endif while( bStatus && nRecordCount-- ) { @@ -263,6 +377,33 @@ 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 ) { + 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 : diff --git a/svtools/source/filter.vcl/wmf/winmtf.cxx b/svtools/source/filter.vcl/wmf/winmtf.cxx index 787e6522b890..4579c5bda9f6 100644 --- a/svtools/source/filter.vcl/wmf/winmtf.cxx +++ b/svtools/source/filter.vcl/wmf/winmtf.cxx @@ -38,6 +38,9 @@ #define WIN_MTF_MAX_CLIP_DEPTH 16 +#define EMFP_DEBUG(x) +//#define EMFP_DEBUG(x) x + void WinMtfClipPath::ImpUpdateType() { if ( !aPolyPoly.Count() ) @@ -2201,3 +2204,36 @@ void WinMtfOutput::AddFromGDIMetaFile( GDIMetaFile& rGDIMetaFile ) rGDIMetaFile.Play( *mpGDIMetaFile, 0xFFFFFFFF ); } +void WinMtfOutput::PassEMFPlusHeaderInfo() +{ + EMFP_DEBUG(printf ("\t\t\tadd EMF_PLUS header info\n")); + + SvMemoryStream mem; + sal_Int32 nLeft, nRight, nTop, nBottom; + + nLeft = mrclFrame.Left(); + nTop = mrclFrame.Top(); + nRight = mrclFrame.Right(); + nBottom = mrclFrame.Bottom(); + + // emf header info + mem << nLeft << nTop << nRight << nBottom; + mem << mnPixX << mnPixY << mnMillX << mnMillY; + + float one, zero; + + one = 1; + zero = 0; + + // add transformation matrix to be used in vcl's metaact.cxx for + // rotate and scale operations + mem << one << zero << zero << one << zero << zero; + + mpGDIMetaFile->AddAction( new MetaCommentAction( "EMF_PLUS_HEADER_INFO", 0, (const BYTE*) mem.GetData(), mem.GetEndOfData() ) ); +} + +void WinMtfOutput::PassEMFPlus( void* pBuffer, UINT32 nLength ) +{ + EMFP_DEBUG(printf ("\t\t\tadd EMF_PLUS comment length %d\n", nLength)); + mpGDIMetaFile->AddAction( new MetaCommentAction( "EMF_PLUS", 0, static_cast<const BYTE*>(pBuffer), nLength ) ); +} diff --git a/svtools/source/filter.vcl/wmf/winmtf.hxx b/svtools/source/filter.vcl/wmf/winmtf.hxx index fb4fd2fe0c57..aa630d6ebfa4 100644 --- a/svtools/source/filter.vcl/wmf/winmtf.hxx +++ b/svtools/source/filter.vcl/wmf/winmtf.hxx @@ -672,6 +672,9 @@ class WinMtfOutput void UpdateClipRegion(); void AddFromGDIMetaFile( GDIMetaFile& rGDIMetaFile ); + void PassEMFPlus( void* pBuffer, UINT32 nLength ); + void PassEMFPlusHeaderInfo(); + WinMtfOutput( GDIMetaFile& rGDIMetaFile ); virtual ~WinMtfOutput(); }; @@ -710,6 +713,8 @@ class EnhWMFReader : public WinMtf { sal_Bool bRecordPath; sal_Int32 nRecordCount; + BOOL bEMFPlus; + BOOL ReadHeader(); Rectangle ReadRectangle( INT32, INT32, INT32, INT32 ); // Liesst und konvertiert ein Rechteck @@ -717,10 +722,12 @@ class EnhWMFReader : public WinMtf public: EnhWMFReader( SvStream& rStreamWMF, GDIMetaFile& rGDIMetaFile, FilterConfigItem* pConfigItem = NULL ) - : WinMtf( new WinMtfOutput( rGDIMetaFile ), rStreamWMF, pConfigItem ), bRecordPath( sal_False ) {}; + : WinMtf( new WinMtfOutput( rGDIMetaFile ), rStreamWMF, pConfigItem ), bRecordPath( sal_False ), bEMFPlus (FALSE) {}; ~EnhWMFReader(); BOOL ReadEnhWMF(); + void ReadEMFPlusComment(sal_uInt32 length, sal_Bool& bHaveDC); + void ReadGDIComment(); }; //============================ WMFReader ================================== |