23#include <osl/diagnose.h>
32#include <rtl/bootstrap.hxx>
41#define EMR_POLYBEZIER 2
44#define EMR_POLYBEZIERTO 5
45#define EMR_POLYLINETO 6
46#define EMR_POLYPOLYLINE 7
47#define EMR_POLYPOLYGON 8
48#define EMR_SETWINDOWEXTEX 9
49#define EMR_SETWINDOWORGEX 10
50#define EMR_SETVIEWPORTEXTEX 11
51#define EMR_SETVIEWPORTORGEX 12
52#define EMR_SETBRUSHORGEX 13
54#define EMR_SETPIXELV 15
55#define EMR_SETMAPPERFLAGS 16
56#define EMR_SETMAPMODE 17
57#define EMR_SETBKMODE 18
58#define EMR_SETPOLYFILLMODE 19
60#define EMR_SETSTRETCHBLTMODE 21
61#define EMR_SETTEXTALIGN 22
62#define EMR_SETCOLORADJUSTMENT 23
63#define EMR_SETTEXTCOLOR 24
64#define EMR_SETBKCOLOR 25
65#define EMR_OFFSETCLIPRGN 26
66#define EMR_MOVETOEX 27
67#define EMR_SETMETARGN 28
68#define EMR_EXCLUDECLIPRECT 29
69#define EMR_INTERSECTCLIPRECT 30
70#define EMR_SCALEVIEWPORTEXTEX 31
71#define EMR_SCALEWINDOWEXTEX 32
73#define EMR_RESTOREDC 34
74#define EMR_SETWORLDTRANSFORM 35
75#define EMR_MODIFYWORLDTRANSFORM 36
76#define EMR_SELECTOBJECT 37
77#define EMR_CREATEPEN 38
78#define EMR_CREATEBRUSHINDIRECT 39
79#define EMR_DELETEOBJECT 40
80#define EMR_ANGLEARC 41
82#define EMR_RECTANGLE 43
83#define EMR_ROUNDRECT 44
87#define EMR_SELECTPALETTE 48
88#define EMR_CREATEPALETTE 49
89#define EMR_SETPALETTEENTRIES 50
90#define EMR_RESIZEPALETTE 51
91#define EMR_REALIZEPALETTE 52
92#define EMR_EXTFLOODFILL 53
95#define EMR_POLYDRAW 56
96#define EMR_SETARCDIRECTION 57
97#define EMR_SETMITERLIMIT 58
98#define EMR_BEGINPATH 59
100#define EMR_CLOSEFIGURE 61
101#define EMR_FILLPATH 62
102#define EMR_STROKEANDFILLPATH 63
103#define EMR_STROKEPATH 64
104#define EMR_FLATTENPATH 65
105#define EMR_WIDENPATH 66
106#define EMR_SELECTCLIPPATH 67
107#define EMR_ABORTPATH 68
109#define EMR_COMMENT 70
111#define EMR_COMMENT_EMFPLUS 0x2B464D45
112#define EMR_COMMENT_EMFSPOOL 0x00000000
113#define EMR_COMMENT_PUBLIC 0x43494447
115#define EMR_FILLRGN 71
116#define EMR_FRAMERGN 72
117#define EMR_INVERTRGN 73
118#define EMR_PAINTRGN 74
119#define EMR_EXTSELECTCLIPRGN 75
121#define EMR_STRETCHBLT 77
122#define EMR_MASKBLT 78
124#define EMR_SETDIBITSTODEVICE 80
125#define EMR_STRETCHDIBITS 81
126#define EMR_EXTCREATEFONTINDIRECTW 82
127#define EMR_EXTTEXTOUTA 83
128#define EMR_EXTTEXTOUTW 84
129#define EMR_POLYBEZIER16 85
130#define EMR_POLYGON16 86
131#define EMR_POLYLINE16 87
132#define EMR_POLYBEZIERTO16 88
133#define EMR_POLYLINETO16 89
134#define EMR_POLYPOLYLINE16 90
135#define EMR_POLYPOLYGON16 91
136#define EMR_POLYDRAW16 92
137#define EMR_CREATEMONOBRUSH 93
138#define EMR_CREATEDIBPATTERNBRUSHPT 94
139#define EMR_EXTCREATEPEN 95
140#define EMR_POLYTEXTOUTA 96
141#define EMR_POLYTEXTOUTW 97
144#define EMR_SETICMMODE 98
145#define EMR_CREATECOLORSPACE 99
146#define EMR_SETCOLORSPACE 100
147#define EMR_DELETECOLORSPACE 101
148#define EMR_GLSRECORD 102
149#define EMR_GLSBOUNDEDRECORD 103
150#define EMR_PIXELFORMAT 104
153#define EMR_DRAWESCAPE 105
154#define EMR_EXTESCAPE 106
155#define EMR_STARTDOC 107
156#define EMR_SMALLTEXTOUT 108
157#define EMR_FORCEUFIMAPPING 109
158#define EMR_NAMEDESCAPE 110
159#define EMR_COLORCORRECTPALETTE 111
160#define EMR_SETICMPROFILEA 112
161#define EMR_SETICMPROFILEW 113
162#define EMR_ALPHABLEND 114
163#define EMR_ALPHADIBBLEND 115
164#define EMR_TRANSPARENTBLT 116
165#define EMR_TRANSPARENTDIB 117
166#define EMR_GRADIENTFILL 118
167#define EMR_SETLINKEDUFIS 119
168#define EMR_SETTEXTJUSTIFICATION 120
170#define PDF_SIGNATURE 0x50444620
182 PT_CLOSEFIGURE = 0x01,
189record_type_name(sal_uInt32 nRecType)
319 static char buffer[11];
328 unsigned char aBlendOperation;
329 unsigned char aBlendFlags;
330 unsigned char aSrcConstantAlpha;
331 unsigned char aAlphaFormat;
338 rInStream.
ReadUChar(rBlendFun.aBlendOperation);
339 rInStream.
ReadUChar(rBlendFun.aBlendFlags);
340 rInStream.
ReadUChar(rBlendFun.aSrcConstantAlpha);
341 rInStream.
ReadUChar(rBlendFun.aAlphaFormat);
350 sal_uInt32 nHdSize,
nType, nCountRects, nRgnSize;
356 sal_Int32 nLeft, nTop, nRight, nBottom;
366 SAL_INFO(
"emfio",
"\t\tBounds Left: " << nLeft <<
", top: " << nTop <<
", right: " << nRight <<
", bottom: " << nBottom);
371 if (o3tl::checked_multiply<sal_uInt32>(nCountRects, 16, nSize))
376 for (sal_uInt32
i = 0;
i < nCountRects; ++
i)
382 nLeft += aWinOrg.
X();
383 nRight += aWinOrg.
X();
385 nBottom += aWinOrg.
Y();
387 SAL_INFO(
"emfio",
"\t\t" <<
i <<
" Left: " << nLeft <<
", top: " << nTop <<
", right: " << nRight <<
", bottom: " << nBottom);
405 , mbRecordPath(false)
407 , mbEMFPlusDualMode(false)
422 sal_uInt32 nPublicCommentIdentifier(0);
425 SAL_INFO(
"emfio",
"\t\tEMR_COMMENT_PUBLIC, id: 0x" << std::hex << nCommentId << std::dec);
426 switch (nPublicCommentIdentifier)
430 SAL_INFO(
"emfio",
"\t\t\tEMR_COMMENT_BEGINGROUP");
434 SAL_INFO(
"emfio",
"\t\t\t\tBounding rect");
440 sal_uInt32 nDescChars(0);
444 for (sal_uInt32
i=0;
i < nDescChars;
i++)
452 aDesc = aDesc + OUStringChar(cUniChar);
455 SAL_INFO(
"emfio",
"\t\tDescription: " << aDesc);
460 SAL_INFO(
"emfio",
"\t\t\tEMR_COMMENT_ENDGROUP");
468 SAL_WARN(
"emfio",
"\t\tEMR_COMMENT_WINDOWS_METAFILE not implemented");
472 SAL_WARN(
"emfio",
"\t\tEMR_COMMENT_PUBLIC not implemented, id: 0x" << std::hex << nCommentId << std::dec);
481 sal_uInt32 nCountFormats(0);
483 if (nCountFormats < 1)
489 sal_uInt32 nSignature(0);
503 sal_uInt32 nSizeData(0);
510 sal_uInt32 nOffData(0);
517 std::vector<char> aPdfData(nSizeData);
525 aPdfStream.
WriteBytes(aPdfData.data(), aPdfData.size());
539 const std::shared_ptr<VectorGraphicData> pVectorGraphicData
541 if (!pVectorGraphicData)
546 if (pVectorGraphicData->getType() != VectorGraphicDataType::Pdf)
560 #if OSL_DEBUG_LEVEL > 1
564 SvFileStream file( OUString(
"/tmp/emf-stream.emf" ), StreamMode::WRITE | StreamMode::TRUNC );
577 auto buffer = std::make_unique<char[]>(
length );
585 sal_uInt32 nRemainder =
length;
587 const size_t nRequiredHeaderSize = 12;
588 while (nRemainder >= nRequiredHeaderSize)
590 sal_uInt16
type(0), flags(0);
591 sal_uInt32
size(0), dataSize(0);
594 nRemainder -= nRequiredHeaderSize;
596 SAL_INFO(
"emfio",
"\t\tEMF+ record type: 0x" << std::hex <<
type << std::dec);
603 SAL_INFO(
"emfio",
"\t\tEMF+ lock DC (device context)");
610 if (
type == 0x4001 && flags & 1 )
613 SAL_INFO (
"emfio",
"\t\tEMF+ dual mode detected");
618 sal_uInt32 nRemainingRecordData =
size >= nRequiredHeaderSize ?
619 size-nRequiredHeaderSize : 0;
621 nRemainingRecordData = std::min(nRemainingRecordData, nRemainder);
623 nRemainder -= nRemainingRecordData;
647 sal_uInt32 nPoints(0), nStartIndex(0);
656 return ReadPolygon<T>(nStartIndex, nPoints, nNextPos);
672 SAL_WARN_IF(!bRecordOk,
"emfio",
"polygon record has more polygons than we can handle");
673 if (!bRecordOk || !nPoints)
677 auto nMaxPossiblePoints = nRemainingSize / (
sizeof(T) * 2);
678 auto nPointCount = nPoints - nStartIndex;
679 if (nPointCount > nMaxPossiblePoints)
681 SAL_WARN(
"emfio",
"polygon claims more points than record can provide, truncating");
682 nPoints = nMaxPossiblePoints + nStartIndex;
691 SAL_INFO(
"emfio",
"\t\t\tPoint " <<
i <<
" of " << nPoints - 1 <<
": " << nX <<
", " << nY);
695 SAL_WARN(
"emfio",
"short read on polygon, truncating");
699 aPolygon[
i ] =
Point( nX, nY );
712 SAL_INFO(
"emfio",
"\t\tPolyline: ");
716 sal_uInt32 nNumberOfPolylines = 0;
718 SAL_INFO(
"emfio",
"\t\t\tPolylines: " << nNumberOfPolylines);
724 const auto nEndPos = std::min(nNextPos,
mnEndPos);
731 ( nNumberOfPolylines *
sizeof( sal_uInt16 ) ) <= ( nEndPos -
mpInputStream->
Tell() ))
735 std::unique_ptr< sal_uInt32[] > pnPolylinePointCount(
new sal_uInt32[ nNumberOfPolylines ] );
740 SAL_INFO(
"emfio",
"\t\t\tPoint " <<
i <<
" of " << nNumberOfPolylines <<
": " << nPoints);
741 pnPolylinePointCount[
i ] = nPoints;
747 tools::Polygon aPolygon = ReadPolygon<T>(0, pnPolylinePointCount[
i], nNextPos);
762 sal_uInt32 nPoly(0), nGesPoints(0), nReadPoints(0);
765 SAL_INFO(
"emfio",
"\t\t\tPolygons: " << nPoly);
766 SAL_INFO(
"emfio",
"\t\t\tPoints: " << nGesPoints);
768 const auto nEndPos = std::min(nNextPos,
mnEndPos);
782 std::vector<sal_uInt16> aPoints(nPoly);
785 sal_uInt32 nPoints(0);
788 SAL_INFO(
"emfio",
"\t\t\t\tPolygon " <<
i <<
" points: " << nPoints);
790 aPoints[
i] =
static_cast<sal_uInt16
>(nPoints);
799 const sal_uInt16 nPointCount(aPoints[
i]);
800 std::vector<Point> aPtAry(nPointCount);
805 aPtAry[j] =
Point( nX, nY );
815 OSL_ENSURE(nReadPoints == nGesPoints,
"The number Points processed from EMR_POLYPOLYGON is unequal imported number (!)");
820 sal_uInt32 nStretchBltMode = 0;
821 sal_uInt32 nNextPos(0),
822 nW(0), nH(0), nColor(0),
nIndex(0),
823 nDat32(0), nNom1(0), nDen1(0), nNom2(0), nDen2(0);
824 sal_Int32 nX32(0), nY32(0), nx32(0), ny32(0);
827 bool bHaveDC =
false;
829 OUString aEMFPlusDisable;
830 rtl::Bootstrap::get(
"EMF_PLUS_DISABLE", aEMFPlusDisable);
831 bool bEnableEMFPlus = aEMFPlusDisable.isEmpty();
839 SAL_INFO(
"emfio",
"EMF+ reading is " << (bEnableEMFPlus ?
"enabled" :
"disabled"));
843 sal_uInt32 nRecType(0), nRecSize(0);
860 const sal_uInt32 nMaxPossibleRecSize =
mnEndPos - (nCurPos - 8);
861 if (nRecSize > nMaxPossibleRecSize)
867 nNextPos = nCurPos + (nRecSize - 8);
878 SAL_INFO(
"emfio",
"0x" << std::hex << (nNextPos - nRecSize) <<
"-0x" << nNextPos <<
" " << record_type_name(nRecType) <<
" size: "
879 << std::dec << nRecSize);
890 sal_uInt32 nCommentId;
894 SAL_INFO(
"emfio",
"\t\tbegin " <<
static_cast<char>(nCommentId & 0xff) <<
static_cast<char>((nCommentId & 0xff00) >> 8) <<
static_cast<char>((nCommentId & 0xff0000) >> 16) <<
static_cast<char>((nCommentId & 0xff000000) >> 24) <<
" id: 0x" << std::hex << nCommentId << std::dec);
908 SAL_WARN(
"emfio",
"\t\tEMFSPOOL not implemented, id: 0x" << std::hex << nCommentId << std::dec);
914 SAL_WARN(
"emfio",
"\t\tunknown id: 0x" << std::hex << nCommentId << std::dec);
947 sal_uInt32 nPointsCount(0), nBezierCount(0);
948 std::vector<Point> aPoints;
949 bool wrongFile =
false;
950 std::vector<unsigned char> aPointTypes;
962 aPoints.push_back(
Point(nX, nY));
967 unsigned char nPointType(0);
969 aPointTypes.push_back(nPointType);
971 nPointsCount = std::min(aPoints.size(), aPointTypes.size());
972 for (sal_uInt32
i = 0;
i < nPointsCount;
i++)
975 "\t\t" <<
i <<
"/" << nPointsCount - 1 <<
" PT_MOVETO, "
976 << aPoints[
i].getX() <<
", " << aPoints[
i].getY());
977 SAL_INFO_IF((aPointTypes[
i] != PT_MOVETO) && (aPointTypes[
i] & PT_LINETO),
"emfio",
978 "\t\t" <<
i <<
"/" << nPointsCount - 1 <<
" PT_LINETO, "
979 << aPoints[
i].getX() <<
", " << aPoints[
i].getY());
980 SAL_INFO_IF((aPointTypes[
i] != PT_MOVETO) && (aPointTypes[
i] & PT_CLOSEFIGURE),
"emfio",
981 "\t\t" <<
i <<
"/" << nPointsCount - 1 <<
" PT_CLOSEFIGURE, "
982 << aPoints[
i].getX() <<
", " << aPoints[
i].getY());
983 SAL_INFO_IF((aPointTypes[
i] != PT_MOVETO) && (aPointTypes[
i] & PT_BEZIERTO),
"emfio",
984 "\t\t" <<
i <<
"/" << nPointsCount - 1 <<
" PT_BEZIERTO, "
985 << aPoints[
i].getX() <<
", " << aPoints[
i].getY());
987 if ((aPointTypes[
i] != PT_MOVETO) && (aPointTypes[
i] & PT_BEZIERTO))
989 else if (nBezierCount % 3 == 0)
995 "EMF file error: Number of Bezier points is not set of three.");
999 if (wrongFile)
break;
1000 for (sal_uInt32
i = 0;
i < nPointsCount;
i++)
1002 if (aPointTypes[
i] == PT_MOVETO)
1004 else if (aPointTypes[
i] & PT_LINETO)
1007 if (aPointTypes[
i] & PT_CLOSEFIGURE)
1010 else if (aPointTypes[
i] & PT_BEZIERTO)
1012 if (nPointsCount -
i < 3)
1014 SAL_WARN(
"emfio",
"EMF file error: Not enough Bezier points.");
1019 aPolygon[1] = aPoints[
i++];
1020 aPolygon[2] = aPoints[
i++];
1021 aPolygon[3] = aPoints[
i];
1023 if (aPointTypes[
i] & PT_CLOSEFIGURE)
1036 ReadAndDrawPolyLine<sal_Int32>(nNextPos);
1040 ReadAndDrawPolyPolygon<sal_Int32>(nNextPos);
1045 sal_Int32
w = 0,
h = 0;
1056 SAL_INFO(
"emfio",
"\t\tPoint: (" << nX32 <<
", " << nY32 <<
")");
1064 SAL_INFO(
"emfio",
"\t\tHorizontal scale: " << nNom1 <<
" / " << nDen1);
1065 SAL_INFO(
"emfio",
"\t\tVertical scale: " << nNom2 <<
" / " << nDen2);
1067 if (nDen1 != 0 && nDen2 != 0)
1068 ScaleWinExt(
static_cast<double>(nNom1) / nDen1,
static_cast<double>(nNom2) / nDen2 );
1070 SAL_WARN(
"vcl.emf",
"ignoring bogus divide by zero");
1077 SAL_INFO(
"emfio",
"\t\tPoint: (" << nX32 <<
", " << nY32 <<
")");
1085 SAL_INFO(
"emfio",
"\t\tHorizontal scale: " << nNom1 <<
" / " << nDen1);
1086 SAL_INFO(
"emfio",
"\t\tVertical scale: " << nNom2 <<
" / " << nDen2);
1088 if (nDen1 != 0 && nDen2 != 0)
1089 ScaleDevExt(
static_cast<double>(nNom1) / nDen1,
static_cast<double>(nNom2) / nDen2 );
1091 SAL_WARN(
"vcl.emf",
"ignoring bogus divide by zero");
1097 sal_Int32
w = 0,
h = 0;
1113 SAL_INFO(
"emfio",
"\t\tPoint: (" << nX32 <<
", " << nY32 <<
")");
1120 sal_uInt32 nMapMode(0);
1122 SAL_INFO(
"emfio",
"\t\tMapMode: 0x" << std::hex << nMapMode << std::dec);
1130 SAL_INFO(
"emfio",
"\t\tBkMode: 0x" << std::hex << nDat32 << std::dec);
1141 SAL_INFO(
"emfio",
"\t\tROP2: 0x" << std::hex << nDat32 << std::dec);
1149 SAL_INFO(
"emfio",
"\t\tStretchBltMode: 0x" << std::hex << nDat32 << std::dec);
1156 SAL_INFO(
"emfio",
"\t\tTextAlign: 0x" << std::hex << nDat32 << std::dec);
1183 SAL_INFO(
"emfio",
"\t\tPoint: (" << nX32 <<
", " << nY32 <<
")");
1191 SAL_INFO(
"emfio",
"\t\tPoint: (" << nX32 <<
", " << nY32 <<
")");
1200 SAL_INFO(
"emfio",
"\t\tPoint: (" << nX32 <<
", " << nY32 <<
")");
1201 SAL_INFO(
"emfio",
"\t\tPoint: (" << nx32 <<
", " << ny32 <<
")");
1213 sal_Int32 nSavedDC(0);
1215 SAL_INFO(
"emfio",
"\t\t SavedDC Index: " << nSavedDC );
1233 sal_uInt32 nMode(0);
1253 sal_uInt32 nPenStyle(0);
1254 sal_Int32 nPenWidth(0), nIgnored;
1256 SAL_INFO(
"emfio",
"\t\tIndex: " <<
nIndex <<
" Style: 0x" << std::hex
1257 << nPenStyle << std::dec
1258 <<
" PenWidth: " << nPenWidth);
1273 sal_uInt32 offBmi, cbBmi, offBits, cbBits, nPenStyle, nWidth, nBrushStyle, elpNumEntries;
1284 SAL_INFO(
"emfio",
"\t\tStyle: 0x" << std::hex << nPenStyle << std::dec);
1289 SAL_INFO(
"emfio",
"\t\tWidth: " << nWidth);
1320 SAL_INFO(
"emfio",
"\t\t Rectangle, left: " << nX32 <<
", top: " << nY32 <<
", right: " << nx32 <<
", bottom: " << ny32);
1322 sal_Int32
w(0),
h(0);
1324 SAL_WARN(
"emfio",
"broken ellipse");
1329 Point aCenter( nX32 + dw, nY32 + dh );
1339 SAL_INFO(
"emfio",
"\t\t Rectangle, left: " << nX32 <<
", top: " << nY32 <<
", right: " << nx32 <<
", bottom: " << ny32);
1343 Point(nX32, ny32) };
1345 aPoly.
Optimize( PolyOptimizeFlags::CLOSE );
1362 sal_Int32 nStartX, nStartY, nEndX, nEndY;
1368 SAL_INFO(
"emfio",
"\t\t Bounds: " << nX32 <<
":" << nY32 <<
", " << nx32 <<
":" << ny32 <<
", Start: " << nStartX <<
":" << nStartY <<
", End: " << nEndX <<
":" << nEndY );
1381 sal_Int32 nStartX, nStartY, nEndX, nEndY;
1432 sal_Int32 nClippingMode(0);
1440 sal_uInt32 nRemainingRecSize = nRecSize - 8;
1441 if (nRemainingRecSize < 8)
1445 sal_Int32 nClippingMode(0), cbRgnData(0);
1448 nRemainingRecSize -= 8;
1470 sal_Int32 xDest(0), yDest(0), cxDest(0), cyDest(0);
1472 BLENDFUNCTION aFunc;
1473 sal_Int32 xSrc(0), ySrc(0), cxSrc(0), cySrc(0);
1475 sal_uInt32 BkColorSrc(0), iUsageSrc(0), offBmiSrc(0);
1476 sal_uInt32 cbBmiSrc(0), offBitsSrc(0), cbBitsSrc(0);
1499 const sal_uInt32 nSourceSize = cbBmiSrc + cbBitsSrc + 14;
1501 sal_uInt32 nDeltaToDIB5HeaderSize(0);
1502 const bool bReadAlpha(0x01 == aFunc.aAlphaFormat);
1503 if (bSafeRead && bReadAlpha)
1509 if (cbBmiSrc > nHeaderSize)
1512 nDeltaToDIB5HeaderSize = nHeaderSize - cbBmiSrc;
1516 const sal_uInt32 nTargetSize(cbBmiSrc + nDeltaToDIB5HeaderSize + cbBitsSrc + 14);
1517 char* pBuf =
new char[ nTargetSize ];
1518 SvMemoryStream aTmp( pBuf, nTargetSize, StreamMode::READ | StreamMode::WRITE );
1528 .
WriteUInt32( cbBmiSrc + nDeltaToDIB5HeaderSize + 14 );
1532 char* pWritePos = pBuf + 14;
1534 if (nRead != cbBmiSrc)
1537 memset(pWritePos + nRead, 0, cbBmiSrc - nRead);
1545 memset(pBuf + cbBmiSrc + 14, 0, nDeltaToDIB5HeaderSize);
1550 pWritePos = pBuf + 14 + nDeltaToDIB5HeaderSize + cbBmiSrc;
1552 if (nRead != cbBitsSrc)
1555 memset(pWritePos + nRead, 0, cbBitsSrc - nRead);
1570 aBitmapEx =
BitmapEx(aBitmap, aAlpha);
1577 if(
ReadDIB(aBitmap, aTmp,
true))
1579 if(0xff != aFunc.aSrcConstantAlpha)
1597 if (cxSrc > 0 && cySrc > 0 && xSrc >= 0 && ySrc >= 0)
1605 aBitmapEx.
Crop( aCropRect );
1610 static bool bDoSaveForVisualControl(
false);
1612 if(bDoSaveForVisualControl)
1615 static const OUString sDumpPath(OUString::createFromAscii(std::getenv(
"VCL_DUMP_BMP_PATH")));
1616 if(!sDumpPath.isEmpty())
1619 StreamMode::WRITE | StreamMode::TRUNC);
1621 aPNGWriter.
write(aBitmapEx);
1635 sal_Int32 xDest, yDest, cxDest, cyDest, xSrc, ySrc, cxSrc, cySrc;
1636 sal_uInt32 dwRop, iUsageSrc, offBmiSrc, cbBmiSrc, offBitsSrc, cbBitsSrc;
1659 sal_uInt32 nSize = cbBmiSrc + cbBitsSrc + 14;
1662 char* pBuf =
new char[ nSize ];
1663 SvMemoryStream aTmp( pBuf, nSize, StreamMode::READ | StreamMode::WRITE );
1673 char* pWritePos = pBuf + 14;
1675 if (nRead != cbBmiSrc)
1678 memset(pWritePos + nRead, 0, cbBmiSrc - nRead);
1682 pWritePos = pBuf + 14 + cbBmiSrc;
1684 if (nRead != cbBitsSrc)
1687 memset(pWritePos + nRead, 0, cbBitsSrc - nRead);
1694 if ( (cxSrc > 0) && (cySrc > 0) &&
1695 (xSrc >= 0) && (ySrc >= 0) &&
1702 aBitmap.
Crop( aCropRect );
1713 sal_Int32 xDest, yDest, xSrc, ySrc, cxSrc, cySrc, cxDest, cyDest;
1714 sal_uInt32 offBmiSrc, cbBmiSrc, offBitsSrc, cbBitsSrc, iUsageSrc, dwRop;
1745 sal_uInt32 nSize = cbBmiSrc + cbBitsSrc + 14;
1748 char* pBuf =
new char[ nSize ];
1749 SvMemoryStream aTmp( pBuf, nSize, StreamMode::READ | StreamMode::WRITE );
1759 char* pWritePos = pBuf + 14;
1761 if (nRead != cbBmiSrc)
1764 memset(pWritePos + nRead, 0, cbBmiSrc - nRead);
1768 pWritePos = pBuf + 14 + cbBmiSrc;
1770 if (nRead != cbBitsSrc)
1773 memset(pWritePos + nRead, 0, cbBitsSrc - nRead);
1783 if ( (cxSrc > 0) && (cySrc > 0) &&
1784 (xSrc >= 0) && (ySrc >= 0) &&
1785 (xSrc <= nWidthDiff) && (ySrc <= nHeightDiff) )
1788 aBitmap.
Crop( aCropRect );
1820 sal_uInt16 nChar(0);
1822 lfFaceName[
i] = nChar;
1853 sal_Int32 nLeft, nTop, nRight, nBottom;
1854 sal_uInt32 nGfxMode;
1855 float nXScale, nYScale;
1856 sal_uInt32 ncStrings( 1 );
1857 sal_Int32 ptlReferenceX, ptlReferenceY;
1858 sal_uInt32 nLen, nOffString, nOptions, offDx;
1859 sal_Int32 nLeftRect, nTopRect, nRightRect, nBottomRect;
1865 SAL_INFO(
"emfio",
"\t\tBounds: " << nLeft <<
", " << nTop <<
", " << nRight <<
", " << nBottom);
1866 SAL_INFO(
"emfio",
"\t\tiGraphicsMode: 0x" << std::hex << nGfxMode << std::dec);
1867 SAL_INFO(
"emfio",
"\t\t Scale: " << nXScale <<
" x " << nYScale);
1871 SAL_INFO(
"emfio",
"\t\t Number of Text objects: " << ncStrings);
1872 if ( ncStrings == 0 )
1876 SAL_INFO(
"emfio",
"\t\tReference: (" << ptlReferenceX <<
", " << ptlReferenceY <<
")");
1885 const tools::Rectangle aRect( nLeftRect, nTopRect, nRightRect, nBottomRect );
1899 Point aPos( ptlReferenceX, ptlReferenceY );
1900 bool bOffStringSane = nOffString <=
mnEndPos - nCurPos;
1901 if ( bOffStringSane )
1909 std::vector<char> pBuf( nLen );
1911 aText = OUString(pBuf.data(), nLen,
GetCharSet());
1922 SAL_INFO(
"emfio",
"\t\tText: " << aText);
1923 SAL_INFO(
"emfio",
"\t\tDxBuffer:");
1926 std::unique_ptr<tools::Long[]> pDYAry;
1929 sal_Int32 nBytesEach;
1942 bool bOverflow = o3tl::checked_multiply<sal_Int32>(nLen, nBytesEach, nDxSize);
1943 if (!bOverflow && offDx && ((nCurPos + offDx + nDxSize) <= nNextPos ) && nNextPos <=
mnEndPos)
1946 aDXAry.
resize(aText.getLength());
1949 pDYAry.reset(
new tools::Long[aText.getLength()] );
1952 for (sal_Int32
i = 0;
i < aText.getLength(); ++
i)
1954 sal_Int32 nDxCount = 1;
1955 if (
static_cast<sal_uInt32
>( aText.getLength() ) != nLen )
1959 if (aTmp.getLength() > 1)
1961 nDxCount = aTmp.getLength();
1973 sal_Int32 nDxTmp = 0;
1978 sal_Int32 nDyTmp = 0;
1980 pDYAry[
i] += nDyTmp;
1984 SAL_INFO(
"emfio",
"\t\t\tSpacing " <<
i <<
": " << aDXAry[
i]);
2022 ReadAndDrawPolyLine<sal_Int16>(nNextPos);
2026 ReadAndDrawPolyPolygon<sal_Int16>(nNextPos);
2031 sal_uInt32 nRemainingRecSize = nRecSize - 8;
2032 if (nRemainingRecSize < 24)
2036 sal_uInt32 nRgnDataSize;
2040 nRemainingRecSize -= 24;
2056 sal_uInt32 nRemainingRecSize = nRecSize - 8;
2057 if (nRemainingRecSize < 20)
2061 sal_uInt32 nRgnDataSize;
2065 nRemainingRecSize -= 20;
2085 sal_uInt32 usage, offBmi, cbBmi, offBits, cbBits;
2097 sal_uInt32 nSize = cbBmi + cbBits + 14;
2100 char* pBuf =
new char[ nSize ];
2102 SvMemoryStream aTmp( pBuf, nSize, StreamMode::READ | StreamMode::WRITE );
2112 char* pWritePos = pBuf + 14;
2117 memset(pWritePos + nRead, 0, cbBmi - nRead);
2121 pWritePos = pBuf + 14 + cbBmi;
2123 if (nRead != cbBits)
2126 memset(pWritePos + nRead, 0, cbBits - nRead);
2184 SAL_WARN(
"emfio",
"TODO: EMF record not implemented: " << record_type_name(nRecType));
2192 default :
SAL_INFO(
"emfio",
"Unknown Meta Action");
break;
2214 sal_uInt32
nType(0), nHeaderSize(0);
2216 SAL_INFO (
"emfio",
"0x0-0x" << std::hex << nHeaderSize <<
" " << record_type_name(
nType) <<
" size: " << std::dec << nHeaderSize);
2217 if (
nType != 0x00000001)
2220 SAL_WARN(
"emfio",
"EMF header type is not set to 0x00000001 - possibly corrupted file?");
2227 SAL_INFO(
"emfio",
"\tBounding rectangle");
2231 SAL_INFO(
"emfio",
"\tPicture frame");
2234 sal_uInt32 nSignature(0);
2236 SAL_INFO(
"emfio",
"\tSignature: 0x" << std::hex << nSignature << std::dec);
2240 if (nSignature != 0x464d4520)
2242 SAL_WARN(
"emfio",
"EMF\t\tSignature is not 0x464d4520 (\"FME\") - possibly corrupted file?");
2252 SAL_WARN(
"emfio",
"EMF\t\tThis really should be 0x00010000, though not absolutely essential...");
2264 SAL_WARN(
"emfio",
"EMF\t\tEMF Header object records number of bytes as " <<
mnEndPos
2265 <<
", however the file size is actually " << nActualFileSize
2266 <<
" bytes. Possible file corruption?");
2275 sal_uInt16 nHandlesCount;
2277 SAL_INFO(
"emfio",
"\tGraphics: " << nHandlesCount);
2283 sal_uInt16 nReserved(0);
2285 SAL_INFO(
"emfio",
"\tReserved: 0x" << std::hex << nReserved << std::dec);
2287 if ( nReserved != 0x0000 )
2289 SAL_WARN(
"emfio",
"EMF\t\tEMF Header object's reserved field is NOT 0x0000... possible "
2300 sal_uInt32 nPalEntries(0);
2302 SAL_INFO(
"emfio",
"\tPalette entries: " << nPalEntries);
2303 sal_Int32 nPixX(0), nPixY(0), nMillX(0), nMillY(0);
2306 SAL_INFO(
"emfio",
"\tRef (pixels): " << nPixX <<
", " << nPixY);
2309 SAL_INFO(
"emfio",
"\tRef (mm): " << nMillX <<
", " << nMillY);
2321 sal_Int32 nLeft(0), nTop(0), nRight(0), nBottom(0);
2327 SAL_INFO(
"emfio",
"\t\tLeft: " << nLeft <<
", top: " << nTop <<
", right: " << nRight <<
", bottom: " << nBottom);
2328 if (nLeft > nRight || nTop > nBottom)
2330 SAL_WARN(
"emfio",
"broken rectangle");
2340 Point aBR(o3tl::saturating_add<sal_Int32>(x2, -1), o3tl::saturating_add<sal_Int32>(y2, -1));
bool Crop(const tools::Rectangle &rRectPixel)
const Size & GetSizePixel() const
bool Crop(const tools::Rectangle &rRectPixel)
Size GetSizePixel() const
BitmapEx GetBitmapEx(const GraphicConversionParameters &rParameters=GraphicConversionParameters()) const
const std::shared_ptr< VectorGraphicData > & getVectorGraphicData() const
void resize(size_t nSize)
sal_Int32 get(size_t nIndex) const
void set(size_t nIndex, sal_Int32 nValue)
constexpr tools::Long Y() const
constexpr tools::Long X() const
constexpr tools::Long Height() const
constexpr tools::Long Width() const
void ObjectOwnsMemory(bool bOwn)
SvStream & ReadInt16(sal_Int16 &rInt16)
std::size_t WriteBytes(const void *pData, std::size_t nSize)
SvStream & WriteUChar(unsigned char nChar)
SvStream & WriteUInt16(sal_uInt16 nUInt16)
SvStream & ReadFloat(float &rFloat)
SvStream & WriteUInt32(sal_uInt32 nUInt32)
SvStream & ReadUInt32(sal_uInt32 &rUInt32)
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)
SvStream & WriteStream(SvStream &rStream)
void append(const B2DPolygon &rPolygon, sal_uInt32 nCount=1)
basegfx::B2DTuple maSizeHint
tools::Polygon ReadPolygonWithSkip(const bool skipFirst, sal_uInt32 nNextPos)
Reads polygons from the stream.
void ReadAndDrawPolyLine(sal_uInt32 nNextPos)
Reads a polyline from the WMF file and draws it The <class T> parameter refers to the type of the poi...
bool mbReadOtherGraphicFormat
Another format is read already, can ignore actual EMF data.
tools::Rectangle ReadRectangle()
EmfReader(SvStream &rStreamWMF, GDIMetaFile &rGDIMetaFile)
void ReadEMFPlusComment(sal_uInt32 length, bool &bHaveDC)
void ReadMultiformatsComment()
Parses EMR_COMMENT_MULTIFORMATS.
tools::Polygon ReadPolygon(sal_uInt32 nStartIndex, sal_uInt32 nPoints, sal_uInt32 nNextPos)
Reads polygons from the stream.
void ReadGDIComment(sal_uInt32 nCommentId)
void ReadAndDrawPolyPolygon(sal_uInt32 nNextPos)
Reads a poly polygon from the WMF file and draws it.
void applyAlternativeFontScale()
bool write(const BitmapEx &rBitmap)
#define EMR_COMMENT_EMFPLUS
#define EMR_INTERSECTCLIPRECT
#define EMR_SELECTCLIPPATH
#define EMR_SETWINDOWEXTEX
#define EMR_SETVIEWPORTEXTEX
#define EMR_CREATEPALETTE
#define EMR_EXTSELECTCLIPRGN
#define EMR_SETICMPROFILEA
#define EMR_SETMAPPERFLAGS
#define EMR_SETMITERLIMIT
#define EMR_SETCOLORADJUSTMENT
#define EMR_STROKEANDFILLPATH
#define EMR_COMMENT_PUBLIC
#define EMR_EXCLUDECLIPRECT
#define EMR_CREATEMONOBRUSH
#define EMR_COMMENT_EMFSPOOL
#define EMR_SELECTPALETTE
#define EMR_GLSBOUNDEDRECORD
#define EMR_STRETCHDIBITS
#define EMR_SETICMPROFILEW
#define EMR_SETLINKEDUFIS
#define EMR_POLYPOLYGON16
#define EMR_SETARCDIRECTION
#define EMR_SETSTRETCHBLTMODE
#define EMR_SETPALETTEENTRIES
#define EMR_ALPHADIBBLEND
#define EMR_TRANSPARENTDIB
#define EMR_OFFSETCLIPRGN
#define EMR_REALIZEPALETTE
#define EMR_SETCOLORSPACE
#define EMR_SETPOLYFILLMODE
#define EMR_SETWINDOWORGEX
#define EMR_EXTCREATEFONTINDIRECTW
#define EMR_SETBRUSHORGEX
constexpr sal_Int32 ARCDIRECTION_CLOCKWISE
#define EMR_RESIZEPALETTE
#define EMR_POLYBEZIERTO16
#define EMR_CREATEDIBPATTERNBRUSHPT
#define EMR_SETTEXTJUSTIFICATION
#define EMR_CREATECOLORSPACE
#define EMR_COLORCORRECTPALETTE
#define EMR_SETVIEWPORTORGEX
#define EMR_CREATEBRUSHINDIRECT
#define EMR_POLYPOLYLINE16
#define EMR_MODIFYWORLDTRANSFORM
#define EMR_TRANSPARENTBLT
#define EMR_SCALEWINDOWEXTEX
#define EMR_SETWORLDTRANSFORM
#define EMR_SCALEVIEWPORTEXTEX
#define EMR_SETDIBITSTODEVICE
#define EMR_DELETECOLORSPACE
#define EMR_FORCEUFIMAPPING
#define SAL_INFO_IF(condition, area, stream)
#define SAL_WARN_IF(condition, area, stream)
#define SAL_WARN(area, stream)
#define SAL_INFO(area, stream)
B2DPolygon createPolygonFromRect(const B2DRectangle &rRect, double fRadiusX, double fRadiusY)
B2DPolyPolygon stripNeutralPolygons(const B2DPolyPolygon &rCandidate)
B2DPolyPolygon solveCrossovers(const B2DPolyPolygon &rCandidate, size_t *pPointLimit=nullptr)
B2DPolyPolygon stripDispensablePolygons(const B2DPolyPolygon &rCandidate, bool bKeepAboveZero=false)
const sal_uInt32 EMR_COMMENT_WINDOWS_METAFILE
static SvStream & operator>>(SvStream &rStream, sal_Int16 &n)
constexpr sal_uInt32 ENHMETA_STOCK_OBJECT
constexpr sal_Int32 LF_FACESIZE
const sal_uInt32 EMR_COMMENT_ENDGROUP
const sal_uInt32 EMR_COMMENT_MULTIFORMATS
constexpr sal_Int32 RDH_RECTANGLES
static SvStream & operator>>(SvStream &rStream, sal_Int32 &n)
const sal_uInt32 EMR_COMMENT_BEGINGROUP
std::enable_if< std::is_signed< T >::value, bool >::type checked_add(T a, T b, T &result)
int sprintf(char(&s)[N], char const *format, T &&... arguments)
constexpr T saturating_add(T a, T b)
std::enable_if< std::is_signed< T >::value, bool >::type checked_sub(T a, T b, T &result)
bool ImportPDF(SvStream &rStream, Graphic &rGraphic)
TOOLS_DLLPUBLIC OUString read_uInt16s_ToOUString(SvStream &rStrm, std::size_t nUnits)
TOOLS_DLLPUBLIC bool checkSeek(SvStream &rSt, sal_uInt64 nOffset)
sal_uInt8 lfPitchAndFamily
sal_uInt8 lfClipPrecision