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_VCL_SOURCE_FILTER_WMF_WINMTF_HXX
21 #define INCLUDED_VCL_SOURCE_FILTER_WMF_WINMTF_HXX
23 #include <sal/config.h>
25 #include <vcl/graph.hxx>
26 #include <basegfx/tools/b2dclipstate.hxx>
27 #include <vcl/font.hxx>
28 #include <vcl/bitmapaccess.hxx>
29 #include <vcl/lineinfo.hxx>
30 #include <vcl/fltcall.hxx>
31 #include <o3tl/make_unique.hxx>
35 #define COMPLEXREGION 3
52 #define MWT_IDENTITY 1
53 #define MWT_LEFTMULTIPLY 2
54 #define MWT_RIGHTMULTIPLY 3
57 #define ENHMETA_STOCK_OBJECT 0x80000000
59 /* Stock Logical Objects */
61 #define LTGRAY_BRUSH 1
63 #define DKGRAY_BRUSH 3
69 #define ANSI_FIXED_FONT 11
70 #define ANSI_VAR_FONT 12
71 #define SYSTEM_FIXED_FONT 16
73 enum class WMFRasterOp
{
86 #define MM_LOENGLISH 4
87 #define MM_HIENGLISH 5
89 #define MM_ISOTROPIC 7
90 #define MM_ANISOTROPIC 8
93 #define GM_COMPATIBLE 1
96 /* StretchBlt() modes */
97 #define BLACKONWHITE 1
98 #define WHITEONBLACK 2
99 #define COLORONCOLOR 3
101 #define STRETCH_ANDSCANS BLACKONWHITE
102 #define STRETCH_ORSCANS WHITEONBLACK
103 #define STRETCH_DELETESCANS COLORONCOLOR
105 #define LF_FACESIZE 32
111 sal_Int32 lfEscapement
;
112 sal_Int32 lfOrientation
;
115 sal_uInt8 lfUnderline
;
116 sal_uInt8 lfStrikeOut
;
118 sal_uInt8 lfOutPrecision
;
119 sal_uInt8 lfClipPrecision
;
121 sal_uInt8 lfPitchAndFamily
;
122 OUString alfFaceName
;
124 struct WMF_EXTERNALHEADER
;
126 #define TA_NOUPDATECP 0x0000
127 #define TA_UPDATECP 0x0001
128 #define TA_LEFT 0x0000
129 #define TA_RIGHT 0x0002
130 #define TA_CENTER 0x0006
131 #define TA_RIGHT_CENTER (TA_RIGHT | TA_CENTER)
132 #define TA_TOP 0x0000
133 #define TA_BOTTOM 0x0008
134 #define TA_BASELINE 0x0018
136 #define SRCCOPY 0x00CC0020L
137 #define SRCPAINT 0x00EE0086L
138 #define SRCAND 0x008800C6L
139 #define SRCINVERT 0x00660046L
140 #define SRCERASE 0x00440328L
141 #define PATCOPY 0x00F00021L
142 #define PATINVERT 0x005A0049L
143 #define BLACKNESS 0x00000042L
144 #define WHITENESS 0x00FF0062L
150 #define PS_DASHDOTDOT 4
152 #define PS_INSIDEFRAME 6
153 #define PS_STYLE_MASK 15
155 #define PS_ENDCAP_ROUND 0x000
156 #define PS_ENDCAP_SQUARE 0x100
157 #define PS_ENDCAP_FLAT 0x200
158 #define PS_ENDCAP_STYLE_MASK 0xF00
160 #define PS_JOIN_ROUND 0x0000
161 #define PS_JOIN_BEVEL 0x1000
162 #define PS_JOIN_MITER 0x2000
163 #define PS_JOIN_STYLE_MASK 0xF000
165 #define ANSI_CHARSET 0
166 #define DEFAULT_CHARSET 1
167 #define SYMBOL_CHARSET 2
168 #define SHIFTJIS_CHARSET 128
169 #define HANGEUL_CHARSET 129
170 #define GB2312_CHARSET 134
171 #define CHINESEBIG5_CHARSET 136
172 #define OEM_CHARSET 255
174 #define JOHAB_CHARSET 130
175 #define HEBREW_CHARSET 177
176 #define ARABIC_CHARSET 178
177 #define GREEK_CHARSET 161
178 #define TURKISH_CHARSET 162
179 #define VIETNAMESE_CHARSET 163
180 #define THAI_CHARSET 222
181 #define EASTEUROPE_CHARSET 238
182 #define RUSSIAN_CHARSET 204
183 #define MAC_CHARSET 77
184 #define BALTIC_CHARSET 186
186 #define ETO_CLIPPED 0x0004
188 #define ETO_GLYPH_INDEX 0x0010
189 #define ETO_RTLREADING 0x0080
190 /*_WIN32_WINNT >= 0x0500*/
191 #define ETO_PDY 0x2000
193 #define DEFAULT_PITCH 0x00
194 #define FIXED_PITCH 0x01
195 #define VARIABLE_PITCH 0x02
198 #define FF_DONTCARE 0x00
199 #define FF_ROMAN 0x10
200 #define FF_SWISS 0x20
201 #define FF_MODERN 0x30
202 #define FF_SCRIPT 0x40
203 #define FF_DECORATIVE 0x50
206 #define FW_EXTRALIGHT 200
208 #define FW_NORMAL 400
209 #define FW_MEDIUM 500
210 #define FW_SEMIBOLD 600
212 #define FW_EXTRABOLD 800
213 #define FW_ULTRALIGHT 200
214 #define FW_ULTRABOLD 800
223 #define BS_DIBPATTERN 5
224 #define BS_DIBPATTERNPT 6
225 #define BS_PATTERN8X8 7
226 #define BS_DIBPATTERN8X8 8
227 #define BS_MONOPATTERN 9
230 #define RDH_RECTANGLES 1
232 #define W_MFCOMMENT 15
234 #define PRIVATE_ESCAPE_UNICODE 2
238 #define UNDOCUMENTED_WIN_RCL_RELATION 32
239 #define MS_FIXPOINT_BITCOUNT_28_4 4
240 #define HUNDREDTH_MILLIMETERS_PER_MILLIINCH 2.54
241 #define MILLIINCH_PER_TWIPS 1.44
243 //============================ WMFReader ==================================
247 basegfx::tools::B2DClipState maClip
;
250 WinMtfClipPath(): maClip() {};
252 void setClipPath( const tools::PolyPolygon
& rPolyPolygon
, sal_Int32 nClippingMode
);
253 void intersectClipRect( const Rectangle
& rRect
);
254 void excludeClipRect( const Rectangle
& rRect
);
255 void moveClipRegion( const Size
& rSize
);
256 void setDefaultClipPath();
258 bool isEmpty() const { return maClip
.isCleared(); }
260 basegfx::B2DPolyPolygon
getClipPath() const;
262 bool operator==( const WinMtfClipPath
& rPath
) const
264 return maClip
== rPath
.maClip
;
268 class WinMtfPathObj
: public tools::PolyPolygon
285 void AddPoint( const Point
& rPoint
);
286 void AddPolygon( const tools::Polygon
& rPoly
);
287 void AddPolyLine( const tools::Polygon
& rPoly
);
288 void AddPolyPolygon( const tools::PolyPolygon
& rPolyPolygon
);
293 virtual ~GDIObj() = default; // Polymorphic base class
296 struct WinMtfFontStyle
: GDIObj
300 explicit WinMtfFontStyle( LOGFONTW
& rLogFont
);
304 enum class WinMtfFillStyleType
309 struct WinMtfFillStyle
: GDIObj
313 WinMtfFillStyleType aType
;
317 : aFillColor(Color(COL_BLACK
))
318 , bTransparent(false)
319 , aType(WinMtfFillStyleType::Solid
)
322 WinMtfFillStyle(const Color
& rColor
, bool bTrans
= false)
324 , bTransparent(bTrans
)
325 , aType(WinMtfFillStyleType::Solid
)
328 explicit WinMtfFillStyle(Bitmap
& rBmp
)
329 : bTransparent(false)
330 , aType(WinMtfFillStyleType::Pattern
)
334 bool operator==( const WinMtfFillStyle
& rStyle
)
336 return aFillColor
== rStyle
.aFillColor
337 && bTransparent
== rStyle
.bTransparent
338 && aType
== rStyle
.aType
;
342 struct WinMtfLineStyle
: GDIObj
349 : aLineColor (COL_BLACK
)
350 , bTransparent(false)
353 WinMtfLineStyle(const Color
& rColor
, bool bTrans
= false)
354 : aLineColor (rColor
)
355 , bTransparent(bTrans
)
358 WinMtfLineStyle( const Color
& rColor
, const LineInfo
& rStyle
, bool bTrans
)
359 : aLineColor (rColor
)
361 , bTransparent(bTrans
)
364 bool operator==( const WinMtfLineStyle
& rStyle
)
366 return aLineColor
== rStyle
.aLineColor
367 && bTransparent
== rStyle
.bTransparent
368 && aLineInfo
== rStyle
.aLineInfo
;
394 sal_uInt32 nMapMode
, nGfxMode
;
395 ComplexTextLayoutFlags nTextLayoutMode
;
396 sal_Int32 nWinOrgX
, nWinOrgY
, nWinExtX
, nWinExtY
;
397 sal_Int32 nDevOrgX
, nDevOrgY
, nDevWidth
, nDevHeight
;
399 WinMtfLineStyle aLineStyle
;
400 WinMtfFillStyle aFillStyle
;
405 sal_uInt32 nTextAlign
;
409 WinMtfPathObj aPathObj
;
410 WinMtfClipPath aClipPath
;
413 bool bFillStyleSelected
;
423 BSaveStruct(const Bitmap
& rBmp
, const Rectangle
& rOutRect
, sal_uInt32 nRop
)
429 BSaveStruct(const BitmapEx
& rBmpEx
, const Rectangle
& rOutRect
, sal_uInt32 nRop
)
437 class WinMtfOutput final
439 WinMtfPathObj aPathObj
;
440 WinMtfClipPath aClipPath
;
442 WinMtfLineStyle maLatestLineStyle
;
443 WinMtfLineStyle maLineStyle
;
444 WinMtfLineStyle m_NopLineStyle
;
445 WinMtfFillStyle maLatestFillStyle
;
446 WinMtfFillStyle maFillStyle
;
447 WinMtfFillStyle m_NopFillStyle
;
448 vcl::Font maLatestFont
;
450 sal_uInt32 mnLatestTextAlign
;
451 sal_uInt32 mnTextAlign
;
452 Color maLatestTextColor
;
454 Color maLatestBkColor
;
456 ComplexTextLayoutFlags mnLatestTextLayoutMode
;
457 ComplexTextLayoutFlags mnTextLayoutMode
;
458 BkMode mnLatestBkMode
;
460 RasterOp meLatestRasterOp
;
463 std::vector
< std::unique_ptr
<GDIObj
> > vGDIObj
;
469 bool mbFillStyleSelected
;
470 bool mbClipNeedsUpdate
;
473 std::vector
< std::shared_ptr
<SaveStruct
> > vSaveStack
;
475 sal_uInt32 mnGfxMode
;
476 sal_uInt32 mnMapMode
;
479 sal_Int32 mnDevOrgX
, mnDevOrgY
;
480 sal_Int32 mnDevWidth
, mnDevHeight
;
481 sal_Int32 mnWinOrgX
, mnWinOrgY
; // aktuel window origin
482 sal_Int32 mnWinExtX
, mnWinExtY
; // aktuel window extend
486 sal_Int32 mnPixX
, mnPixY
; // Reference Device in pixel
487 sal_Int32 mnMillX
, mnMillY
; // Reference Device in Mill
488 Rectangle mrclFrame
; // rectangle in logical units 1/100th mm
489 Rectangle mrclBounds
;
491 GDIMetaFile
* mpGDIMetaFile
;
493 void UpdateLineStyle();
494 void UpdateFillStyle();
496 Point
ImplMap( const Point
& rPt
);
497 Point
ImplScale( const Point
& rPt
);
498 Size
ImplMap( const Size
& rSize
, bool bDoWorldTransform
= true);
499 Rectangle
ImplMap( const Rectangle
& rRectangle
);
500 void ImplMap( vcl::Font
& rFont
);
501 tools::Polygon
& ImplMap( tools::Polygon
& rPolygon
);
502 tools::PolyPolygon
& ImplMap( tools::PolyPolygon
& rPolyPolygon
);
503 void ImplScale( tools::Polygon
& rPolygon
);
504 tools::PolyPolygon
& ImplScale( tools::PolyPolygon
& rPolyPolygon
);
505 void ImplResizeObjectArry( sal_uInt32 nNewEntry
);
506 void ImplSetNonPersistentLineColorTransparenz();
507 void ImplDrawClippedPolyPolygon( const tools::PolyPolygon
& rPolyPoly
);
508 void ImplDrawBitmap( const Point
& rPos
, const Size
& rSize
, const BitmapEx
& rBitmap
);
512 void SetDevByWin(); //Hack to set varying defaults for incompletely defined files.
513 void SetDevOrg( const Point
& rPoint
);
514 void SetDevOrgOffset( sal_Int32 nXAdd
, sal_Int32 nYAdd
);
515 void SetDevExt( const Size
& rSize
,bool regular
= true);
516 void ScaleDevExt( double fX
, double fY
);
518 void SetWinOrg( const Point
& rPoint
, bool bIsEMF
= false);
519 void SetWinOrgOffset( sal_Int32 nX
, sal_Int32 nY
);
520 void SetWinExt( const Size
& rSize
, bool bIsEMF
= false);
521 void ScaleWinExt( double fX
, double fY
);
523 void SetrclBounds( const Rectangle
& rRect
);
524 void SetrclFrame( const Rectangle
& rRect
);
525 void SetRefPix( const Size
& rSize
);
526 void SetRefMill( const Size
& rSize
);
528 void SetMapMode( sal_uInt32 mnMapMode
);
529 void SetWorldTransform( const XForm
& rXForm
);
530 void ModifyWorldTransform( const XForm
& rXForm
, sal_uInt32 nMode
);
535 WMFRasterOp
SetRasterOp( WMFRasterOp nRasterOp
);
536 void StrokeAndFillPath( bool bStroke
, bool bFill
);
538 void SetGfxMode( sal_Int32 nGfxMode
){ mnGfxMode
= nGfxMode
; };
539 sal_Int32
GetGfxMode() const { return mnGfxMode
; };
540 void SetBkMode( BkMode nMode
);
541 void SetBkColor( const Color
& rColor
);
542 void SetTextColor( const Color
& rColor
);
543 void SetTextAlign( sal_uInt32 nAlign
);
545 void CreateObject( std::unique_ptr
<GDIObj
> pObject
);
546 void CreateObjectIndexed( sal_Int32 nIndex
, std::unique_ptr
<GDIObj
> pObject
);
550 CreateObject(o3tl::make_unique
<GDIObj
>());
553 void DeleteObject( sal_Int32 nIndex
);
554 void SelectObject( sal_Int32 nIndex
);
555 rtl_TextEncoding
GetCharSet(){ return maFont
.GetCharSet(); };
556 const vcl::Font
& GetFont() const { return maFont
;}
557 void SetTextLayoutMode( ComplexTextLayoutFlags nLayoutMode
);
559 void ClearPath(){ aPathObj
.Init(); };
560 void ClosePath(){ aPathObj
.ClosePath(); };
561 const tools::PolyPolygon
& GetPathObj(){ return aPathObj
; };
563 void MoveTo( const Point
& rPoint
, bool bRecordPath
= false );
564 void LineTo( const Point
& rPoint
, bool bRecordPath
= false );
565 void DrawPixel( const Point
& rSource
, const Color
& rColor
);
566 void DrawRect( const Rectangle
& rRect
, bool bEdge
= true );
567 void DrawRoundRect( const Rectangle
& rRect
, const Size
& rSize
);
568 void DrawEllipse( const Rectangle
& rRect
);
570 const Rectangle
& rRect
,
571 const Point
& rStartAngle
,
572 const Point
& rEndAngle
,
576 const Rectangle
& rRect
,
577 const Point
& rStartAngle
,
578 const Point
& rEndAngle
581 const Rectangle
& rRect
,
582 const Point
& rStartAngle
,
583 const Point
& rEndAngle
585 void DrawPolygon( tools::Polygon
& rPolygon
, bool bRecordPath
= false );
586 void DrawPolygon( tools::Polygon
& rPolygon
, bool /*bDrawTo*/, bool bRecordPath
)
588 //For ReadAndDrawPolygon template compatibility
589 DrawPolygon(rPolygon
, bRecordPath
);
591 void DrawPolyPolygon( tools::PolyPolygon
& rPolyPolygon
, bool bRecordPath
= false );
592 void DrawPolyLine( tools::Polygon
& rPolygon
,
593 bool bDrawTo
= false,
594 bool bRecordPath
= false
596 void DrawPolyBezier( tools::Polygon
& rPolygin
,
600 void DrawText( Point
& rPosition
,
602 long* pDXArry
= nullptr,
603 bool bRecordPath
= false,
604 sal_Int32 nGraphicsMode
= GM_COMPATIBLE
);
606 void ResolveBitmapActions( std::vector
<std::unique_ptr
<BSaveStruct
>>& rSaveList
);
608 void IntersectClipRect( const Rectangle
& rRect
);
609 void ExcludeClipRect( const Rectangle
& rRect
);
610 void MoveClipRegion( const Size
& rSize
);
612 const tools::PolyPolygon
& rPolyPoly
,
613 sal_Int32 nClippingMode
,
616 void SetDefaultClipPath();
617 void UpdateClipRegion();
618 void AddFromGDIMetaFile( GDIMetaFile
& rGDIMetaFile
);
620 void PassEMFPlus( void* pBuffer
, sal_uInt32 nLength
);
621 void PassEMFPlusHeaderInfo();
623 explicit WinMtfOutput( GDIMetaFile
& rGDIMetaFile
);
631 std::unique_ptr
<WinMtfOutput
> pOut
;
632 SvStream
* pWMF
; // the WMF/EMF file to be read
634 sal_uInt32 nStartPos
, nEndPos
;
635 std::vector
<std::unique_ptr
<BSaveStruct
>> aBmpSaveList
;
637 FilterConfigItem
* pFilterConfigItem
;
639 css::uno::Reference
< css::task::XStatusIndicator
> xStatusIndicator
;
641 // assures aSampledBrush is the actual brush of the GDIMetaFile
644 void Callback( sal_uInt16 nPercent
);
647 GDIMetaFile
& rGDIMetaFile
,
648 SvStream
& rStreamWMF
,
649 FilterConfigItem
* pConfigItem
654 class EnhWMFReader
: public WinMtf
657 sal_Int32 nRecordCount
;
661 // reads and converts the rectangle
662 static Rectangle
ReadRectangle( sal_Int32
, sal_Int32
, sal_Int32
, sal_Int32
);
665 EnhWMFReader(SvStream
& rStreamWMF
, GDIMetaFile
& rGDIMetaFile
, FilterConfigItem
* pConfigItem
= nullptr);
670 template <class T
> void ReadAndDrawPolyPolygon();
671 template <class T
> void ReadAndDrawPolyLine();
672 template <class T
> tools::Polygon
ReadPolygon(sal_uInt32 nStartIndex
, sal_uInt32 nPoints
);
673 template <class T
, class Drawer
> void ReadAndDrawPolygon(Drawer drawer
, const bool skipFirst
);
675 Rectangle
ReadRectangle();
676 void ReadEMFPlusComment(sal_uInt32 length
, bool& bHaveDC
);
679 class WMFReader
: public WinMtf
683 sal_uInt16 nUnitsPerInch
;
687 std::unique_ptr
<SvMemoryStream
> pEMFStream
;
689 // total number of comment records containing EMF data
690 sal_uInt32 nEMFRecCount
;
692 // number of EMF records read
695 // total size of embedded EMF data
698 sal_uInt32 nSkipActions
;
699 sal_uInt32 nCurrentAction
;
701 WMF_EXTERNALHEADER
* pExternalHeader
;
703 // reads header of the WMF-Datei
706 // reads parameters of the record with the functionnumber nFunction.
707 void ReadRecordParams( sal_uInt16 nFunction
);
709 Point
ReadPoint(); // reads and converts a point (first X then Y)
710 Point
ReadYX(); // reads and converts a point (first Y then X)
711 Rectangle
ReadRectangle(); // reads and converts a rectangle
713 void GetPlaceableBound( Rectangle
& rSize
, SvStream
* pStrm
);
717 WMFReader(SvStream
& rStreamWMF
, GDIMetaFile
& rGDIMetaFile
,
718 FilterConfigItem
* pConfigItem
,
719 WMF_EXTERNALHEADER
* pExtHeader
= nullptr);
721 // read WMF file from stream and fill the GDIMetaFile
727 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */