b9eaed7a4c
EMR_EXTSELECTCLIPRGN would not factor in WinOrg coordinates which would give the clip box wrong coordinates causing some graphics to look chopped in the wrong way. Change-Id: I4f9a1b1c27fc276d188d0d865991795dab48dce5 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/142110 Tested-by: Jenkins Reviewed-by: Miklos Vajna <vmiklos@collabora.com>
843 lines
29 KiB
C++
843 lines
29 KiB
C++
/* -*- 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);
|
|
Point GetWinOrg() { return Point(mnWinOrgX, mnWinOrgY); }
|
|
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: */
|