30#include <rtl/tencinfo.h>
32#include <osl/endian.h>
41#include <osl/thread.h>
49 W_META_SETBKCOLOR = 0x0201,
51 W_META_SETMAPMODE = 0x0103,
53 W_META_SETRELABS = 0x0105,
54 W_META_SETPOLYFILLMODE = 0x0106,
56 W_META_SETTEXTCHAREXTRA = 0x0108,
58 W_META_SETTEXTJUSTIFICATION = 0x020A,
61 W_META_SETVIEWPORTORG = 0x020D,
62 W_META_SETVIEWPORTEXT = 0x020E,
63 W_META_OFFSETWINDOWORG = 0x020F,
64 W_META_SCALEWINDOWEXT = 0x0410,
65 W_META_OFFSETVIEWPORTORG = 0x0211,
66 W_META_SCALEVIEWPORTEXT = 0x0412,
69 W_META_EXCLUDECLIPRECT = 0x0415,
73 W_META_FLOODFILL = 0x0419,
77 W_META_PATBLT = 0x061D,
80 W_META_OFFSETCLIPRGN = 0x0220,
82 W_META_BITBLT = 0x0922,
83 W_META_STRETCHBLT = 0x0B23,
88 W_META_FILLREGION = 0x0228,
89 W_META_FRAMEREGION = 0x0429,
90 W_META_INVERTREGION = 0x012A,
91 W_META_PAINTREGION = 0x012B,
92 W_META_SELECTCLIPREGION = 0x012C,
95 W_META_DRAWTEXT = 0x062F,
97 W_META_SETMAPPERFLAGS = 0x0231,
99 W_META_SETDIBTODEV = 0x0d33,
100 W_META_SELECTPALETTE = 0x0234,
101 W_META_REALIZEPALETTE = 0x0035,
102 W_META_ANIMATEPALETTE = 0x0436,
103 W_META_SETPALENTRIES = 0x0037,
105 W_META_RESIZEPALETTE = 0x0139,
106 W_META_DIBBITBLT = 0x0940,
107 W_META_DIBSTRETCHBLT = 0x0b41,
108 W_META_DIBCREATEPATTERNBRUSH = 0x0142,
110 W_META_EXTFLOODFILL = 0x0548,
111 W_META_RESETDC = 0x014C,
112 W_META_STARTDOC = 0x014D,
113 W_META_STARTPAGE = 0x004F,
114 W_META_ENDPAGE = 0x0050,
115 W_META_ABORTDOC = 0x0052,
116 W_META_ENDDOC = 0x005E,
118 W_META_CREATEPALETTE = 0x00f7,
119 W_META_CREATEBRUSH = 0x00F8,
120 W_META_CREATEPATTERNBRUSH = 0x01F9,
124 W_META_CREATEBITMAPINDIRECT = 0x02FD,
125 W_META_CREATEBITMAP = 0x06FE,
126 W_META_CREATEREGION = 0x06FF
131 Point aSource(rSource);
133 aSource.setY( -rSource.
Y() );
134 if (aSource.X() < rPlaceableBound.
Left())
135 rPlaceableBound.
SetLeft( aSource.X() );
136 if (aSource.X() > rPlaceableBound.
Right())
137 rPlaceableBound.
SetRight( aSource.X() );
138 if (aSource.Y() < rPlaceableBound.
Top())
139 rPlaceableBound.
SetTop( aSource.Y() );
140 if (aSource.Y() > rPlaceableBound.
Bottom())
141 rPlaceableBound.
SetBottom( aSource.Y() );
146 GetWinExtMax(rSource.
TopLeft(), rPlaceableBound, nMapMode);
147 GetWinExtMax(rSource.
BottomRight(), rPlaceableBound, nMapMode);
151 record_type_name(sal_uInt16 nRecType)
159 case W_META_SETBKCOLOR:
return "META_SETBKCOLOR";
161 case W_META_SETMAPMODE:
return "META_SETMAPMODE";
163 case W_META_SETRELABS:
return "META_SETRELABS";
164 case W_META_SETPOLYFILLMODE:
return "META_SETPOLYFILLMODE";
166 case W_META_SETTEXTCHAREXTRA:
return "META_SETTEXTCHAREXTRA";
168 case W_META_SETTEXTJUSTIFICATION:
return "META_SETTEXTJUSTIFICATION";
171 case W_META_SETVIEWPORTORG:
return "META_SETVIEWPORTORG";
172 case W_META_SETVIEWPORTEXT:
return "META_SETVIEWPORTEXT";
173 case W_META_OFFSETWINDOWORG:
return "META_OFFSETWINDOWORG";
174 case W_META_SCALEWINDOWEXT:
return "META_SCALEWINDOWEXT";
175 case W_META_OFFSETVIEWPORTORG:
return "META_OFFSETVIEWPORTORG";
176 case W_META_SCALEVIEWPORTEXT:
return "META_SCALEVIEWPORTEXT";
179 case W_META_EXCLUDECLIPRECT:
return "META_EXCLUDECLIPRECT";
183 case W_META_FLOODFILL:
return "META_FLOODFILL";
187 case W_META_PATBLT:
return "META_PATBLT";
190 case W_META_OFFSETCLIPRGN:
return "META_OFFSETCLIPRGN";
192 case W_META_BITBLT:
return "META_BITBLT";
193 case W_META_STRETCHBLT:
return "META_STRETCHBLT";
198 case W_META_FILLREGION:
return "META_FILLREGION";
199 case W_META_FRAMEREGION:
return "META_FRAMEREGION";
200 case W_META_INVERTREGION:
return "META_INVERTREGION";
201 case W_META_PAINTREGION:
return "META_PAINTREGION";
202 case W_META_SELECTCLIPREGION:
return "META_SELECTCLIPREGION";
205 case W_META_DRAWTEXT:
return "META_DRAWTEXT";
207 case W_META_SETMAPPERFLAGS:
return "META_SETMAPPERFLAGS";
209 case W_META_SETDIBTODEV:
return "META_SETDIBTODEV";
210 case W_META_SELECTPALETTE:
return "META_SELECTPALETTE";
211 case W_META_REALIZEPALETTE:
return "META_REALIZEPALETTE";
212 case W_META_ANIMATEPALETTE:
return "META_ANIMATEPALETTE";
213 case W_META_SETPALENTRIES:
return "META_SETPALENTRIES";
215 case W_META_RESIZEPALETTE:
return "META_RESIZEPALETTE";
216 case W_META_DIBBITBLT:
return "META_DIBBITBLT";
217 case W_META_DIBSTRETCHBLT:
return "META_DIBSTRETCHBLT";
218 case W_META_DIBCREATEPATTERNBRUSH:
return "META_DIBCREATEPATTERNBRUSH";
220 case W_META_EXTFLOODFILL:
return "META_EXTFLOODFILL";
221 case W_META_RESETDC:
return "META_RESETDC";
222 case W_META_STARTDOC:
return "META_STARTDOC";
223 case W_META_STARTPAGE:
return "META_STARTPAGE";
224 case W_META_ENDPAGE:
return "META_ENDPAGE";
225 case W_META_ABORTDOC:
return "META_ABORTDOC";
226 case W_META_ENDDOC:
return "META_ENDDOC";
228 case W_META_CREATEPALETTE:
return "META_CREATEPALETTE";
229 case W_META_CREATEBRUSH:
return "META_CREATEBRUSH";
230 case W_META_CREATEPATTERNBRUSH:
return "META_CREATEPATTERNBRUSH";
234 case W_META_CREATEBITMAPINDIRECT:
return "META_CREATEBITMAPINDIRECT";
235 case W_META_CREATEBITMAP:
return "META_CREATEBITMAP";
236 case W_META_CREATEREGION:
return "META_CREATEREGION";
240 static char buffer[11];
241 o3tl::sprintf(buffer,
"0x%08" SAL_PRIxUINT32, sal_uInt32(nRecType));
253 short nX = 0, nY = 0;
255 return Point( nX, nY );
260 short nX = 0, nY = 0;
262 return Point( nX, nY );
272 if (aTL.
X() > aBR.
X() || aTL.
Y() > aBR.
Y())
274 SAL_WARN(
"emfio",
"broken rectangle");
284 return Size( nW, nH );
289 SAL_INFO(
"emfio",
"\t" << record_type_name(nFunc));
292 case W_META_SETBKCOLOR:
307 case W_META_SETMAPMODE:
309 sal_Int16 nMapMode = 0;
317 sal_uInt16 nROP2 = 0;
337 short nWidth = 0, nHeight = 0;
343 case W_META_OFFSETWINDOWORG:
345 short nXAdd = 0, nYAdd = 0;
351 case W_META_SCALEWINDOWEXT:
353 short nXNum = 0, nXDenom = 0, nYNum = 0, nYDenom = 0;
355 if (!nYDenom || !nXDenom)
360 ScaleWinExt(
static_cast<double>(nXNum) / nXDenom,
static_cast<double>(nYNum) / nYDenom );
364 case W_META_SETVIEWPORTORG:
365 case W_META_SETVIEWPORTEXT:
368 case W_META_OFFSETVIEWPORTORG:
370 short nXAdd = 0, nYAdd = 0;
376 case W_META_SCALEVIEWPORTEXT:
378 short nXNum = 0, nXDenom = 0, nYNum = 0, nYDenom = 0;
380 if (!nYDenom || !nXDenom)
385 ScaleDevExt(
static_cast<double>(nXNum) / nXDenom,
static_cast<double>(nYNum) / nYDenom );
432 DrawArc( aRect, aStart, aEnd );
448 DrawPie( aRect, aStart, aEnd );
464 bool bRecordOk =
true;
466 sal_uInt16 nPoints(0);
481 SAL_WARN_IF(!bRecordOk,
"emfio",
"polygon record has more points than we can handle");
495 sal_uInt16 nPolyCount(0);
500 bool bRecordOk =
true;
507 std::unique_ptr<sal_uInt16[]> xPolygonPointCounts(
new sal_uInt16[nPolyCount]);
508 sal_uInt16* pnPoints = xPolygonPointCounts.get();
510 sal_uInt16 nPoints = 0;
521 nPoints += pnPoints[
a];
524 SAL_WARN_IF(!bRecordOk,
"emfio",
"polypolygon record has more polygons than we can handle");
537 const sal_uInt16 nPointCount(pnPoints[
a]);
545 std::unique_ptr<Point[]> xPolygonPoints(
new Point[nPointCount]);
546 Point* pPtAry = xPolygonPoints.get();
571 bool bRecordOk =
true;
573 sal_uInt16 nPoints(0);
588 SAL_WARN_IF(!bRecordOk,
"emfio",
"polyline record has more points than we can handle");
608 sal_Int16 nSavedDC(0);
610 SAL_INFO(
"emfio",
"\t\t SavedDC: " << nSavedDC );
622 case W_META_OFFSETCLIPRGN:
631 const sal_uInt32 nNonStringLen =
sizeof(sal_uInt32) + 4 *
sizeof(sal_uInt16);
632 const sal_uInt32 nRecSize =
mnRecSize * 2;
634 if (nRecSize < nNonStringLen)
636 SAL_WARN(
"emfio",
"W_META_TEXTOUT too short");
642 sal_uInt16 nStoredLength = (
nLength + 1) &~ 1;
644 if (nRecSize - nNonStringLen < nStoredLength)
646 SAL_WARN(
"emfio",
"W_META_TEXTOUT too short, truncating string");
647 nLength = nStoredLength = nRecSize - nNonStringLen;
652 std::vector<char> aChars(nStoredLength);
664 sal_uInt32 nNonStringLen =
sizeof(sal_uInt32) + 5 *
sizeof(sal_uInt16);
665 const sal_uInt32 nRecSize =
mnRecSize * 2;
667 if (nRecSize < nNonStringLen)
669 SAL_WARN(
"emfio",
"W_META_EXTTEXTOUT too short");
675 sal_uInt16 nLen = 0, nOptions = 0;
677 SAL_INFO(
"emfio",
"\t\t\t Pos: " << aPosition.
getX() <<
":" << aPosition.
getY() <<
" String Length: " << nLen <<
" Options: " << nOptions );
681 nNonStringLen += 2 *
sizeof(sal_uInt16);
683 if (nRecSize < nNonStringLen)
685 SAL_WARN(
"emfio",
"W_META_TEXTOUT too short");
693 SAL_INFO(
"emfio",
"\t\t\t Rectangle : " << aTopLeft.
getX() <<
":" << aTopLeft.
getY() <<
", " << aBottomRight.
getX() <<
":" << aBottomRight.
getY() );
705 sal_Int32 nOriginalTextLen = nLen;
706 sal_Int32 nOriginalBlockLen = ( nOriginalTextLen + 1 ) &~ 1;
708 auto nMaxStreamPos = nRecordPos + nRecSize;
712 SAL_WARN(
"emfio",
"exttextout record claimed more data than the stream can provide");
713 nOriginalTextLen = nOriginalBlockLen = nRemainingSize;
716 std::vector<char>
pChar(nOriginalBlockLen);
719 sal_Int32 nNewTextLen = aText.getLength();
728 SAL_INFO(
"emfio",
"\t\t\t Text : " << aText );
730 std::unique_ptr<tools::Long[]> pDYAry;
732 auto nDxAryEntries = nDxArySize >> 1;
733 bool bUseDXAry =
false;
735 if ( ( ( nDxAryEntries % nOriginalTextLen ) == 0 ) && ( nNewTextLen <= nOriginalTextLen ) )
738 aDXAry.
resize( nNewTextLen );
743 for (
i = 0;
i < nNewTextLen;
i++ )
747 sal_Int32 nDxCount = 1;
748 if ( nNewTextLen != nOriginalTextLen )
752 if ( aTmp.getLength() > 1 )
754 nDxCount = aTmp.getLength();
758 sal_Int16 nDx = 0, nDy = 0;
763 sal_Int16 nDxTmp = 0;
770 sal_Int16 nDyTmp = 0;
782 if (
i == nNewTextLen )
786 DrawText( aPosition, aText, &aDXAry, pDYAry.
get() );
797 case W_META_SELECTPALETTE:
799 sal_uInt16 nObjIndex = 0;
807 sal_uInt16 nAlign = 0;
814 case W_META_STRETCHBLT:
816 sal_uInt32 nRasterOperation = 0;
817 sal_Int16 nSrcHeight = 0, nSrcWidth = 0, nYSrc, nXSrc, nSye, nSxe, nBitmapType, nWidth, nHeight, nBytesPerScan;
819 const bool bNoSourceBitmap = ( nRecordSize == (
static_cast< sal_uInt32
>( nFunc ) >> 8 ) + 3 );
822 SAL_INFO(
"emfio",
"\t\t Raster operation: 0x" << std::hex << nRasterOperation << std::dec <<
", No source bitmap: " << bNoSourceBitmap);
824 if( nFunc == W_META_STRETCHBLT )
828 if ( bNoSourceBitmap )
834 SAL_INFO(
"emfio",
"\t\t Bitmap type:" << nBitmapType <<
" Width:" << nWidth <<
" Height:" << nHeight <<
" WidthBytes:" << nBytesPerScan <<
" Planes: " <<
static_cast< sal_uInt16
>( nPlanes ) <<
" BitCount: " <<
static_cast< sal_uInt16
>(
nBitCount ) );
837 SAL_WARN(
"emfio",
"\t\t TODO The unsupported Bitmap record. Please fill a bug.");
840 bool bOk = nWidth > 0 && nHeight > 0 && nBytesPerScan > 0
850 bOk = nBytesPerScan >= nWidth *
nBitCount / 8;
854 std::unique_ptr< sal_uInt8[] >
pData;
859 ( nXSrc + nSxe <= nWidth ) &&
860 ( nYSrc + nSye <= nHeight ) )
863 aBitmap.
Crop( aCropRect );
866 maBmpSaveList.emplace_back(aBitmap, aDestRect, nRasterOperation);
871 case W_META_DIBBITBLT:
872 case W_META_DIBSTRETCHBLT:
875 sal_uInt32 nRasterOperation = 0;
876 sal_uInt16 nColorUsage = 0;
877 sal_Int16 nSrcHeight = 0, nSrcWidth = 0, nYSrc = 0, nXSrc = 0;
879 const bool bNoSourceBitmap = ( nFunc !=
W_META_STRETCHDIB ) && ( nRecordSize == ( (
static_cast< sal_uInt32
>( nFunc ) >> 8 ) + 3 ) );
882 SAL_INFO(
"emfio",
"\t\t Raster operation: 0x" << std::hex << nRasterOperation << std::dec <<
", No source bitmap: " << bNoSourceBitmap);
888 if( nFunc == W_META_DIBSTRETCHBLT ||
895 if ( bNoSourceBitmap )
902 if ( !bNoSourceBitmap )
907 sal_uInt32 nHeaderSize(0);
909 if ( nHeaderSize == 0xC )
920 SAL_WARN(
"emfio",
"\tTODO Read DIB failed. Interrupting processing whole image. Please report bug report." );
923 if ( nSrcHeight && nSrcWidth &&
928 aBmp.
Crop( aCropRect );
931 maBmpSaveList.emplace_back(aBmp, aDestRect, nRasterOperation);
936 case W_META_DIBCREATEPATTERNBRUSH:
939 sal_uInt32 nRed(0), nGreen(0), nBlue(0),
nCount(1);
940 sal_uInt16 nStyle(0), nColorUsage(0);
944 SAL_INFO(
"emfio",
"\t\t Style:" << nStyle <<
", ColorUsage: " << nColorUsage );
947 SAL_WARN(
"emfio",
"\tTODO: Pattern brush style is not supported." );
952 SAL_WARN(
"emfio",
"\tTODO Read DIB failed. Interrupting processing whole image. Please report bug report." );
962 nRed += aColor.GetRed();
963 nGreen += aColor.GetGreen();
964 nBlue += aColor.GetBlue();
967 nCount = pBmp->Height() * pBmp->Width();
972 CreateObject(std::make_unique<WinMtfFillStyle>( aColor,
false ));
984 case W_META_CREATEPALETTE:
986 sal_uInt16 nStart = 0;
987 sal_uInt16 nNumberOfEntries = 0;
991 SAL_INFO(
"emfio",
"\t\t Start 0x" << std::hex << nStart << std::dec <<
", Number of entries: " << nNumberOfEntries);
992 sal_uInt32 nPalleteEntry;
993 std::vector< Color > aPaletteColors;
994 for (sal_uInt16
i = 0;
i < nNumberOfEntries; ++
i)
998 SAL_INFO(
"emfio",
"\t\t " <<
i <<
". Palette entry: " << std::setw(10) << std::showbase <<std::hex << nPalleteEntry << std::dec );
999 aPaletteColors.push_back(
Color(
static_cast<sal_uInt8>(nPalleteEntry),
static_cast<sal_uInt8>(nPalleteEntry >> 8),
static_cast<sal_uInt8>(nPalleteEntry >> 16)));
1001 CreateObject(std::make_unique<WinMtfPalette>( aPaletteColors ));
1005 case W_META_CREATEBRUSH:
1007 SAL_WARN(
"emfio",
"TODO: Not implemented. Please fill the bug report" );
1012 case W_META_CREATEPATTERNBRUSH:
1014 SAL_WARN(
"emfio",
"TODO: Not implemented. Please fill the bug report" );
1022 sal_uInt16 nStyle = 0;
1023 sal_uInt16 nWidth = 0;
1024 sal_uInt16 nHeight = 0;
1035 sal_uInt16 nBrushStyle = 0;
1047 sal_Int16 lfEscapement = 0;
1048 sal_Int16 lfOrientation = 0;
1049 sal_Int16 lfWeight = 0;
1065 lfFaceName[nRet] = 0;
1072 rtl_TextEncoding eCharSet;
1074 eCharSet = osl_getThreadTextEncoding();
1076 eCharSet = rtl_getTextEncodingFromWindowsCharset( aLogFont.
lfCharSet );
1077 if ( eCharSet == RTL_TEXTENCODING_DONTKNOW )
1078 eCharSet = osl_getThreadTextEncoding();
1079 if ( eCharSet == RTL_TEXTENCODING_SYMBOL )
1080 eCharSet = RTL_TEXTENCODING_MS_1252;
1081 aLogFont.
alfFaceName = OUString( lfFaceName, strlen(lfFaceName), eCharSet );
1083 CreateObject(std::make_unique<WinMtfFontStyle>( aLogFont ));
1087 case W_META_CREATEBITMAPINDIRECT:
1089 SAL_WARN(
"emfio",
"TODO: W_META_CREATEBITMAPINDIRECT is not implemented. Please fill the bug report" );
1094 case W_META_CREATEBITMAP:
1096 SAL_WARN(
"emfio",
"TODO: W_META_CREATEBITMAP is not implemented. Please fill the bug report" );
1101 case W_META_CREATEREGION:
1103 SAL_WARN(
"emfio",
"TODO: W_META_CREATEREGION is not implemented. Please fill the bug report" );
1108 case W_META_EXCLUDECLIPRECT :
1110 SAL_WARN(
"emfio",
"TODO: Not working correctly. Please fill the bug report" );
1117 sal_uInt32 nROP = 0;
1126 case W_META_SELECTCLIPREGION:
1128 sal_uInt16 nObjIndex = 0;
1130 SAL_WARN(
"emfio",
"TODO: W_META_SELECTCLIPREGION is not implemented. Please fill the bug report" );
1142 sal_uInt64 nMetaRecSize =
static_cast< sal_uInt64
>(
mnRecSize - 2 ) * 2;
1153 sal_uInt16 nMode = 0, nLen = 0;
1158 sal_uInt32 nNewMagic = 0;
1161 if( nNewMagic == 0x2c2a4f4f && nLen >= 14 )
1163 sal_uInt16 nMagic2 = 0;
1165 if( nMagic2 == 0x0a )
1167 sal_uInt32 nCheck = 0, nEsc = 0;
1171 sal_uInt32 nEscLen = nLen - 14;
1174 #ifdef OSL_BIGENDIAN
1175 sal_uInt32 nTmp = OSL_SWAPDWORD( nEsc );
1176 sal_uInt32 nCheckSum = rtl_crc32( 0, &nTmp, 4 );
1178 sal_uInt32 nCheckSum = rtl_crc32( 0, &nEsc, 4 );
1180 std::unique_ptr<sal_Int8[]>
pData;
1182 if ( (
static_cast< sal_uInt64
>( nEscLen ) +
mpInputStream->
Tell() ) > nMetaRecEndPos )
1191 nCheckSum = rtl_crc32( nCheckSum,
pData.get(), nEscLen );
1193 if ( nCheck == nCheckSum )
1203 sal_uInt32 nStringLen, nDXCount;
1208 sal_Int32 nTmpX(0), nTmpY(0);
1215 if ( (
static_cast< sal_uInt64
>( nStringLen ) *
sizeof(
sal_Unicode ) ) < ( nEscLen - aMemoryStream.
Tell() ) )
1219 if ( (
static_cast< sal_uInt64
>( nDXCount ) *
sizeof( sal_Int32 ) ) >= ( nEscLen - aMemoryStream.
Tell() ) )
1223 for (sal_uInt32
i = 0;
i < nDXCount;
i++ )
1230 DrawText( aPt, aString, aDXAry.
empty() ?
nullptr : &aDXAry );
1240 else if ( (nNewMagic ==
static_cast< sal_uInt32
>(0x43464D57)) && (nLen >= 34) && (
static_cast<sal_Int32
>(nLen + 10) <=
static_cast<sal_Int32
>(
mnRecSize * 2) ))
1242 sal_uInt32 nComType = 0,
nVersion = 0, nFlags = 0, nComRecCount = 0,
1243 nCurRecSize = 0, nRemainingSize = 0, nEMFTotalSize = 0;
1244 sal_uInt16 nCheck = 0;
1251 if( nComType == 0x01 &&
nVersion == 0x10000 && nComRecCount )
1259 SAL_WARN(
"emfio",
"emf size claims to be larger than remaining data");
1281 SAL_WARN(
"emfio",
"emf record size claims to be larger than remaining data");
1288 std::vector<sal_Int8>
aBuf(nCurRecSize);
1290 if(
nCount == nCurRecSize )
1302 case W_META_SETRELABS:
1303 case W_META_SETPOLYFILLMODE:
1305 case W_META_SETTEXTCHAREXTRA:
1306 case W_META_SETTEXTJUSTIFICATION:
1307 case W_META_FLOODFILL :
1308 case W_META_FILLREGION:
1309 case W_META_FRAMEREGION:
1310 case W_META_INVERTREGION:
1311 case W_META_PAINTREGION:
1312 case W_META_DRAWTEXT:
1313 case W_META_SETMAPPERFLAGS:
1314 case W_META_SETDIBTODEV:
1315 case W_META_REALIZEPALETTE:
1316 case W_META_ANIMATEPALETTE:
1317 case W_META_SETPALENTRIES:
1318 case W_META_RESIZEPALETTE:
1319 case W_META_EXTFLOODFILL:
1320 case W_META_RESETDC:
1321 case W_META_STARTDOC:
1322 case W_META_STARTPAGE:
1323 case W_META_ENDPAGE:
1324 case W_META_ABORTDOC:
1327 SAL_WARN(
"emfio",
"TODO: WMF record not implemented: " << record_type_name(nFunc));
1333 SAL_WARN(
"emfio",
"Unknown Meta Action: 0x" << std::hex << nFunc << std::dec);
1347 sal_uInt32 nPlaceableMetaKey(0);
1370 aPlaceableBound.
SetLeft( nVal );
1372 aPlaceableBound.
SetTop( nVal );
1407 aPlaceableBound = aExtRect;
1409 SAL_INFO(
"emfio",
"External header size "
1410 " left: " << aPlaceableBound.
Left() <<
" top: " << aPlaceableBound.
Top()
1411 <<
" right: " << aPlaceableBound.
Right() <<
" bottom: " << aPlaceableBound.
Bottom());
1424 const double fMaxWidth =
static_cast<double>(
aMaxWidth);
1425 double fRatio = aPlaceableBound.
GetWidth() / fMaxWidth;
1430 SAL_INFO(
"emfio",
"Placeable bounds "
1431 " left: " << aPlaceableBound.
Left() <<
" top: " << aPlaceableBound.
Top()
1432 <<
" right: " << aPlaceableBound.
Right() <<
" bottom: " << aPlaceableBound.
Bottom());
1441 std::abs( aPlaceableBound.
GetWidth() ), std::abs( aPlaceableBound.
GetHeight() ) );
1446 Size aDevExt( 10000, 10000 );
1447 if( ( std::abs( aWMFSize.
Width() ) > 1 ) && ( std::abs( aWMFSize.
Height() ) > 1 ) )
1450 MapMode aWMFMap( MapUnit::MapInch,
Point(), aFrac, aFrac );
1452 aDevExt =
Size( std::abs( aSize100.
Width() ), std::abs( aSize100.
Height() ) );
1459 sal_uInt32 nMetaKey(0);
1463 if (nMetaKey != 0x00090001)
1465 sal_uInt16 aNextWord(0);
1467 if (nMetaKey != 0x10000 || aNextWord != 0x09)
1485 sal_uInt16 nFunction;
1508 bool bEMFAvailable =
false;
1516 (
mnRecSize == 3 && nFunction == W_META_EOF)
1526 const sal_uInt32 nMaxPossibleRecordSize = nAvailableBytes/2;
1533 if ( !bEMFAvailable )
1537 && ( nFunction != W_META_DIBBITBLT )
1538 && ( nFunction != W_META_DIBSTRETCHBLT )
1553 std::unique_ptr<EmfReader> pEMFReader(std::make_unique<EmfReader>(aStream, aMeta));
1555 bEMFAvailable = pEMFReader->ReadEnhWMF();
1601 bool bBoundsDetermined =
false;
1607 std::optional<Size> aWinExt;
1609 Point aViewportOrg(0,0);
1610 std::optional<Size> aViewportExt;
1612 MappingMode eMapMode = MappingMode::MM_ANISOTROPIC;
1616 sal_uInt16 nFunction;
1628 else if (pStm->
eof() || nRSize < 3)
1634 else if ( nRSize == 3 && nFunction == W_META_EOF )
1653 sal_Int16 nWidth(0), nHeight(0);
1656 aWinExt =
Size(nWidth, nHeight);
1660 case W_META_SETVIEWPORTORG:
1666 case W_META_SETVIEWPORTEXT:
1668 sal_Int16 nWidth(0), nHeight(0);
1671 aViewportExt =
Size(nWidth, nHeight);
1675 case W_META_SETMAPMODE :
1677 sal_Int16 nMapMode(0);
1686 GetWinExtMax(
ReadYX(), aBound, eMapMode );
1687 bBoundsDetermined =
true;
1693 case W_META_EXCLUDECLIPRECT :
1697 bBoundsDetermined =
true;
1705 bBoundsDetermined =
true;
1716 bBoundsDetermined =
true;
1722 bool bRecordOk =
true;
1724 sal_uInt16 nPoints(0);
1727 if (nPoints > pStm->
remainingSize() / (2 *
sizeof(sal_uInt16)))
1733 for(sal_uInt16
i = 0;
i < nPoints;
i++ )
1735 GetWinExtMax(
ReadPoint(), aBound, eMapMode );
1736 bBoundsDetermined =
true;
1740 bRecordOk &= pStm->
good();
1742 SAL_WARN_IF(!bRecordOk,
"emfio",
"polyline record claimed more points than the stream can provide");
1755 bool bRecordOk =
true;
1756 sal_uInt16 nPoly(0), nPoints(0);
1764 for(sal_uInt16
i = 0;
i < nPoly;
i++ )
1777 SAL_WARN_IF(!bRecordOk,
"emfio",
"polypolygon record has more polygons than we can handle");
1779 bRecordOk &= pStm->
good();
1788 if (nPoints > pStm->
remainingSize() / (2 *
sizeof(sal_uInt16)))
1794 for (sal_uInt16
i = 0;
i < nPoints;
i++ )
1796 GetWinExtMax(
ReadPoint(), aBound, eMapMode );
1797 bBoundsDetermined =
true;
1801 SAL_WARN_IF(!bRecordOk,
"emfio",
"polypolygon record claimed more points than the stream can provide");
1803 bRecordOk &= pStm->
good();
1816 bool bRecordOk =
true;
1818 sal_uInt16 nPoints(0);
1820 if (nPoints > pStm->
remainingSize() / (2 *
sizeof(sal_uInt16)))
1826 for (sal_uInt16
i = 0;
i < nPoints; ++
i)
1828 GetWinExtMax(
ReadPoint(), aBound, eMapMode );
1829 bBoundsDetermined =
true;
1833 SAL_WARN_IF(!bRecordOk,
"emfio",
"polyline record claimed more points than the stream can provide");
1835 bRecordOk &= pStm->
good();
1849 GetWinExtMax(
ReadYX(), aBound, eMapMode );
1850 bBoundsDetermined =
true;
1862 GetWinExtMax(
ReadYX(), aBound, eMapMode );
1863 bBoundsDetermined =
true;
1870 sal_uInt16 nLen(0), nOptions;
1876 GetWinExtMax( aPosition, aBound, eMapMode );
1877 bBoundsDetermined =
true;
1882 case W_META_DIBBITBLT:
1883 case W_META_DIBSTRETCHBLT:
1884 case W_META_STRETCHBLT:
1887 sal_uInt32 nRasterOperation;
1888 sal_Int16 nYSrc, nXSrc;
1889 sal_uInt16 nColorUsage;
1895 if( nFunction == W_META_DIBSTRETCHBLT ||
1896 nFunction == W_META_STRETCHBLT ||
1899 sal_Int16 nSrcHeight, nSrcWidth;
1906 const bool bNoSourceBitmap = ( nFunction !=
W_META_STRETCHDIB ) && ( nRSize == ( (
static_cast< sal_uInt32
>( nFunction ) >> 8 ) + 3 ) );
1907 if ( bNoSourceBitmap )
1914 GetWinExtMax( aDestRect, aBound, eMapMode );
1915 bBoundsDetermined =
true;
1926 bBoundsDetermined =
true;
1931 const auto nAvailableBytes = nEnd -
nPos;
1932 const auto nMaxPossibleRecordSize = nAvailableBytes/2;
1933 if (nRSize <= nMaxPossibleRecordSize)
1967 auto nWidth = rPlaceableBound.
GetWidth();
1968 auto nHeight = rPlaceableBound.
GetHeight();
1972 SAL_INFO(
"emfio",
"Window dimension "
1973 " left: " << rPlaceableBound.
Left() <<
" top: " << rPlaceableBound.
Top()
1974 <<
" right: " << rPlaceableBound.
Right() <<
" bottom: " << rPlaceableBound.
Bottom());
1976 else if (aViewportExt)
1979 SAL_INFO(
"emfio",
"Viewport dimension "
1980 " left: " << rPlaceableBound.
Left() <<
" top: " << rPlaceableBound.
Top()
1981 <<
" right: " << rPlaceableBound.
Right() <<
" bottom: " << rPlaceableBound.
Bottom());
1983 else if (bBoundsDetermined)
1985 rPlaceableBound = aBound;
1986 SAL_INFO(
"emfio",
"Determined dimension "
1987 " left: " << rPlaceableBound.
Left() <<
" top: " << rPlaceableBound.
Top()
1988 <<
" right: " << rPlaceableBound.
Right() <<
" bottom: " << rPlaceableBound.
Bottom());
1993 rPlaceableBound.
SetTop( 0 );
1996 SAL_INFO(
"emfio",
"Default dimension "
1997 " left: " << rPlaceableBound.
Left() <<
" top: " << rPlaceableBound.
Top()
1998 <<
" right: " << rPlaceableBound.
Right() <<
" bottom: " << rPlaceableBound.
Bottom());
2003 :
MtfTools(rGDIMetaFile, rStreamWMF)
2004 , mnUnitsPerInch(96)
2006 , mbPlaceable(false)
2011 , mpExternalHeader(pExternalHeader)
static OutputDevice * GetDefaultDevice()
bool Crop(const tools::Rectangle &rRectPixel)
bool Crop(const tools::Rectangle &rRectPixel)
Size GetSizePixel() const
void resize(size_t nSize)
sal_Int32 get(size_t nIndex) const
void set(size_t nIndex, sal_Int32 nValue)
SAL_WARN_UNUSED_RESULT Point LogicToLogic(const Point &rPtSource, const MapMode *pMapModeSource, const MapMode *pMapModeDest) const
constexpr tools::Long Y() const
void setX(tools::Long nX)
void setY(tools::Long nY)
tools::Long AdjustY(tools::Long nVertMove)
tools::Long AdjustX(tools::Long nHorzMove)
constexpr tools::Long X() const
constexpr tools::Long getX() const
constexpr tools::Long getY() const
constexpr tools::Long Height() const
constexpr tools::Long Width() const
virtual sal_uInt64 TellEnd()
SvStream & ReadInt16(sal_Int16 &rInt16)
std::size_t WriteBytes(const void *pData, std::size_t nSize)
SvStream & ReadUInt32(sal_uInt32 &rUInt32)
void SetError(ErrCode nErrorCode)
sal_uInt64 Seek(sal_uInt64 nPos)
SvStream & ReadInt32(sal_Int32 &rInt32)
std::size_t ReadBytes(void *pData, std::size_t nSize)
sal_uInt64 SeekRel(sal_Int64 nPos)
SvStream & ReadUInt16(sal_uInt16 &rUInt16)
sal_uInt64 remainingSize()
SvStream & ReadUChar(unsigned char &rChar)
void applyAlternativeFontScale()
WmfReader(SvStream &rStreamWMF, GDIMetaFile &rGDIMetaFile, const WmfExternal *pExternalHeader)
void ReadRecordParams(sal_uInt32 nRecordSize, sal_uInt16 nFunction)
tools::Rectangle ReadRectangle()
void GetPlaceableBound(tools::Rectangle &rSize, SvStream *pStrm)
sal_uInt16 mnUnitsPerInch
std::optional< std::vector< sal_uInt8 > > mpEMFStream
const WmfExternal * mpExternalHeader
constexpr ::Color COL_WHITE(0xFF, 0xFF, 0xFF)
#define SVSTREAM_FILEFORMAT_ERROR
#define SVSTREAM_GENERALERROR
#define SAL_WARN_IF(condition, area, stream)
#define SAL_WARN(area, stream)
#define SAL_INFO(area, stream)
std::unique_ptr< sal_Int32[]> pData
constexpr sal_Int32 LF_FACESIZE
constexpr sal_Int32 PRIVATE_ESCAPE_UNICODE
constexpr sal_Int32 W_MFCOMMENT
const tools::Long aMaxWidth
constexpr std::enable_if_t< std::is_signed_v< T >, std::make_unsigned_t< T > > make_unsigned(T value)
int sprintf(char(&s)[N], char const *format, T &&... arguments)
constexpr Point convert(const Point &rPoint, o3tl::Length eFrom, o3tl::Length eTo)
BitmapEx CreateFromData(sal_uInt8 const *pData, sal_Int32 nWidth, sal_Int32 nHeight, sal_Int32 nStride, sal_Int8 nBitCount, bool bReversColors, bool bReverseAlpha)
TOOLS_DLLPUBLIC OUString read_uInt16s_ToOUString(SvStream &rStrm, std::size_t nUnits)
#define STREAM_SEEK_TO_BEGIN
sal_uInt8 lfPitchAndFamily
sal_uInt8 lfClipPrecision
#define W_META_SELECTOBJECT
#define W_META_EXTTEXTOUT
#define W_META_SETTEXTALIGN
#define W_META_SETSTRETCHBLTMODE
#define W_META_POLYPOLYGON
#define W_META_CREATEPENINDIRECT
#define W_META_SETWINDOWEXT
#define W_META_SETTEXTCOLOR
#define W_META_SETWINDOWORG
#define W_META_CREATEFONTINDIRECT
#define W_META_DELETEOBJECT
#define W_META_STRETCHDIB
#define W_META_CREATEBRUSHINDIRECT
#define W_META_INTERSECTCLIPRECT