/* -*- 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 .
*/
#pragma once
#include <wmfemfhelper.hxx>
#include <basegfx/matrix/b2dhommatrix.hxx>
#include <drawinglayer/attribute/linestartendattribute.hxx>
#include <tools/stream.hxx>
#include <basegfx/point/b2dpoint.hxx>
#include <map>
// predefines
namespace basegfx { class B2DPolyPolygon; }
namespace emfplushelper
{
// EMF+ commands
#define EmfPlusRecordTypeHeader 0 x4001
#define EmfPlusRecordTypeEndOfFile 0 x4002
#define EmfPlusRecordTypeComment 0 x4003
#define EmfPlusRecordTypeGetDC 0 x4004
//TODO EmfPlusRecordTypeMultiFormatStart 0x4005
//TODO EmfPlusRecordTypeMultiFormatSection 0x4006
//TODO EmfPlusRecordTypeMultiFormatEnd 0x4007
#define EmfPlusRecordTypeObject 0 x4008
//TODO EmfPlusRecordTypeClear 0x4009
#define EmfPlusRecordTypeFillRects 0 x400A
#define EmfPlusRecordTypeDrawRects 0 x400B
#define EmfPlusRecordTypeFillPolygon 0 x400C
#define EmfPlusRecordTypeDrawLines 0 x400D
#define EmfPlusRecordTypeFillEllipse 0 x400E
#define EmfPlusRecordTypeDrawEllipse 0 x400F
#define EmfPlusRecordTypeFillPie 0 x4010
#define EmfPlusRecordTypeDrawPie 0 x4011
#define EmfPlusRecordTypeDrawArc 0 x4012
#define EmfPlusRecordTypeFillRegion 0 x4013
#define EmfPlusRecordTypeFillPath 0 x4014
#define EmfPlusRecordTypeDrawPath 0 x4015
#define EmfPlusRecordTypeFillClosedCurve 0 x4016
#define EmfPlusRecordTypeDrawClosedCurve 0 x4017
#define EmfPlusRecordTypeDrawCurve 0 x4018
#define EmfPlusRecordTypeDrawBeziers 0 x4019
#define EmfPlusRecordTypeDrawImage 0 x401A
#define EmfPlusRecordTypeDrawImagePoints 0 x401B
#define EmfPlusRecordTypeDrawString 0 x401C
#define EmfPlusRecordTypeSetRenderingOrigin 0 x401D
#define EmfPlusRecordTypeSetAntiAliasMode 0 x401E
#define EmfPlusRecordTypeSetTextRenderingHint 0 x401F
#define EmfPlusRecordTypeSetTextContrast 0 x4020
#define EmfPlusRecordTypeSetInterpolationMode 0 x4021
#define EmfPlusRecordTypeSetPixelOffsetMode 0 x4022
//TODO EmfPlusRecordTypeSetCompositingMode 0x4023
#define EmfPlusRecordTypeSetCompositingQuality 0 x4024
#define EmfPlusRecordTypeSave 0 x4025
#define EmfPlusRecordTypeRestore 0 x4026
#define EmfPlusRecordTypeBeginContainer 0 x4027
#define EmfPlusRecordTypeBeginContainerNoParams 0 x4028
#define EmfPlusRecordTypeEndContainer 0 x4029
#define EmfPlusRecordTypeSetWorldTransform 0 x402A
#define EmfPlusRecordTypeResetWorldTransform 0 x402B
#define EmfPlusRecordTypeMultiplyWorldTransform 0 x402C
#define EmfPlusRecordTypeTranslateWorldTransform 0 x402D
#define EmfPlusRecordTypeScaleWorldTransform 0 x402E
#define EmfPlusRecordTypeRotateWorldTransform 0 x402F
#define EmfPlusRecordTypeSetPageTransform 0 x4030
#define EmfPlusRecordTypeResetClip 0 x4031
#define EmfPlusRecordTypeSetClipRect 0 x4032
#define EmfPlusRecordTypeSetClipPath 0 x4033
#define EmfPlusRecordTypeSetClipRegion 0 x4034
#define EmfPlusRecordTypeOffsetClip 0 x4035
#define EmfPlusRecordTypeDrawDriverString 0 x4036
//TODO EmfPlusRecordTypeStrokeFillPath 0x4037
//TODO EmfPlusRecordTypeSerializableObject 0x4038
//TODO EmfPlusRecordTypeSetTSGraphics 0x4039
//TODO EmfPlusRecordTypeSetTSClip 0x403A
// EMF+object types
#define EmfPlusObjectTypeBrush 0 x100
#define EmfPlusObjectTypePen 0 x200
#define EmfPlusObjectTypePath 0 x300
#define EmfPlusObjectTypeRegion 0 x400
#define EmfPlusObjectTypeImage 0 x500
#define EmfPlusObjectTypeFont 0 x600
#define EmfPlusObjectTypeStringFormat 0 x700
#define EmfPlusObjectTypeImageAttributes 0 x800
#define EmfPlusObjectTypeCustomLineCap 0 x900
enum PixelOffsetMode
{
PixelOffsetModeDefault = 0 x00,
PixelOffsetModeHighSpeed = 0 x01,
PixelOffsetModeHighQuality = 0 x02,
PixelOffsetModeNone = 0 x03,
PixelOffsetModeHalf = 0 x04
};
enum SmoothingMode
{
SmoothingModeDefault = 0 x00,
SmoothingModeHighSpeed = 0 x01,
SmoothingModeHighQuality = 0 x02,
SmoothingModeNone = 0 x03,
SmoothingModeAntiAlias8x4 = 0 x04,
SmoothingModeAntiAlias8x8 = 0 x05
};
enum InterpolationMode
{
InterpolationModeDefault = 0 x00,
InterpolationModeLowQuality = 0 x01,
InterpolationModeHighQuality = 0 x02,
InterpolationModeBilinear = 0 x03,
InterpolationModeBicubic = 0 x04,
InterpolationModeNearestNeighbor = 0 x05,
InterpolationModeHighQualityBilinear = 0 x06,
InterpolationModeHighQualityBicubic = 0 x07
};
enum TextRenderingHint
{
TextRenderingHintSystemDefault = 0 x00,
TextRenderingHintSingleBitPerPixelGridFit = 0 x01,
TextRenderingHintSingleBitPerPixel = 0 x02,
TextRenderingHintAntialiasGridFit = 0 x03,
TextRenderingHintAntialias = 0 x04,
TextRenderingHintClearTypeGridFit = 0 x05
};
enum UnitType
{
UnitTypeWorld = 0 x00,
UnitTypeDisplay = 0 x01,
UnitTypePixel = 0 x02,
UnitTypePoint = 0 x03,
UnitTypeInch = 0 x04,
UnitTypeDocument = 0 x05,
UnitTypeMillimeter = 0 x06
};
enum EmfPlusCombineMode
{
EmfPlusCombineModeReplace = 0 x00000000,
EmfPlusCombineModeIntersect = 0 x00000001,
EmfPlusCombineModeUnion = 0 x00000002,
EmfPlusCombineModeXOR = 0 x00000003,
EmfPlusCombineModeExclude = 0 x00000004,
EmfPlusCombineModeComplement = 0 x00000005
};
const char * emfTypeToName(sal_uInt16 type);
OUString UnitTypeToString(sal_uInt16 nType);
struct EMFPObject
{
virtual ~EMFPObject();
};
typedef std::map<int , wmfemfhelper::PropertyHolder> GraphicStateMap;
struct EmfPlusHelperData
{
private :
/* EMF+ */
basegfx::B2DHomMatrix maBaseTransform;
basegfx::B2DHomMatrix maWorldTransform;
basegfx::B2DHomMatrix maMapTransform;
std::unique_ptr<EMFPObject> maEMFPObjects[256 ];
float mfPageScale;
sal_Int32 mnOriginX;
sal_Int32 mnOriginY;
sal_uInt32 mnHDPI;
sal_uInt32 mnVDPI;
bool mbSetTextContrast;
sal_uInt16 mnTextContrast;
/* EMF+ emf header info */
sal_Int32 mnFrameLeft;
sal_Int32 mnFrameTop;
sal_Int32 mnFrameRight;
sal_Int32 mnFrameBottom;
sal_Int32 mnPixX;
sal_Int32 mnPixY;
sal_Int32 mnMmX;
sal_Int32 mnMmY;
/* multipart object data */
bool mbMultipart;
sal_uInt16 mMFlags;
SvMemoryStream mMStream;
/* emf+ graphic state stack */
GraphicStateMap mGSStack;
GraphicStateMap mGSContainerStack;
/* Performance optimizators */
/* Extracted Scale values from Transformation Matrix */
double mdExtractedXScale;
double mdExtractedYScale;
/// data holders
wmfemfhelper::TargetHolders& mrTargetHolders;
wmfemfhelper::PropertyHolders& mrPropertyHolders;
wmfemfhelper::PropertyHolder aGetDCState;
bool bIsGetDCProcessing;
// readers
void processObjectRecord(SvMemoryStream& rObjectStream, sal_uInt16 flags, sal_uInt32 dataSize, bool bUseWholeStream = false );
static void ReadPoint(SvStream& s, float & x, float & y, sal_uInt32 flags);
// internal mapper
void mappingChanged();
// stack actions
void GraphicStatePush(GraphicStateMap& map, sal_Int32 index);
void GraphicStatePop(GraphicStateMap& map, sal_Int32 index);
drawinglayer::attribute::LineStartEndAttribute CreateLineEnd(const sal_Int32 aCap,
const float aPenWidth) const ;
// primitive creators
void EMFPPlusDrawPolygon(const ::basegfx::B2DPolyPolygon& polygon, sal_uInt32 penIndex);
void EMFPPlusFillPolygon(const ::basegfx::B2DPolyPolygon& polygon, const bool isColor, const sal_uInt32 brushIndexOrColor);
void EMFPPlusFillPolygonSolidColor(const ::basegfx::B2DPolyPolygon& polygon, Color const & color);
// helper functions
Color EMFPGetBrushColorOrARGBColor(const sal_uInt16 flags, const sal_uInt32 brushIndexOrColor) const ;
enum class Direction
{
horizontal,
vertical
};
sal_uInt32 DPI(Direction d) { return d == Direction::horizontal ? mnHDPI : mnVDPI; }
double unitToPixel(double n, sal_uInt32 aUnitType, Direction d);
public :
EmfPlusHelperData(
SvMemoryStream& rMS,
wmfemfhelper::TargetHolders& rTargetHolders,
wmfemfhelper::PropertyHolders& rPropertyHolders);
~EmfPlusHelperData();
void processEmfPlusData(
SvMemoryStream& rMS,
const drawinglayer::geometry::ViewInformation2D& rViewInformation);
// mappers
::basegfx::B2DPoint Map(double ix, double iy) const ;
// readers
static void ReadRectangle(SvStream& s, float & x, float & y, float &width, float & height, bool bCompressed = false );
static bool readXForm(SvStream& rIn, basegfx::B2DHomMatrix& rTarget);
static ::basegfx::B2DPolyPolygon combineClip(::basegfx::B2DPolyPolygon const & leftPolygon, int combineMode, ::basegfx::B2DPolyPolygon const & rightPolygon);
};
}
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
Messung V0.5 in Prozent C=93 H=98 G=95
¤ Dauer der Verarbeitung: 0.9 Sekunden
(vorverarbeitet am 2026-09-11)
¤
*© Formatika GbR, Deutschland