1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #ifndef INCLUDED_EMFIO_INC_MTFTOOLS_HXX
21 #define INCLUDED_EMFIO_INC_MTFTOOLS_HXX
23 #include <config_options.h>
24 #include <basegfx/utils/b2dclipstate.hxx>
25 #include <tools/poly.hxx>
26 #include <vcl/font.hxx>
27 #include <vcl/bitmapex.hxx>
28 #include <vcl/lineinfo.hxx>
29 #include <vcl/outdevstate.hxx>
30 #include <rtl/ref.hxx>
32 #include "emfiodllapi.h"
36 #define COMPLEXREGION 3
55 #define MWT_IDENTITY 1
56 #define MWT_LEFTMULTIPLY 2
57 #define MWT_RIGHTMULTIPLY 3
60 #define ENHMETA_STOCK_OBJECT 0x80000000
62 /* Stock Logical Objects */
64 #define LTGRAY_BRUSH 1
66 #define DKGRAY_BRUSH 3
72 #define ANSI_FIXED_FONT 11
73 #define ANSI_VAR_FONT 12
74 #define SYSTEM_FIXED_FONT 16
78 enum class WMFRasterOp
{
92 #define MM_LOENGLISH 4
93 #define MM_HIENGLISH 5
95 #define MM_ISOTROPIC 7
96 #define MM_ANISOTROPIC 8
99 #define GM_COMPATIBLE 1
100 #define GM_ADVANCED 2
102 /* StretchBlt() modes */
103 #define BLACKONWHITE 1
104 #define WHITEONBLACK 2
105 #define COLORONCOLOR 3
107 #define STRETCH_ANDSCANS BLACKONWHITE
108 #define STRETCH_ORSCANS WHITEONBLACK
109 #define STRETCH_DELETESCANS COLORONCOLOR
111 #define LF_FACESIZE 32
119 sal_Int32 lfEscapement
;
120 sal_Int32 lfOrientation
;
123 sal_uInt8 lfUnderline
;
124 sal_uInt8 lfStrikeOut
;
126 sal_uInt8 lfOutPrecision
;
127 sal_uInt8 lfClipPrecision
;
129 sal_uInt8 lfPitchAndFamily
;
130 OUString alfFaceName
;
144 , lfPitchAndFamily(0)
150 #define TA_NOUPDATECP 0x0000
151 #define TA_UPDATECP 0x0001
152 #define TA_LEFT 0x0000
153 #define TA_RIGHT 0x0002
154 #define TA_CENTER 0x0006
155 #define TA_RIGHT_CENTER (TA_RIGHT | TA_CENTER)
156 #define TA_TOP 0x0000
157 #define TA_BOTTOM 0x0008
158 #define TA_BASELINE 0x0018
160 #define SRCCOPY 0x00CC0020L
161 #define SRCPAINT 0x00EE0086L
162 #define SRCAND 0x008800C6L
163 #define SRCINVERT 0x00660046L
164 #define SRCERASE 0x00440328L
165 #define PATCOPY 0x00F00021L
166 #define PATINVERT 0x005A0049L
167 #define BLACKNESS 0x00000042L
168 #define WHITENESS 0x00FF0062L
174 #define PS_DASHDOTDOT 4
176 #define PS_INSIDEFRAME 6
177 #define PS_STYLE_MASK 15
179 #define PS_ENDCAP_ROUND 0x000
180 #define PS_ENDCAP_SQUARE 0x100
181 #define PS_ENDCAP_FLAT 0x200
182 #define PS_ENDCAP_STYLE_MASK 0xF00
184 #define PS_JOIN_ROUND 0x0000
185 #define PS_JOIN_BEVEL 0x1000
186 #define PS_JOIN_MITER 0x2000
187 #define PS_JOIN_STYLE_MASK 0xF000
189 #define ANSI_CHARSET 0
190 #define DEFAULT_CHARSET 1
191 #define SYMBOL_CHARSET 2
192 #define SHIFTJIS_CHARSET 128
193 #define HANGEUL_CHARSET 129
194 #define GB2312_CHARSET 134
195 #define CHINESEBIG5_CHARSET 136
196 #define OEM_CHARSET 255
198 #define JOHAB_CHARSET 130
199 #define HEBREW_CHARSET 177
200 #define ARABIC_CHARSET 178
201 #define GREEK_CHARSET 161
202 #define TURKISH_CHARSET 162
203 #define VIETNAMESE_CHARSET 163
204 #define THAI_CHARSET 222
205 #define EASTEUROPE_CHARSET 238
206 #define RUSSIAN_CHARSET 204
207 #define MAC_CHARSET 77
208 #define BALTIC_CHARSET 186
210 #define ETO_CLIPPED 0x0004
212 #define ETO_GLYPH_INDEX 0x0010
213 #define ETO_RTLREADING 0x0080
214 /*_WIN32_WINNT >= 0x0500*/
215 #define ETO_PDY 0x2000
217 #define DEFAULT_PITCH 0x00
218 #define FIXED_PITCH 0x01
219 #define VARIABLE_PITCH 0x02
222 #define FF_DONTCARE 0x00
223 #define FF_ROMAN 0x10
224 #define FF_SWISS 0x20
225 #define FF_MODERN 0x30
226 #define FF_SCRIPT 0x40
227 #define FF_DECORATIVE 0x50
230 #define FW_EXTRALIGHT 200
232 #define FW_NORMAL 400
233 #define FW_MEDIUM 500
234 #define FW_SEMIBOLD 600
236 #define FW_EXTRABOLD 800
237 #define FW_ULTRALIGHT 200
238 #define FW_ULTRABOLD 800
247 #define BS_DIBPATTERN 5
248 #define BS_DIBPATTERNPT 6
249 #define BS_PATTERN8X8 7
250 #define BS_DIBPATTERN8X8 8
251 #define BS_MONOPATTERN 9
253 #define RDH_RECTANGLES 1
254 #define W_MFCOMMENT 15
255 #define PRIVATE_ESCAPE_UNICODE 2
258 #define UNDOCUMENTED_WIN_RCL_RELATION 32
259 #define MS_FIXPOINT_BITCOUNT_28_4 4
260 #define HUNDREDTH_MILLIMETERS_PER_MILLIINCH 2.54
261 #define MILLIINCH_PER_TWIPS 1.44
263 class MetaFontAction
;
265 //============================ WmfReader ==================================
271 basegfx::utils::B2DClipState maClip
;
274 WinMtfClipPath() : maClip() {};
276 void setClipPath(const basegfx::B2DPolyPolygon
&, sal_Int32 nClippingMode
);
277 void intersectClip(const basegfx::B2DPolyPolygon
& rPolyPolygon
);
278 void excludeClip(const basegfx::B2DPolyPolygon
& rPolyPolygon
);
279 void moveClipRegion(const Size
& rSize
);
280 void setDefaultClipPath();
282 bool isEmpty() const { return maClip
.isCleared(); }
284 basegfx::utils::B2DClipState
const & getClip() const { return maClip
; }
285 basegfx::B2DPolyPolygon
const & getClipPath() const;
287 bool operator==(const WinMtfClipPath
& rPath
) const
289 return maClip
== rPath
.maClip
;
293 class WinMtfPathObj
: public tools::PolyPolygon
310 void AddPoint(const Point
& rPoint
);
311 void AddPolygon(const tools::Polygon
& rPoly
);
312 void AddPolyLine(const tools::Polygon
& rPoly
);
313 void AddPolyPolygon(const tools::PolyPolygon
& rPolyPolygon
);
316 struct EMFIO_DLLPUBLIC GDIObj
318 virtual ~GDIObj() = default; // Polymorphic base class
321 struct UNLESS_MERGELIBS(EMFIO_DLLPUBLIC
) WinMtfFontStyle final
: GDIObj
325 explicit WinMtfFontStyle(LOGFONTW
const & rLogFont
);
328 enum class WinMtfFillStyleType
333 struct WinMtfFillStyle final
: GDIObj
337 WinMtfFillStyleType aType
;
341 : aFillColor(COL_BLACK
)
342 , bTransparent(false)
343 , aType(WinMtfFillStyleType::Solid
)
346 WinMtfFillStyle(const Color
& rColor
, bool bTrans
= false)
348 , bTransparent(bTrans
)
349 , aType(WinMtfFillStyleType::Solid
)
352 explicit WinMtfFillStyle(Bitmap
const & rBmp
)
353 : bTransparent(false)
354 , aType(WinMtfFillStyleType::Pattern
)
358 bool operator==(const WinMtfFillStyle
& rStyle
) const
360 return aFillColor
== rStyle
.aFillColor
361 && bTransparent
== rStyle
.bTransparent
362 && aType
== rStyle
.aType
;
367 struct WinMtfPalette final
: GDIObj
369 std::vector
< Color
> aPaletteColors
;
372 : aPaletteColors(std::vector
< Color
>{})
375 WinMtfPalette(const std::vector
< Color
> rPaletteColors
)
376 : aPaletteColors(rPaletteColors
)
382 struct WinMtfLineStyle final
: GDIObj
389 : aLineColor(COL_BLACK
)
390 , bTransparent(false)
393 WinMtfLineStyle(const Color
& rColor
, bool bTrans
= false)
395 , bTransparent(bTrans
)
398 WinMtfLineStyle(const Color
& rColor
, const LineInfo
& rStyle
, bool bTrans
)
401 , bTransparent(bTrans
)
404 bool operator==(const WinMtfLineStyle
& rStyle
) const
406 return aLineColor
== rStyle
.aLineColor
407 && bTransparent
== rStyle
.bTransparent
408 && aLineInfo
== rStyle
.aLineInfo
;
431 SvStream
& operator >> (SvStream
& rInStream
, XForm
& rXForm
);
436 sal_uInt32 nMapMode
, nGfxMode
;
437 ComplexTextLayoutFlags nTextLayoutMode
;
438 sal_Int32 nWinOrgX
, nWinOrgY
, nWinExtX
, nWinExtY
;
439 sal_Int32 nDevOrgX
, nDevOrgY
, nDevWidth
, nDevHeight
;
441 WinMtfLineStyle aLineStyle
;
442 WinMtfFillStyle aFillStyle
;
447 sal_uInt32 nTextAlign
;
451 WinMtfPathObj maPathObj
;
452 WinMtfClipPath maClipPath
;
455 bool bFillStyleSelected
;
461 tools::Rectangle aOutRect
;
463 bool m_bForceAlpha
= false;
465 BSaveStruct(const Bitmap
& rBmp
, const tools::Rectangle
& rOutRect
, sal_uInt32 nRop
)
471 BSaveStruct(const BitmapEx
& rBmpEx
, const tools::Rectangle
& rOutRect
, sal_uInt32 nRop
,
472 bool bForceAlpha
= false)
476 , m_bForceAlpha(bForceAlpha
)
480 // tdf#127471 implement detection and correction of wrongly scaled
481 // fonts in own-written, old (before this fix) EMF/WMF files
482 class ScaledFontDetectCorrectHelper
485 rtl::Reference
<MetaFontAction
> maCurrentMetaFontAction
;
486 std::vector
<double> maAlternativeFontScales
;
487 std::vector
<std::pair
<rtl::Reference
<MetaFontAction
>, double>> maPositiveIdentifiedCases
;
488 std::vector
<std::pair
<rtl::Reference
<MetaFontAction
>, double>> maNegativeIdentifiedCases
;
491 ScaledFontDetectCorrectHelper();
492 void endCurrentMetaFontAction();
493 void newCurrentMetaFontAction(rtl::Reference
<MetaFontAction
>& rNewMetaFontAction
);
494 void evaluateAlternativeFontScale(OUString
const & rText
, tools::Long nImportedTextLength
);
495 void applyAlternativeFontScale();
500 MtfTools(MtfTools
const &) = delete;
501 MtfTools
& operator =(MtfTools
const &) = delete;
504 WinMtfPathObj maPathObj
;
505 WinMtfClipPath maClipPath
;
507 WinMtfLineStyle maLatestLineStyle
;
508 WinMtfLineStyle maLineStyle
;
509 WinMtfLineStyle maNopLineStyle
;
510 WinMtfFillStyle maLatestFillStyle
;
511 WinMtfFillStyle maFillStyle
;
512 WinMtfFillStyle maNopFillStyle
;
513 WinMtfPalette maPalette
;
515 vcl::Font maLatestFont
;
517 sal_uInt32 mnLatestTextAlign
;
518 sal_uInt32 mnTextAlign
;
519 Color maLatestTextColor
;
521 Color maLatestBkColor
;
523 ComplexTextLayoutFlags mnLatestTextLayoutMode
;
524 ComplexTextLayoutFlags mnTextLayoutMode
;
525 BkMode mnLatestBkMode
;
527 RasterOp meLatestRasterOp
;
530 std::vector
< std::unique_ptr
<GDIObj
> > mvGDIObj
;
533 std::vector
< std::shared_ptr
<SaveStruct
> > mvSaveStack
;
535 sal_uInt32 mnGfxMode
;
536 sal_uInt32 mnMapMode
;
541 sal_Int32 mnDevWidth
;
542 sal_Int32 mnDevHeight
;
548 sal_Int32 mnPixX
; // Reference Device in pixel
549 sal_Int32 mnPixY
; // Reference Device in pixel
550 sal_Int32 mnMillX
; // Reference Device in Mill
551 sal_Int32 mnMillY
; // Reference Device in Mill
552 tools::Rectangle mrclFrame
;
553 tools::Rectangle mrclBounds
;
555 GDIMetaFile
* mpGDIMetaFile
;
557 SvStream
* mpInputStream
; // the WMF/EMF file to be read
558 sal_uInt32 mnStartPos
;
560 std::vector
<std::unique_ptr
<BSaveStruct
>> maBmpSaveList
;
562 // tdf#127471 always try to detect - only used with ScaledText
563 ScaledFontDetectCorrectHelper maScaledFontHelper
;
566 bool mbFillStyleSelected
: 1;
567 bool mbClipNeedsUpdate
: 1;
568 bool mbComplexClip
: 1;
569 bool mbIsMapWinSet
: 1;
570 bool mbIsMapDevSet
: 1;
572 void UpdateLineStyle();
573 void UpdateFillStyle();
575 Point
ImplMap(const Point
& rPt
);
576 Point
ImplScale(const Point
& rPt
);
577 Size
ImplMap(const Size
& rSize
, bool bDoWorldTransform
= true);
578 tools::Rectangle
ImplMap(const tools::Rectangle
& rRectangle
);
579 void ImplMap(vcl::Font
& rFont
);
580 tools::Polygon
& ImplMap(tools::Polygon
& rPolygon
);
581 tools::PolyPolygon
& ImplMap(tools::PolyPolygon
& rPolyPolygon
);
582 void ImplScale(tools::Polygon
& rPolygon
);
583 tools::PolyPolygon
& ImplScale(tools::PolyPolygon
& rPolyPolygon
);
584 void ImplResizeObjectArry(sal_uInt32 nNewEntry
);
585 void ImplSetNonPersistentLineColorTransparenz();
586 void ImplDrawClippedPolyPolygon(const tools::PolyPolygon
& rPolyPoly
);
587 void ImplDrawBitmap(const Point
& rPos
, const Size
& rSize
, const BitmapEx
& rBitmap
);
591 void SetDevByWin(); //Hack to set varying defaults for incompletely defined files.
592 void SetDevOrg(const Point
& rPoint
);
593 void SetDevOrgOffset(sal_Int32 nXAdd
, sal_Int32 nYAdd
);
594 void SetDevExt(const Size
& rSize
, bool regular
= true);
595 void ScaleDevExt(double fX
, double fY
);
597 void SetWinOrg(const Point
& rPoint
, bool bIsEMF
= false);
598 void SetWinOrgOffset(sal_Int32 nX
, sal_Int32 nY
);
599 void SetWinExt(const Size
& rSize
, bool bIsEMF
= false);
600 void ScaleWinExt(double fX
, double fY
);
602 void SetrclBounds(const tools::Rectangle
& rRect
);
603 void SetrclFrame(const tools::Rectangle
& rRect
);
604 void SetRefPix(const Size
& rSize
);
605 void SetRefMill(const Size
& rSize
);
607 void SetMapMode(sal_uInt32 mnMapMode
);
608 void SetWorldTransform(const XForm
& rXForm
);
609 void ModifyWorldTransform(const XForm
& rXForm
, sal_uInt32 nMode
);
614 WMFRasterOp
SetRasterOp(WMFRasterOp nRasterOp
);
615 void StrokeAndFillPath(bool bStroke
, bool bFill
);
617 void SetGfxMode(sal_Int32 nGfxMode
) { mnGfxMode
= nGfxMode
; };
618 sal_Int32
GetGfxMode() const { return mnGfxMode
; };
619 void SetBkMode(BkMode nMode
);
620 void SetBkColor(const Color
& rColor
);
621 void SetTextColor(const Color
& rColor
);
622 void SetTextAlign(sal_uInt32 nAlign
);
624 void CreateObject(std::unique_ptr
<GDIObj
> pObject
);
625 void CreateObjectIndexed(sal_Int32 nIndex
, std::unique_ptr
<GDIObj
> pObject
);
628 void DeleteObject(sal_Int32 nIndex
);
629 void SelectObject(sal_Int32 nIndex
);
630 rtl_TextEncoding
GetCharSet() const { return maFont
.GetCharSet(); };
631 const vcl::Font
& GetFont() const { return maFont
; }
632 void SetTextLayoutMode(ComplexTextLayoutFlags nLayoutMode
);
634 void ClearPath() { maPathObj
.Init(); };
635 void ClosePath() { maPathObj
.ClosePath(); };
636 const tools::PolyPolygon
& GetPathObj() const { return maPathObj
; };
638 void MoveTo(const Point
& rPoint
, bool bRecordPath
= false);
639 void LineTo(const Point
& rPoint
, bool bRecordPath
= false);
640 void DrawPixel(const Point
& rSource
, const Color
& rColor
);
641 void DrawRect(const tools::Rectangle
& rRect
, bool bEdge
= true);
642 void DrawRoundRect(const tools::Rectangle
& rRect
, const Size
& rSize
);
643 void DrawEllipse(const tools::Rectangle
& rRect
);
645 const tools::Rectangle
& rRect
,
646 const Point
& rStartAngle
,
647 const Point
& rEndAngle
,
651 const tools::Rectangle
& rRect
,
652 const Point
& rStartAngle
,
653 const Point
& rEndAngle
656 const tools::Rectangle
& rRect
,
657 const Point
& rStartAngle
,
658 const Point
& rEndAngle
660 void DrawPolygon(tools::Polygon rPolygon
, bool bRecordPath
);
661 void DrawPolyPolygon(tools::PolyPolygon
& rPolyPolygon
, bool bRecordPath
= false);
662 void DrawPolyLine(tools::Polygon rPolygon
,
663 bool bDrawTo
= false,
664 bool bRecordPath
= false
666 void DrawPolyBezier(tools::Polygon rPolygon
,
670 void DrawText(Point
& rPosition
,
671 OUString
const & rString
,
672 tools::Long
* pDXArry
= nullptr,
673 tools::Long
* pDYArry
= nullptr,
674 bool bRecordPath
= false,
675 sal_Int32 nGraphicsMode
= GM_COMPATIBLE
);
677 void ResolveBitmapActions(std::vector
<std::unique_ptr
<BSaveStruct
>>& rSaveList
);
679 void IntersectClipRect(const tools::Rectangle
& rRect
);
680 void ExcludeClipRect(const tools::Rectangle
& rRect
);
681 void MoveClipRegion(const Size
& rSize
);
683 const tools::PolyPolygon
& rPolyPoly
,
684 sal_Int32 nClippingMode
,
687 void SetDefaultClipPath();
688 void UpdateClipRegion();
689 void AddFromGDIMetaFile(GDIMetaFile
& rGDIMetaFile
);
691 void PassEMFPlus(void const * pBuffer
, sal_uInt32 nLength
);
692 void PassEMFPlusHeaderInfo();
696 explicit MtfTools(GDIMetaFile
& rGDIMetaFile
, SvStream
& rStreamWMF
);
697 ~MtfTools() COVERITY_NOEXCEPT_FALSE
;
703 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */