summaryrefslogtreecommitdiff
path: root/svtools
diff options
context:
space:
mode:
authorsb <sb@openoffice.org>2010-02-08 09:18:14 +0100
committersb <sb@openoffice.org>2010-02-08 09:18:14 +0100
commit9ec2223b100751fd4a3f64eb8a4a8686305ab074 (patch)
tree06fb3197763688a27b16726ad6d10ec601cb1ce1 /svtools
parent4e0a003d8289b16c012fc936cc9f1fa2130b2bd9 (diff)
parentda2c680d23b67d4721aa29f740475fd6d40e2e08 (diff)
sb118: merged in DEV300_m71
Diffstat (limited to 'svtools')
-rw-r--r--svtools/source/control/ctrlbox.cxx1
-rw-r--r--svtools/source/filter.vcl/jpeg/jpeg.cxx39
-rw-r--r--svtools/source/filter.vcl/jpeg/jpeg.h2
-rw-r--r--svtools/source/filter.vcl/jpeg/jpegc.c14
-rw-r--r--svtools/source/filter.vcl/wmf/emfwr.cxx103
-rw-r--r--svtools/source/filter.vcl/wmf/emfwr.hxx1
-rw-r--r--svtools/source/filter.vcl/wmf/winmtf.cxx9
-rw-r--r--svtools/source/filter.vcl/wmf/winmtf.hxx15
-rw-r--r--svtools/source/filter.vcl/wmf/winwmf.cxx216
-rw-r--r--svtools/source/filter.vcl/wmf/wmfwr.cxx81
-rw-r--r--svtools/source/filter.vcl/wmf/wmfwr.hxx9
-rw-r--r--svtools/source/misc/ehdl.cxx26
12 files changed, 398 insertions, 118 deletions
diff --git a/svtools/source/control/ctrlbox.cxx b/svtools/source/control/ctrlbox.cxx
index b0d20bf7ce30..1a6465bd5c5d 100644
--- a/svtools/source/control/ctrlbox.cxx
+++ b/svtools/source/control/ctrlbox.cxx
@@ -1152,6 +1152,7 @@ void FontSizeBox::ImplInit()
SetDecimalDigits( 1 );
SetMin( 20 );
SetMax( 9999 );
+ SetProminentEntryType( PROMINENT_MIDDLE );
}
// -----------------------------------------------------------------------
diff --git a/svtools/source/filter.vcl/jpeg/jpeg.cxx b/svtools/source/filter.vcl/jpeg/jpeg.cxx
index 81d07ccd5e79..ee2b2baebee0 100644
--- a/svtools/source/filter.vcl/jpeg/jpeg.cxx
+++ b/svtools/source/filter.vcl/jpeg/jpeg.cxx
@@ -656,10 +656,14 @@ void* JPEGWriter::GetScanline( long nY )
aColor = pAcc->GetPaletteColor( (BYTE) pAcc->GetPixel( nY, nX ) );
#ifndef SYSTEM_JPEG
*pTmp++ = aColor.GetBlue();
+ if ( bGreys )
+ continue;
*pTmp++ = aColor.GetGreen();
*pTmp++ = aColor.GetRed();
#else
*pTmp++ = aColor.GetRed();
+ if ( bGreys )
+ continue;
*pTmp++ = aColor.GetGreen();
*pTmp++ = aColor.GetBlue();
#endif
@@ -672,10 +676,14 @@ void* JPEGWriter::GetScanline( long nY )
aColor = pAcc->GetPixel( nY, nX );
#ifndef SYSTEM_JPEG
*pTmp++ = aColor.GetBlue();
+ if ( bGreys )
+ continue;
*pTmp++ = aColor.GetGreen();
*pTmp++ = aColor.GetRed();
#else
*pTmp++ = aColor.GetRed();
+ if ( bGreys )
+ continue;
*pTmp++ = aColor.GetGreen();
*pTmp++ = aColor.GetBlue();
#endif
@@ -711,20 +719,43 @@ BOOL JPEGWriter::Write( const Graphic& rGraphic )
pAcc = aGraphicBmp.AcquireReadAccess();
+ if ( !bGreys ) // bitmap was not explicitely converted into greyscale,
+ { // check if source is greyscale only
+
+ sal_Bool bIsGrey = sal_True;
+
+ long nWidth = pAcc->Width();
+ for ( long nY = 0; bIsGrey && ( nY < pAcc->Height() ); nY++ )
+ {
+ BitmapColor aColor;
+ for( long nX = 0L; bIsGrey && ( nX < nWidth ); nX++ )
+ {
+ aColor = pAcc->HasPalette() ? pAcc->GetPaletteColor( (BYTE) pAcc->GetPixel( nY, nX ) )
+ : pAcc->GetPixel( nY, nX );
+ bIsGrey = ( aColor.GetRed() == aColor.GetGreen() ) && ( aColor.GetRed() == aColor.GetBlue() );
+ }
+ }
+ if ( bIsGrey )
+ bGreys = sal_True;
+ }
+
if( pAcc )
{
+ if ( bGreys )
+ bNative = ( pAcc->GetScanlineFormat() == BMP_FORMAT_8BIT_PAL );
+ else
#ifndef SYSTEM_JPEG
- bNative = ( pAcc->GetScanlineFormat() == BMP_FORMAT_24BIT_TC_BGR );
+ bNative = ( pAcc->GetScanlineFormat() == BMP_FORMAT_24BIT_TC_BGR );
#else
- bNative = ( pAcc->GetScanlineFormat() == BMP_FORMAT_24BIT_TC_RGB );
+ bNative = ( pAcc->GetScanlineFormat() == BMP_FORMAT_24BIT_TC_RGB );
#endif
if( !bNative )
- pBuffer = new BYTE[ AlignedWidth4Bytes( pAcc->Width() * 24L ) ];
+ pBuffer = new BYTE[ AlignedWidth4Bytes( bGreys ? pAcc->Width() * 8L : pAcc->Width() * 24L ) ];
JPEGCallbackStruct aCallbackData;
aCallbackData.xStatusIndicator = xStatusIndicator;
- bRet = (BOOL) WriteJPEG( this, &rOStm, pAcc->Width(), pAcc->Height(), nQuality, &aCallbackData );
+ bRet = (BOOL) WriteJPEG( this, &rOStm, pAcc->Width(), pAcc->Height(), bGreys, nQuality, &aCallbackData );
delete[] pBuffer;
pBuffer = NULL;
diff --git a/svtools/source/filter.vcl/jpeg/jpeg.h b/svtools/source/filter.vcl/jpeg/jpeg.h
index eaeaa503b5e9..4d5aafe413bb 100644
--- a/svtools/source/filter.vcl/jpeg/jpeg.h
+++ b/svtools/source/filter.vcl/jpeg/jpeg.h
@@ -64,7 +64,7 @@ void* JPEGMalloc( size_t size );
void JPEGFree( void *ptr );
long JPEGCallback( void* pCallbackData, long nPercent );
-long WriteJPEG( void* pJPEGWriter, void* pOStm, long nWidth, long nHeight,
+long WriteJPEG( void* pJPEGWriter, void* pOStm, long nWidth, long nHeight, long bGreyScale,
long nQualityPercent, void* pCallbackData );
void* GetScanline( void* pJPEGWriter, long nY );
diff --git a/svtools/source/filter.vcl/jpeg/jpegc.c b/svtools/source/filter.vcl/jpeg/jpegc.c
index 84394d945f79..0525877f2614 100644
--- a/svtools/source/filter.vcl/jpeg/jpegc.c
+++ b/svtools/source/filter.vcl/jpeg/jpegc.c
@@ -182,7 +182,7 @@ Exit:
}
long WriteJPEG( void* pJPEGWriter, void* pOStm,
- long nWidth, long nHeight,
+ long nWidth, long nHeight, long bGreys,
long nQualityPercent, void* pCallbackData )
{
struct jpeg_compress_struct cinfo;
@@ -208,8 +208,16 @@ long WriteJPEG( void* pJPEGWriter, void* pOStm,
cinfo.image_width = (JDIMENSION) nWidth;
cinfo.image_height = (JDIMENSION) nHeight;
- cinfo.input_components = 3;
- cinfo.in_color_space = JCS_RGB;
+ if ( bGreys )
+ {
+ cinfo.input_components = 1;
+ cinfo.in_color_space = JCS_GRAYSCALE;
+ }
+ else
+ {
+ cinfo.input_components = 3;
+ cinfo.in_color_space = JCS_RGB;
+ }
jpeg_set_defaults( &cinfo );
jpeg_set_quality( &cinfo, (int) nQualityPercent, FALSE );
diff --git a/svtools/source/filter.vcl/wmf/emfwr.cxx b/svtools/source/filter.vcl/wmf/emfwr.cxx
index e011dde1a0e8..1bc5364a191a 100644
--- a/svtools/source/filter.vcl/wmf/emfwr.cxx
+++ b/svtools/source/filter.vcl/wmf/emfwr.cxx
@@ -165,6 +165,8 @@
#define TA_RTLREADING 256
#define TA_MASK (TA_BASELINE+TA_CENTER+TA_UPDATECP+TA_RTLREADING)
+#define MM_ANISOTROPIC 8
+
// -------------
// - EMFWriter -
// -------------
@@ -184,19 +186,37 @@ BOOL EMFWriter::WriteEMF( const GDIMetaFile& rMtf, SvStream& rOStm, FilterConfig
maVDev.SetMapMode( rMtf.GetPrefMapMode() );
mpFilterConfigItem = pFilterConfigItem;
+ // don't work with pixel as destination map mode -> higher resolution preferrable
+ maDestMapMode.SetMapUnit( MAP_100TH_MM );
+
const Size aMtfSizePix( maVDev.LogicToPixel( rMtf.GetPrefSize(), rMtf.GetPrefMapMode() ) );
const Size aMtfSizeLog( maVDev.LogicToLogic( rMtf.GetPrefSize(), rMtf.GetPrefMapMode(), MAP_100TH_MM ) );
// seek over header
- rOStm.SeekRel( 100 );
+ // use [MS-EMF 2.2.11] HeaderExtension2 Object, otherwise resulting EMF cannot be converted with GetWinMetaFileBits()
+ rOStm.SeekRel( 108 );
// write initial values
- ImplBeginRecord( WIN_EMR_SETWINDOWORGEX );
- (*mpStm) << (INT32) 0 << (INT32) 0;
+
+ // set 100th mm map mode in EMF
+ ImplBeginRecord( WIN_EMR_SETMAPMODE );
+ (*mpStm) << (INT32) MM_ANISOTROPIC;
+ ImplEndRecord();
+
+ ImplBeginRecord( WIN_EMR_SETVIEWPORTEXTEX );
+ (*mpStm) << (INT32) maVDev.ImplGetDPIX() << (INT32) maVDev.ImplGetDPIY();
ImplEndRecord();
ImplBeginRecord( WIN_EMR_SETWINDOWEXTEX );
- (*mpStm) << (INT32) aMtfSizePix.Width() << (INT32) aMtfSizePix.Height();
+ (*mpStm) << (INT32) 2540 << (INT32) 2540;
+ ImplEndRecord();
+
+ ImplBeginRecord( WIN_EMR_SETVIEWPORTORGEX );
+ (*mpStm) << (INT32) 0 << (INT32) 0;
+ ImplEndRecord();
+
+ ImplBeginRecord( WIN_EMR_SETWINDOWORGEX );
+ (*mpStm) << (INT32) 0 << (INT32) 0;
ImplEndRecord();
ImplWriteRasterOp( ROP_OVERPAINT );
@@ -210,7 +230,7 @@ BOOL EMFWriter::WriteEMF( const GDIMetaFile& rMtf, SvStream& rOStm, FilterConfig
ImplBeginRecord( WIN_EMR_EOF );
(*mpStm)<< (sal_uInt32)0 // nPalEntries
- << (sal_uInt32)0x16 // offPalEntries
+ << (sal_uInt32)0x10 // offPalEntries
<< (sal_uInt32)0x14; // nSizeLast
ImplEndRecord();
@@ -218,14 +238,15 @@ BOOL EMFWriter::WriteEMF( const GDIMetaFile& rMtf, SvStream& rOStm, FilterConfig
// write header
const ULONG nEndPos = mpStm->Tell(); mpStm->Seek( nHeaderPos );
- (*mpStm) << (UINT32) 0x00000001 << (UINT32) 100;
- (*mpStm) << (INT32) 0 << (INT32) 0 << (INT32) ( aMtfSizePix.Width() - 1 ) << (INT32) ( aMtfSizePix.Height() - 1 );
- (*mpStm) << (INT32) 0 << (INT32) 0 << (INT32) ( aMtfSizeLog.Width() - 1 ) << (INT32) ( aMtfSizeLog.Height() - 1 );
- (*mpStm) << (UINT32) 0x464d4520 << (UINT32) 0x10000 << (UINT32) ( nEndPos - nHeaderPos );
- (*mpStm) << (UINT32) mnRecordCount << (UINT16) ( mnHandleCount + 1 ) << (UINT16) 0 << (UINT32) 0 << (UINT32) 0 << (UINT32) 0;
- (*mpStm) << (INT32) aMtfSizePix.Width() << (INT32) aMtfSizePix.Height();
- (*mpStm) << (INT32) ( aMtfSizeLog.Width() / 100 ) << (INT32) ( aMtfSizeLog.Height() / 100 );
- (*mpStm) << (UINT32) 0 << (UINT32) 0 << (UINT32) 0;
+ (*mpStm) << (UINT32) 0x00000001 << (UINT32) 108 //use [MS-EMF 2.2.11] HeaderExtension2 Object
+ << (INT32) 0 << (INT32) 0 << (INT32) ( aMtfSizePix.Width() - 1 ) << (INT32) ( aMtfSizePix.Height() - 1 )
+ << (INT32) 0 << (INT32) 0 << (INT32) ( aMtfSizeLog.Width() - 1 ) << (INT32) ( aMtfSizeLog.Height() - 1 )
+ << (UINT32) 0x464d4520 << (UINT32) 0x10000 << (UINT32) ( nEndPos - nHeaderPos )
+ << (UINT32) mnRecordCount << (UINT16) ( mnHandleCount + 1 ) << (UINT16) 0 << (UINT32) 0 << (UINT32) 0 << (UINT32) 0
+ << (INT32) aMtfSizePix.Width() << (INT32) aMtfSizePix.Height()
+ << (INT32) ( aMtfSizeLog.Width() / 100 ) << (INT32) ( aMtfSizeLog.Height() / 100 )
+ << (UINT32) 0 << (UINT32) 0 << (UINT32) 0
+ << (INT32) ( aMtfSizeLog.Width() * 10 ) << (INT32) ( aMtfSizeLog.Height() * 10 ); //use [MS-EMF 2.2.11] HeaderExtension2 Object
mpStm->Seek( nEndPos );
delete[] mpHandlesUsed;
@@ -523,35 +544,32 @@ void EMFWriter::ImplWriteRasterOp( RasterOp eRop )
void EMFWriter::ImplWriteExtent( long nExtent )
{
- const Size aSize( maVDev.LogicToPixel( Size( nExtent, nExtent ) ) );
- (*mpStm) << (INT32) aSize.Width();
+ nExtent = maVDev.LogicToLogic( Size( nExtent, 0 ), maVDev.GetMapMode(), maDestMapMode ).Width();
+ (*mpStm) << (INT32) nExtent;
}
// -----------------------------------------------------------------------------
void EMFWriter::ImplWritePoint( const Point& rPoint )
{
- const Point aPoint( maVDev.LogicToPixel( rPoint ) );
-
- (*mpStm) << (INT32) aPoint.X() << (INT32) aPoint.Y();
+ const Point aPoint( maVDev.LogicToLogic( rPoint, maVDev.GetMapMode(), maDestMapMode ));
+ (*mpStm) << (INT32) aPoint.X() << (INT32) aPoint.Y();
}
// -----------------------------------------------------------------------------
void EMFWriter::ImplWriteSize( const Size& rSize)
{
- const Size aSize( maVDev.LogicToPixel( rSize ) );
-
- (*mpStm) << (INT32) aSize.Width() << (INT32) aSize.Height();
+ const Size aSize( maVDev.LogicToLogic( rSize, maVDev.GetMapMode(), maDestMapMode ));
+ (*mpStm) << (INT32) aSize.Width() << (INT32) aSize.Height();
}
// -----------------------------------------------------------------------------
void EMFWriter::ImplWriteRect( const Rectangle& rRect )
{
- const Rectangle aRect( maVDev.LogicToPixel( rRect ) );
-
- (*mpStm) << aRect.Left() << aRect.Top() << aRect.Right() << aRect.Bottom();
+ const Rectangle aRect( maVDev.LogicToLogic ( rRect, maVDev.GetMapMode(), maDestMapMode ));
+ (*mpStm) << aRect.Left() << aRect.Top() << aRect.Right() << aRect.Bottom();
}
// -----------------------------------------------------------------------------
@@ -650,12 +668,20 @@ void EMFWriter::ImplWritePath( const PolyPolygon& rPolyPoly, sal_Bool bClosed )
const Polygon& rPoly = rPolyPoly[ i ];
while ( n < rPoly.GetSize() )
{
- sal_uInt16 nBezPoints = 0;
- if ( n )
+ if( n == 0 )
{
- while ( ( ( nBezPoints + n + 2 ) < rPoly.GetSize() ) && ( rPoly.GetFlags( nBezPoints + n ) == POLY_CONTROL ) )
- nBezPoints += 3;
+ ImplBeginRecord( WIN_EMR_MOVETOEX );
+ ImplWritePoint( rPoly[ 0 ] );
+ ImplEndRecord();
+ n++;
+ continue;
}
+
+ sal_uInt16 nBezPoints = 0;
+
+ while ( ( ( nBezPoints + n + 2 ) < rPoly.GetSize() ) && ( rPoly.GetFlags( nBezPoints + n ) == POLY_CONTROL ) )
+ nBezPoints += 3;
+
if ( nBezPoints )
{
ImplBeginRecord( WIN_EMR_POLYBEZIERTO );
@@ -675,22 +701,26 @@ void EMFWriter::ImplWritePath( const PolyPolygon& rPolyPoly, sal_Bool bClosed )
sal_uInt16 nPoints = 1;
while( ( nPoints + n ) < rPoly.GetSize() && ( rPoly.GetFlags( nPoints + n ) != POLY_CONTROL ) )
nPoints++;
- ImplBeginRecord( WIN_EMR_MOVETOEX );
- ImplWritePoint( rPoly[ n ] );
- ImplEndRecord();
+
if ( nPoints > 1 )
{
ImplBeginRecord( WIN_EMR_POLYLINETO );
- Polygon aNewPoly( nPoints );
- aNewPoly[ 0 ] = rPoly[ n ];
- for ( o = 1; o < nPoints; o++ )
- aNewPoly[ o ] = rPoly[ n + o ];
+ Polygon aNewPoly( nPoints + 1 );
+ aNewPoly[ 0 ] = rPoly[ n - 1];
+ for ( o = 1; o <= nPoints; o++ )
+ aNewPoly[ o ] = rPoly[ n - 1 + o ];
ImplWriteRect( aNewPoly.GetBoundRect() );
- (*mpStm) << (sal_uInt32)( nPoints - 1 );
+ (*mpStm) << (sal_uInt32)( nPoints );
for( o = 1; o < aNewPoly.GetSize(); o++ )
ImplWritePoint( aNewPoly[ o ] );
ImplEndRecord();
}
+ else
+ {
+ ImplBeginRecord( WIN_EMR_LINETO );
+ ImplWritePoint( rPoly[ n ] );
+ ImplEndRecord();
+ }
n = n + nPoints;
}
if ( bClosed && ( n == rPoly.GetSize() ) )
@@ -703,6 +733,7 @@ void EMFWriter::ImplWritePath( const PolyPolygon& rPolyPoly, sal_Bool bClosed )
ImplBeginRecord( WIN_EMR_ENDPATH );
ImplEndRecord();
ImplBeginRecord( bClosed ? WIN_EMR_FILLPATH : WIN_EMR_STROKEPATH );
+ ImplWriteRect( rPolyPoly.GetBoundRect() );
ImplEndRecord();
}
diff --git a/svtools/source/filter.vcl/wmf/emfwr.hxx b/svtools/source/filter.vcl/wmf/emfwr.hxx
index 2d3c8801ba49..29715c59df0f 100644
--- a/svtools/source/filter.vcl/wmf/emfwr.hxx
+++ b/svtools/source/filter.vcl/wmf/emfwr.hxx
@@ -50,6 +50,7 @@ class EMFWriter
private:
VirtualDevice maVDev;
+ MapMode maDestMapMode;
FilterConfigItem* mpFilterConfigItem;
SvStream* mpStm;
BOOL* mpHandlesUsed;
diff --git a/svtools/source/filter.vcl/wmf/winmtf.cxx b/svtools/source/filter.vcl/wmf/winmtf.cxx
index 6f1caae18750..58dfdec45ee1 100644
--- a/svtools/source/filter.vcl/wmf/winmtf.cxx
+++ b/svtools/source/filter.vcl/wmf/winmtf.cxx
@@ -1522,9 +1522,9 @@ void WinMtfOutput::DrawText( Point& rPosition, String& rText, sal_Int32* pDXArry
aTmp.SetFillColor( maBkColor );
if( mnBkMode == TRANSPARENT )
- maFont.SetTransparent( sal_True );
+ aTmp.SetTransparent( sal_True );
else
- maFont.SetTransparent( sal_False );
+ aTmp.SetTransparent( sal_False );
if ( ( mnTextAlign & TA_BASELINE) == TA_BASELINE )
aTmp.SetAlign( ALIGN_BASELINE );
@@ -2195,3 +2195,8 @@ void WinMtfOutput::Pop()
}
}
+void WinMtfOutput::AddFromGDIMetaFile( GDIMetaFile& rGDIMetaFile )
+{
+ rGDIMetaFile.Play( *mpGDIMetaFile, 0xFFFFFFFF );
+}
+
diff --git a/svtools/source/filter.vcl/wmf/winmtf.hxx b/svtools/source/filter.vcl/wmf/winmtf.hxx
index ada590a19675..f3b2482f63bc 100644
--- a/svtools/source/filter.vcl/wmf/winmtf.hxx
+++ b/svtools/source/filter.vcl/wmf/winmtf.hxx
@@ -672,6 +672,7 @@ class WinMtfOutput
void MoveClipRegion( const Size& rSize );
void SetClipPath( const PolyPolygon& rPolyPoly, sal_Int32 nClippingMode, sal_Bool bIsMapped );
void UpdateClipRegion();
+ void AddFromGDIMetaFile( GDIMetaFile& rGDIMetaFile );
WinMtfOutput( GDIMetaFile& rGDIMetaFile );
virtual ~WinMtfOutput();
@@ -734,6 +735,18 @@ private:
UINT16 nUnitsPerInch;
sal_uInt32 nRecSize;
+ // embedded EMF data
+ SvMemoryStream* pEMFStream;
+
+ // total number of comment records containing EMF data
+ sal_uInt32 nEMFRecCount;
+
+ // number of EMF records read
+ sal_uInt32 nEMFRec;
+
+ // total size of embedded EMF data
+ sal_uInt32 nEMFSize;
+
sal_uInt32 nSkipActions;
sal_uInt32 nCurrentAction;
sal_uInt32 nUnicodeEscapeAction;
@@ -755,6 +768,8 @@ public:
WMFReader( SvStream& rStreamWMF, GDIMetaFile& rGDIMetaFile, FilterConfigItem* pConfigItem = NULL )
: WinMtf( new WinMtfOutput( rGDIMetaFile ), rStreamWMF, pConfigItem ) {};
+ ~WMFReader();
+
// Liesst aus dem Stream eine WMF-Datei und fuellt das GDIMetaFile
void ReadWMF();
};
diff --git a/svtools/source/filter.vcl/wmf/winwmf.cxx b/svtools/source/filter.vcl/wmf/winwmf.cxx
index 0930b0ece8a8..f9ae46e98e12 100644
--- a/svtools/source/filter.vcl/wmf/winwmf.cxx
+++ b/svtools/source/filter.vcl/wmf/winwmf.cxx
@@ -32,6 +32,7 @@
#include "precompiled_svtools.hxx"
#include "winmtf.hxx"
+#include <vcl/gdimtf.hxx>
#include <rtl/crc.h>
#include <rtl/tencinfo.h>
#include <osl/endian.h>
@@ -831,81 +832,136 @@ void WMFReader::ReadRecordParams( USHORT nFunc )
pWMF->SetError( SVSTREAM_FILEFORMAT_ERROR );
break;
}
- if ( nRecSize >= 12 ) // minimal escape lenght
+ if ( nRecSize >= 4 ) // minimal escape lenght
{
- sal_uInt16 nMode, nLen, OO;
- sal_uInt32 Magic, nCheck,nEsc;
+ sal_uInt16 nMode, nLen;
*pWMF >> nMode
- >> nLen
- >> OO
- >> Magic
- >> nCheck
- >> nEsc;
- if ( ( nMode == W_MFCOMMENT ) && ( nLen >= 14 ) && ( OO == 0x4f4f ) && ( Magic == 0xa2c2a ) )
+ >> nLen;
+ if ( ( nMode == W_MFCOMMENT ) && ( nLen >= 4 ) )
{
- sal_uInt32 nEscLen = nLen - 14;
- if ( nEscLen <= ( nRecSize * 2 ) )
+ sal_uInt32 nNewMagic; // we have to read int32 for
+ *pWMF >> nNewMagic; // META_ESCAPE_ENHANCED_METAFILE CommentIdentifier
+
+ if( nNewMagic == 0x2c2a4f4f && nLen >= 14 )
{
+ sal_uInt16 nMagic2;
+ *pWMF >> nMagic2;
+ if( nMagic2 == 0x0a ) // 2nd half of magic
+ { // continue with private escape
+ sal_uInt32 nCheck, nEsc;
+ *pWMF >> nCheck
+ >> nEsc;
+
+ sal_uInt32 nEscLen = nLen - 14;
+ if ( nEscLen <= ( nRecSize * 2 ) )
+ {
#ifdef OSL_BIGENDIAN
- sal_uInt32 nTmp = SWAPLONG( nEsc );
- sal_uInt32 nCheckSum = rtl_crc32( 0, &nTmp, 4 );
+ sal_uInt32 nTmp = SWAPLONG( nEsc );
+ sal_uInt32 nCheckSum = rtl_crc32( 0, &nTmp, 4 );
#else
- sal_uInt32 nCheckSum = rtl_crc32( 0, &nEsc, 4 );
+ sal_uInt32 nCheckSum = rtl_crc32( 0, &nEsc, 4 );
#endif
- sal_Int8* pData = NULL;
+ sal_Int8* pData = NULL;
- if ( ( static_cast< sal_uInt64 >( nEscLen ) + pWMF->Tell() ) > nMetaRecEndPos )
- {
- pWMF->SetError( SVSTREAM_FILEFORMAT_ERROR );
- break;
- }
- if ( nEscLen > 0 )
- {
- pData = new sal_Int8[ nEscLen ];
- pWMF->Read( pData, nEscLen );
- nCheckSum = rtl_crc32( nCheckSum, pData, nEscLen );
- }
- if ( nCheck == nCheckSum )
- {
- switch( nEsc )
- {
- case PRIVATE_ESCAPE_UNICODE :
- { // we will use text instead of polygons only if we have the correct font
- if ( aVDev.IsFontAvailable( pOut->GetFont().GetName() ) )
+ if ( ( static_cast< sal_uInt64 >( nEscLen ) + pWMF->Tell() ) > nMetaRecEndPos )
+ {
+ pWMF->SetError( SVSTREAM_FILEFORMAT_ERROR );
+ break;
+ }
+ if ( nEscLen > 0 )
+ {
+ pData = new sal_Int8[ nEscLen ];
+ pWMF->Read( pData, nEscLen );
+ nCheckSum = rtl_crc32( nCheckSum, pData, nEscLen );
+ }
+ if ( nCheck == nCheckSum )
+ {
+ switch( nEsc )
{
- Point aPt;
- String aString;
- sal_uInt32 i, nStringLen, nDXCount;
- sal_Int32* pDXAry = NULL;
- SvMemoryStream aMemoryStream( nEscLen );
- aMemoryStream.Write( pData, nEscLen );
- aMemoryStream.Seek( STREAM_SEEK_TO_BEGIN );
- aMemoryStream >> aPt.X()
- >> aPt.Y()
- >> nStringLen;
-
- if ( ( static_cast< sal_uInt64 >( nStringLen ) * sizeof( sal_Unicode ) ) < ( nEscLen - aMemoryStream.Tell() ) )
- {
- sal_Unicode* pBuf = aString.AllocBuffer( (xub_StrLen)nStringLen );
- for ( i = 0; i < nStringLen; i++ )
- aMemoryStream >> pBuf[ i ];
- aMemoryStream >> nDXCount;
- if ( ( static_cast< sal_uInt64 >( nDXCount ) * sizeof( sal_Int32 ) ) >= ( nEscLen - aMemoryStream.Tell() ) )
- nDXCount = 0;
- if ( nDXCount )
- pDXAry = new sal_Int32[ nDXCount ];
- for ( i = 0; i < nDXCount; i++ )
- aMemoryStream >> pDXAry[ i ];
- aMemoryStream >> nSkipActions;
- pOut->DrawText( aPt, aString, pDXAry );
- delete[] pDXAry;
+ case PRIVATE_ESCAPE_UNICODE :
+ { // we will use text instead of polygons only if we have the correct font
+ if ( aVDev.IsFontAvailable( pOut->GetFont().GetName() ) )
+ {
+ Point aPt;
+ String aString;
+ sal_uInt32 i, nStringLen, nDXCount;
+ sal_Int32* pDXAry = NULL;
+ SvMemoryStream aMemoryStream( nEscLen );
+ aMemoryStream.Write( pData, nEscLen );
+ aMemoryStream.Seek( STREAM_SEEK_TO_BEGIN );
+ aMemoryStream >> aPt.X()
+ >> aPt.Y()
+ >> nStringLen;
+
+ if ( ( static_cast< sal_uInt64 >( nStringLen ) * sizeof( sal_Unicode ) ) < ( nEscLen - aMemoryStream.Tell() ) )
+ {
+ sal_Unicode* pBuf = aString.AllocBuffer( (xub_StrLen)nStringLen );
+ for ( i = 0; i < nStringLen; i++ )
+ aMemoryStream >> pBuf[ i ];
+ aMemoryStream >> nDXCount;
+ if ( ( static_cast< sal_uInt64 >( nDXCount ) * sizeof( sal_Int32 ) ) >= ( nEscLen - aMemoryStream.Tell() ) )
+ nDXCount = 0;
+ if ( nDXCount )
+ pDXAry = new sal_Int32[ nDXCount ];
+ for ( i = 0; i < nDXCount; i++ )
+ aMemoryStream >> pDXAry[ i ];
+ aMemoryStream >> nSkipActions;
+ pOut->DrawText( aPt, aString, pDXAry );
+ delete[] pDXAry;
+ }
+ }
}
+ break;
}
}
- break;
+ delete[] pData;
+ }
+ }
+ }
+ else if ( (nNewMagic == static_cast< sal_uInt32 >(0x43464D57)) && (nLen >= 34) && ( (sal_Int32)(nLen + 10) <= (sal_Int32)(nRecSize * 2) ))
+ {
+ sal_uInt32 nComType, nVersion, nFlags, nComRecCount,
+ nCurRecSize, nRemainingSize, nEMFTotalSize;
+ sal_uInt16 nCheck;
+
+ *pWMF >> nComType >> nVersion >> nCheck >> nFlags
+ >> nComRecCount >> nCurRecSize
+ >> nRemainingSize >> nEMFTotalSize; // the nRemainingSize is not mentioned in MSDN documentation
+ // but it seems to be required to read in data produced by OLE
+
+ if( nComType == 0x01 && nVersion == 0x10000 && nComRecCount )
+ {
+ if( !nEMFRec )
+ { // first EMF comment
+ nEMFRecCount = nComRecCount;
+ nEMFSize = nEMFTotalSize;
+ pEMFStream = new SvMemoryStream( nEMFSize );
+ }
+ else if( ( nEMFRecCount != nComRecCount ) || ( nEMFSize != nEMFTotalSize ) ) // add additional checks here
+ {
+ // total records should be the same as in previous comments
+ nEMFRecCount = 0xFFFFFFFF;
+ delete pEMFStream;
+ pEMFStream = NULL;
+ }
+ nEMFRec++;
+
+ if( pEMFStream && nCurRecSize + 34 > nLen )
+ {
+ nEMFRecCount = 0xFFFFFFFF;
+ delete pEMFStream;
+ pEMFStream = NULL;
+ }
+
+ if( pEMFStream )
+ {
+ sal_Int8* pBuf = new sal_Int8[ nCurRecSize ];
+ sal_uInt32 nCount = pWMF->Read( pBuf, nCurRecSize );
+ if( nCount == nCurRecSize )
+ pEMFStream->Write( pBuf, nCount );
+ delete[] pBuf;
}
}
- delete[] pData;
}
}
}
@@ -1023,6 +1079,11 @@ void WMFReader::ReadWMF()
nCurrentAction = 0;
nUnicodeEscapeAction = 0;
+ pEMFStream = NULL;
+ nEMFRecCount = 0;
+ nEMFRec = 0;
+ nEMFSize = 0;
+
pOut->SetMapMode( MM_ANISOTROPIC );
pOut->SetWinOrg( Point() );
pOut->SetWinExt( Size( 1, 1 ) );
@@ -1070,6 +1131,33 @@ void WMFReader::ReadWMF()
ReadRecordParams( nFunction );
else
nSkipActions--;
+
+ if( pEMFStream && nEMFRecCount == nEMFRec )
+ {
+ GDIMetaFile aMeta;
+ pEMFStream->Seek( 0 );
+ EnhWMFReader* pEMFReader = new EnhWMFReader ( *pEMFStream, aMeta );
+ BOOL bRead = pEMFReader->ReadEnhWMF();
+ delete pEMFReader; // destroy first!!!
+
+ if( bRead )
+ {
+ pOut->AddFromGDIMetaFile( aMeta );
+ pOut->SetrclFrame( Rectangle(0, 0, aMeta.GetPrefSize().Width(), aMeta.GetPrefSize().Height() ));
+ // we have successfully read the embedded EMF data
+ // no need to process WMF data further
+ break;
+ }
+ else
+ {
+ // something went wrong
+ // continue with WMF, don't try this again
+ delete pEMFStream;
+ pEMFStream = NULL;
+ }
+
+ }
+
nPos += nRecSize * 2;
if ( nPos <= nEndPos )
pWMF->Seek( nPos );
@@ -1333,3 +1421,9 @@ sal_Bool WMFReader::GetPlaceableBound( Rectangle& rPlaceableBound, SvStream* pSt
return bRet;
}
+WMFReader::~WMFReader()
+{
+ if( pEMFStream )
+ delete pEMFStream;
+}
+
diff --git a/svtools/source/filter.vcl/wmf/wmfwr.cxx b/svtools/source/filter.vcl/wmf/wmfwr.cxx
index 30d4ff06c0d2..c4f53046c29a 100644
--- a/svtools/source/filter.vcl/wmf/wmfwr.cxx
+++ b/svtools/source/filter.vcl/wmf/wmfwr.cxx
@@ -34,6 +34,7 @@
#include <vcl/salbtype.hxx>
#include "wmfwr.hxx"
#include <unotools/fontcvt.hxx>
+#include "emfwr.hxx"
#include <rtl/crc.h>
#include <rtl/tencinfo.h>
#include <tools/tenccvt.hxx>
@@ -1875,6 +1876,7 @@ BOOL WMFWriter::WriteWMF( const GDIMetaFile& rMTF, SvStream& rTargetStream,
{
WMFWriterAttrStackMember * pAt;
+ bEmbedEMF = TRUE;
bStatus=TRUE;
pConvert = 0;
pVirDev = new VirtualDevice;
@@ -1938,6 +1940,8 @@ BOOL WMFWriter::WriteWMF( const GDIMetaFile& rMTF, SvStream& rTargetStream,
CountActionsAndBitmaps(rMTF);
WriteHeader(rMTF,bPlaceable);
+ if( bEmbedEMF )
+ WriteEmbeddedEMF( rMTF );
WMFRecord_SetWindowOrg(Point(0,0));
WMFRecord_SetWindowExt(rMTF.GetPrefSize());
WMFRecord_SetBkMode( TRUE );
@@ -2016,3 +2020,80 @@ USHORT WMFWriter::CalcSaveTargetMapMode(MapMode& rMapMode,
return nDivisor;
}
+
+// ------------------------------------------------------------------------
+
+void WMFWriter::WriteEmbeddedEMF( const GDIMetaFile& rMTF )
+{
+ EMFWriter aEMFWriter;
+ SvMemoryStream aStream;
+
+ if( aEMFWriter.WriteEMF( rMTF, aStream ) )
+ {
+ sal_Size nTotalSize = aStream.Tell();
+ if( nTotalSize > SAL_MAX_UINT32 )
+ return;
+ aStream.Seek( 0 );
+ sal_uInt32 nRemainingSize = static_cast< sal_uInt32 >( nTotalSize );
+ sal_uInt32 nRecCounts = ( (nTotalSize - 1) / 0x2000 ) + 1;
+ sal_uInt16 nCheckSum = 0, nWord;
+
+ sal_uInt32 nPos = 0;
+
+ while( nPos + 1 < nTotalSize )
+ {
+ aStream >> nWord;
+ nCheckSum ^= nWord;
+ nPos += 2;
+ }
+
+ nCheckSum = static_cast< sal_uInt16 >( nCheckSum * -1 );
+
+ aStream.Seek( 0 );
+ while( nRemainingSize > 0 )
+ {
+ sal_uInt32 nCurSize;
+ if( nRemainingSize > 0x2000 )
+ {
+ nCurSize = 0x2000;
+ nRemainingSize -= 0x2000;
+ }
+ else
+ {
+ nCurSize = nRemainingSize;
+ nRemainingSize = 0;
+ }
+ WriteEMFRecord( aStream,
+ nCurSize,
+ nRemainingSize,
+ nTotalSize,
+ nRecCounts,
+ nCheckSum );
+ nCheckSum = 0;
+ }
+ }
+}
+
+// ------------------------------------------------------------------------
+
+void WMFWriter::WriteEMFRecord( SvMemoryStream& rStream, sal_uInt32 nCurSize, sal_uInt32 nRemainingSize,
+ sal_uInt32 nTotalSize, sal_uInt32 nRecCounts, sal_uInt16 nCheckSum )
+{
+ // according to http://msdn.microsoft.com/en-us/library/dd366152%28PROT.13%29.aspx
+ WriteRecordHeader( 0, W_META_ESCAPE );
+ *pWMF << (sal_uInt16)W_MFCOMMENT // same as META_ESCAPE_ENHANCED_METAFILE
+ << (sal_uInt16)( nCurSize + 34 ) // we will always have a 34 byte escape header:
+ << (sal_uInt32) 0x43464D57 // WMFC
+ << (sal_uInt32) 0x00000001 // Comment type
+ << (sal_uInt32) 0x00010000 // version
+ << nCheckSum // check sum
+ << (sal_uInt32) 0 // flags = 0
+ << nRecCounts // total number of records
+ << nCurSize // size of this record's data
+ << nRemainingSize // remaining size of data in following records, missing in MSDN documentation
+ << nTotalSize; // total size of EMF stream
+
+ pWMF->Write( static_cast< const sal_Char* >( rStream.GetData() ) + rStream.Tell(), nCurSize );
+ rStream.SeekRel( nCurSize );
+ UpdateRecordHeader();
+}
diff --git a/svtools/source/filter.vcl/wmf/wmfwr.hxx b/svtools/source/filter.vcl/wmf/wmfwr.hxx
index 03ca14e7633f..6b2ff0b04e0a 100644
--- a/svtools/source/filter.vcl/wmf/wmfwr.hxx
+++ b/svtools/source/filter.vcl/wmf/wmfwr.hxx
@@ -131,6 +131,8 @@ private:
ULONG nWrittenBitmaps; // Anzahl der bereits geschriebenen Bitmaps
ULONG nActBitmapPercent; // Wieviel Prozent die naechste Bitmap schon geschrieben ist.
+ BOOL bEmbedEMF; // optionally embedd EMF data into WMF
+
void MayCallback();
// Berechnet anhand der obigen 5 Parameter eine Prozentzahl
// und macht dann ggf. einen Callback. Setzt bStatus auf FALSE wenn User abbrechen
@@ -211,6 +213,13 @@ private:
void WriteHeader(const GDIMetaFile & rMTF, BOOL bPlaceable);
void UpdateHeader();
+ void WriteEmbeddedEMF( const GDIMetaFile& rMTF );
+ void WriteEMFRecord( SvMemoryStream& rStream, sal_uInt32 nCurSize,
+ sal_uInt32 nRemainingSize,
+ sal_uInt32 nTotalSize,
+ sal_uInt32 nRecCounts,
+ sal_uInt16 nCheckSum );
+
USHORT CalcSaveTargetMapMode(MapMode& rMapMode, const Size& rPrefSize);
public:
diff --git a/svtools/source/misc/ehdl.cxx b/svtools/source/misc/ehdl.cxx
index 4084aa47bc80..3a31c1b812a6 100644
--- a/svtools/source/misc/ehdl.cxx
+++ b/svtools/source/misc/ehdl.cxx
@@ -321,16 +321,21 @@ BOOL SfxErrorHandler::GetClassString(ULONG lClassId, String &rStr) const
*/
{
-
- ResId aId(RID_ERRHDL, *pMgr);
- ErrorResource_Impl aEr(aId, (USHORT)lClassId);
- if(aEr)
+ BOOL bRet = FALSE;
+ com::sun::star::lang::Locale aLocale( Application::GetSettings().GetUILocale() );
+ ResMgr* pResMgr = ResMgr::CreateResMgr(CREATEVERSIONRESMGR_NAME(ofa), aLocale );
+ if( pResMgr )
{
- rStr=((ResString)aEr).GetString();
- return TRUE;
+ ResId aId(RID_ERRHDL, *pResMgr );
+ ErrorResource_Impl aEr(aId, (USHORT)lClassId);
+ if(aEr)
+ {
+ rStr=((ResString)aEr).GetString();
+ bRet = TRUE;
+ }
}
- else
- return FALSE;
+ delete pResMgr;
+ return bRet;
}
//-------------------------------------------------------------------------
@@ -379,10 +384,10 @@ BOOL SfxErrorHandler::GetErrorString(
BOOL bRet = FALSE;
rStr=String(SvtResId(RID_ERRHDL_CLASS));
- ResId *pResId = new ResId(nId, *pMgr);
+ ResId aResId(nId, *pMgr);
{
- ErrorResource_Impl aEr(*pResId, (USHORT)lErrId);
+ ErrorResource_Impl aEr(aResId, (USHORT)lErrId);
if(aEr)
{
ResString aErrorString(aEr);
@@ -408,7 +413,6 @@ BOOL SfxErrorHandler::GetErrorString(
rStr.SearchAndReplace(String::CreateFromAscii( "$(CLASS)" ),aErrStr);
}
- delete pResId;
return bRet;
}