summaryrefslogtreecommitdiff
path: root/cppcanvas/source/mtfrenderer/emfplus.cxx
diff options
context:
space:
mode:
authorMark Page <aptitude@btconnect.com>2016-11-24 11:33:23 +0000
committerjan iversen <jani@documentfoundation.org>2017-01-23 11:44:45 +0000
commitf671121525b854b6776d7e0ae1ad04d50d7373dc (patch)
tree233a425f92aca7b77d6d992baf5768f29db6c198 /cppcanvas/source/mtfrenderer/emfplus.cxx
parent04f1d35e7eda2c3b178649610d609ee99342bf41 (diff)
Split emfplus.cxx into multiple files
This helps make emfplus.cxx more readable. No source code was changed, only moved except these renamed to avoid inheritance warnings:: EMFPBrush::transformation renamed to brush_transformation EMFPPen::transformation renamed to pen_transformation Change-Id: I6952d6300c9c459833c2dda2b715d851b9e80de7 Reviewed-on: https://gerrit.libreoffice.org/31165 Tested-by: Jenkins <ci@libreoffice.org> Reviewed-by: jan iversen <jani@documentfoundation.org>
Diffstat (limited to 'cppcanvas/source/mtfrenderer/emfplus.cxx')
-rw-r--r--cppcanvas/source/mtfrenderer/emfplus.cxx1047
1 files changed, 14 insertions, 1033 deletions
diff --git a/cppcanvas/source/mtfrenderer/emfplus.cxx b/cppcanvas/source/mtfrenderer/emfplus.cxx
index b1c02f1cd0db..11dbf62f8872 100644
--- a/cppcanvas/source/mtfrenderer/emfplus.cxx
+++ b/cppcanvas/source/mtfrenderer/emfplus.cxx
@@ -47,6 +47,14 @@
#include <polypolyaction.hxx>
#include <textaction.hxx>
+#include <emfpbrush.hxx>
+#include <emfpcustomlinecap.hxx>
+#include <emfpfont.hxx>
+#include <emfpimage.hxx>
+#include <emfppath.hxx>
+#include <emfppen.hxx>
+#include <emfpregion.hxx>
+
namespace
{
@@ -96,27 +104,6 @@ namespace
#define EmfPlusRegionInitialStateInfinite 0x10000003
-const sal_Int32 EmfPlusLineStyleSolid = 0x00000000;
-const sal_Int32 EmfPlusLineStyleDash = 0x00000001;
-const sal_Int32 EmfPlusLineStyleDot = 0x00000002;
-const sal_Int32 EmfPlusLineStyleDashDot = 0x00000003;
-const sal_Int32 EmfPlusLineStyleDashDotDot = 0x00000004;
-const sal_Int32 EmfPlusLineStyleCustom = 0x00000005;
-
-const sal_uInt32 EmfPlusCustomLineCapDataTypeDefault = 0x00000000;
-const sal_uInt32 EmfPlusCustomLineCapDataTypeAdjustableArrow = 0x00000001;
-
-const sal_uInt32 EmfPlusCustomLineCapDataFillPath = 0x00000001;
-const sal_uInt32 EmfPlusCustomLineCapDataLinePath = 0x00000002;
-
-const sal_uInt32 EmfPlusLineCapTypeSquare = 0x00000001;
-const sal_uInt32 EmfPlusLineCapTypeRound = 0x00000002;
-
-const sal_uInt32 EmfPlusLineJoinTypeMiter = 0x00000000;
-const sal_uInt32 EmfPlusLineJoinTypeBevel = 0x00000001;
-const sal_uInt32 EmfPlusLineJoinTypeRound = 0x00000002;
-const sal_uInt32 EmfPlusLineJoinTypeMiterClipped = 0x00000003;
-
enum EmfPlusCombineMode
{
EmfPlusCombineModeReplace = 0x00000000,
@@ -127,63 +114,6 @@ enum EmfPlusCombineMode
EmfPlusCombineModeComplement = 0x00000005
};
-enum EmfPlusHatchStyle
-{
- HatchStyleHorizontal = 0x00000000,
- HatchStyleVertical = 0x00000001,
- HatchStyleForwardDiagonal = 0x00000002,
- HatchStyleBackwardDiagonal = 0x00000003,
- HatchStyleLargeGrid = 0x00000004,
- HatchStyleDiagonalCross = 0x00000005,
- HatchStyle05Percent = 0x00000006,
- HatchStyle10Percent = 0x00000007,
- HatchStyle20Percent = 0x00000008,
- HatchStyle25Percent = 0x00000009,
- HatchStyle30Percent = 0x0000000A,
- HatchStyle40Percent = 0x0000000B,
- HatchStyle50Percent = 0x0000000C,
- HatchStyle60Percent = 0x0000000D,
- HatchStyle70Percent = 0x0000000E,
- HatchStyle75Percent = 0x0000000F,
- HatchStyle80Percent = 0x00000010,
- HatchStyle90Percent = 0x00000011,
- HatchStyleLightDownwardDiagonal = 0x00000012,
- HatchStyleLightUpwardDiagonal = 0x00000013,
- HatchStyleDarkDownwardDiagonal = 0x00000014,
- HatchStyleDarkUpwardDiagonal = 0x00000015,
- HatchStyleWideDownwardDiagonal = 0x00000016,
- HatchStyleWideUpwardDiagonal = 0x00000017,
- HatchStyleLightVertical = 0x00000018,
- HatchStyleLightHorizontal = 0x00000019,
- HatchStyleNarrowVertical = 0x0000001A,
- HatchStyleNarrowHorizontal = 0x0000001B,
- HatchStyleDarkVertical = 0x0000001C,
- HatchStyleDarkHorizontal = 0x0000001D,
- HatchStyleDashedDownwardDiagonal = 0x0000001E,
- HatchStyleDashedUpwardDiagonal = 0x0000001F,
- HatchStyleDashedHorizontal = 0x00000020,
- HatchStyleDashedVertical = 0x00000021,
- HatchStyleSmallConfetti = 0x00000022,
- HatchStyleLargeConfetti = 0x00000023,
- HatchStyleZigZag = 0x00000024,
- HatchStyleWave = 0x00000025,
- HatchStyleDiagonalBrick = 0x00000026,
- HatchStyleHorizontalBrick = 0x00000027,
- HatchStyleWeave = 0x00000028,
- HatchStylePlaid = 0x00000029,
- HatchStyleDivot = 0x0000002A,
- HatchStyleDottedGrid = 0x0000002B,
- HatchStyleDottedDiamond = 0x0000002C,
- HatchStyleShingle = 0x0000002D,
- HatchStyleTrellis = 0x0000002E,
- HatchStyleSphere = 0x0000002F,
- HatchStyleSmallGrid = 0x00000030,
- HatchStyleSmallCheckerBoard = 0x00000031,
- HatchStyleLargeCheckerBoard = 0x00000032,
- HatchStyleOutlinedDiamond = 0x00000033,
- HatchStyleSolidDiamond = 0x00000034
-};
-
const char* emfTypeToName(sal_uInt16 type)
{
switch(type)
@@ -234,955 +164,6 @@ namespace cppcanvas
{
namespace internal
{
- struct EMFPPath : public EMFPObject
- {
- ::basegfx::B2DPolyPolygon aPolygon;
- sal_Int32 nPoints;
- float* pPoints;
- sal_uInt8* pPointTypes;
-
- public:
- EMFPPath (sal_Int32 _nPoints, bool bLines = false)
- {
- if( _nPoints<0 || sal_uInt32(_nPoints)>SAL_MAX_INT32/(2*sizeof(float)) )
- _nPoints = SAL_MAX_INT32/(2*sizeof(float));
- nPoints = _nPoints;
- pPoints = new float [nPoints*2];
- if (!bLines)
- pPointTypes = new sal_uInt8 [_nPoints];
- else
- pPointTypes = nullptr;
- }
-
- virtual ~EMFPPath () override
- {
- delete [] pPoints;
- delete [] pPointTypes;
- }
-
- // TODO: remove rR argument when debug code is not longer needed
- void Read (SvStream& s, sal_uInt32 pathFlags, ImplRenderer& rR)
- {
- for (int i = 0; i < nPoints; i ++) {
- if (pathFlags & 0x4000) {
- // EMFPlusPoint: stored in signed short 16bit integer format
- sal_Int16 x, y;
-
- s.ReadInt16( x ).ReadInt16( y );
- SAL_INFO ("cppcanvas.emf", "EMF+\tEMFPlusPoint [x,y]: " << x << "," << y);
- pPoints [i*2] = x;
- pPoints [i*2 + 1] = y;
- } else if (!(pathFlags & 0xC000)) {
- // EMFPlusPointF: stored in Single (float) format
- s.ReadFloat( pPoints [i*2] ).ReadFloat( pPoints [i*2 + 1] );
- SAL_INFO ("cppcanvas.emf", "EMF+\tEMFPlusPointF [x,y]: " << pPoints [i*2] << "," << pPoints [i*2 + 1]);
- } else { //if (pathFlags & 0x8000)
- // EMFPlusPointR: points are stored in EMFPlusInteger7 or
- // EMFPlusInteger15 objects, see section 2.2.2.21/22
- SAL_INFO("cppcanvas.emf", "EMF+\t\tTODO - parse EMFPlusPointR object (section 2.2.1.6)");
- }
-
- }
-
- if (pPointTypes)
- for (int i = 0; i < nPoints; i ++) {
- s.ReadUChar( pPointTypes [i] );
- SAL_INFO ("cppcanvas.emf", "EMF+\tpoint type: " << (int)pPointTypes [i]);
- }
-
- aPolygon.clear ();
-
-#if OSL_DEBUG_LEVEL > 1
- const ::basegfx::B2DRectangle aBounds (::basegfx::tools::getRange (GetPolygon (rR)));
-
- SAL_INFO ("cppcanvas.emf",
- "EMF+\tpolygon bounding box: " << aBounds.getMinX () << "," << aBounds.getMinY () << aBounds.getWidth () << "x" << aBounds.getHeight () << " (mapped)");
-#else
- (void) rR; // avoid warnings
-#endif
- }
-
- ::basegfx::B2DPolyPolygon& GetPolygon (ImplRenderer& rR, bool bMapIt = true)
- {
- ::basegfx::B2DPolygon polygon;
-
- aPolygon.clear ();
-
- int last_normal = 0, p = 0;
- ::basegfx::B2DPoint prev, mapped;
- bool hasPrev = false;
- for (int i = 0; i < nPoints; i ++) {
- if (p && pPointTypes && (pPointTypes [i] == 0)) {
- aPolygon.append (polygon);
- last_normal = i;
- p = 0;
- polygon.clear ();
- }
-
- if (bMapIt)
- mapped = rR.Map (pPoints [i*2], pPoints [i*2 + 1]);
- else
- mapped = ::basegfx::B2DPoint (pPoints [i*2], pPoints [i*2 + 1]);
- if (pPointTypes) {
- if ((pPointTypes [i] & 0x07) == 3) {
- if (((i - last_normal )% 3) == 1) {
- polygon.setNextControlPoint (p - 1, mapped);
- SAL_INFO ("cppcanvas.emf", "polygon append next: " << p - 1 << " mapped: " << mapped.getX () << "," << mapped.getY ());
- continue;
- } else if (((i - last_normal) % 3) == 2) {
- prev = mapped;
- hasPrev = true;
- continue;
- }
- } else
- last_normal = i;
- }
- polygon.append (mapped);
- SAL_INFO ("cppcanvas.emf", "polygon append point: " << pPoints [i*2] << "," << pPoints [i*2 + 1] << " mapped: " << mapped.getX () << ":" << mapped.getY ());
- if (hasPrev) {
- polygon.setPrevControlPoint (p, prev);
- SAL_INFO ("cppcanvas.emf", "polygon append prev: " << p << " mapped: " << prev.getX () << "," << prev.getY ());
- hasPrev = false;
- }
- p ++;
- if (pPointTypes && (pPointTypes [i] & 0x80)) { // closed polygon
- polygon.setClosed (true);
- aPolygon.append (polygon);
- SAL_INFO ("cppcanvas.emf", "close polygon");
- last_normal = i + 1;
- p = 0;
- polygon.clear ();
- }
- }
-
- if (polygon.count ()) {
- aPolygon.append (polygon);
-
-#if OSL_DEBUG_LEVEL > 1
- for (unsigned int i=0; i<aPolygon.count(); i++) {
- polygon = aPolygon.getB2DPolygon(i);
- SAL_INFO ("cppcanvas.emf", "polygon: " << i);
- for (unsigned int j=0; j<polygon.count(); j++) {
- ::basegfx::B2DPoint point = polygon.getB2DPoint(j);
- SAL_INFO ("cppcanvas.emf", "point: " << point.getX() << "," << point.getY());
- if (polygon.isPrevControlPointUsed(j)) {
- point = polygon.getPrevControlPoint(j);
- SAL_INFO ("cppcanvas.emf", "prev: " << point.getX() << "," << point.getY());
- }
- if (polygon.isNextControlPointUsed(j)) {
- point = polygon.getNextControlPoint(j);
- SAL_INFO ("cppcanvas.emf", "next: " << point.getX() << "," << point.getY());
- }
- }
- }
-#endif
- }
-
- return aPolygon;
- }
- };
-
- struct EMFPRegion : public EMFPObject
- {
- sal_Int32 parts;
- sal_Int32 *combineMode;
- sal_Int32 initialState;
- float ix, iy, iw, ih;
-
- EMFPRegion ()
- : parts(0)
- , combineMode(nullptr)
- , initialState(0)
- , ix(0.0)
- , iy(0.0)
- , iw(0.0)
- , ih(0.0)
- {
- }
-
- virtual ~EMFPRegion () override
- {
- if (combineMode) {
- delete [] combineMode;
- combineMode = nullptr;
- }
- }
-
- void Read (SvStream& s)
- {
- sal_uInt32 header;
-
- s.ReadUInt32( header ).ReadInt32( parts );
-
- SAL_INFO ("cppcanvas.emf", "EMF+\tregion");
- SAL_INFO ("cppcanvas.emf", "EMF+\theader: 0x" << std::hex << header << " parts: " << parts << std::dec );
-
- if (parts) {
- if( parts<0 || sal_uInt32(parts)>SAL_MAX_INT32/sizeof(sal_Int32) )
- parts = SAL_MAX_INT32/sizeof(sal_Int32);
-
- combineMode = new sal_Int32 [parts];
-
- for (int i = 0; i < parts; i ++) {
- s.ReadInt32( combineMode [i] );
- SAL_INFO ("cppcanvas.emf", "EMF+\tcombine mode [" << i << "]: 0x" << std::hex << combineMode [i] << std::dec);
- }
- }
-
- s.ReadInt32( initialState );
- SAL_INFO ("cppcanvas.emf", "EMF+\tinitial state: 0x" << std::hex << initialState << std::dec);
- }
- };
-
- struct EMFPBrush : public EMFPObject
- {
- ::Color solidColor;
- sal_uInt32 type;
- sal_uInt32 additionalFlags;
-
- /* linear gradient */
- sal_Int32 wrapMode;
- float areaX, areaY, areaWidth, areaHeight;
- ::Color secondColor; // first color is stored in solidColor;
- XForm transformation;
- bool hasTransformation;
- sal_Int32 blendPoints;
- float* blendPositions;
- float* blendFactors;
- sal_Int32 colorblendPoints;
- float* colorblendPositions;
- ::Color* colorblendColors;
- sal_Int32 surroundColorsNumber;
- ::Color* surroundColors;
- EMFPPath *path;
- EmfPlusHatchStyle hatchStyle;
-
- public:
- EMFPBrush ()
- : type(0)
- , additionalFlags(0)
- , wrapMode(0)
- , areaX(0.0)
- , areaY(0.0)
- , areaWidth(0.0)
- , areaHeight(0.0)
- , hasTransformation(false)
- , blendPoints(0)
- , blendPositions(nullptr)
- , blendFactors(nullptr)
- , colorblendPoints(0)
- , colorblendPositions(nullptr)
- , colorblendColors(nullptr)
- , surroundColorsNumber(0)
- , surroundColors(nullptr)
- , path(nullptr)
- , hatchStyle(HatchStyleHorizontal)
- {
- }
-
- virtual ~EMFPBrush () override
- {
- if (blendPositions != nullptr) {
- delete[] blendPositions;
- blendPositions = nullptr;
- }
- if (colorblendPositions != nullptr) {
- delete[] colorblendPositions;
- colorblendPositions = nullptr;
- }
- if (colorblendColors != nullptr) {
- delete[] colorblendColors;
- colorblendColors = nullptr;
- }
- if (surroundColors != nullptr) {
- delete[] surroundColors;
- surroundColors = nullptr;
- }
- if (path) {
- delete path;
- path = nullptr;
- }
- }
-
- sal_uInt32 GetType() const { return type; }
- const ::Color& GetColor() const { return solidColor; }
-
- void Read (SvStream& s, ImplRenderer& rR)
- {
- sal_uInt32 header;
-
- s.ReadUInt32( header ).ReadUInt32( type );
-
- SAL_INFO ("cppcanvas.emf", "EMF+\tbrush");
- SAL_INFO ("cppcanvas.emf", "EMF+\theader: 0x" << std::hex << header << " type: " << type << std::dec);
-
- switch (type) {
- case 0:
- {
- sal_uInt32 color;
-
- s.ReadUInt32( color );
- solidColor = ::Color (0xff - (color >> 24), (color >> 16) & 0xff, (color >> 8) & 0xff, color & 0xff);
- SAL_INFO ("cppcanvas.emf", "EMF+\tsolid color: 0x" << std::hex << color << std::dec);
- break;
- }
- case 1:
- {
- sal_uInt32 style;
- sal_uInt32 foregroundColor;
- sal_uInt32 backgroundColor;
- s.ReadUInt32( style );
- s.ReadUInt32( foregroundColor );
- s.ReadUInt32( backgroundColor );
-
- hatchStyle = static_cast<EmfPlusHatchStyle>(style);
- solidColor = ::Color(0xff - (foregroundColor >> 24), (foregroundColor >> 16) & 0xff, (foregroundColor >> 8) & 0xff, foregroundColor & 0xff);
- secondColor = ::Color(0xff - (backgroundColor >> 24), (backgroundColor >> 16) & 0xff, (backgroundColor >> 8) & 0xff, backgroundColor & 0xff);
- SAL_INFO ("cppcanvas.emf", "EMF+\thatch style " << style << " foregroundcolor: 0x" << solidColor.AsRGBHexString() << " background 0x" << secondColor.AsRGBHexString());
- break;
- }
- // path gradient
- case 3:
- {
- s.ReadUInt32( additionalFlags ).ReadInt32( wrapMode );
-
- SAL_INFO ("cppcanvas.emf", "EMF+\tpath gradient, additional flags: 0x" << std::hex << additionalFlags << std::dec);
-
- sal_uInt32 color;
-
- s.ReadUInt32( color );
- solidColor = ::Color (0xff - (color >> 24), (color >> 16) & 0xff, (color >> 8) & 0xff, color & 0xff);
- SAL_INFO("cppcanvas.emf", "EMF+\tcenter color: 0x" << std::hex << color << std::dec);
-
- s.ReadFloat( areaX ).ReadFloat( areaY );
- SAL_INFO("cppcanvas.emf", "EMF+\tcenter point: " << areaX << "," << areaY);
-
- s.ReadInt32( surroundColorsNumber );
- SAL_INFO("cppcanvas.emf", "EMF+\tsurround colors: " << surroundColorsNumber);
-
- if( surroundColorsNumber<0 || sal_uInt32(surroundColorsNumber)>SAL_MAX_INT32/sizeof(::Color) )
- surroundColorsNumber = SAL_MAX_INT32/sizeof(::Color);
-
- surroundColors = new ::Color [surroundColorsNumber];
- for (int i = 0; i < surroundColorsNumber; i++) {
- s.ReadUInt32( color );
- surroundColors[i] = ::Color (0xff - (color >> 24), (color >> 16) & 0xff, (color >> 8) & 0xff, color & 0xff);
- if (i == 0)
- secondColor = surroundColors [0];
- SAL_INFO("cppcanvas.emf", "EMF+\tsurround color[" << i << "]: 0x" << std::hex << color << std::dec);
- }
-
- if (additionalFlags & 0x01) {
- sal_Int32 pathLength;
-
- s.ReadInt32( pathLength );
- SAL_INFO("cppcanvas.emf", "EMF+\tpath length: " << pathLength);
-
- sal_uInt64 const pos = s.Tell ();
-
- sal_uInt32 pathHeader;
- sal_Int32 pathPoints, pathFlags;
- s.ReadUInt32( pathHeader ).ReadInt32( pathPoints ).ReadInt32( pathFlags );
-
- SAL_INFO("cppcanvas.emf", "EMF+\tpath (brush path gradient)");
- SAL_INFO("cppcanvas.emf", "EMF+\theader: 0x" << std::hex << pathHeader << " points: " << std::dec << pathPoints << " additional flags: 0x" << std::hex << pathFlags << std::dec );
-
- path = new EMFPPath (pathPoints);
- path->Read (s, pathFlags, rR);
-
- s.Seek (pos + pathLength);
-
- const ::basegfx::B2DRectangle aBounds (::basegfx::tools::getRange (path->GetPolygon (rR, false)));
- areaWidth = aBounds.getWidth ();
- areaHeight = aBounds.getHeight ();
-
- SAL_INFO("cppcanvas.emf", "EMF+\tpolygon bounding box: " << aBounds.getMinX () << "," << aBounds.getMinY () << " " << aBounds.getWidth () << "x" << aBounds.getHeight ());
-
-
- if (additionalFlags & 0x02) {
- SAL_INFO("cppcanvas.emf", "EMF+\tuse transformation");
- ReadXForm( s, transformation );
- hasTransformation = true;
- SAL_INFO("cppcanvas.emf",
- "EMF+\tm11: " << transformation.eM11 << " m12: " << transformation.eM12 <<
- "\nEMF+\tm21: " << transformation.eM21 << " m22: " << transformation.eM22 <<
- "\nEMF+\tdx: " << transformation.eDx << " dy: " << transformation.eDy);
-
- }
- if (additionalFlags & 0x08) {
- s.ReadInt32( blendPoints );
- SAL_INFO("cppcanvas.emf", "EMF+\tuse blend, points: " << blendPoints);
- if( blendPoints<0 || sal_uInt32(blendPoints)>SAL_MAX_INT32/(2*sizeof(float)) )
- blendPoints = SAL_MAX_INT32/(2*sizeof(float));
- blendPositions = new float [2*blendPoints];
- blendFactors = blendPositions + blendPoints;
- for (int i=0; i < blendPoints; i ++) {
- s.ReadFloat( blendPositions [i] );
- SAL_INFO("cppcanvas.emf", "EMF+\tposition[" << i << "]: " << blendPositions [i]);
- }
- for (int i=0; i < blendPoints; i ++) {
- s.ReadFloat( blendFactors [i] );
- SAL_INFO("cppcanvas.emf", "EMF+\tfactor[" << i << "]: " << blendFactors [i]);
- }
- }
-
- if (additionalFlags & 0x04) {
- s.ReadInt32( colorblendPoints );
- SAL_INFO("cppcanvas.emf", "EMF+\tuse color blend, points: " << colorblendPoints);
- if( colorblendPoints<0 || sal_uInt32(colorblendPoints)>SAL_MAX_INT32/sizeof(float) )
- colorblendPoints = SAL_MAX_INT32/sizeof(float);
- if( sal_uInt32(colorblendPoints)>SAL_MAX_INT32/sizeof(::Color) )
- colorblendPoints = SAL_MAX_INT32/sizeof(::Color);
- colorblendPositions = new float [colorblendPoints];
- colorblendColors = new ::Color [colorblendPoints];
- for (int i=0; i < colorblendPoints; i ++) {
- s.ReadFloat( colorblendPositions [i] );
- SAL_INFO("cppcanvas.emf", "EMF+\tposition[" << i << "]: " << colorblendPositions [i]);
- }
- for (int i=0; i < colorblendPoints; i ++) {
- s.ReadUInt32( color );
- colorblendColors [i] = ::Color (0xff - (color >> 24), (color >> 16) & 0xff, (color >> 8) & 0xff, color & 0xff);
- SAL_INFO("cppcanvas.emf", "EMF+\tcolor[" << i << "]: 0x" << std::hex << color << std::dec);
- }
- }
- }
- break;
- }
- // linear gradient
- case 4:
- {
- s.ReadUInt32( additionalFlags ).ReadInt32( wrapMode );
-
- SAL_INFO("cppcanvas.emf", "EMF+\tlinear gradient, additional flags: 0x" << std::hex << additionalFlags << std::dec);
-
- s.ReadFloat( areaX ).ReadFloat( areaY ).ReadFloat( areaWidth ).ReadFloat( areaHeight );
-
- SAL_INFO("cppcanvas.emf", "EMF+\tarea: " << areaX << "," << areaY << " - " << areaWidth << "x" << areaHeight);
-
- sal_uInt32 color;
-
- s.ReadUInt32( color );
- solidColor = ::Color (0xff - (color >> 24), (color >> 16) & 0xff, (color >> 8) & 0xff, color & 0xff);
- SAL_INFO("cppcanvas.emf", "EMF+\tfirst color: 0x" << std::hex << color << std::dec);
-
- s.ReadUInt32( color );
- secondColor = ::Color (0xff - (color >> 24), (color >> 16) & 0xff, (color >> 8) & 0xff, color & 0xff);
- SAL_INFO("cppcanvas.emf", "EMF+\tsecond color: 0x" << std::hex << color << std::dec);
-
- // repeated colors, unknown meaning, see http://www.aces.uiuc.edu/~jhtodd/Metafile/MetafileRecords/ObjectBrush.html
- s.ReadUInt32( color );
- s.ReadUInt32( color );
-
- if (additionalFlags & 0x02) {
- SAL_INFO("cppcanvas.emf", "EMF+\tuse transformation");
- ReadXForm( s, transformation );
- hasTransformation = true;
- SAL_INFO("cppcanvas.emf",
- "EMF+\tm11: " << transformation.eM11 << " m12: " << transformation.eM12 <<
- "\nEMF+\tm21: " << transformation.eM21 << " m22: " << transformation.eM22 <<
- "\nEMF+\tdx: " << transformation.eDx << " dy: " << transformation.eDy);
- }
- if (additionalFlags & 0x08) {
- s.ReadInt32( blendPoints );
- SAL_INFO("cppcanvas.emf", "EMF+\tuse blend, points: " << blendPoints);
- if( blendPoints<0 || sal_uInt32(blendPoints)>SAL_MAX_INT32/(2*sizeof(float)) )
- blendPoints = SAL_MAX_INT32/(2*sizeof(float));
- blendPositions = new float [2*blendPoints];
- blendFactors = blendPositions + blendPoints;
- for (int i=0; i < blendPoints; i ++) {
- s.ReadFloat( blendPositions [i] );
- SAL_INFO("cppcanvas.emf", "EMF+\tposition[" << i << "]: " << blendPositions [i]);
- }
- for (int i=0; i < blendPoints; i ++) {
- s.ReadFloat( blendFactors [i] );
- SAL_INFO("cppcanvas.emf", "EMF+\tfactor[" << i << "]: " << blendFactors [i]);
- }
- }
-
- if (additionalFlags & 0x04) {
- s.ReadInt32( colorblendPoints );
- SAL_INFO("cppcanvas.emf", "EMF+\tuse color blend, points: " << colorblendPoints);
- if( colorblendPoints<0 || sal_uInt32(colorblendPoints)>SAL_MAX_INT32/sizeof(float) )
- colorblendPoints = SAL_MAX_INT32/sizeof(float);
- if( sal_uInt32(colorblendPoints)>SAL_MAX_INT32/sizeof(::Color) )
- colorblendPoints = sal_uInt32(SAL_MAX_INT32)/sizeof(::Color);
- colorblendPositions = new float [colorblendPoints];
- colorblendColors = new ::Color [colorblendPoints];
- for (int i=0; i < colorblendPoints; i ++) {
- s.ReadFloat( colorblendPositions [i] );
- SAL_INFO("cppcanvas.emf", "EMF+\tposition[" << i << "]: " << colorblendPositions [i]);
- }
- for (int i=0; i < colorblendPoints; i ++) {
- s.ReadUInt32( color );
- colorblendColors [i] = ::Color (0xff - (color >> 24), (color >> 16) & 0xff, (color >> 8) & 0xff, color & 0xff);
- SAL_INFO("cppcanvas.emf", "EMF+\tcolor[" << i << "]: 0x" << std::hex << color << std::dec);
- }
- }
-
- break;
- }
- default:
- SAL_INFO("cppcanvas.emf", "EMF+\tunhandled brush type: " << std::hex << type << std::dec);
- }
- }
- };
-
- /// Convert stroke caps between EMF+ and rendering API
- sal_Int8 lcl_convertStrokeCap(sal_uInt32 nEmfStroke)
- {
- switch (nEmfStroke)
- {
- case EmfPlusLineCapTypeSquare: return rendering::PathCapType::SQUARE;
- case EmfPlusLineCapTypeRound: return rendering::PathCapType::ROUND;
- }
-
- // we have no mapping for EmfPlusLineCapTypeTriangle = 0x00000003,
- // so return BUTT always
- return rendering::PathCapType::BUTT;
- }
-
- sal_Int8 lcl_convertLineJoinType(sal_uInt32 nEmfLineJoin)
- {
- switch (nEmfLineJoin)
- {
- case EmfPlusLineJoinTypeMiter: // fall-through
- case EmfPlusLineJoinTypeMiterClipped: return rendering::PathJoinType::MITER;
- case EmfPlusLineJoinTypeBevel: return rendering::PathJoinType::BEVEL;
- case EmfPlusLineJoinTypeRound: return rendering::PathJoinType::ROUND;
- }
- assert(false); // Line Join type isn't in specification.
- return 0;
- }
-
- struct EMFPCustomLineCap : public EMFPObject
- {
- sal_uInt32 type;
- sal_uInt32 strokeStartCap, strokeEndCap, strokeJoin;
- float miterLimit;
- basegfx::B2DPolyPolygon polygon;
- bool mbIsFilled;
-
- public:
- EMFPCustomLineCap()
- : EMFPObject()
- , type(0)
- , strokeStartCap(0)
- , strokeEndCap(0)
- , strokeJoin(0)
- , miterLimit(0.0)
- , mbIsFilled(false)
- {
- }
-
- void SetAttributes(rendering::StrokeAttributes& aAttributes)
- {
- aAttributes.StartCapType = lcl_convertStrokeCap(strokeStartCap);
- aAttributes.EndCapType = lcl_convertStrokeCap(strokeEndCap);
- aAttributes.JoinType = lcl_convertLineJoinType(strokeJoin);
-
- aAttributes.MiterLimit = miterLimit;
- }
-
- void ReadPath(SvStream& s, ImplRenderer& rR, bool bFill)
- {
- sal_Int32 pathLength;
- s.ReadInt32( pathLength );
- SAL_INFO("cppcanvas.emf", "EMF+\t\tpath length: " << pathLength);
-
- sal_uInt32 pathHeader;
- sal_Int32 pathPoints, pathFlags;
- s.ReadUInt32( pathHeader ).ReadInt32( pathPoints ).ReadInt32( pathFlags );
-
- SAL_INFO("cppcanvas.emf", "EMF+\t\tpath (custom cap line path)");
- SAL_INFO("cppcanvas.emf", "EMF+\t\theader: 0x" << std::hex << pathHeader << " points: " << std::dec << pathPoints << " additional flags: 0x" << std::hex << pathFlags << std::dec );
-
- EMFPPath path(pathPoints);
- path.Read(s, pathFlags, rR);
-
- polygon = path.GetPolygon(rR, false);
- mbIsFilled = bFill;
-
- // transformation to convert the path to what LibreOffice
- // expects
- B2DHomMatrix aMatrix;
- aMatrix.scale(1.0, -1.0);
-
- polygon.transform(aMatrix);
- };
-
- void Read (SvStream& s, ImplRenderer& rR)
- {
- sal_uInt32 header;
-
- s.ReadUInt32( header ).ReadUInt32( type );
-
- SAL_INFO("cppcanvas.emf", "EMF+\t\tcustom cap");
- SAL_INFO("cppcanvas.emf", "EMF+\t\theader: 0x" << std::hex << header << " type: " << type << std::dec);
-
- if (type == EmfPlusCustomLineCapDataTypeDefault)
- {
- sal_uInt32 customLineCapDataFlags, baseCap;
- float baseInset;
- float widthScale;
- float fillHotSpotX, fillHotSpotY, strokeHotSpotX, strokeHotSpotY;
-
- s.ReadUInt32( customLineCapDataFlags ).ReadUInt32( baseCap ).ReadFloat( baseInset )
- .ReadUInt32( strokeStartCap ).ReadUInt32( strokeEndCap ).ReadUInt32( strokeJoin )
- .ReadFloat( miterLimit ).ReadFloat( widthScale )
- .ReadFloat( fillHotSpotX ).ReadFloat( fillHotSpotY ).ReadFloat( strokeHotSpotX ).ReadFloat( strokeHotSpotY );
-
- SAL_INFO("cppcanvas.emf", "EMF+\t\tcustomLineCapDataFlags: 0x" << std::hex << customLineCapDataFlags);
- SAL_INFO("cppcanvas.emf", "EMF+\t\tbaseCap: 0x" << std::hex << baseCap);
- SAL_INFO("cppcanvas.emf", "EMF+\t\tbaseInset: " << baseInset);
- SAL_INFO("cppcanvas.emf", "EMF+\t\tstrokeStartCap: 0x" << std::hex << strokeStartCap);
- SAL_INFO("cppcanvas.emf", "EMF+\t\tstrokeEndCap: 0x" << std::hex << strokeEndCap);
- SAL_INFO("cppcanvas.emf", "EMF+\t\tstrokeJoin: 0x" << std::hex << strokeJoin);
- SAL_INFO("cppcanvas.emf", "EMF+\t\tmiterLimit: " << miterLimit);
- SAL_INFO("cppcanvas.emf", "EMF+\t\twidthScale: " << widthScale);
-
- if (customLineCapDataFlags & EmfPlusCustomLineCapDataFillPath)
- {
- ReadPath(s, rR, true);
- }
-
- if (customLineCapDataFlags & EmfPlusCustomLineCapDataLinePath)
- {
- ReadPath(s, rR, false);
- }
- }
- else if (type == EmfPlusCustomLineCapDataTypeAdjustableArrow)
- {
- // TODO only reads the data, does not use them [I've had
- // no test document to be able to implement it]
-
- sal_Int32 width, height, middleInset, fillState, lineStartCap;
- sal_Int32 lineEndCap, lineJoin, widthScale;
- float fillHotSpotX, fillHotSpotY, lineHotSpotX, lineHotSpotY;
-
- s.ReadInt32( width ).ReadInt32( height ).ReadInt32( middleInset ).ReadInt32( fillState ).ReadInt32( lineStartCap )
- .ReadInt32( lineEndCap ).ReadInt32( lineJoin ).ReadFloat( miterLimit ).ReadInt32( widthScale )
- .ReadFloat( fillHotSpotX ).ReadFloat( fillHotSpotY ).ReadFloat( lineHotSpotX ).ReadFloat( lineHotSpotY );
-
- SAL_INFO("cppcanvas.emf", "EMF+\t\tTODO - actually read EmfPlusCustomLineCapArrowData object (section 2.2.2.12)");
- }
- }
- };
-
- struct EMFPPen : public EMFPBrush
- {
- XForm transformation;
- float width;
- sal_Int32 startCap;
- sal_Int32 endCap;
- sal_Int32 lineJoin;
- float mitterLimit;
- sal_Int32 dashStyle;
- sal_Int32 dashCap;
- float dashOffset;
- sal_Int32 dashPatternLen;
- float *dashPattern;
- sal_Int32 alignment;
- sal_Int32 compoundArrayLen;
- float *compoundArray;
- sal_Int32 customStartCapLen;
- EMFPCustomLineCap *customStartCap;
- sal_Int32 customEndCapLen;
- EMFPCustomLineCap *customEndCap;
-
- public:
- EMFPPen ()
- : EMFPBrush()
- , width(0.0)
- , startCap(0)
- , endCap(0)
- , lineJoin(0)
- , mitterLimit(0.0)
- , dashStyle(0)
- , dashCap(0)
- , dashOffset(0.0)
- , dashPatternLen(0)
- , dashPattern(nullptr)
- , alignment(0)
- , compoundArrayLen(0)
- , compoundArray(nullptr)
- , customStartCapLen(0)
- , customStartCap(nullptr)
- , customEndCapLen(0)
- , customEndCap(nullptr)
- {
- }
-
- virtual ~EMFPPen() override
- {
- delete[] dashPattern;
- delete[] compoundArray;
- delete customStartCap;
- delete customEndCap;
- }
-
- void SetStrokeWidth(rendering::StrokeAttributes& rStrokeAttributes, ImplRenderer& rR, const OutDevState& rState)
- {
-#if OSL_DEBUG_LEVEL > 1
- if (width == 0.0) {
- SAL_INFO ("cppcanvas.emf", "TODO: pen with zero width - using minimal which might not be correct\n");
- }
-#endif
- rStrokeAttributes.StrokeWidth = fabs((rState.mapModeTransform * rR.MapSize (width == 0.0 ? 0.05 : width, 0)).getLength());
- }
-
- void SetStrokeAttributes(rendering::StrokeAttributes& rStrokeAttributes)
- {
- rStrokeAttributes.JoinType = lcl_convertLineJoinType(lineJoin);
-
- if (dashStyle != EmfPlusLineStyleSolid)
- {
- const float dash[] = {3, 3};
- const float dot[] = {1, 3};
- const float dashdot[] = {3, 3, 1, 3};
- const float dashdotdot[] = {3, 3, 1, 3, 1, 3};
-
- sal_Int32 nLen = 0;
- const float *pPattern = nullptr;
- switch (dashStyle)
- {
- case EmfPlusLineStyleDash: nLen = SAL_N_ELEMENTS(dash); pPattern = dash; break;
- case EmfPlusLineStyleDot: nLen = SAL_N_ELEMENTS(dot); pPattern = dot; break;
- case EmfPlusLineStyleDashDot: nLen = SAL_N_ELEMENTS(dashdot); pPattern = dashdot; break;
- case EmfPlusLineStyleDashDotDot: nLen = SAL_N_ELEMENTS(dashdotdot); pPattern = dashdotdot; break;
- case EmfPlusLineStyleCustom: nLen = dashPatternLen; pPattern = dashPattern; break;
- }
- if (nLen > 0)
- {
- uno::Sequence<double> aDashArray(nLen);
- for (int i = 0; i < nLen; ++i)
- aDashArray[i] = pPattern[i];
-
- rStrokeAttributes.DashArray = aDashArray;
- }
- }
- }
-
- void Read (SvStream& s, ImplRenderer& rR, sal_Int32, sal_Int32 )
- {
- sal_uInt32 header, unknown, penFlags, unknown2;
- int i;
-
- s.ReadUInt32( header ).ReadUInt32( unknown ).ReadUInt32( penFlags ).ReadUInt32( unknown2 ).ReadFloat( width );
-
- SAL_INFO("cppcanvas.emf", "EMF+\tpen");
- SAL_INFO("cppcanvas.emf", "EMF+\theader: 0x" << std::hex << header << " unknown: 0x" << unknown <<
- " additional flags: 0x" << penFlags << " unknown: 0x" << unknown2 << " width: " << std::dec << width );
-
- if (penFlags & 1)
- ReadXForm( s, transformation );
-
- if (penFlags & 2)
- {
- s.ReadInt32( startCap );
- SAL_INFO("cppcanvas.emf", "EMF+\t\tstartCap: 0x" << std::hex << startCap);
- }
- else
- startCap = 0;
-
- if (penFlags & 4)
- {
- s.ReadInt32( endCap );
- SAL_INFO("cppcanvas.emf", "EMF+\t\tendCap: 0x" << std::hex << endCap);
- }
- else
- endCap = 0;
-
- if (penFlags & 8)
- s.ReadInt32( lineJoin );
- else
- lineJoin = 0;
-
- if (penFlags & 16)
- s.ReadFloat( mitterLimit );
- else
- mitterLimit = 0;
-
- if (penFlags & 32)
- {
- s.ReadInt32( dashStyle );
- SAL_INFO("cppcanvas.emf", "EMF+\t\tdashStyle: 0x" << std::hex << dashStyle);
- }
- else
- dashStyle = 0;
-
- if (penFlags & 64)
- s.ReadInt32( dashCap );
- else
- dashCap = 0;
-
- if (penFlags & 128)
- s.ReadFloat( dashOffset );
- else
- dashOffset = 0;
-
- if (penFlags & 256)
- {
- dashStyle = EmfPlusLineStyleCustom;
-
- s.ReadInt32( dashPatternLen );
- SAL_INFO("cppcanvas.emf", "EMF+\t\tdashPatternLen: " << dashPatternLen);
-
- if( dashPatternLen<0 || sal_uInt32(dashPatternLen)>SAL_MAX_INT32/sizeof(float) )
- dashPatternLen = SAL_MAX_INT32/sizeof(float);
- dashPattern = new float [dashPatternLen];
- for (i = 0; i < dashPatternLen; i++)
- {
- s.ReadFloat( dashPattern [i] );
- SAL_INFO("cppcanvas.emf", "EMF+\t\t\tdashPattern[" << i << "]: " << dashPattern[i]);
- }
- }
- else
- dashPatternLen = 0;
-
- if (penFlags & 512)
- s.ReadInt32( alignment );
- else
- alignment = 0;
-
- if (penFlags & 1024) {
- s.ReadInt32( compoundArrayLen );
- if( compoundArrayLen<0 || sal_uInt32(compoundArrayLen)>SAL_MAX_INT32/sizeof(float) )
- compoundArrayLen = SAL_MAX_INT32/sizeof(float);
- compoundArray = new float [compoundArrayLen];
- for (i = 0; i < compoundArrayLen; i++)
- s.ReadFloat( compoundArray [i] );
- } else
- compoundArrayLen = 0;
-
- if (penFlags & 2048)
- {
- s.ReadInt32( customStartCapLen );
- SAL_INFO("cppcanvas.emf", "EMF+\t\tcustomStartCapLen: " << customStartCapLen);
- sal_uInt64 const pos = s.Tell();
-
- customStartCap = new EMFPCustomLineCap();
- customStartCap->Read(s, rR);
-
- // maybe we don't read everything yet, play it safe ;-)
- s.Seek(pos + customStartCapLen);
- }
- else
- customStartCapLen = 0;
-
- if (penFlags & 4096)
- {
- s.ReadInt32( customEndCapLen );
- SAL_INFO("cppcanvas.emf", "EMF+\t\tcustomEndCapLen: " << customEndCapLen);
- sal_uInt64 const pos = s.Tell();
-
- customEndCap = new EMFPCustomLineCap();
- customEndCap->Read(s, rR);
-
- // maybe we don't read everything yet, play it safe ;-)
- s.Seek(pos + customEndCapLen);
- }
- else
- customEndCapLen = 0;
-
- EMFPBrush::Read (s, rR);
- }
- };
-
- struct EMFPImage : public EMFPObject
- {
- sal_uInt32 type;
- sal_Int32 width;
- sal_Int32 height;
- sal_Int32 stride;
- sal_Int32 pixelFormat;
- Graphic graphic;
-
-
- void Read (SvMemoryStream &s, sal_uInt32 dataSize, bool bUseWholeStream)
- {
- sal_uInt32 header, bitmapType;
-
- s.ReadUInt32( header ).ReadUInt32( type );
-
- SAL_INFO("cppcanvas.emf", "EMF+\timage\nEMF+\theader: 0x" << std::hex << header << " type: " << type << std::dec );
-
- if (type == 1) { // bitmap
- s.ReadInt32( width ).ReadInt32( height ).ReadInt32( stride ).ReadInt32( pixelFormat ).ReadUInt32( bitmapType );
- SAL_INFO("cppcanvas.emf", "EMF+\tbitmap width: " << width << " height: " << height << " stride: " << stride << " pixelFormat: 0x" << std::hex << pixelFormat << std::dec);
- if ((bitmapType != 0) || (width == 0)) { // non native formats
- GraphicFilter filter;
-
- filter.ImportGraphic (graphic, OUString(), s);
- SAL_INFO("cppcanvas.emf", "EMF+\tbitmap width: " << graphic.GetBitmap().GetSizePixel().Width() << " height: " << graphic.GetBitmap().GetSizePixel().Height());
- }
-
- } else if (type == 2) { // metafile
- sal_Int32 mfType, mfSize;
-
- s.ReadInt32( mfType ).ReadInt32( mfSize );
- if (bUseWholeStream)
- dataSize = s.remainingSize();
- else
- dataSize -= 16;
- SAL_INFO("cppcanvas.emf", "EMF+\tmetafile type: " << mfType << " dataSize: " << mfSize << " real size calculated from record dataSize: " << dataSize);
-
- GraphicFilter filter;
- // workaround buggy metafiles, which have wrong mfSize set (n#705956 for example)
- SvMemoryStream mfStream (const_cast<char *>(static_cast<char const *>(s.GetData()) + s.Tell()), dataSize, StreamMode::READ);
-
- filter.ImportGraphic (graphic, OUString(), mfStream);
-
- // debug code - write the stream to debug file /tmp/emf-stream.emf
-#if OSL_DEBUG_LEVEL > 1
- mfStream.Seek(0);
- static sal_Int32 emfp_debug_stream_number = 0;
- OUString emfp_debug_filename = "/tmp/emf-embedded-stream" +
- OUString::number(emfp_debug_stream_number++) + ".emf";
-
- SvFileStream file( emfp_debug_filename, StreamMode::WRITE | StreamMode::TRUNC );
-
- mfStream.WriteStream(file);
- file.Flush();
- file.Close();
-#endif
- }
- }
- };
-
- struct EMFPFont : public EMFPObject
- {
- float emSize;
- sal_uInt32 sizeUnit;
- sal_Int32 fontFlags;
- OUString family;
-
- void Read (SvMemoryStream &s)
- {
- sal_uInt32 header;
- sal_uInt32 reserved;
- sal_uInt32 length;
-
- s.ReadUInt32( header ).ReadFloat( emSize ).ReadUInt32( sizeUnit ).ReadInt32( fontFlags ).ReadUInt32( reserved ).ReadUInt32( length );
-
- OSL_ASSERT( ( header >> 12 ) == 0xdbc01 );
-
- SAL_INFO("cppcanvas.emf", "EMF+\tfont\nEMF+\theader: 0x" << std::hex << (header >> 12) << " version: 0x" << (header & 0x1fff) << " size: " << std::dec << emSize << " unit: 0x" << std::hex << sizeUnit << std::dec);
- SAL_INFO("cppcanvas.emf", "EMF+\tflags: 0x" << std::hex << fontFlags << " reserved: 0x" << reserved << " length: 0x" << std::hex << length << std::dec);
-
- if (length > 0 && length < 0x4000)
- {
- rtl_uString *pStr = rtl_uString_alloc(length);
- sal_Unicode *chars = pStr->buffer;
-
- for (sal_uInt32 i = 0; i < length; ++i)
- s.ReadUtf16(chars[i]);
-
- family = OUString(pStr, SAL_NO_ACQUIRE);
- SAL_INFO("cppcanvas.emf", "EMF+\tfamily: " << family);
- }
- }
- };
-
void ImplRenderer::ReadRectangle (SvStream& s, float& x, float& y, float &width, float& height, bool bCompressed)
{
if (bCompressed) {
@@ -1368,12 +349,12 @@ namespace cppcanvas
if (brush->hasTransformation) {
::basegfx::B2DHomMatrix aTransformation;
- aTransformation.set (0, 0, brush->transformation.eM11);
- aTransformation.set (0, 1, brush->transformation.eM21);
- aTransformation.set (0, 2, brush->transformation.eDx);
- aTransformation.set (1, 0, brush->transformation.eM12);
- aTransformation.set (1, 1, brush->transformation.eM22);
- aTransformation.set (1, 2, brush->transformation.eDy);
+ aTransformation.set (0, 0, brush->brush_transformation.eM11);
+ aTransformation.set (0, 1, brush->brush_transformation.eM21);
+ aTransformation.set (0, 2, brush->brush_transformation.eDx);
+ aTransformation.set (1, 0, brush->brush_transformation.eM12);
+ aTransformation.set (1, 1, brush->brush_transformation.eM22);
+ aTransformation.set (1, 2, brush->brush_transformation.eDy);
aTextureTransformation *= aTransformation;
}