summaryrefslogtreecommitdiffstats
path: root/emfio/inc
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--emfio/inc/emfiodllapi.h33
-rw-r--r--emfio/inc/emfreader.hxx68
-rw-r--r--emfio/inc/mtftools.hxx842
-rw-r--r--emfio/inc/pch/precompiled_emfio.cxx12
-rw-r--r--emfio/inc/pch/precompiled_emfio.hxx52
-rw-r--r--emfio/inc/wmfreader.hxx82
6 files changed, 1089 insertions, 0 deletions
diff --git a/emfio/inc/emfiodllapi.h b/emfio/inc/emfiodllapi.h
new file mode 100644
index 000000000..af672949d
--- /dev/null
+++ b/emfio/inc/emfiodllapi.h
@@ -0,0 +1,33 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#ifndef INCLUDED_EMFIO_INC_EMFIODLLAPI_H
+#define INCLUDED_EMFIO_INC_EMFIODLLAPI_H
+
+#include <sal/types.h>
+
+#if defined(EMFIO_DLLIMPLEMENTATION)
+#define EMFIO_DLLPUBLIC SAL_DLLPUBLIC_EXPORT
+#else
+#define EMFIO_DLLPUBLIC SAL_DLLPUBLIC_IMPORT
+#endif
+
+#endif // INCLUDED_EMFIO_INC_EMFIODLLAPI_H
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/emfio/inc/emfreader.hxx b/emfio/inc/emfreader.hxx
new file mode 100644
index 000000000..a09ad6fa2
--- /dev/null
+++ b/emfio/inc/emfreader.hxx
@@ -0,0 +1,68 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#ifndef INCLUDED_EMFIO_INC_EMFREADER_HXX
+#define INCLUDED_EMFIO_INC_EMFREADER_HXX
+
+#include "mtftools.hxx"
+
+namespace emfio
+{
+ class EmfReader : public MtfTools
+ {
+ private:
+ sal_uInt32 mnRecordCount;
+
+ bool mbRecordPath : 1;
+ bool mbEMFPlus : 1;
+ bool mbEMFPlusDualMode : 1;
+ /// Another format is read already, can ignore actual EMF data.
+ bool mbReadOtherGraphicFormat = false;
+ basegfx::B2DTuple maSizeHint;
+ bool mbEnableEMFPlus = true;
+
+ bool ReadHeader();
+ // reads and converts the rectangle
+ static tools::Rectangle ReadRectangle(sal_Int32, sal_Int32, sal_Int32, sal_Int32);
+
+ public:
+ EmfReader(SvStream& rStreamWMF, GDIMetaFile& rGDIMetaFile);
+ ~EmfReader();
+
+ bool ReadEnhWMF();
+ void ReadGDIComment(sal_uInt32 nCommentId);
+ /// Parses EMR_COMMENT_MULTIFORMATS.
+ void ReadMultiformatsComment();
+ void SetSizeHint(const basegfx::B2DTuple& rSizeHint) { maSizeHint = rSizeHint; }
+ void SetEnableEMFPlus(bool bEnableEMFPlus) { mbEnableEMFPlus = bEnableEMFPlus; }
+
+ private:
+ template <class T> void ReadAndDrawPolyPolygon(sal_uInt32 nNextPos);
+ template <class T> void ReadAndDrawPolyLine(sal_uInt32 nNextPos);
+ template <class T> tools::Polygon ReadPolygon(sal_uInt32 nStartIndex, sal_uInt32 nPoints, sal_uInt32 nNextPos);
+ template <class T> tools::Polygon ReadPolygonWithSkip(const bool skipFirst, sal_uInt32 nNextPos);
+
+ tools::Rectangle ReadRectangle();
+ void ReadEMFPlusComment(sal_uInt32 length, bool& bHaveDC);
+ };
+}
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/emfio/inc/mtftools.hxx b/emfio/inc/mtftools.hxx
new file mode 100644
index 000000000..997f2287f
--- /dev/null
+++ b/emfio/inc/mtftools.hxx
@@ -0,0 +1,842 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#ifndef INCLUDED_EMFIO_INC_MTFTOOLS_HXX
+#define INCLUDED_EMFIO_INC_MTFTOOLS_HXX
+
+#include <config_options.h>
+#include <basegfx/utils/b2dclipstate.hxx>
+#include <tools/poly.hxx>
+#include <vcl/font.hxx>
+#include <vcl/bitmapex.hxx>
+#include <vcl/lineinfo.hxx>
+#include <vcl/rendercontext/State.hxx>
+#include <vcl/metaact.hxx>
+#include <rtl/ref.hxx>
+
+#include "emfiodllapi.h"
+
+namespace emfio
+{
+ /* [MS-EMF] - v20210625 - pages 43, 107 */
+ enum class RegionMode : sal_uInt32
+ {
+ RGN_AND = 0x01,
+ RGN_OR = 0x02,
+ RGN_XOR = 0x03,
+ RGN_DIFF = 0x04,
+ RGN_COPY = 0x05
+ };
+
+ /* [MS-EMF] - v20210625 - pages 40, 198 */
+ enum class BackgroundMode : sal_uInt32
+ {
+ NONE = 0,
+ Transparent = 1,
+ OPAQUE = 2,
+ };
+
+ /* [MS-EMF] - v20210625 - pages 40, 210 */
+ /* xform stuff */
+ enum class ModifyWorldTransformMode : sal_uInt32
+ {
+ MWT_IDENTITY = 0x01,
+ MWT_LEFTMULTIPLY = 0x02,
+ MWT_RIGHTMULTIPLY = 0x03,
+ MWT_SET = 0x04
+ };
+
+ constexpr sal_uInt32 ENHMETA_STOCK_OBJECT = 0x80000000;
+
+ /* [MS-EMF] - v20210625 - pages 44, 45, 182 */
+ /* Stock Logical Objects */
+ enum class StockObject : sal_uInt32
+ {
+ WHITE_BRUSH = 0,
+ LTGRAY_BRUSH = 1,
+ GRAY_BRUSH = 2,
+ DKGRAY_BRUSH = 3,
+ BLACK_BRUSH = 4,
+ NULL_BRUSH = 5,
+ WHITE_PEN = 6,
+ BLACK_PEN = 7,
+ NULL_PEN = 8,
+ ANSI_FIXED_FONT = 11,
+ ANSI_VAR_FONT = 12,
+ SYSTEM_FIXED_FONT = 16
+ };
+
+ /* Note: This enum is incomplete compared to the specification */
+ /* [MS-WMF] - v20210625 - pages 25-26 */
+ enum class WMFRasterOp : sal_uInt16
+ {
+ NONE = 0,
+ Black = 1,
+ Not = 6,
+ XorPen = 7,
+ Nop = 11,
+ CopyPen = 13
+ };
+
+ /* Note: We have MapMode elsewhere, so we use MappingMode instead */
+ /* [MS-EMF] - v20210625 - pages 38-50, 202 */
+ /* Mapping modes */
+ enum MappingMode : sal_uInt32
+ {
+ MM_TEXT = 0x01,
+ MM_LOMETRIC = 0x02,
+ MM_HIMETRIC = 0x03,
+ MM_LOENGLISH = 0x04,
+ MM_HIENGLISH = 0x05,
+ MM_TWIPS = 0x06,
+ MM_ISOTROPIC = 0x07,
+ MM_ANISOTROPIC = 0x08
+ };
+
+ /* Note: No type is specified, but 32-bit unsigned is used to provide
+ * to match the number of bits in the binary literal, and also the
+ * previous definition of SetGfxMode() and GetGfxMode() functions */
+ /* [MS-EMF] - v20210625 - pages 35 */
+ /* Graphics modes */
+ enum class GraphicsMode : sal_uInt32
+ {
+ GM_COMPATIBLE = 0x00000001,
+ GM_ADVANCED = 0x00000002
+ } ;
+
+ /* [MS-WMF] - v20210625 - pages 46 */
+ /* StretchBlt() modes */
+ enum class StretchMode : sal_uInt16
+ {
+ BLACKONWHITE = 0x0001,
+ WHITEONBLACK = 0x0002,
+ COLORONCOLOR = 0x0003,
+ HALFTONE = 0x0004,
+ STRETCH_ANDSCANS = BLACKONWHITE,
+ STRETCH_ORSCANS = WHITEONBLACK,
+ STRETCH_DELETESCANS = COLORONCOLOR
+ };
+
+ constexpr sal_Int32 LF_FACESIZE = 32;
+
+ struct LOGFONTW
+ {
+ sal_Int32 lfHeight;
+ sal_Int32 lfWidth;
+ sal_Int32 lfEscapement;
+ sal_Int32 lfOrientation;
+ sal_Int32 lfWeight;
+ sal_uInt8 lfItalic;
+ sal_uInt8 lfUnderline;
+ sal_uInt8 lfStrikeOut;
+ sal_uInt8 lfCharSet;
+ sal_uInt8 lfOutPrecision;
+ sal_uInt8 lfClipPrecision;
+ sal_uInt8 lfQuality;
+ sal_uInt8 lfPitchAndFamily;
+ OUString alfFaceName;
+ LOGFONTW()
+ : lfHeight(0)
+ , lfWidth(0)
+ , lfEscapement(0)
+ , lfOrientation(0)
+ , lfWeight(0)
+ , lfItalic(0)
+ , lfUnderline(0)
+ , lfStrikeOut(0)
+ , lfCharSet(0)
+ , lfOutPrecision(0)
+ , lfClipPrecision(0)
+ , lfQuality(0)
+ , lfPitchAndFamily(0)
+ {
+ }
+ };
+
+ /* [MS-WMF] - v20210625 - pages 153 */
+ enum TextAlignmentMode : sal_uInt16
+ {
+ TA_NOUPDATECP = 0x0000,
+ TA_UPDATECP = 0x0001,
+ TA_LEFT = 0x0000,
+ TA_RIGHT = 0x0002,
+ TA_CENTER = 0x0006,
+ TA_RIGHT_CENTER = (TA_RIGHT | TA_CENTER),
+ TA_TOP = 0x0000,
+ TA_BOTTOM = 0x0008,
+ TA_BASELINE = 0x0018,
+ TA_RTLREADING = 0x0100
+ };
+
+ /* Note: This enum is incomplete compared to the specification */
+ /* [MS-EMF] - v20210625 - pages 47-50, 126 */
+ /* Ternary raster operations */
+ enum TernaryRasterOperation : sal_uInt32
+ {
+ SRCCOPY = 0x00CC0020L,
+ SRCPAINT = 0x00EE0086L,
+ SRCAND = 0x008800C6L,
+ SRCINVERT = 0x00660046L,
+ SRCERASE = 0x00440328L,
+ PATCOPY = 0x00F00021L,
+ PATINVERT = 0x005A0049L,
+ BLACKNESS = 0x00000042L,
+ WHITENESS = 0x00FF0062L
+ };
+
+ /* [MS-EMF] - v20210625 - pages 40, 41, 65 */
+ enum PenStyle : sal_uInt32
+ {
+ PS_COSMETIC = 0x00000000,
+ PS_SOLID = 0x00000000,
+ PS_DASH = 0x00000001,
+ PS_DOT = 0x00000002,
+ PS_DASHDOT = 0x00000003,
+ PS_DASHDOTDOT = 0x00000004,
+ PS_NULL = 0x00000005,
+ PS_INSIDEFRAME = 0x00000006,
+ PS_USERSTYLE = 0x00000007,
+ PS_ALTERNATE = 0x00000008,
+ PS_STYLE_MASK = 0x0000000F,
+
+ PS_ENDCAP_ROUND = 0x00000000,
+ PS_ENDCAP_SQUARE = 0x00000100,
+ PS_ENDCAP_FLAT = 0x00000200,
+ PS_ENDCAP_STYLE_MASK = 0x00000F00,
+
+ PS_JOIN_ROUND = 0x00000000,
+ PS_JOIN_BEVEL = 0x00001000,
+ PS_JOIN_MITER = 0x00002000,
+ PS_JOIN_STYLE_MASK = 0x0000F000,
+
+ PS_GEOMETRIC = 0x00010000
+ };
+
+ /* [MS-WMF] - v20210625 - pages 30, 82 */
+ /* Character Sets */
+ enum CharacterSet : sal_uInt8
+ {
+ ANSI_CHARSET = 0x00000000,
+ DEFAULT_CHARSET = 0x00000001,
+ SYMBOL_CHARSET = 0x00000002,
+ SHIFTJIS_CHARSET = 0x00000080,
+ HANGUL_CHARSET = 0x00000081,
+ GB2312_CHARSET = 0x00000086,
+ CHINESEBIG5_CHARSET = 0x00000088,
+ OEM_CHARSET = 0x000000FF,
+ /* WINVER >= 0x0400 */
+ MAC_CHARSET = 0x0000004D,
+ JOHAB_CHARSET = 0x00000082,
+ GREEK_CHARSET = 0x000000A1,
+ TURKISH_CHARSET = 0x000000A2,
+ VIETNAMESE_CHARSET = 0x000000A3,
+ HEBREW_CHARSET = 0x000000B1,
+ ARABIC_CHARSET = 0x000000B2,
+ BALTIC_CHARSET = 0x000000BA,
+ RUSSIAN_CHARSET = 0x000000CC,
+ THAI_CHARSET = 0x000000DE,
+ EASTEUROPE_CHARSET = 0x000000EE
+ };
+
+ /* Note: This enum is incomplete compared to the specification */
+ /* [MS-EMF] - v20210625 - pages 32, 283 */
+ enum ExtTextOutOptions : sal_uInt32
+ {
+ ETO_OPAQUE = 0x0002,
+ ETO_CLIPPED = 0x0004,
+ /* WINVER >= 0x0400 */
+ ETO_GLYPH_INDEX = 0x0010,
+ ETO_RTLREADING = 0x0080,
+ /* _WIN32_WINNT >= 0x0500 */
+ ETO_NO_RECT = 0x0100,
+ ETO_PDY = 0x2000
+ };
+
+ /* [MS-WMF] - v20210625 - pages 44, 96 */
+ /* This is packed into a byte as 2 bits */
+ enum PitchFont : sal_uInt8
+ {
+ DEFAULT_PITCH = 0,
+ FIXED_PITCH = 1,
+ VARIABLE_PITCH = 2
+ };
+
+ /* [MS-WMF] - v20210625 - pages 33, */
+ enum FamilyFont : sal_uInt8
+ {
+ FF_DONTCARE = 0x00,
+ FF_ROMAN = 0x01,
+ FF_SWISS = 0x02,
+ FF_MODERN = 0x03,
+ FF_SCRIPT = 0x04,
+ FF_DECORATIVE = 0x05
+ };
+
+ enum WeightFont
+ {
+ FW_THIN = 100,
+ FW_EXTRALIGHT = 200,
+ FW_LIGHT = 300,
+ FW_NORMAL = 400,
+ FW_MEDIUM = 500,
+ FW_SEMIBOLD = 600,
+ FW_BOLD = 700,
+ FW_EXTRABOLD = 800,
+ FW_ULTRALIGHT = 200,
+ FW_ULTRABOLD = 800,
+ FW_BLACK = 900
+ };
+
+ /* [MS-WMF] - v20210625 - pages 29, 30, 182 */
+ enum class BrushStyle : sal_uInt16
+ {
+ BS_SOLID = 0,
+ BS_NULL = 1,
+ BS_HOLLOW = 1,
+ BS_HATCHED = 2,
+ BS_PATTERN = 3,
+ BS_INDEXED = 4,
+ BS_DIBPATTERN = 5,
+ BS_DIBPATTERNPT = 6,
+ BS_PATTERN8X8 = 7,
+ BS_DIBPATTERN8X8 = 8,
+ BS_MONOPATTERN = 9
+ };
+
+ constexpr sal_Int32 RDH_RECTANGLES = 1;
+ constexpr sal_Int32 W_MFCOMMENT = 15;
+ constexpr sal_Int32 PRIVATE_ESCAPE_UNICODE = 2;
+
+ //Scalar constants
+ constexpr sal_Int32 UNDOCUMENTED_WIN_RCL_RELATION = 32;
+ constexpr sal_Int32 MS_FIXPOINT_BITCOUNT_28_4 = 4;
+}
+
+//============================ WmfReader ==================================
+
+namespace emfio
+{
+ class WinMtfClipPath
+ {
+ basegfx::utils::B2DClipState maClip;
+
+ public:
+ WinMtfClipPath() : maClip() {};
+
+ void setClipPath(const basegfx::B2DPolyPolygon&, RegionMode nClippingMode);
+ void intersectClip(const basegfx::B2DPolyPolygon& rPolyPolygon);
+ void excludeClip(const basegfx::B2DPolyPolygon& rPolyPolygon);
+ void moveClipRegion(const Size& rSize);
+ void setDefaultClipPath();
+
+ bool isEmpty() const { return maClip.isCleared(); }
+
+ basegfx::utils::B2DClipState const & getClip() const { return maClip; }
+ basegfx::B2DPolyPolygon const & getClipPath() const;
+
+ bool operator==(const WinMtfClipPath& rPath) const
+ {
+ return maClip == rPath.maClip;
+ };
+ };
+
+ class WinMtfPathObj : public tools::PolyPolygon
+ {
+ bool bClosed;
+
+ public:
+
+ WinMtfPathObj() :
+ bClosed(true)
+ {}
+
+ void Init()
+ {
+ Clear();
+ bClosed = true;
+ }
+
+ void ClosePath();
+ void AddPoint(const Point& rPoint);
+ void AddPolygon(const tools::Polygon& rPoly);
+ void AddPolyLine(const tools::Polygon& rPoly);
+ void AddPolyPolygon(const tools::PolyPolygon& rPolyPolygon);
+ };
+
+ struct EMFIO_DLLPUBLIC GDIObj
+ {
+ GDIObj() = default;
+ GDIObj(GDIObj const &) = default;
+ virtual ~GDIObj() = default; // Polymorphic base class
+ GDIObj & operator =(GDIObj const &) = default;
+ };
+
+ struct UNLESS_MERGELIBS(EMFIO_DLLPUBLIC) WinMtfFontStyle final : GDIObj
+ {
+ vcl::Font aFont;
+
+ explicit WinMtfFontStyle(LOGFONTW const & rLogFont);
+ };
+
+ enum class WinMtfFillStyleType
+ {
+ Solid, Pattern
+ };
+
+ struct WinMtfFillStyle final : GDIObj
+ {
+ Color aFillColor;
+ bool bTransparent;
+ WinMtfFillStyleType aType;
+ Bitmap aBmp;
+
+ WinMtfFillStyle()
+ : aFillColor(COL_BLACK)
+ , bTransparent(false)
+ , aType(WinMtfFillStyleType::Solid)
+ {}
+
+ WinMtfFillStyle(const Color& rColor, bool bTrans = false)
+ : aFillColor(rColor)
+ , bTransparent(bTrans)
+ , aType(WinMtfFillStyleType::Solid)
+ {}
+
+ explicit WinMtfFillStyle(Bitmap const & rBmp)
+ : bTransparent(false)
+ , aType(WinMtfFillStyleType::Pattern)
+ , aBmp(rBmp)
+ {}
+
+ bool operator==(const WinMtfFillStyle& rStyle) const
+ {
+ return aFillColor == rStyle.aFillColor
+ && bTransparent == rStyle.bTransparent
+ && aType == rStyle.aType;
+ }
+ };
+
+
+ struct WinMtfPalette final : GDIObj
+ {
+ std::vector< Color > aPaletteColors;
+
+ WinMtfPalette()
+ : aPaletteColors(std::vector< Color >{})
+ {}
+
+ WinMtfPalette(const std::vector< Color > rPaletteColors)
+ : aPaletteColors(rPaletteColors)
+ {}
+
+ };
+
+
+ struct WinMtfLineStyle final : GDIObj
+ {
+ Color aLineColor;
+ LineInfo aLineInfo;
+ bool bTransparent;
+
+ WinMtfLineStyle()
+ : aLineColor(COL_BLACK)
+ , bTransparent(false)
+ {}
+
+ WinMtfLineStyle(const Color& rColor, bool bTrans = false)
+ : aLineColor(rColor)
+ , bTransparent(bTrans)
+ {}
+
+ WinMtfLineStyle(const Color& rColor, const sal_uInt32 nStyle, const sal_Int32 nPenWidth)
+ : aLineColor(rColor)
+ {
+ // 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);
+ 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:
+ aLineInfo.SetStyle(LineStyle::NONE);
+ break;
+ case PS_INSIDEFRAME: // TODO Implement PS_INSIDEFRAME
+ case PS_SOLID:
+ default:
+ aLineInfo.SetStyle(LineStyle::Solid);
+ }
+ if (nPenWidth)
+ switch (nStyle & PS_ENDCAP_STYLE_MASK)
+ {
+ case PS_ENDCAP_ROUND:
+ aLineInfo.SetLineCap(css::drawing::LineCap_ROUND);
+ break;
+ case PS_ENDCAP_SQUARE:
+ aLineInfo.SetLineCap(css::drawing::LineCap_SQUARE);
+ break;
+ case PS_ENDCAP_FLAT:
+ default:
+ aLineInfo.SetLineCap(css::drawing::LineCap_BUTT);
+ }
+ else
+ 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_BEVEL:
+ aLineInfo.SetLineJoin(basegfx::B2DLineJoin::Bevel);
+ break;
+ // Undocumented but based on experiments with MS Paint and MS Word,
+ // the default Join Style is PS_JOIN_MITER
+ case PS_JOIN_MITER:
+ default:
+ aLineInfo.SetLineJoin(basegfx::B2DLineJoin::Miter);
+ }
+ bTransparent = aLineInfo.GetStyle() == LineStyle::NONE;
+ }
+
+ bool operator==(const WinMtfLineStyle& rStyle) const
+ {
+ return aLineColor == rStyle.aLineColor
+ && bTransparent == rStyle.bTransparent
+ && aLineInfo == rStyle.aLineInfo;
+ }
+ };
+
+ struct XForm
+ {
+ float eM11;
+ float eM12;
+ float eM21;
+ float eM22;
+ float eDx;
+ float eDy;
+
+ XForm()
+ : eM11(1.0f)
+ , eM12(0.0f)
+ , eM21(0.0f)
+ , eM22(1.0f)
+ , eDx(0.0f)
+ , eDy(0.0f)
+ {}
+ };
+
+ SvStream& operator >> (SvStream& rInStream, XForm& rXForm);
+
+ struct SaveStruct
+ {
+ BackgroundMode nBkMode;
+ MappingMode eMapMode;
+ GraphicsMode eGfxMode;
+ vcl::text::ComplexTextLayoutFlags nTextLayoutMode;
+ sal_Int32 nWinOrgX, nWinOrgY, nWinExtX, nWinExtY;
+ sal_Int32 nDevOrgX, nDevOrgY, nDevWidth, nDevHeight;
+
+ WinMtfLineStyle aLineStyle;
+ WinMtfFillStyle aFillStyle;
+
+ vcl::Font aFont;
+ Color aBkColor;
+ Color aTextColor;
+ sal_uInt32 nTextAlign;
+ RasterOp eRasterOp;
+
+ Point aActPos;
+ WinMtfPathObj maPathObj;
+ WinMtfClipPath maClipPath;
+ XForm aXForm;
+
+ bool bClockWiseArcDirection;
+ bool bFillStyleSelected;
+ };
+
+ struct BSaveStruct
+ {
+ BitmapEx aBmpEx;
+ tools::Rectangle aOutRect;
+ sal_uInt32 nWinRop;
+ bool m_bForceAlpha = false;
+
+ BSaveStruct(const Bitmap& rBmp, const tools::Rectangle& rOutRect, sal_uInt32 nRop)
+ : aBmpEx(rBmp)
+ , aOutRect(rOutRect)
+ , nWinRop(nRop)
+ {}
+
+ BSaveStruct(const BitmapEx& rBmpEx, const tools::Rectangle& rOutRect, sal_uInt32 nRop,
+ bool bForceAlpha = false)
+ : aBmpEx(rBmpEx)
+ , aOutRect(rOutRect)
+ , nWinRop(nRop)
+ , m_bForceAlpha(bForceAlpha)
+ {}
+ };
+
+ // tdf#127471 implement detection and correction of wrongly scaled
+ // fonts in own-written, old (before this fix) EMF/WMF files
+ class ScaledFontDetectCorrectHelper
+ {
+ private:
+ rtl::Reference<MetaFontAction> maCurrentMetaFontAction;
+ std::vector<double> maAlternativeFontScales;
+ std::vector<std::pair<rtl::Reference<MetaFontAction>, double>> maPositiveIdentifiedCases;
+ std::vector<std::pair<rtl::Reference<MetaFontAction>, double>> maNegativeIdentifiedCases;
+
+ public:
+ ScaledFontDetectCorrectHelper();
+ void endCurrentMetaFontAction();
+ void newCurrentMetaFontAction(const rtl::Reference<MetaFontAction>& rNewMetaFontAction);
+ void evaluateAlternativeFontScale(OUString const & rText, tools::Long nImportedTextLength);
+ void applyAlternativeFontScale();
+ };
+
+ class MtfTools
+ {
+ MtfTools(MtfTools const &) = delete;
+ MtfTools& operator =(MtfTools const &) = delete;
+
+ protected:
+ WinMtfPathObj maPathObj;
+ WinMtfClipPath maClipPath;
+
+ WinMtfLineStyle maLatestLineStyle;
+ WinMtfLineStyle maLineStyle;
+ WinMtfLineStyle maNopLineStyle;
+ WinMtfFillStyle maLatestFillStyle;
+ WinMtfFillStyle maFillStyle;
+ WinMtfFillStyle maNopFillStyle;
+ WinMtfPalette maPalette;
+
+ vcl::Font maLatestFont;
+ vcl::Font maFont;
+ sal_uInt32 mnLatestTextAlign;
+ sal_uInt32 mnTextAlign;
+ Color maLatestTextColor;
+ Color maTextColor;
+ Color maLatestBkColor;
+ Color maBkColor;
+ vcl::text::ComplexTextLayoutFlags mnLatestTextLayoutMode;
+ vcl::text::ComplexTextLayoutFlags mnTextLayoutMode;
+ BackgroundMode mnLatestBkMode;
+ BackgroundMode mnBkMode;
+ RasterOp meLatestRasterOp;
+ RasterOp meRasterOp;
+
+ std::vector< std::unique_ptr<GDIObj> > mvGDIObj;
+ Point maActPos;
+ WMFRasterOp mnRop;
+ std::vector< std::shared_ptr<SaveStruct> > mvSaveStack;
+
+ GraphicsMode meGfxMode;
+ MappingMode meMapMode;
+
+ XForm maXForm;
+ sal_Int32 mnDevOrgX;
+ sal_Int32 mnDevOrgY;
+ sal_Int32 mnDevWidth;
+ sal_Int32 mnDevHeight;
+ sal_Int32 mnWinOrgX;
+ sal_Int32 mnWinOrgY;
+ sal_Int32 mnWinExtX;
+ sal_Int32 mnWinExtY;
+
+ sal_Int32 mnPixX; // Reference Device in pixel
+ sal_Int32 mnPixY; // Reference Device in pixel
+ sal_Int32 mnMillX; // Reference Device in Mill
+ sal_Int32 mnMillY; // Reference Device in Mill
+ tools::Rectangle mrclFrame;
+ tools::Rectangle mrclBounds;
+
+ GDIMetaFile* mpGDIMetaFile;
+
+ SvStream* mpInputStream; // the WMF/EMF file to be read
+ sal_uInt32 mnStartPos;
+ sal_uInt32 mnEndPos;
+ std::vector<BSaveStruct> maBmpSaveList;
+
+ // tdf#127471 always try to detect - only used with ScaledText
+ ScaledFontDetectCorrectHelper maScaledFontHelper;
+
+ bool mbNopMode : 1;
+ bool mbClockWiseArcDirection : 1;
+ bool mbFillStyleSelected : 1;
+ bool mbClipNeedsUpdate : 1;
+ bool mbComplexClip : 1;
+ bool mbIsMapWinSet : 1;
+ bool mbIsMapDevSet : 1;
+
+ void UpdateLineStyle();
+ void UpdateFillStyle();
+
+ Point ImplMap(const Point& rPt);
+ Point ImplScale(const Point& rPt);
+ Size ImplMap(const Size& rSize, bool bDoWorldTransform = true);
+ tools::Rectangle ImplMap(const tools::Rectangle& rRectangle);
+ void ImplMap(vcl::Font& rFont);
+ tools::Polygon& ImplMap(tools::Polygon& rPolygon);
+ tools::PolyPolygon& ImplMap(tools::PolyPolygon& rPolyPolygon);
+ void ImplScale(tools::Polygon& rPolygon);
+ tools::PolyPolygon& ImplScale(tools::PolyPolygon& rPolyPolygon);
+ void ImplResizeObjectArry(sal_uInt32 nNewEntry);
+ void ImplSetNonPersistentLineColorTransparenz();
+ void ImplDrawClippedPolyPolygon(const tools::PolyPolygon& rPolyPoly);
+ void ImplDrawBitmap(const Point& rPos, const Size& rSize, const BitmapEx& rBitmap);
+
+ public:
+
+ void SetDevByWin(); //Hack to set varying defaults for incompletely defined files.
+ void SetDevOrg(const Point& rPoint);
+ void SetDevOrgOffset(sal_Int32 nXAdd, sal_Int32 nYAdd);
+ void SetDevExt(const Size& rSize, bool regular = true);
+ void ScaleDevExt(double fX, double fY);
+
+ void SetWinOrg(const Point& rPoint, bool bIsEMF = false);
+ void SetWinOrgOffset(sal_Int32 nX, sal_Int32 nY);
+ void SetWinExt(const Size& rSize, bool bIsEMF = false);
+ void ScaleWinExt(double fX, double fY);
+
+ void SetrclBounds(const tools::Rectangle& rRect);
+ void SetrclFrame(const tools::Rectangle& rRect);
+ void SetRefPix(const Size& rSize);
+ void SetRefMill(const Size& rSize);
+
+ void SetMapMode(MappingMode mnMapMode);
+ void SetWorldTransform(const XForm& rXForm);
+ void ModifyWorldTransform(const XForm& rXForm, ModifyWorldTransformMode nMode);
+
+ void Push();
+ void Pop( const sal_Int32 nSavedDC = -1 );
+
+ WMFRasterOp SetRasterOp(WMFRasterOp nRasterOp);
+ void StrokeAndFillPath(bool bStroke, bool bFill);
+
+ void SetArcDirection(bool bCounterClockWise);
+ bool IsArcDirectionClockWise() { return mbClockWiseArcDirection; };
+ void SetGfxMode(GraphicsMode nGfxMode) { meGfxMode = nGfxMode; };
+ GraphicsMode GetGfxMode() const { return meGfxMode; };
+ void SetBkMode(BackgroundMode nMode);
+ void SetBkColor(const Color& rColor);
+ void SetTextColor(const Color& rColor);
+ void SetTextAlign(sal_uInt32 nAlign);
+
+ void CreateObject(std::unique_ptr<GDIObj> pObject);
+ void CreateObjectIndexed(sal_uInt32 nIndex, std::unique_ptr<GDIObj> pObject);
+ void CreateObject();
+
+ void DeleteObject(sal_uInt32 nIndex);
+ void SelectObject(sal_uInt32 nIndex);
+ rtl_TextEncoding GetCharSet() const { return maFont.GetCharSet(); };
+ const vcl::Font& GetFont() const { return maFont; }
+ void SetTextLayoutMode(vcl::text::ComplexTextLayoutFlags nLayoutMode);
+
+ void ClearPath() { maPathObj.Init(); };
+ void ClosePath() { maPathObj.ClosePath(); };
+ const tools::PolyPolygon& GetPathObj() const { return maPathObj; };
+
+ void MoveTo(const Point& rPoint, bool bRecordPath = false);
+ void LineTo(const Point& rPoint, bool bRecordPath = false);
+ void DrawPixel(const Point& rSource, const Color& rColor);
+ void DrawRect(const tools::Rectangle& rRect, bool bEdge = true);
+ void DrawRectWithBGColor(const tools::Rectangle& rRect);
+ void DrawRoundRect(const tools::Rectangle& rRect, const Size& rSize);
+ void DrawEllipse(const tools::Rectangle& rRect);
+ void DrawArc(
+ const tools::Rectangle& rRect,
+ const Point& rStartAngle,
+ const Point& rEndAngle,
+ bool bDrawTo = false
+ );
+ void DrawPie(
+ const tools::Rectangle& rRect,
+ const Point& rStartAngle,
+ const Point& rEndAngle
+ );
+ void DrawChord(
+ const tools::Rectangle& rRect,
+ const Point& rStartAngle,
+ const Point& rEndAngle
+ );
+ void DrawPolygon(tools::Polygon rPolygon, bool bRecordPath);
+ void DrawPolyPolygon(tools::PolyPolygon& rPolyPolygon, bool bRecordPath = false);
+ void DrawPolyLine(tools::Polygon rPolygon,
+ bool bDrawTo = false,
+ bool bRecordPath = false
+ );
+ void DrawPolyBezier(tools::Polygon rPolygon,
+ bool bDrawTo,
+ bool bRecordPath
+ );
+ void DrawText(Point& rPosition,
+ OUString const & rString,
+ std::vector<sal_Int32>* pDXArry = nullptr,
+ tools::Long* pDYArry = nullptr,
+ bool bRecordPath = false,
+ GraphicsMode nGraphicsMode = GraphicsMode::GM_COMPATIBLE);
+
+ void ResolveBitmapActions(std::vector<BSaveStruct>& rSaveList);
+
+ void IntersectClipRect(const tools::Rectangle& rRect);
+ void ExcludeClipRect(const tools::Rectangle& rRect);
+ void MoveClipRegion(const Size& rSize);
+ void SetClipPath(
+ const tools::PolyPolygon& rPolyPoly,
+ RegionMode nClippingMode,
+ bool bIsMapped
+ );
+ void SetDefaultClipPath();
+ void UpdateClipRegion();
+ void AddFromGDIMetaFile(GDIMetaFile& rGDIMetaFile);
+
+ void PassEMFPlus(void const * pBuffer, sal_uInt32 nLength);
+ void PassEMFPlusHeaderInfo();
+
+ Color ReadColor();
+
+ explicit MtfTools(GDIMetaFile& rGDIMetaFile, SvStream& rStreamWMF);
+ ~MtfTools() COVERITY_NOEXCEPT_FALSE;
+ };
+}
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/emfio/inc/pch/precompiled_emfio.cxx b/emfio/inc/pch/precompiled_emfio.cxx
new file mode 100644
index 000000000..d87142820
--- /dev/null
+++ b/emfio/inc/pch/precompiled_emfio.cxx
@@ -0,0 +1,12 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#include "precompiled_emfio.hxx"
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/emfio/inc/pch/precompiled_emfio.hxx b/emfio/inc/pch/precompiled_emfio.hxx
new file mode 100644
index 000000000..4c258670a
--- /dev/null
+++ b/emfio/inc/pch/precompiled_emfio.hxx
@@ -0,0 +1,52 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+/*
+ This file has been autogenerated by update_pch.sh. It is possible to edit it
+ manually (such as when an include file has been moved/renamed/removed). All such
+ manual changes will be rewritten by the next run of update_pch.sh (which presumably
+ also fixes all possible problems, so it's usually better to use it).
+
+ Generated on 2021-03-08 13:13:45 using:
+ ./bin/update_pch emfio emfio --cutoff=8 --exclude:system --exclude:module --include:local
+
+ If after updating build fails, use the following command to locate conflicting headers:
+ ./bin/update_pch_bisect ./emfio/inc/pch/precompiled_emfio.hxx "make emfio.build" --find-conflicts
+*/
+
+#include <sal/config.h>
+#if PCH_LEVEL >= 1
+#include <memory>
+#include <vector>
+#endif // PCH_LEVEL >= 1
+#if PCH_LEVEL >= 2
+#include <osl/diagnose.h>
+#include <osl/endian.h>
+#include <osl/mutex.hxx>
+#include <osl/thread.h>
+#include <rtl/bootstrap.hxx>
+#include <rtl/crc.h>
+#include <rtl/instance.hxx>
+#include <rtl/ref.hxx>
+#include <rtl/string.hxx>
+#include <rtl/tencinfo.h>
+#include <sal/log.hxx>
+#include <sal/macros.h>
+#include <sal/types.h>
+#include <vcl/bitmapex.hxx>
+#include <vcl/dllapi.h>
+#endif // PCH_LEVEL >= 2
+#if PCH_LEVEL >= 3
+#include <salhelper/simplereferenceobject.hxx>
+#include <tools/gen.hxx>
+#endif // PCH_LEVEL >= 3
+#if PCH_LEVEL >= 4
+#endif // PCH_LEVEL >= 4
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/emfio/inc/wmfreader.hxx b/emfio/inc/wmfreader.hxx
new file mode 100644
index 000000000..5c6979550
--- /dev/null
+++ b/emfio/inc/wmfreader.hxx
@@ -0,0 +1,82 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#ifndef INCLUDED_EMFIO_INC_WMFREADER_HXX
+#define INCLUDED_EMFIO_INC_WMFREADER_HXX
+
+#include "mtftools.hxx"
+#include <tools/stream.hxx>
+
+// predefines
+struct WmfExternal;
+
+namespace emfio
+{
+ class WmfReader : public MtfTools
+ {
+ private:
+ sal_uInt16 mnUnitsPerInch;
+ sal_uInt32 mnRecSize;
+ bool mbPlaceable;
+
+ // embedded EMF data
+ std::optional<std::vector<sal_uInt8>> mpEMFStream;
+
+ // total number of comment records containing EMF data
+ sal_uInt32 mnEMFRecCount;
+
+ // number of EMF records read
+ sal_uInt32 mnEMFRec;
+
+ // total size of embedded EMF data
+ sal_uInt32 mnEMFSize;
+
+ sal_uInt32 mnSkipActions;
+
+ // eventually handed over external header
+ const WmfExternal* mpExternalHeader;
+
+ bool mbEnableEMFPlus = true;
+
+ // reads header of the WMF-Datei
+ bool ReadHeader();
+
+ // reads parameters of the record with the functionnumber nFunction.
+ void ReadRecordParams(sal_uInt32 nRecordSize, sal_uInt16 nFunction);
+
+ Point ReadPoint(); // reads and converts a point (first X then Y)
+ Point ReadYX(); // reads and converts a point (first Y then X)
+ tools::Rectangle ReadRectangle(); // reads and converts a rectangle
+ Size ReadYXExt();
+ void GetPlaceableBound(tools::Rectangle& rSize, SvStream* pStrm);
+
+ public:
+ WmfReader(SvStream& rStreamWMF, GDIMetaFile& rGDIMetaFile, const WmfExternal* pExternalHeader);
+
+ // read WMF file from stream and fill the GDIMetaFile
+ void ReadWMF();
+
+ // Allows disabling EMF+ if EMF is embedded in this WMF.
+ void SetEnableEMFPlus(bool bEnableEMFPlus) { mbEnableEMFPlus = bEnableEMFPlus; }
+ };
+}
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */