calc: on editing invalidation of view with different zoom is wrong
[LibreOffice.git] / drawinglayer / source / tools / emfpbrush.cxx
blobc79b0ded0748c71bdccbc227c2196a9157ca18cf
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
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 #include <basegfx/range/b2drange.hxx>
21 #include <basegfx/range/b2drectangle.hxx>
22 #include <basegfx/polygon/b2dpolypolygontools.hxx>
23 #include <o3tl/safeint.hxx>
24 #include <sal/log.hxx>
25 #include "emfpbrush.hxx"
26 #include "emfppath.hxx"
28 namespace emfplushelper
30 EMFPBrush::EMFPBrush()
31 : type(0)
32 , additionalFlags(0)
33 , wrapMode(0)
34 , firstPointX(0.0)
35 , firstPointY(0.0)
36 , aWidth(0.0)
37 , aHeight(0.0)
38 , hasTransformation(false)
39 , blendPoints(0)
40 , blendFactors(nullptr)
41 , colorblendPoints(0)
42 , surroundColorsNumber(0)
43 , hatchStyle(HatchStyleHorizontal)
47 EMFPBrush::~EMFPBrush()
51 static OUString BrushTypeToString(sal_uInt32 type)
53 switch (type)
55 case BrushTypeSolidColor: return "BrushTypeSolidColor";
56 case BrushTypeHatchFill: return "BrushTypeHatchFill";
57 case BrushTypeTextureFill: return "BrushTypeTextureFill";
58 case BrushTypePathGradient: return "BrushTypePathGradient";
59 case BrushTypeLinearGradient: return "BrushTypeLinearGradient";
61 return "";
64 void EMFPBrush::Read(SvStream& s, EmfPlusHelperData const & rR)
66 sal_uInt32 header;
68 s.ReadUInt32(header).ReadUInt32(type);
70 SAL_INFO("drawinglayer.emf", "EMF+\t\t\tHeader: 0x" << std::hex << header);
71 SAL_INFO("drawinglayer.emf", "EMF+\t\t\tType: " << BrushTypeToString(type) << "(0x" << type << ")" << std::dec);
73 switch (type)
75 case BrushTypeSolidColor:
77 sal_uInt32 color;
78 s.ReadUInt32(color);
80 solidColor = ::Color(ColorAlpha, (color >> 24), (color >> 16) & 0xff, (color >> 8) & 0xff, color & 0xff);
81 SAL_INFO("drawinglayer.emf", "EMF+\t\t\t\tSolid color: 0x" << std::hex << color << std::dec);
82 break;
84 case BrushTypeHatchFill:
86 sal_uInt32 style;
87 sal_uInt32 foregroundColor;
88 sal_uInt32 backgroundColor;
89 s.ReadUInt32(style);
90 s.ReadUInt32(foregroundColor);
91 s.ReadUInt32(backgroundColor);
93 hatchStyle = static_cast<EmfPlusHatchStyle>(style);
94 solidColor = ::Color(ColorAlpha, (foregroundColor >> 24), (foregroundColor >> 16) & 0xff, (foregroundColor >> 8) & 0xff, foregroundColor & 0xff);
95 secondColor = ::Color(ColorAlpha, (backgroundColor >> 24), (backgroundColor >> 16) & 0xff, (backgroundColor >> 8) & 0xff, backgroundColor & 0xff);
96 SAL_INFO("drawinglayer.emf", "EMF+\t\t\t\tHatch style: 0x" << std::hex << style);
97 SAL_INFO("drawinglayer.emf", "EMF+\t\t\t\tForeground color: 0x" << solidColor.AsRGBHexString());
98 SAL_INFO("drawinglayer.emf", "EMF+\t\t\t\tBackground color: 0x" << secondColor.AsRGBHexString());
99 break;
101 case BrushTypeTextureFill:
103 SAL_WARN("drawinglayer.emf", "EMF+\tTODO: implement BrushTypeTextureFill brush");
104 break;
106 case BrushTypePathGradient:
108 s.ReadUInt32(additionalFlags).ReadInt32(wrapMode);
109 SAL_INFO("drawinglayer.emf", "EMF+\t\t\t\tAdditional flags: 0x" << std::hex << additionalFlags << std::dec);
110 sal_uInt32 color;
111 s.ReadUInt32(color);
112 solidColor = ::Color(ColorAlpha, (color >> 24), (color >> 16) & 0xff, (color >> 8) & 0xff, color & 0xff);
113 SAL_INFO("drawinglayer.emf", "EMF+\t\t\t\tCenter color: 0x" << std::hex << color << std::dec);
114 s.ReadFloat(firstPointX).ReadFloat(firstPointY);
115 SAL_INFO("drawinglayer.emf", "EMF+\t\t\t\tCenter point: " << firstPointX << "," << firstPointY);
116 s.ReadUInt32(surroundColorsNumber);
117 SAL_INFO("drawinglayer.emf", "EMF+\t\t\t\t number of surround colors: " << surroundColorsNumber);
119 surroundColors.reset( new ::Color[surroundColorsNumber] );
121 for (sal_uInt32 i = 0; i < surroundColorsNumber; i++)
123 s.ReadUInt32(color);
124 surroundColors[i] = ::Color(ColorAlpha, (color >> 24), (color >> 16) & 0xff, (color >> 8) & 0xff, color & 0xff);
125 if (i == 0)
126 secondColor = surroundColors[0];
127 SAL_INFO("drawinglayer.emf", "EMF+\t\t\t\tSurround color[" << i << "]: 0x" << std::hex << color << std::dec);
130 if (additionalFlags & 0x01) // BrushDataPath
132 sal_Int32 pathLength;
134 s.ReadInt32(pathLength);
135 SAL_INFO("drawinglayer.emf", "EMF+\t\t\t\tPath length: " << pathLength);
137 sal_uInt64 const pos = s.Tell();
139 sal_uInt32 pathHeader;
140 sal_Int32 pathPoints, pathFlags;
141 s.ReadUInt32(pathHeader).ReadInt32(pathPoints).ReadInt32(pathFlags);
143 SAL_INFO("drawinglayer.emf", "EMF+\t\t\t\tPath (brush path gradient)");
144 SAL_INFO("drawinglayer.emf", "EMF+\t\t\t\t\tHeader: 0x" << std::hex << pathHeader);
145 SAL_INFO("drawinglayer.emf", "EMF+\t\t\t\t\tPoints: " << std::dec << pathPoints);
146 SAL_INFO("drawinglayer.emf", "EMF+\t\t\t\t\tAdditional flags: 0x" << std::hex << pathFlags << std::dec);
148 path.reset( new EMFPPath(pathPoints) );
149 path->Read(s, pathFlags);
151 s.Seek(pos + pathLength);
153 const ::basegfx::B2DRectangle aBounds(::basegfx::utils::getRange(path->GetPolygon(rR, false)));
154 aWidth = aBounds.getWidth();
155 aHeight = aBounds.getHeight();
156 SAL_INFO("drawinglayer.emf", "EMF+\t\t\t\tPolygon bounding box: " << aBounds.getMinX() << "," << aBounds.getMinY() << " "
157 << aBounds.getWidth() << "x" << aBounds.getHeight());
159 else
161 sal_Int32 boundaryPointCount;
162 s.ReadInt32(boundaryPointCount);
164 sal_uInt64 const pos = s.Tell();
165 SAL_INFO("drawinglayer.emf", "EMF+\t use boundary, points: " << boundaryPointCount);
166 path.reset( new EMFPPath(boundaryPointCount) );
167 path->Read(s, 0x0);
169 s.Seek(pos + 8 * boundaryPointCount);
171 const ::basegfx::B2DRectangle aBounds(::basegfx::utils::getRange(path->GetPolygon(rR, false)));
172 aWidth = aBounds.getWidth();
173 aHeight = aBounds.getHeight();
174 SAL_INFO("drawinglayer.emf", "EMF+\t\t\t\tPolygon bounding box: " << aBounds.getMinX() << "," << aBounds.getMinY() << " "
175 << aBounds.getWidth() << "x" << aBounds.getHeight());
178 if (additionalFlags & 0x02) // BrushDataTransform
180 EmfPlusHelperData::readXForm(s, brush_transformation);
181 hasTransformation = true;
182 SAL_INFO("drawinglayer.emf", "EMF+\t\t\t\tUse brush transformation: " << brush_transformation);
185 // BrushDataPresetColors and BrushDataBlendFactorsH
186 if ((additionalFlags & 0x04) && (additionalFlags & 0x08))
188 SAL_WARN("drawinglayer.emf", "EMF+\t Brush must not contain both BrushDataPresetColors and BrushDataBlendFactorsH");
189 return;
191 if (additionalFlags & 0x08) // BrushDataBlendFactorsH
193 s.ReadUInt32(blendPoints);
194 SAL_INFO("drawinglayer.emf", "EMF+\t\t\t\tuse blend, points: " << blendPoints);
195 blendPositions.reset( new float[2 * blendPoints] );
196 blendFactors = blendPositions.get() + blendPoints;
198 for (sal_uInt32 i = 0; i < blendPoints; i++)
200 s.ReadFloat(blendPositions[i]);
201 SAL_INFO("drawinglayer.emf", "EMF+\t\t\t\tposition[" << i << "]: " << blendPositions[i]);
204 for (sal_uInt32 i = 0; i < blendPoints; i++)
206 s.ReadFloat(blendFactors[i]);
207 SAL_INFO("drawinglayer.emf", "EMF+\t\t\t\tFactor[" << i << "]: " << blendFactors[i]);
211 if (additionalFlags & 0x04) // BrushDataPresetColors
213 s.ReadUInt32(colorblendPoints);
214 SAL_INFO("drawinglayer.emf", "EMF+\t\t\t\tUse color blend, points: " << colorblendPoints);
215 colorblendPositions.reset( new float[colorblendPoints] );
216 colorblendColors.reset( new ::Color[colorblendPoints] );
218 for (sal_uInt32 i = 0; i < colorblendPoints; i++)
220 s.ReadFloat(colorblendPositions[i]);
221 SAL_INFO("drawinglayer.emf", "EMF+\tposition[" << i << "]: " << colorblendPositions[i]);
224 for (sal_uInt32 i = 0; i < colorblendPoints; i++)
226 s.ReadUInt32(color);
227 colorblendColors[i] = ::Color(ColorAlpha, (color >> 24), (color >> 16) & 0xff, (color >> 8) & 0xff, color & 0xff);
228 SAL_INFO("drawinglayer.emf", "EMF+\t\t\t\tColor[" << i << "]: 0x" << std::hex << color << std::dec);
232 break;
234 case BrushTypeLinearGradient:
236 s.ReadUInt32(additionalFlags).ReadInt32(wrapMode);
237 SAL_INFO("drawinglayer.emf", "EMF+\t\t\t\tLinear gradient, additional flags: 0x" << std::hex << additionalFlags << std::dec << ", wrapMode: " << wrapMode);
238 s.ReadFloat(firstPointX).ReadFloat(firstPointY).ReadFloat(aWidth).ReadFloat(aHeight);
239 SAL_INFO("drawinglayer.emf", "EMF+\t\t\t\tFirst gradient point: " << firstPointX << ":" << firstPointY
240 << ", size " << aWidth << "x" << aHeight);
241 sal_uInt32 color;
242 s.ReadUInt32(color);
243 solidColor = ::Color(ColorAlpha, (color >> 24), (color >> 16) & 0xff, (color >> 8) & 0xff, color & 0xff);
244 SAL_INFO("drawinglayer.emf", "EMF+\t\t\t\tfirst color: 0x" << std::hex << color << std::dec);
245 s.ReadUInt32(color);
246 secondColor = ::Color(ColorAlpha, (color >> 24), (color >> 16) & 0xff, (color >> 8) & 0xff, color & 0xff);
247 SAL_INFO("drawinglayer.emf", "EMF+\t\t\t\tsecond color: 0x" << std::hex << color << std::dec);
249 // repeated colors, unknown meaning, see http://www.aces.uiuc.edu/~jhtodd/Metafile/MetafileRecords/ObjectBrush.html
250 s.ReadUInt32(color);
251 s.ReadUInt32(color);
253 if (additionalFlags & 0x02) //BrushDataTransform
255 EmfPlusHelperData::readXForm(s, brush_transformation);
256 hasTransformation = true;
257 SAL_INFO("drawinglayer.emf", "EMF+\t\t\t\tUse brush transformation: " << brush_transformation);
259 // BrushDataPresetColors and BrushDataBlendFactorsH
260 if ((additionalFlags & 0x04) && (additionalFlags & 0x08))
262 SAL_WARN("drawinglayer.emf", "EMF+\t Brush must not contain both BrushDataPresetColors and BrushDataBlendFactorsH");
263 return;
266 if (additionalFlags & 0x08) // BrushDataBlendFactorsH
268 s.ReadUInt32(blendPoints);
269 SAL_INFO("drawinglayer.emf", "EMF+\t\t\t\tUse blend, points: " << blendPoints);
270 blendPositions.reset( new float[2 * blendPoints] );
271 blendFactors = blendPositions.get() + blendPoints;
273 for (sal_uInt32 i = 0; i < blendPoints; i++)
275 s.ReadFloat(blendPositions[i]);
276 SAL_INFO("drawinglayer.emf", "EMF+\t\t\t\tPosition[" << i << "]: " << blendPositions[i]);
279 for (sal_uInt32 i = 0; i < blendPoints; i++)
281 s.ReadFloat(blendFactors[i]);
282 SAL_INFO("drawinglayer.emf", "EMF+\t\t\t\tFactor[" << i << "]: " << blendFactors[i]);
286 if (additionalFlags & 0x04)
288 s.ReadUInt32(colorblendPoints);
289 SAL_INFO("drawinglayer.emf", "EMF+\t\t\t\tUse color blend, points: " << colorblendPoints);
290 colorblendPositions.reset( new float[colorblendPoints] );
291 colorblendColors.reset( new ::Color[colorblendPoints] );
293 for (sal_uInt32 i = 0; i < colorblendPoints; i++)
295 s.ReadFloat(colorblendPositions[i]);
296 SAL_INFO("drawinglayer.emf", "EMF+\t\t\t\tPosition[" << i << "]: " << colorblendPositions[i]);
299 for (sal_uInt32 i = 0; i < colorblendPoints; i++)
301 s.ReadUInt32(color);
302 colorblendColors[i] = ::Color(ColorAlpha, (color >> 24), (color >> 16) & 0xff, (color >> 8) & 0xff, color & 0xff);
303 SAL_INFO("drawinglayer.emf", "EMF+\t\t\t\tColor[" << i << "]: 0x" << std::hex << color << std::dec);
307 break;
309 default:
311 SAL_WARN("drawinglayer.emf", "EMF+\tunhandled brush type: " << std::hex << type << std::dec);
317 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */