Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*
3 : * This file is part of the LibreOffice project.
4 : *
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/.
8 : */
9 :
10 : #include <com/sun/star/container/XNamed.hpp>
11 : #include <com/sun/star/drawing/XEnhancedCustomShapeDefaulter.hpp>
12 : #include <com/sun/star/drawing/XDrawPageSupplier.hpp>
13 : #include <com/sun/star/drawing/LineStyle.hpp>
14 : #include <com/sun/star/drawing/EnhancedCustomShapeSegment.hpp>
15 : #include <com/sun/star/drawing/EnhancedCustomShapeParameterPair.hpp>
16 : #include <com/sun/star/drawing/EnhancedCustomShapeSegmentCommand.hpp>
17 : #include <com/sun/star/table/BorderLine2.hpp>
18 : #include <com/sun/star/text/HoriOrientation.hpp>
19 : #include <com/sun/star/text/RelOrientation.hpp>
20 : #include <com/sun/star/text/SizeType.hpp>
21 : #include <com/sun/star/text/VertOrientation.hpp>
22 : #include <com/sun/star/text/WrapTextMode.hpp>
23 : #include <com/sun/star/text/WritingMode.hpp>
24 :
25 : #include <ooxml/resourceids.hxx> // NS_ooxml namespace
26 : #include <filter/msfilter/escherex.hxx>
27 : #include <filter/msfilter/util.hxx>
28 :
29 : #include <dmapper/DomainMapper.hxx>
30 : #include "../dmapper/GraphicHelpers.hxx"
31 : #include <rtfsdrimport.hxx>
32 : #include <rtfreferenceproperties.hxx>
33 :
34 : #include <oox/vml/vmlformatting.hxx>
35 : #include <oox/helper/modelobjecthelper.hxx>
36 : #include <oox/drawingml/shapepropertymap.hxx>
37 : #include <oox/helper/propertyset.hxx>
38 :
39 : #define TWIP_TO_MM100(TWIP) ((TWIP) >= 0 ? (((TWIP)*127L+36L)/72L) : (((TWIP)*127L-36L)/72L))
40 :
41 : namespace writerfilter {
42 : namespace rtftok {
43 :
44 206 : RTFSdrImport::RTFSdrImport(RTFDocumentImpl& rDocument,
45 : uno::Reference<lang::XComponent> const& xDstDoc)
46 206 : : m_rImport(rDocument)
47 : {
48 206 : uno::Reference<drawing::XDrawPageSupplier> xDrawings(xDstDoc, uno::UNO_QUERY);
49 206 : if (xDrawings.is())
50 193 : m_xDrawPage.set(xDrawings->getDrawPage(), uno::UNO_QUERY);
51 206 : }
52 :
53 412 : RTFSdrImport::~RTFSdrImport()
54 : {
55 412 : }
56 :
57 68 : void RTFSdrImport::createShape(OUString aStr, uno::Reference<drawing::XShape>& xShape, uno::Reference<beans::XPropertySet>& xPropertySet)
58 : {
59 68 : if (m_rImport.getModelFactory().is())
60 67 : xShape.set(m_rImport.getModelFactory()->createInstance(aStr), uno::UNO_QUERY);
61 68 : xPropertySet.set(xShape, uno::UNO_QUERY);
62 68 : }
63 :
64 27 : std::vector<beans::PropertyValue> RTFSdrImport::getTextFrameDefaults(bool bNew)
65 : {
66 27 : std::vector<beans::PropertyValue> aRet;
67 54 : beans::PropertyValue aPropertyValue;
68 :
69 27 : aPropertyValue.Name = "HoriOrient";
70 27 : aPropertyValue.Value <<= text::HoriOrientation::NONE;
71 27 : aRet.push_back(aPropertyValue);
72 27 : aPropertyValue.Name = "HoriOrientRelation";
73 27 : aPropertyValue.Value <<= text::RelOrientation::FRAME;
74 27 : aRet.push_back(aPropertyValue);
75 27 : aPropertyValue.Name = "VertOrient";
76 27 : aPropertyValue.Value <<= text::VertOrientation::NONE;
77 27 : aRet.push_back(aPropertyValue);
78 27 : aPropertyValue.Name = "VertOrientRelation";
79 27 : aPropertyValue.Value <<= text::RelOrientation::FRAME;
80 27 : aRet.push_back(aPropertyValue);
81 27 : if (!bNew)
82 : {
83 7 : aPropertyValue.Name = "BackColorTransparency";
84 7 : aPropertyValue.Value <<= sal_Int32(100);
85 7 : aRet.push_back(aPropertyValue);
86 : }
87 : // See the spec, new-style frame default margins are specified in EMUs.
88 27 : aPropertyValue.Name = "LeftBorderDistance";
89 27 : aPropertyValue.Value <<= sal_Int32(bNew ? (91440 / 360) : 0);
90 27 : aRet.push_back(aPropertyValue);
91 27 : aPropertyValue.Name = "RightBorderDistance";
92 27 : aPropertyValue.Value <<= sal_Int32(bNew ? (91440 / 360) : 0);
93 27 : aRet.push_back(aPropertyValue);
94 27 : aPropertyValue.Name = "TopBorderDistance";
95 27 : aPropertyValue.Value <<= sal_Int32(bNew ? (45720 / 360) : 0);
96 27 : aRet.push_back(aPropertyValue);
97 27 : aPropertyValue.Name = "BottomBorderDistance";
98 27 : aPropertyValue.Value <<= sal_Int32(bNew ? (45720 / 360) : 0);
99 27 : aRet.push_back(aPropertyValue);
100 27 : aPropertyValue.Name = "SizeType";
101 27 : aPropertyValue.Value <<= text::SizeType::FIX;
102 27 : aRet.push_back(aPropertyValue);
103 54 : return aRet;
104 : }
105 :
106 42 : void RTFSdrImport::resolveDhgt(uno::Reference<beans::XPropertySet> xPropertySet, sal_Int32 nZOrder)
107 : {
108 42 : writerfilter::dmapper::DomainMapper& rMapper = (writerfilter::dmapper::DomainMapper&)m_rImport.Mapper();
109 42 : writerfilter::dmapper::GraphicZOrderHelper* pHelper = rMapper.graphicZOrderHelper();
110 42 : xPropertySet->setPropertyValue("ZOrder", uno::makeAny(pHelper->findZOrder(nZOrder)));
111 42 : pHelper->addItem(xPropertySet, nZOrder);
112 42 : }
113 :
114 23 : void RTFSdrImport::resolveFLine(uno::Reference<beans::XPropertySet> xPropertySet, sal_Int32 nFLine)
115 : {
116 23 : if (nFLine == 0)
117 10 : xPropertySet->setPropertyValue("LineStyle", uno::makeAny(drawing::LineStyle_NONE));
118 23 : }
119 :
120 22 : void RTFSdrImport::applyProperty(uno::Reference<drawing::XShape> xShape, OUString aKey, OUString aValue)
121 : {
122 22 : uno::Reference<beans::XPropertySet> xPropertySet(xShape, uno::UNO_QUERY);
123 22 : sal_Int16 nHoriOrient = 0;
124 22 : sal_Int16 nVertOrient = 0;
125 44 : boost::optional<bool> obFitShapeToText;
126 22 : bool bFilled = true;
127 :
128 22 : if (aKey == "posh")
129 : {
130 5 : switch (aValue.toInt32())
131 : {
132 : case 1:
133 0 : nHoriOrient = text::HoriOrientation::LEFT;
134 0 : break;
135 : case 2:
136 5 : nHoriOrient = text::HoriOrientation::CENTER;
137 5 : break;
138 : case 3:
139 0 : nHoriOrient = text::HoriOrientation::RIGHT;
140 0 : break;
141 : case 4:
142 0 : nHoriOrient = text::HoriOrientation::INSIDE;
143 0 : break;
144 : case 5:
145 0 : nHoriOrient = text::HoriOrientation::OUTSIDE;
146 0 : break;
147 : default:
148 0 : break;
149 : }
150 : }
151 17 : else if (aKey == "posv")
152 : {
153 3 : switch (aValue.toInt32())
154 : {
155 : case 1:
156 2 : nVertOrient = text::VertOrientation::TOP;
157 2 : break;
158 : case 2:
159 1 : nVertOrient = text::VertOrientation::CENTER;
160 1 : break;
161 : case 3:
162 0 : nVertOrient = text::VertOrientation::BOTTOM;
163 0 : break;
164 : default:
165 0 : break;
166 : }
167 : }
168 14 : else if (aKey == "fFitShapeToText")
169 3 : obFitShapeToText.reset(aValue.toInt32() == 1);
170 11 : else if (aKey == "fFilled")
171 11 : bFilled = aValue.toInt32() == 1;
172 :
173 22 : if (nHoriOrient != 0)
174 5 : xPropertySet->setPropertyValue("HoriOrient", uno::makeAny(nHoriOrient));
175 22 : if (nVertOrient != 0)
176 3 : xPropertySet->setPropertyValue("VertOrient", uno::makeAny(nVertOrient));
177 22 : if (obFitShapeToText)
178 : {
179 3 : xPropertySet->setPropertyValue("SizeType", uno::makeAny(*obFitShapeToText ? text::SizeType::MIN : text::SizeType::FIX));
180 3 : xPropertySet->setPropertyValue("FrameIsAutomaticHeight", uno::makeAny(*obFitShapeToText));
181 : }
182 22 : if (!bFilled)
183 30 : xPropertySet->setPropertyValue("BackColorTransparency", uno::makeAny(sal_Int32(100)));
184 22 : }
185 :
186 45 : void RTFSdrImport::resolve(RTFShape& rShape, bool bClose)
187 : {
188 45 : int nType = -1;
189 45 : bool bPib = false;
190 45 : bool bCustom = false;
191 45 : bool bTextFrame = false;
192 :
193 45 : uno::Reference<drawing::XShape> xShape;
194 84 : uno::Reference<beans::XPropertySet> xPropertySet;
195 : // Create this early, as custom shapes may have properties before the type arrives.
196 45 : createShape("com.sun.star.drawing.CustomShape", xShape, xPropertySet);
197 84 : uno::Any aAny;
198 84 : beans::PropertyValue aPropertyValue;
199 45 : awt::Rectangle aViewBox;
200 84 : std::vector<beans::PropertyValue> aPathPropVec;
201 : // Default line color is black in Word, blue in Writer.
202 84 : uno::Any aLineColor = uno::makeAny(COL_BLACK);
203 : // Default line width is 0.75 pt (26 mm100) in Word, 0 in Writer.
204 84 : uno::Any aLineWidth = uno::makeAny(sal_Int32(26));
205 45 : text::WritingMode eWritingMode = text::WritingMode_LR_TB;
206 : // Groupshape support
207 84 : boost::optional<sal_Int32> oGroupLeft, oGroupTop, oGroupRight, oGroupBottom;
208 84 : boost::optional<sal_Int32> oRelLeft, oRelTop, oRelRight, oRelBottom;
209 :
210 : // Importing these are not trivial, let the VML import do the hard work.
211 84 : oox::vml::FillModel aFillModel; // Gradient.
212 84 : oox::vml::ShadowModel aShadowModel; // Shadow.
213 :
214 1392 : for (std::vector< std::pair<OUString, OUString> >::iterator i = rShape.aProperties.begin();
215 928 : i != rShape.aProperties.end(); ++i)
216 : {
217 419 : if ( i->first == "shapeType" )
218 : {
219 43 : nType = i->second.toInt32();
220 43 : switch (nType)
221 : {
222 : case ESCHER_ShpInst_Line:
223 3 : createShape("com.sun.star.drawing.LineShape", xShape, xPropertySet);
224 3 : break;
225 : case ESCHER_ShpInst_Rectangle:
226 : case ESCHER_ShpInst_TextBox:
227 31 : if (!bClose)
228 : {
229 20 : createShape("com.sun.star.text.TextFrame", xShape, xPropertySet);
230 20 : bTextFrame = true;
231 20 : std::vector<beans::PropertyValue> aDefaults = getTextFrameDefaults(true);
232 200 : for (size_t j = 0; j < aDefaults.size(); ++j)
233 200 : xPropertySet->setPropertyValue(aDefaults[j].Name, aDefaults[j].Value);
234 : }
235 : else
236 11 : bCustom = true;
237 31 : break;
238 : default:
239 9 : bCustom = true;
240 9 : break;
241 : }
242 :
243 : // Defaults
244 43 : aAny <<= (sal_uInt32)0xffffff; // White in Word, kind of blue in Writer.
245 43 : if (xPropertySet.is() && !bTextFrame)
246 23 : xPropertySet->setPropertyValue("FillColor", aAny);
247 : }
248 376 : else if ( i->first == "wzName" )
249 : {
250 2 : if (bTextFrame)
251 : {
252 0 : uno::Reference<container::XNamed> xNamed(xShape, uno::UNO_QUERY);
253 0 : xNamed->setName(i->second);
254 : }
255 : else
256 2 : xPropertySet->setPropertyValue("Name", uno::makeAny(i->second));
257 : }
258 374 : else if ( i->first == "wzDescription" )
259 8 : xPropertySet->setPropertyValue("Description", uno::makeAny(i->second));
260 366 : else if ( i->first == "pib" )
261 : {
262 4 : m_rImport.setDestinationText(i->second);
263 4 : bPib = true;
264 : }
265 362 : else if (i->first == "fillColor" && xPropertySet.is())
266 : {
267 16 : aAny <<= msfilter::util::BGRToRGB(i->second.toInt32());
268 16 : if (bTextFrame)
269 8 : xPropertySet->setPropertyValue("BackColor", aAny);
270 : else
271 8 : xPropertySet->setPropertyValue("FillColor", aAny);
272 :
273 : // fillType will decide, possible it'll be the start color of a gradient.
274 16 : aFillModel.moColor.set(OUString("#") + OStringToOUString(msfilter::util::ConvertColor(aAny.get<sal_Int32>()), RTL_TEXTENCODING_UTF8));
275 : }
276 346 : else if ( i->first == "fillBackColor" )
277 : // fillType will decide, possible it'll be the end color of a gradient.
278 6 : aFillModel.moColor2.set(OUString("#") + OStringToOUString(msfilter::util::ConvertColor(msfilter::util::BGRToRGB(i->second.toInt32())), RTL_TEXTENCODING_UTF8));
279 340 : else if (i->first == "lineColor")
280 17 : aLineColor <<= msfilter::util::BGRToRGB(i->second.toInt32());
281 323 : else if ( i->first == "lineBackColor" )
282 : ; // Ignore: complementer of lineColor
283 322 : else if (i->first == "txflTextFlow" && xPropertySet.is())
284 : {
285 2 : if (i->second.toInt32() == 1)
286 0 : eWritingMode = text::WritingMode_TB_RL;
287 : }
288 320 : else if (i->first == "fLine" && xPropertySet.is())
289 5 : resolveFLine(xPropertySet, i->second.toInt32());
290 315 : else if (i->first == "fillOpacity" && xPropertySet.is())
291 : {
292 0 : int opacity = 100 - (i->second.toInt32())*100/65536;
293 0 : aAny <<= uno::makeAny(sal_uInt32(opacity));
294 0 : xPropertySet->setPropertyValue("FillTransparence", aAny);
295 : }
296 315 : else if (i->first == "rotation" && xPropertySet.is())
297 : {
298 0 : aAny <<= i->second.toInt32()*100/65536;
299 0 : xPropertySet->setPropertyValue("RotateAngle", aAny);
300 : }
301 315 : else if (i->first == "lineWidth")
302 19 : aLineWidth <<= i->second.toInt32()/360;
303 296 : else if ( i->first == "pVerticies" )
304 : {
305 3 : uno::Sequence<drawing::EnhancedCustomShapeParameterPair> aCoordinates;
306 3 : sal_Int32 nSize = 0; // Size of a token (it's value is hardwired in the exporter)
307 3 : sal_Int32 nCount = 0; // Number of tokens
308 3 : sal_Int32 nCharIndex = 0; // Character index
309 3 : sal_Int32 nIndex = 0; // Array index
310 122 : do
311 : {
312 122 : OUString aToken = i->second.getToken(0, ';', nCharIndex);
313 122 : if (!nSize)
314 3 : nSize = aToken.toInt32();
315 119 : else if (!nCount)
316 : {
317 3 : nCount = aToken.toInt32();
318 3 : aCoordinates.realloc(nCount);
319 : }
320 : else
321 : {
322 : // The coordinates are in an (x,y) form.
323 116 : aToken = aToken.copy(1, aToken.getLength() - 2);
324 116 : sal_Int32 nI = 0;
325 116 : boost::optional<sal_Int32> oX;
326 232 : boost::optional<sal_Int32> oY;
327 232 : do
328 : {
329 232 : OUString aPoint = aToken.getToken(0, ',', nI);
330 232 : if (!oX)
331 116 : oX.reset(aPoint.toInt32());
332 : else
333 116 : oY.reset(aPoint.toInt32());
334 : }
335 232 : while (nI >= 0);
336 116 : aCoordinates[nIndex].First.Value <<= *oX;
337 116 : aCoordinates[nIndex].Second.Value <<= *oY;
338 232 : nIndex++;
339 122 : }
340 : }
341 122 : while (nCharIndex >= 0);
342 3 : aPropertyValue.Name = "Coordinates";
343 3 : aPropertyValue.Value <<= aCoordinates;
344 3 : aPathPropVec.push_back(aPropertyValue);
345 : }
346 293 : else if ( i->first == "pSegmentInfo" )
347 : {
348 3 : uno::Sequence<drawing::EnhancedCustomShapeSegment> aSegments;
349 3 : sal_Int32 nSize = 0;
350 3 : sal_Int32 nCount = 0;
351 3 : sal_Int32 nCharIndex = 0;
352 3 : sal_Int32 nIndex = 0;
353 24 : do
354 : {
355 24 : sal_Int32 nSeg = i->second.getToken(0, ';', nCharIndex).toInt32();
356 24 : if (!nSize)
357 3 : nSize = nSeg;
358 21 : else if (!nCount)
359 : {
360 3 : nCount = nSeg;
361 3 : aSegments.realloc(nCount);
362 : }
363 : else
364 : {
365 18 : sal_Int32 nPoints = 1;
366 18 : if (nSeg >= 0x2000 && nSeg < 0x20FF)
367 : {
368 3 : nPoints = nSeg & 0x0FFF;
369 3 : nSeg &= 0xFF00;
370 : }
371 :
372 18 : switch (nSeg)
373 : {
374 : case 0x0001: // lineto
375 3 : aSegments[nIndex].Command = drawing::EnhancedCustomShapeSegmentCommand::LINETO;
376 3 : aSegments[nIndex].Count = sal_Int32(1);
377 3 : break;
378 : case 0x4000: // moveto
379 5 : aSegments[nIndex].Command = drawing::EnhancedCustomShapeSegmentCommand::MOVETO;
380 5 : aSegments[nIndex].Count = sal_Int32(1);
381 5 : break;
382 : case 0x2000: // curveto
383 3 : aSegments[nIndex].Command = drawing::EnhancedCustomShapeSegmentCommand::CURVETO;
384 3 : aSegments[nIndex].Count = sal_Int32(nPoints);
385 3 : break;
386 : case 0xb300: // arcto
387 0 : aSegments[nIndex].Command = drawing::EnhancedCustomShapeSegmentCommand::ARCTO;
388 0 : aSegments[nIndex].Count = sal_Int32(0);
389 0 : break;
390 : case 0xac00:
391 : case 0xaa00: // nofill
392 : case 0xab00: // nostroke
393 : case 0x6001: // close
394 1 : break;
395 : case 0x8000: // end
396 5 : aSegments[nIndex].Command = drawing::EnhancedCustomShapeSegmentCommand::ENDSUBPATH;
397 5 : aSegments[nIndex].Count = sal_Int32(0);
398 5 : break;
399 : default: // given number of lineto elements
400 1 : aSegments[nIndex].Command = drawing::EnhancedCustomShapeSegmentCommand::LINETO;
401 1 : aSegments[nIndex].Count = nSeg;
402 1 : break;
403 : }
404 18 : nIndex++;
405 : }
406 : }
407 24 : while (nCharIndex >= 0);
408 3 : aPropertyValue.Name = "Segments";
409 3 : aPropertyValue.Value <<= aSegments;
410 3 : aPathPropVec.push_back(aPropertyValue);
411 : }
412 290 : else if ( i->first == "geoLeft" )
413 2 : aViewBox.X = i->second.toInt32();
414 288 : else if ( i->first == "geoTop" )
415 2 : aViewBox.Y = i->second.toInt32();
416 286 : else if ( i->first == "geoRight" )
417 3 : aViewBox.Width = i->second.toInt32();
418 283 : else if ( i->first == "geoBottom" )
419 3 : aViewBox.Height = i->second.toInt32();
420 280 : else if ( i->first == "dhgt" )
421 : {
422 7 : resolveDhgt(xPropertySet, i->second.toInt32());
423 : // dhgt is Word 2007, \shpz is Word 97-2003, the previous has priority.
424 7 : rShape.oZ.reset();
425 : }
426 : // These are in EMU, convert to mm100.
427 273 : else if (i->first == "dxTextLeft")
428 11 : xPropertySet->setPropertyValue("LeftBorderDistance", uno::makeAny(i->second.toInt32() / 360));
429 262 : else if (i->first == "dyTextTop")
430 11 : xPropertySet->setPropertyValue("TopBorderDistance", uno::makeAny(i->second.toInt32() / 360));
431 251 : else if (i->first == "dxTextRight")
432 11 : xPropertySet->setPropertyValue("RightBorderDistance", uno::makeAny(i->second.toInt32() / 360));
433 240 : else if (i->first == "dyTextBottom")
434 11 : xPropertySet->setPropertyValue("BottomBorderDistance", uno::makeAny(i->second.toInt32() / 360));
435 229 : else if (i->first == "dxWrapDistLeft")
436 8 : xPropertySet->setPropertyValue("LeftMargin", uno::makeAny(i->second.toInt32() / 360));
437 221 : else if (i->first == "dyWrapDistTop")
438 8 : xPropertySet->setPropertyValue("TopMargin", uno::makeAny(i->second.toInt32() / 360));
439 213 : else if (i->first == "dxWrapDistRight")
440 8 : xPropertySet->setPropertyValue("RightMargin", uno::makeAny(i->second.toInt32() / 360));
441 205 : else if (i->first == "dyWrapDistBottom")
442 8 : xPropertySet->setPropertyValue("BottomMargin", uno::makeAny(i->second.toInt32() / 360));
443 197 : else if (i->first == "fillType")
444 : {
445 4 : switch (i->second.toInt32())
446 : {
447 : case 7: // Shade using the fillAngle
448 4 : aFillModel.moType.set(oox::XML_gradient);
449 4 : break;
450 : default:
451 : SAL_INFO("writerfilter", "TODO handle fillType value '" << i->second << "'");
452 0 : break;
453 : }
454 : }
455 193 : else if (i->first == "fillFocus")
456 4 : aFillModel.moFocus.set(i->second.toDouble() / 100); // percent
457 189 : else if (i->first == "fShadow" && xPropertySet.is())
458 : {
459 12 : if (i->second.toInt32() == 1)
460 9 : aShadowModel.mbHasShadow = true;
461 : }
462 177 : else if (i->first == "shadowColor")
463 9 : aShadowModel.moColor.set(OUString("#") + OStringToOUString(msfilter::util::ConvertColor(msfilter::util::BGRToRGB(i->second.toInt32())), RTL_TEXTENCODING_UTF8));
464 168 : else if (i->first == "shadowOffsetX")
465 : // EMUs to points
466 9 : aShadowModel.moOffset.set(OUString::number(i->second.toDouble() / 12700) + "pt");
467 159 : else if (i->first == "posh" || i->first == "posv" || i->first == "fFitShapeToText" || i->first == "fFilled")
468 14 : applyProperty(xShape, i->first, i->second);
469 145 : else if (i->first == "posrelh")
470 : {
471 13 : switch (i->second.toInt32())
472 : {
473 : case 1:
474 5 : rShape.nHoriOrientRelation = text::RelOrientation::PAGE_FRAME;
475 5 : break;
476 : default:
477 8 : break;
478 : }
479 : }
480 132 : else if (i->first == "posrelv")
481 : {
482 12 : switch (i->second.toInt32())
483 : {
484 : case 1:
485 5 : rShape.nVertOrientRelation = text::RelOrientation::PAGE_FRAME;
486 5 : break;
487 : default:
488 7 : break;
489 : }
490 : }
491 120 : else if (i->first == "groupLeft")
492 2 : oGroupLeft.reset(TWIP_TO_MM100(i->second.toInt32()));
493 118 : else if (i->first == "groupTop")
494 2 : oGroupTop.reset(TWIP_TO_MM100(i->second.toInt32()));
495 116 : else if (i->first == "groupRight")
496 2 : oGroupRight.reset(TWIP_TO_MM100(i->second.toInt32()));
497 114 : else if (i->first == "groupBottom")
498 2 : oGroupBottom.reset(TWIP_TO_MM100(i->second.toInt32()));
499 112 : else if (i->first == "relLeft")
500 2 : oRelLeft.reset(TWIP_TO_MM100(i->second.toInt32()));
501 110 : else if (i->first == "relTop")
502 2 : oRelTop.reset(TWIP_TO_MM100(i->second.toInt32()));
503 108 : else if (i->first == "relRight")
504 2 : oRelRight.reset(TWIP_TO_MM100(i->second.toInt32()));
505 106 : else if (i->first == "relBottom")
506 2 : oRelBottom.reset(TWIP_TO_MM100(i->second.toInt32()));
507 : else
508 : SAL_INFO("writerfilter", "TODO handle shape property '" << i->first << "':'" << i->second << "'");
509 : }
510 :
511 45 : if (xPropertySet.is())
512 : {
513 44 : if (!bTextFrame)
514 : {
515 24 : xPropertySet->setPropertyValue("LineColor", aLineColor);
516 24 : xPropertySet->setPropertyValue("LineWidth", aLineWidth);
517 : }
518 : else
519 : {
520 : static OUString aBorders[] = {
521 : OUString("TopBorder"), OUString("LeftBorder"), OUString("BottomBorder"), OUString("RightBorder")
522 22 : };
523 100 : for (unsigned int i = 0; i < SAL_N_ELEMENTS(aBorders); ++i)
524 : {
525 80 : table::BorderLine2 aBorderLine = xPropertySet->getPropertyValue(aBorders[i]).get<table::BorderLine2>();
526 80 : aBorderLine.Color = aLineColor.get<sal_Int32>();
527 80 : aBorderLine.LineWidth = aLineWidth.get<sal_Int32>();
528 80 : xPropertySet->setPropertyValue(aBorders[i], uno::makeAny(aBorderLine));
529 : }
530 : }
531 44 : if (rShape.oZ)
532 17 : resolveDhgt(xPropertySet, *rShape.oZ);
533 44 : if (bTextFrame)
534 : // Writer textframes implement text::WritingMode2, which is a different data type.
535 20 : xPropertySet->setPropertyValue("WritingMode", uno::makeAny(sal_Int16(eWritingMode)));
536 : else
537 24 : xPropertySet->setPropertyValue("TextWritingMode", uno::makeAny(eWritingMode));
538 : }
539 :
540 45 : if (nType == ESCHER_ShpInst_PictureFrame) // picture frame
541 : {
542 5 : if (bPib)
543 4 : m_rImport.resolvePict(false);
544 5 : return;
545 : }
546 :
547 40 : if (m_xDrawPage.is() && !bTextFrame)
548 19 : m_xDrawPage->add(xShape);
549 40 : if (bCustom && xShape.is())
550 : {
551 15 : uno::Reference<drawing::XEnhancedCustomShapeDefaulter> xDefaulter(xShape, uno::UNO_QUERY);
552 15 : xDefaulter->createCustomShapeDefaults(OUString::valueOf(sal_Int32(nType)));
553 : }
554 :
555 : // Creating Path property
556 40 : uno::Sequence<beans::PropertyValue> aPathPropSeq(aPathPropVec.size());
557 40 : beans::PropertyValue* pPathValues = aPathPropSeq.getArray();
558 46 : for (std::vector<beans::PropertyValue>::iterator i = aPathPropVec.begin(); i != aPathPropVec.end(); ++i)
559 6 : *pPathValues++ = *i;
560 :
561 : // Creating CustomShapeGeometry property
562 79 : std::vector<beans::PropertyValue> aGeomPropVec;
563 40 : if (aViewBox.X || aViewBox.Y || aViewBox.Width || aViewBox.Height)
564 : {
565 3 : aViewBox.Width -= aViewBox.X;
566 3 : aViewBox.Height -= aViewBox.Y;
567 3 : aPropertyValue.Name = "ViewBox";
568 3 : aPropertyValue.Value <<= aViewBox;
569 3 : aGeomPropVec.push_back(aPropertyValue);
570 : }
571 40 : if (aPathPropSeq.getLength())
572 : {
573 3 : aPropertyValue.Name = "Path";
574 3 : aPropertyValue.Value <<= aPathPropSeq;
575 3 : aGeomPropVec.push_back(aPropertyValue);
576 : }
577 79 : uno::Sequence<beans::PropertyValue> aGeomPropSeq(aGeomPropVec.size());
578 40 : beans::PropertyValue* pGeomValues = aGeomPropSeq.getArray();
579 46 : for (std::vector<beans::PropertyValue>::iterator i = aGeomPropVec.begin(); i != aGeomPropVec.end(); ++i)
580 6 : *pGeomValues++ = *i;
581 40 : if (aGeomPropSeq.getLength() && xPropertySet.is())
582 3 : xPropertySet->setPropertyValue("CustomShapeGeometry", uno::Any(aGeomPropSeq));
583 :
584 : // Set position and size
585 40 : if (xShape.is())
586 : {
587 39 : sal_Int32 nLeft = rShape.nLeft;
588 39 : sal_Int32 nTop = rShape.nTop;
589 :
590 41 : bool bInShapeGroup = oGroupLeft && oGroupTop && oGroupRight && oGroupBottom
591 41 : && oRelLeft && oRelTop && oRelRight && oRelBottom;
592 39 : if (bInShapeGroup)
593 : {
594 : // See lclGetAbsPoint() in the VML import: rShape is the group shape, oGroup is its coordinate system, oRel is the relative child shape.
595 2 : sal_Int32 nShapeWidth = rShape.nRight - rShape.nLeft;
596 2 : sal_Int32 nShapeHeight = rShape.nBottom - rShape.nTop;
597 2 : sal_Int32 nCoordSysWidth = *oGroupRight - *oGroupLeft;
598 2 : sal_Int32 nCoordSysHeight = *oGroupBottom - *oGroupTop;
599 2 : double fWidthRatio = static_cast< double >( nShapeWidth ) / nCoordSysWidth;
600 2 : double fHeightRatio = static_cast< double >( nShapeHeight ) / nCoordSysHeight;
601 2 : nLeft = static_cast< sal_Int32 >( rShape.nLeft + fWidthRatio * (*oRelLeft - *oGroupLeft) );
602 2 : nTop = static_cast< sal_Int32 >( rShape.nTop + fHeightRatio * (*oRelTop - *oGroupTop) );
603 : }
604 :
605 39 : if (bTextFrame)
606 : {
607 20 : xPropertySet->setPropertyValue("HoriOrientPosition", uno::makeAny(nLeft));
608 20 : xPropertySet->setPropertyValue("VertOrientPosition", uno::makeAny(nTop));
609 : }
610 : else
611 19 : xShape->setPosition(awt::Point(nLeft, nTop));
612 :
613 39 : if (bInShapeGroup)
614 2 : xShape->setSize(awt::Size(*oRelRight - *oRelLeft, *oRelBottom - *oRelTop));
615 : else
616 37 : xShape->setSize(awt::Size(rShape.nRight - rShape.nLeft, rShape.nBottom - rShape.nTop));
617 :
618 39 : if (rShape.nHoriOrientRelation != 0)
619 14 : xPropertySet->setPropertyValue("HoriOrientRelation", uno::makeAny(rShape.nHoriOrientRelation));
620 39 : if (rShape.nVertOrientRelation != 0)
621 13 : xPropertySet->setPropertyValue("VertOrientRelation", uno::makeAny(rShape.nVertOrientRelation));
622 39 : if (rShape.nWrap != -1)
623 24 : xPropertySet->setPropertyValue("Surround", uno::makeAny(text::WrapTextMode(rShape.nWrap)));
624 39 : oox::ModelObjectHelper aModelObjectHelper(m_rImport.getModelFactory());
625 39 : if (aFillModel.moType.has())
626 : {
627 4 : oox::drawingml::ShapePropertyMap aPropMap(aModelObjectHelper);
628 4 : aFillModel.pushToPropMap(aPropMap, m_rImport.getGraphicHelper());
629 : // Sets the FillStyle and FillGradient UNO properties.
630 4 : oox::PropertySet(xShape).setProperties(aPropMap);
631 : }
632 :
633 39 : if (aShadowModel.mbHasShadow)
634 : {
635 9 : oox::drawingml::ShapePropertyMap aPropMap(aModelObjectHelper);
636 9 : aShadowModel.pushToPropMap(aPropMap, m_rImport.getGraphicHelper());
637 : // Sets the ShadowFormat UNO property.
638 9 : oox::PropertySet(xShape).setProperties(aPropMap);
639 39 : }
640 : }
641 :
642 40 : if (m_rImport.isInBackground())
643 : {
644 1 : RTFSprms aAttributes;
645 1 : aAttributes.set(NS_ooxml::LN_CT_Background_color, RTFValue::Pointer_t(new RTFValue(xPropertySet->getPropertyValue("FillColor").get<sal_Int32>())));
646 2 : writerfilter::Reference<Properties>::Pointer_t const pProperties(new RTFReferenceProperties(aAttributes));
647 1 : m_rImport.Mapper().props(pProperties);
648 :
649 2 : uno::Reference<lang::XComponent> xComponent(xShape, uno::UNO_QUERY);
650 1 : xComponent->dispose();
651 2 : return;
652 : }
653 :
654 : // Send it to dmapper
655 39 : m_rImport.Mapper().startShape(xShape);
656 39 : if (bClose)
657 : {
658 19 : m_rImport.Mapper().endShape();
659 : }
660 117 : m_xShape = xShape;
661 : }
662 :
663 20 : void RTFSdrImport::close()
664 : {
665 20 : m_rImport.Mapper().endShape();
666 20 : }
667 :
668 8 : void RTFSdrImport::append(OUString aKey, OUString aValue)
669 : {
670 8 : applyProperty(m_xShape, aKey, aValue);
671 8 : }
672 :
673 : } // namespace rtftok
674 24 : } // namespace writerfilter
675 :
676 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|