diff options
Diffstat (limited to 'emfio/source/reader/emfreader.cxx')
-rw-r--r-- | emfio/source/reader/emfreader.cxx | 400 |
1 files changed, 190 insertions, 210 deletions
diff --git a/emfio/source/reader/emfreader.cxx b/emfio/source/reader/emfreader.cxx index a75c0a49e57f..a5bceb5532fe 100644 --- a/emfio/source/reader/emfreader.cxx +++ b/emfio/source/reader/emfreader.cxx @@ -23,15 +23,16 @@ #include <osl/diagnose.h> #include <vcl/dibtools.hxx> #include <o3tl/safeint.hxx> +#include <o3tl/sprintf.hxx> #include <tools/stream.hxx> #include <memory> -#include <unotools/configmgr.hxx> +#include <comphelper/configuration.hxx> #include <vcl/graph.hxx> #include <vcl/pdfread.hxx> #include <rtl/bootstrap.hxx> #ifdef DBG_UTIL -#include <vcl/pngwrite.hxx> +#include <vcl/filter/PngImageWriter.hxx> #endif // GDI-Array @@ -168,9 +169,22 @@ #define PDF_SIGNATURE 0x50444620 // "PDF " +/* [MS-EMF] - v20210625 - page 28 */ +constexpr sal_Int32 ARCDIRECTION_CLOCKWISE = 0x00000002; + namespace { +/* [MS-EMF] - v20210625 - page 41 */ +/* 2.1.26 Point Enumeration */ +enum EMFPointTypes +{ + PT_CLOSEFIGURE = 0x01, + PT_LINETO = 0x02, + PT_BEZIERTO = 0x04, + PT_MOVETO = 0x06 +}; + const char * record_type_name(sal_uInt32 nRecType) { @@ -303,7 +317,7 @@ record_type_name(sal_uInt32 nRecType) // Yes, return a pointer to a static buffer. This is a very // local debugging output function, so no big deal. static char buffer[11]; - sprintf(buffer, "0x%08" SAL_PRIxUINT32, nRecType); + o3tl::sprintf(buffer, "0x%08" SAL_PRIxUINT32, nRecType); return buffer; } #endif @@ -328,7 +342,7 @@ SvStream& operator>>(SvStream& rInStream, BLENDFUNCTION& rBlendFun) return rInStream; } -bool ImplReadRegion( basegfx::B2DPolyPolygon& rPolyPoly, SvStream& rStream, sal_uInt32 nLen ) +bool ImplReadRegion( basegfx::B2DPolyPolygon& rPolyPoly, SvStream& rStream, sal_uInt32 nLen, Point aWinOrg ) { if (nLen < 32) // 32 bytes - Size of RegionDataHeader return false; @@ -346,7 +360,7 @@ bool ImplReadRegion( basegfx::B2DPolyPolygon& rPolyPoly, SvStream& rStream, sal_ rStream.ReadInt32(nRight); rStream.ReadInt32(nBottom); - if (!rStream.good() || nCountRects == 0 || nType != RDH_RECTANGLES) + if (!rStream.good() || nCountRects == 0 || nType != emfio::RDH_RECTANGLES) return false; SAL_INFO("emfio", "\t\tBounds Left: " << nLeft << ", top: " << nTop << ", right: " << nRight << ", bottom: " << nBottom); @@ -365,10 +379,14 @@ bool ImplReadRegion( basegfx::B2DPolyPolygon& rPolyPoly, SvStream& rStream, sal_ rStream.ReadInt32(nTop); rStream.ReadInt32(nRight); rStream.ReadInt32(nBottom); + nLeft += aWinOrg.X(); + nRight += aWinOrg.X(); + nTop += aWinOrg.Y(); + nBottom += aWinOrg.Y(); rPolyPoly.append( basegfx::utils::createPolygonFromRect( ::basegfx::B2DRectangle( nLeft, nTop, nRight, nBottom ) ) ); SAL_INFO("emfio", "\t\t" << i << " Left: " << nLeft << ", top: " << nTop << ", right: " << nRight << ", bottom: " << nBottom); } - if (!utl::ConfigManager::IsFuzzing()) + if (!comphelper::IsFuzzing()) { rPolyPoly = basegfx::utils::solveCrossovers(rPolyPoly); rPolyPoly = basegfx::utils::stripNeutralPolygons(rPolyPoly); @@ -727,7 +745,7 @@ namespace emfio for ( sal_uInt32 i = 0; ( i < nNumberOfPolylines ) && mpInputStream->good(); i++ ) { tools::Polygon aPolygon = ReadPolygon<T>(0, pnPolylinePointCount[i], nNextPos); - DrawPolyLine(aPolygon, false, mbRecordPath); + DrawPolyLine(std::move(aPolygon), false, mbRecordPath); } } @@ -924,6 +942,92 @@ namespace emfio DrawPolyLine(ReadPolygonWithSkip<sal_Int32>(true, nNextPos), true, mbRecordPath); break; + case EMR_POLYDRAW: + { + sal_uInt32 nPointsCount(0), nBezierCount(0); + std::vector<Point> aPoints; + bool wrongFile = false; + std::vector<unsigned char> aPointTypes; + mpInputStream->ReadInt32(nX32) + .ReadInt32(nY32) + .ReadInt32(nx32) + .ReadInt32(ny32) + .ReadUInt32(nPointsCount); + + aPoints.reserve(std::min<size_t>(nPointsCount, mpInputStream->remainingSize() / (sizeof(sal_Int32) * 2))); + for (sal_uInt32 i = 0; i < nPointsCount && mpInputStream->good(); i++) + { + sal_Int32 nX, nY; + *mpInputStream >> nX >> nY; + aPoints.emplace_back(nX, nY); + } + aPointTypes.reserve(std::min<size_t>(nPointsCount, mpInputStream->remainingSize())); + for (sal_uInt32 i = 0; i < nPointsCount && mpInputStream->good(); i++) + { + unsigned char nPointType(0); + mpInputStream->ReadUChar(nPointType); + aPointTypes.push_back(nPointType); + } + nPointsCount = std::min(aPoints.size(), aPointTypes.size()); + for (sal_uInt32 i = 0; i < nPointsCount; i++) + { + SAL_INFO_IF(aPointTypes[i] == PT_MOVETO, "emfio", + "\t\t" << i << "/" << nPointsCount - 1 << " PT_MOVETO, " + << aPoints[i].getX() << ", " << aPoints[i].getY()); + SAL_INFO_IF((aPointTypes[i] != PT_MOVETO) && (aPointTypes[i] & PT_LINETO), "emfio", + "\t\t" << i << "/" << nPointsCount - 1 << " PT_LINETO, " + << aPoints[i].getX() << ", " << aPoints[i].getY()); + SAL_INFO_IF((aPointTypes[i] != PT_MOVETO) && (aPointTypes[i] & PT_CLOSEFIGURE), "emfio", + "\t\t" << i << "/" << nPointsCount - 1 << " PT_CLOSEFIGURE, " + << aPoints[i].getX() << ", " << aPoints[i].getY()); + SAL_INFO_IF((aPointTypes[i] != PT_MOVETO) && (aPointTypes[i] & PT_BEZIERTO), "emfio", + "\t\t" << i << "/" << nPointsCount - 1 << " PT_BEZIERTO, " + << aPoints[i].getX() << ", " << aPoints[i].getY()); + + if ((aPointTypes[i] != PT_MOVETO) && (aPointTypes[i] & PT_BEZIERTO)) + nBezierCount++; + else if (nBezierCount % 3 == 0) + nBezierCount = 0; + else + { + SAL_WARN( + "emfio", + "EMF file error: Number of Bezier points is not set of three."); + wrongFile = true; + } + } + if (wrongFile) break; + for (sal_uInt32 i = 0; i < nPointsCount; i++) + { + if (aPointTypes[i] == PT_MOVETO) + MoveTo(aPoints[i], true); + else if (aPointTypes[i] & PT_LINETO) + { + LineTo(aPoints[i], true); + if (aPointTypes[i] & PT_CLOSEFIGURE) + ClosePath(); + } + else if (aPointTypes[i] & PT_BEZIERTO) + { + if (nPointsCount - i < 3) + { + SAL_WARN("emfio", "EMF file error: Not enough Bezier points."); + break; + } + tools::Polygon aPolygon(4); + aPolygon[0] = maActPos; + aPolygon[1] = aPoints[i++]; + aPolygon[2] = aPoints[i++]; + aPolygon[3] = aPoints[i]; + DrawPolyBezier(std::move(aPolygon), true, true); + if (aPointTypes[i] & PT_CLOSEFIGURE) + ClosePath(); + } + } + StrokeAndFillPath(true, false); + } + break; + case EMR_POLYLINE : DrawPolyLine(ReadPolygonWithSkip<sal_Int32>(false, nNextPos), false, mbRecordPath); break; @@ -1016,7 +1120,7 @@ namespace emfio sal_uInt32 nMapMode(0); mpInputStream->ReadUInt32( nMapMode ); SAL_INFO("emfio", "\t\tMapMode: 0x" << std::hex << nMapMode << std::dec); - SetMapMode( nMapMode ); + SetMapMode( static_cast<MappingMode>(nMapMode) ); } break; @@ -1024,7 +1128,7 @@ namespace emfio { mpInputStream->ReadUInt32( nDat32 ); SAL_INFO("emfio", "\t\tBkMode: 0x" << std::hex << nDat32 << std::dec); - SetBkMode( static_cast<BkMode>(nDat32) ); + SetBkMode( static_cast<BackgroundMode>(nDat32) ); } break; @@ -1060,6 +1164,13 @@ namespace emfio } break; + case EMR_SETARCDIRECTION: + { + mpInputStream->ReadUInt32(nIndex); + SetArcDirection(nIndex == ARCDIRECTION_CLOCKWISE); + } + break; + case EMR_SETBKCOLOR : { SetBkColor( ReadColor() ); @@ -1123,7 +1234,7 @@ namespace emfio XForm aTempXForm; *mpInputStream >> aTempXForm; mpInputStream->ReadUInt32( nMode ); - ModifyWorldTransform( aTempXForm, nMode ); + ModifyWorldTransform( aTempXForm, static_cast<ModifyWorldTransformMode>(nMode) ); } break; @@ -1134,186 +1245,49 @@ namespace emfio } break; - case EMR_CREATEPEN : + case EMR_CREATEPEN: { - mpInputStream->ReadUInt32( nIndex ); - if ( ( nIndex & ENHMETA_STOCK_OBJECT ) == 0 ) + mpInputStream->ReadUInt32(nIndex); + if ((nIndex & ENHMETA_STOCK_OBJECT) == 0) { - LineInfo aLineInfo; - sal_uInt32 nStyle(0); + sal_uInt32 nPenStyle(0); sal_Int32 nPenWidth(0), nIgnored; - - mpInputStream->ReadUInt32( nStyle ).ReadInt32( nPenWidth ).ReadInt32( nIgnored ); - - SAL_INFO("emfio", "\t\tIndex: " << nIndex << " Style: 0x" << std::hex << nStyle << std::dec << " PenWidth: " << nPenWidth); - // According to documentation: nStyle = PS_COSMETIC = 0x0 - line with a width of one logical unit and a style that is a solid color - // tdf#140271 Based on observed behaviour the line width is not constant with PS_COSMETIC - - // Width 0 means default width for LineInfo (HairLine) with 1 pixel wide - aLineInfo.SetWidth( nPenWidth ); - - bool bTransparent = false; - switch( nStyle & PS_STYLE_MASK ) - { - case PS_DASHDOTDOT : - aLineInfo.SetStyle( LineStyle::Dash ); - aLineInfo.SetDashCount( 1 ); - aLineInfo.SetDotCount( 2 ); - break; - case PS_DASHDOT : - aLineInfo.SetStyle( LineStyle::Dash ); - aLineInfo.SetDashCount( 1 ); - aLineInfo.SetDotCount( 1 ); - break; - case PS_DOT : - aLineInfo.SetStyle( LineStyle::Dash ); - aLineInfo.SetDashCount( 0 ); - aLineInfo.SetDotCount( 1 ); - break; - case PS_DASH : - aLineInfo.SetStyle( LineStyle::Dash ); - aLineInfo.SetDashCount( 1 ); - aLineInfo.SetDotCount( 0 ); - break; - case PS_NULL : - bTransparent = true; - aLineInfo.SetStyle( LineStyle::NONE ); - break; - case PS_INSIDEFRAME : - case PS_SOLID : - default : - aLineInfo.SetStyle( LineStyle::Solid ); - } - switch( nStyle & PS_ENDCAP_STYLE_MASK ) - { - case PS_ENDCAP_ROUND : - if ( nPenWidth ) - { - aLineInfo.SetLineCap( css::drawing::LineCap_ROUND ); - break; - } - [[fallthrough]]; - case PS_ENDCAP_SQUARE : - if ( nPenWidth ) - { - aLineInfo.SetLineCap( css::drawing::LineCap_SQUARE ); - break; - } - [[fallthrough]]; - case PS_ENDCAP_FLAT : - default : - aLineInfo.SetLineCap( css::drawing::LineCap_BUTT ); - } - switch( nStyle & PS_JOIN_STYLE_MASK ) - { - case PS_JOIN_ROUND : - aLineInfo.SetLineJoin ( basegfx::B2DLineJoin::Round ); - break; - case PS_JOIN_MITER : - aLineInfo.SetLineJoin ( basegfx::B2DLineJoin::Miter ); - break; - case PS_JOIN_BEVEL : - aLineInfo.SetLineJoin ( basegfx::B2DLineJoin::Bevel ); - break; - default : - aLineInfo.SetLineJoin ( basegfx::B2DLineJoin::NONE ); - } - CreateObjectIndexed(nIndex, std::make_unique<WinMtfLineStyle>( ReadColor(), aLineInfo, bTransparent )); + mpInputStream->ReadUInt32(nPenStyle).ReadInt32(nPenWidth).ReadInt32(nIgnored); + SAL_INFO("emfio", "\t\tIndex: " << nIndex << " Style: 0x" << std::hex + << nPenStyle << std::dec + << " PenWidth: " << nPenWidth); + if ((nPenStyle & PS_STYLE_MASK) > PS_INSIDEFRAME) + nPenStyle = PS_COSMETIC; + if ((nPenStyle & PS_GEOMETRIC) == 0) + nPenWidth = 0; + CreateObjectIndexed(nIndex, std::make_unique<WinMtfLineStyle>(ReadColor(), nPenStyle, nPenWidth)); } } break; - case EMR_EXTCREATEPEN : + case EMR_EXTCREATEPEN: { - mpInputStream->ReadUInt32( nIndex ); - if ( ( nIndex & ENHMETA_STOCK_OBJECT ) == 0 ) + mpInputStream->ReadUInt32(nIndex); + if ((nIndex & ENHMETA_STOCK_OBJECT) == 0) { - sal_uInt32 offBmi, cbBmi, offBits, cbBits, nStyle, nWidth, nBrushStyle, elpNumEntries; - sal_Int32 elpHatch; - mpInputStream->ReadUInt32( offBmi ).ReadUInt32( cbBmi ).ReadUInt32( offBits ).ReadUInt32( cbBits ). ReadUInt32( nStyle ).ReadUInt32( nWidth ).ReadUInt32( nBrushStyle ); - - SAL_INFO("emfio", "\t\tStyle: 0x" << std::hex << nStyle << std::dec); - SAL_INFO("emfio", "\t\tWidth: " << nWidth); + sal_uInt32 offBmi, cbBmi, offBits, cbBits, nPenStyle, nWidth, nBrushStyle, elpNumEntries; + sal_Int32 elpHatch; + mpInputStream->ReadUInt32(offBmi).ReadUInt32(cbBmi).ReadUInt32(offBits).ReadUInt32(cbBits); + mpInputStream->ReadUInt32(nPenStyle).ReadUInt32(nWidth).ReadUInt32(nBrushStyle); Color aColorRef = ReadColor(); - mpInputStream->ReadInt32( elpHatch ).ReadUInt32( elpNumEntries ); + mpInputStream->ReadInt32(elpHatch).ReadUInt32(elpNumEntries); if (!mpInputStream->good()) bStatus = false; else { - LineInfo aLineInfo; - if ( nWidth ) - aLineInfo.SetWidth( nWidth ); - - bool bTransparent = false; - - switch( nStyle & PS_STYLE_MASK ) - { - case PS_DASHDOTDOT : - aLineInfo.SetStyle( LineStyle::Dash ); - aLineInfo.SetDashCount( 1 ); - aLineInfo.SetDotCount( 2 ); - break; - case PS_DASHDOT : - aLineInfo.SetStyle( LineStyle::Dash ); - aLineInfo.SetDashCount( 1 ); - aLineInfo.SetDotCount( 1 ); - break; - case PS_DOT : - aLineInfo.SetStyle( LineStyle::Dash ); - aLineInfo.SetDashCount( 0 ); - aLineInfo.SetDotCount( 1 ); - break; - case PS_DASH : - aLineInfo.SetStyle( LineStyle::Dash ); - aLineInfo.SetDashCount( 1 ); - aLineInfo.SetDotCount( 0 ); - break; - case PS_NULL : - bTransparent = true; - aLineInfo.SetStyle( LineStyle::NONE ); - break; - - case PS_INSIDEFRAME : - case PS_SOLID : - default : - aLineInfo.SetStyle( LineStyle::Solid ); - } - switch( nStyle & PS_ENDCAP_STYLE_MASK ) - { - case PS_ENDCAP_ROUND : - if ( aLineInfo.GetWidth() ) - { - aLineInfo.SetLineCap( css::drawing::LineCap_ROUND ); - break; - } - [[fallthrough]]; - case PS_ENDCAP_SQUARE : - if ( aLineInfo.GetWidth() ) - { - aLineInfo.SetLineCap( css::drawing::LineCap_SQUARE ); - break; - } - [[fallthrough]]; - case PS_ENDCAP_FLAT : - default : - aLineInfo.SetLineCap( css::drawing::LineCap_BUTT ); - } - switch( nStyle & PS_JOIN_STYLE_MASK ) - { - case PS_JOIN_ROUND : - aLineInfo.SetLineJoin ( basegfx::B2DLineJoin::Round ); - break; - case PS_JOIN_MITER : - aLineInfo.SetLineJoin ( basegfx::B2DLineJoin::Miter ); - break; - case PS_JOIN_BEVEL : - aLineInfo.SetLineJoin ( basegfx::B2DLineJoin::Bevel ); - break; - default : - aLineInfo.SetLineJoin ( basegfx::B2DLineJoin::NONE ); - } - CreateObjectIndexed(nIndex, std::make_unique<WinMtfLineStyle>( aColorRef, aLineInfo, bTransparent )); + SAL_INFO("emfio", "\t\tStyle: 0x" << std::hex << nPenStyle << std::dec); + if ((nPenStyle & PS_STYLE_MASK) > PS_INSIDEFRAME) + nPenStyle = PS_COSMETIC; + if ((nPenStyle & PS_GEOMETRIC) == 0) + nWidth = 0; + SAL_INFO("emfio", "\t\tWidth: " << nWidth); + CreateObjectIndexed(nIndex, std::make_unique<WinMtfLineStyle>(aColorRef, nPenStyle, nWidth)); } } } @@ -1326,7 +1300,8 @@ namespace emfio { sal_uInt32 nStyle; mpInputStream->ReadUInt32( nStyle ); - CreateObjectIndexed(nIndex, std::make_unique<WinMtfFillStyle>( ReadColor(), ( nStyle == BS_HOLLOW ) )); + BrushStyle eStyle = static_cast<BrushStyle>(nStyle); + CreateObjectIndexed(nIndex, std::make_unique<WinMtfFillStyle>( ReadColor(), ( eStyle == BrushStyle::BS_HOLLOW ) )); } } break; @@ -1353,7 +1328,7 @@ namespace emfio tools::Long dh = h / 2; Point aCenter( nX32 + dw, nY32 + dh ); tools::Polygon aPoly( aCenter, dw, dh ); - DrawPolygon( aPoly, mbRecordPath ); + DrawPolygon( std::move(aPoly), mbRecordPath ); } } break; @@ -1368,7 +1343,7 @@ namespace emfio Point(nX32, ny32) }; tools::Polygon aPoly(4, aPoints); aPoly.Optimize( PolyOptimizeFlags::CLOSE ); - DrawPolygon( aPoly, mbRecordPath ); + DrawPolygon( std::move(aPoly), mbRecordPath ); } break; @@ -1376,7 +1351,7 @@ namespace emfio { mpInputStream->ReadInt32( nX32 ).ReadInt32( nY32 ).ReadInt32( nx32 ).ReadInt32( ny32 ).ReadUInt32( nW ).ReadUInt32( nH ); tools::Polygon aRoundRectPoly( ReadRectangle( nX32, nY32, nx32, ny32 ), nW, nH ); - DrawPolygon( aRoundRectPoly, mbRecordPath ); + DrawPolygon( std::move(aRoundRectPoly), mbRecordPath ); } break; @@ -1391,11 +1366,12 @@ namespace emfio else { SAL_INFO( "emfio", "\t\t Bounds: " << nX32 << ":" << nY32 << ", " << nx32 << ":" << ny32 << ", Start: " << nStartX << ":" << nStartY << ", End: " << nEndX << ":" << nEndY ); - tools::Polygon aPoly( ReadRectangle( nX32, nY32, nx32, ny32 ), Point( nStartX, nStartY ), Point( nEndX, nEndY ), PolyStyle::Arc ); + tools::Polygon aPoly(ReadRectangle(nX32, nY32, nx32, ny32), Point(nStartX, nStartY), Point(nEndX, nEndY), PolyStyle::Arc, IsArcDirectionClockWise()); + if ( nRecType == EMR_CHORD ) - DrawPolygon( aPoly, mbRecordPath ); + DrawPolygon( std::move(aPoly), mbRecordPath ); else - DrawPolyLine( aPoly, nRecType == EMR_ARCTO, mbRecordPath ); + DrawPolyLine( std::move(aPoly), nRecType == EMR_ARCTO, mbRecordPath ); } } break; @@ -1408,8 +1384,8 @@ namespace emfio bStatus = false; else { - tools::Polygon aPoly( ReadRectangle( nX32, nY32, nx32, ny32 ), Point( nStartX, nStartY ), Point( nEndX, nEndY ), PolyStyle::Pie ); - DrawPolygon( aPoly, mbRecordPath ); + tools::Polygon aPoly(ReadRectangle(nX32, nY32, nx32, ny32), Point(nStartX, nStartY), Point(nEndX, nEndY), PolyStyle::Pie, IsArcDirectionClockWise()); + DrawPolygon( std::move(aPoly), mbRecordPath ); } } break; @@ -1455,7 +1431,7 @@ namespace emfio { sal_Int32 nClippingMode(0); mpInputStream->ReadInt32(nClippingMode); - SetClipPath(GetPathObj(), nClippingMode, true); + SetClipPath(GetPathObj(), static_cast<RegionMode>(nClippingMode), true); } break; @@ -1473,7 +1449,7 @@ namespace emfio // This record's region data should be ignored if mode // is RGN_COPY - see EMF spec section 2.3.2.2 - if (nClippingMode == RGN_COPY) + if (static_cast<RegionMode>(nClippingMode) == RegionMode::RGN_COPY) { SetDefaultClipPath(); } @@ -1481,9 +1457,9 @@ namespace emfio { basegfx::B2DPolyPolygon aPolyPoly; if (cbRgnData) - ImplReadRegion(aPolyPoly, *mpInputStream, nRemainingRecSize); + ImplReadRegion(aPolyPoly, *mpInputStream, nRemainingRecSize, GetWinOrg()); const tools::PolyPolygon aPolyPolygon(aPolyPoly); - SetClipPath(aPolyPolygon, nClippingMode, false); + SetClipPath(aPolyPolygon, static_cast<RegionMode>(nClippingMode), false); } } } @@ -1499,7 +1475,7 @@ namespace emfio sal_uInt32 BkColorSrc(0), iUsageSrc(0), offBmiSrc(0); sal_uInt32 cbBmiSrc(0), offBitsSrc(0), cbBitsSrc(0); - sal_uInt32 nStart = mpInputStream->Tell() - 8; + sal_uInt64 nStart = mpInputStream->Tell() - 8; mpInputStream->SeekRel( 0x10 ); mpInputStream->ReadInt32( xDest ).ReadInt32( yDest ).ReadInt32( cxDest ).ReadInt32( cyDest ); @@ -1630,16 +1606,22 @@ namespace emfio } } - #ifdef DBG_UTIL +#ifdef DBG_UTIL static bool bDoSaveForVisualControl(false); // loplugin:constvars:ignore if(bDoSaveForVisualControl) { - SvFileStream aNew("c:\\metafile_content.png", StreamMode::WRITE|StreamMode::TRUNC); - vcl::PNGWriter aPNGWriter(aBitmapEx); - aPNGWriter.Write(aNew); + // VCL_DUMP_BMP_PATH should be like C:/path/ or ~/path/ + static const OUString sDumpPath(OUString::createFromAscii(std::getenv("VCL_DUMP_BMP_PATH"))); + if(!sDumpPath.isEmpty()) + { + SvFileStream aNew(sDumpPath + "metafile_content.png", + StreamMode::WRITE | StreamMode::TRUNC); + vcl::PngImageWriter aPNGWriter(aNew); + aPNGWriter.write(aBitmapEx); + } } - #endif +#endif maBmpSaveList.emplace_back(aBitmapEx, aRect, SRCAND|SRCINVERT); } } @@ -1654,7 +1636,7 @@ namespace emfio sal_uInt32 dwRop, iUsageSrc, offBmiSrc, cbBmiSrc, offBitsSrc, cbBitsSrc; XForm xformSrc; - sal_uInt32 nStart = mpInputStream->Tell() - 8; + sal_uInt64 nStart = mpInputStream->Tell() - 8; mpInputStream->SeekRel( 0x10 ); mpInputStream->ReadInt32( xDest ).ReadInt32( yDest ).ReadInt32( cxDest ).ReadInt32( cyDest ).ReadUInt32( dwRop ).ReadInt32( xSrc ).ReadInt32( ySrc ) @@ -1730,7 +1712,7 @@ namespace emfio { sal_Int32 xDest, yDest, xSrc, ySrc, cxSrc, cySrc, cxDest, cyDest; sal_uInt32 offBmiSrc, cbBmiSrc, offBitsSrc, cbBitsSrc, iUsageSrc, dwRop; - sal_uInt32 nStart = mpInputStream->Tell() - 8; + sal_uInt64 nStart = mpInputStream->Tell() - 8; mpInputStream->SeekRel( 0x10 ); mpInputStream->ReadInt32( xDest ) @@ -1901,9 +1883,9 @@ namespace emfio else { const tools::Rectangle aRect( nLeftRect, nTopRect, nRightRect, nBottomRect ); - const BkMode mnBkModeBackup = mnBkMode; + const BackgroundMode mnBkModeBackup = mnBkMode; if ( nOptions & ETO_NO_RECT ) // Don't draw the background rectangle and text background - mnBkMode = BkMode::Transparent; + mnBkMode = BackgroundMode::Transparent; else if ( nOptions & ETO_OPAQUE ) DrawRectWithBGColor( aRect ); @@ -1940,7 +1922,7 @@ namespace emfio SAL_INFO("emfio", "\t\tText: " << aText); SAL_INFO("emfio", "\t\tDxBuffer:"); - std::vector<sal_Int32> aDXAry; + KernArray aDXAry; std::unique_ptr<tools::Long[]> pDYAry; sal_Int32 nDxSize; @@ -1980,7 +1962,7 @@ namespace emfio } } - aDXAry[i] = 0; + aDXAry.set(i, 0); if (nOptions & ETO_PDY) { pDYAry[i] = 0; @@ -1990,7 +1972,7 @@ namespace emfio { sal_Int32 nDxTmp = 0; mpInputStream->ReadInt32(nDxTmp); - aDXAry[i] = o3tl::saturating_add(aDXAry[i], nDxTmp); + aDXAry.set(i, o3tl::saturating_add(aDXAry[i], nDxTmp)); if (nOptions & ETO_PDY) { sal_Int32 nDyTmp = 0; @@ -2007,7 +1989,7 @@ namespace emfio Push(); // Save the current clip. It will be restored after text drawing IntersectClipRect( aRect ); } - DrawText(aPos, aText, aDXAry.empty() ? nullptr : &aDXAry, pDYAry.get(), mbRecordPath, nGfxMode); + DrawText(aPos, aText, aDXAry.empty() ? nullptr : &aDXAry, pDYAry.get(), mbRecordPath, static_cast<GraphicsMode>(nGfxMode)); if ( nOptions & ETO_CLIPPED ) Pop(); } @@ -2057,7 +2039,7 @@ namespace emfio mpInputStream->ReadUInt32( nRgnDataSize ).ReadUInt32( nIndex ); nRemainingRecSize -= 24; - if (ImplReadRegion(aPolyPoly, *mpInputStream, nRemainingRecSize)) + if (ImplReadRegion(aPolyPoly, *mpInputStream, nRemainingRecSize, GetWinOrg())) { Push(); SelectObject( nIndex ); @@ -2082,7 +2064,7 @@ namespace emfio mpInputStream->ReadUInt32( nRgnDataSize ); nRemainingRecSize -= 20; - if (ImplReadRegion(aPolyPoly, *mpInputStream, nRemainingRecSize)) + if (ImplReadRegion(aPolyPoly, *mpInputStream, nRemainingRecSize, GetWinOrg())) { tools::PolyPolygon aPolyPolygon(aPolyPoly); DrawPolyPolygon( aPolyPolygon ); @@ -2093,7 +2075,7 @@ namespace emfio case EMR_CREATEDIBPATTERNBRUSHPT : { - sal_uInt32 nStart = mpInputStream->Tell() - 8; + sal_uInt64 nStart = mpInputStream->Tell() - 8; Bitmap aBitmap; mpInputStream->ReadUInt32( nIndex ); @@ -2161,8 +2143,6 @@ namespace emfio case EMR_INVERTRGN : case EMR_FLATTENPATH : case EMR_WIDENPATH : - case EMR_POLYDRAW : - case EMR_SETARCDIRECTION : case EMR_SETPALETTEENTRIES : case EMR_RESIZEPALETTE : case EMR_EXTFLOODFILL : @@ -2276,8 +2256,8 @@ namespace emfio SAL_INFO("emfio", "\tMetafile size: " << mnEndPos); mnEndPos += mnStartPos; - sal_uInt32 nStrmPos = mpInputStream->Tell(); // checking if mnEndPos is valid - sal_uInt32 nActualFileSize = nStrmPos + mpInputStream->remainingSize(); + sal_uInt64 nStrmPos = mpInputStream->Tell(); // checking if mnEndPos is valid + sal_uInt64 nActualFileSize = nStrmPos + mpInputStream->remainingSize(); if ( nActualFileSize < mnEndPos ) { @@ -2348,7 +2328,7 @@ namespace emfio if (nLeft > nRight || nTop > nBottom) { SAL_WARN("emfio", "broken rectangle"); - return tools::Rectangle::Justify(Point(nLeft, nTop), Point(nRight, nBottom)); + return tools::Rectangle::Normalize(Point(nLeft, nTop), Point(nRight, nBottom)); } return tools::Rectangle(nLeft, nTop, nRight, nBottom); |