LibreOffice Module writerfilter (master) 1
rtfsdrimport.cxx
Go to the documentation of this file.
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 "rtfsdrimport.hxx"
11#include <cmath>
12#include <optional>
13#include <com/sun/star/container/XNamed.hpp>
14#include <com/sun/star/drawing/FillStyle.hpp>
15#include <com/sun/star/drawing/EnhancedCustomShapeParameterPair.hpp>
16#include <com/sun/star/drawing/XEnhancedCustomShapeDefaulter.hpp>
17#include <com/sun/star/drawing/XDrawPageSupplier.hpp>
18#include <com/sun/star/drawing/LineStyle.hpp>
19#include <com/sun/star/drawing/EnhancedCustomShapeSegment.hpp>
20#include <com/sun/star/drawing/EnhancedCustomShapeSegmentCommand.hpp>
21#include <com/sun/star/drawing/ColorMode.hpp>
22#include <com/sun/star/lang/XServiceInfo.hpp>
23#include <com/sun/star/table/BorderLine2.hpp>
24#include <com/sun/star/text/HoriOrientation.hpp>
25#include <com/sun/star/text/RelOrientation.hpp>
26#include <com/sun/star/text/SizeType.hpp>
27#include <com/sun/star/text/VertOrientation.hpp>
28#include <com/sun/star/text/WrapTextMode.hpp>
29#include <com/sun/star/text/WritingMode.hpp>
30#include <com/sun/star/text/WritingMode2.hpp>
31#include <com/sun/star/text/TextContentAnchorType.hpp>
32#include <com/sun/star/text/XTextRange.hpp>
33#include <com/sun/star/lang/XMultiServiceFactory.hpp>
34#include <ooxml/resourceids.hxx>
38#include <sal/log.hxx>
39#include <svx/svdtrans.hxx>
48#include <svx/svdobj.hxx>
50#include <o3tl/string_view.hxx>
51
53#include "rtfdocumentimpl.hxx"
54
55using namespace com::sun::star;
56
58{
61 : m_rImport(rDocument)
62 , m_bTextFrame(false)
63 , m_bTextGraphicObject(false)
64 , m_bFakePict(false)
65{
66 uno::Reference<drawing::XDrawPageSupplier> xDrawings(xDstDoc, uno::UNO_QUERY);
67 if (xDrawings.is())
68 m_aParents.push(xDrawings->getDrawPage());
70}
71
73{
74 if (!m_aGraphicZOrderHelpers.empty())
76 if (!m_aParents.empty())
77 m_aParents.pop();
78}
79
80void RTFSdrImport::createShape(const OUString& rService, uno::Reference<drawing::XShape>& xShape,
82{
83 if (m_rImport.getModelFactory().is())
84 xShape.set(m_rImport.getModelFactory()->createInstance(rService), uno::UNO_QUERY);
85 xPropertySet.set(xShape, uno::UNO_QUERY);
86}
87
88std::vector<beans::PropertyValue> RTFSdrImport::getTextFrameDefaults(bool bNew)
89{
90 std::vector<beans::PropertyValue> aRet;
91 beans::PropertyValue aPropertyValue;
92
93 aPropertyValue.Name = "HoriOrient";
94 aPropertyValue.Value <<= text::HoriOrientation::NONE;
95 aRet.push_back(aPropertyValue);
96 aPropertyValue.Name = "HoriOrientRelation";
97 aPropertyValue.Value <<= text::RelOrientation::FRAME;
98 aRet.push_back(aPropertyValue);
99 aPropertyValue.Name = "VertOrient";
100 aPropertyValue.Value <<= text::VertOrientation::NONE;
101 aRet.push_back(aPropertyValue);
102 aPropertyValue.Name = "VertOrientRelation";
103 aPropertyValue.Value <<= text::RelOrientation::FRAME;
104 aRet.push_back(aPropertyValue);
105 if (!bNew)
106 {
107 aPropertyValue.Name = "BackColorTransparency";
108 aPropertyValue.Value <<= sal_Int32(100);
109 aRet.push_back(aPropertyValue);
110 }
111 // See the spec, new-style frame default margins are specified in EMUs.
112 aPropertyValue.Name = "LeftBorderDistance";
113 aPropertyValue.Value <<= sal_Int32(bNew ? (91440 / 360) : 0);
114 aRet.push_back(aPropertyValue);
115 aPropertyValue.Name = "RightBorderDistance";
116 aPropertyValue.Value <<= sal_Int32(bNew ? (91440 / 360) : 0);
117 aRet.push_back(aPropertyValue);
118 aPropertyValue.Name = "TopBorderDistance";
119 aPropertyValue.Value <<= sal_Int32(bNew ? (45720 / 360) : 0);
120 aRet.push_back(aPropertyValue);
121 aPropertyValue.Name = "BottomBorderDistance";
122 aPropertyValue.Value <<= sal_Int32(bNew ? (45720 / 360) : 0);
123 aRet.push_back(aPropertyValue);
124 aPropertyValue.Name = "SizeType";
125 aPropertyValue.Value <<= text::SizeType::FIX;
126 aRet.push_back(aPropertyValue);
127 return aRet;
128}
129
131{
132 m_aParents.push(xParent);
134}
135
137{
138 if (!m_aGraphicZOrderHelpers.empty())
140 if (!m_aParents.empty())
141 m_aParents.pop();
142}
143
145 sal_Int32 const nZOrder, bool const bOldStyle)
146{
147 if (!m_aGraphicZOrderHelpers.empty())
148 {
150 xPropertySet->setPropertyValue("ZOrder", uno::Any(rHelper.findZOrder(nZOrder, bOldStyle)));
151 rHelper.addItem(xPropertySet, nZOrder);
152 }
153}
154
156 const uno::Reference<beans::XPropertySet>& xPropertySet,
157 uno::Any const& rLineColor, uno::Any const& rLineWidth)
158{
159 if (!bTextFrame)
160 {
161 xPropertySet->setPropertyValue("LineColor", rLineColor);
162 xPropertySet->setPropertyValue("LineWidth", rLineWidth);
163 }
164 else
165 {
166 static const char* aBorders[]
167 = { "TopBorder", "LeftBorder", "BottomBorder", "RightBorder" };
168 for (const char* pBorder : aBorders)
169 {
170 auto aBorderLine = xPropertySet->getPropertyValue(OUString::createFromAscii(pBorder))
171 .get<table::BorderLine2>();
172 if (rLineColor.hasValue())
173 aBorderLine.Color = rLineColor.get<sal_Int32>();
174 if (rLineWidth.hasValue())
175 aBorderLine.LineWidth = rLineWidth.get<sal_Int32>();
176 xPropertySet->setPropertyValue(OUString::createFromAscii(pBorder),
177 uno::Any(aBorderLine));
178 }
179 }
180}
181
183 sal_Int32 const nFLine)
184{
185 if (nFLine == 0)
186 xPropertySet->setPropertyValue("LineStyle", uno::Any(drawing::LineStyle_NONE));
187 else
188 xPropertySet->setPropertyValue("LineStyle", uno::Any(drawing::LineStyle_SOLID));
189}
190
192 std::u16string_view aKey, std::u16string_view aValue) const
193{
194 uno::Reference<beans::XPropertySet> xPropertySet(xShape, uno::UNO_QUERY);
195 sal_Int16 nHoriOrient = 0;
196 sal_Int16 nVertOrient = 0;
197 std::optional<bool> obFitShapeToText;
198 bool bFilled = true;
199
200 if (aKey == u"posh")
201 {
202 switch (o3tl::toInt32(aValue))
203 {
204 case 1:
205 nHoriOrient = text::HoriOrientation::LEFT;
206 break;
207 case 2:
208 nHoriOrient = text::HoriOrientation::CENTER;
209 break;
210 case 3:
211 nHoriOrient = text::HoriOrientation::RIGHT;
212 break;
213 case 4:
214 nHoriOrient = text::HoriOrientation::INSIDE;
215 break;
216 case 5:
217 nHoriOrient = text::HoriOrientation::OUTSIDE;
218 break;
219 default:
220 break;
221 }
222 }
223 else if (aKey == u"posv")
224 {
225 switch (o3tl::toInt32(aValue))
226 {
227 case 1:
228 nVertOrient = text::VertOrientation::TOP;
229 break;
230 case 2:
231 nVertOrient = text::VertOrientation::CENTER;
232 break;
233 case 3:
234 nVertOrient = text::VertOrientation::BOTTOM;
235 break;
236 default:
237 break;
238 }
239 }
240 else if (aKey == u"fFitShapeToText")
241 obFitShapeToText = o3tl::toInt32(aValue) == 1;
242 else if (aKey == u"fFilled")
243 bFilled = o3tl::toInt32(aValue) == 1;
244 else if (aKey == u"rotation")
245 {
246 // See DffPropertyReader::Fix16ToAngle(): in RTF, positive rotation angles are clockwise, we have them as counter-clockwise.
247 // Additionally, RTF type is 0..360*2^16, our is 0..360*100.
248 sal_Int32 nRotation = o3tl::toInt32(aValue) * 100 / RTF_MULTIPLIER;
249 uno::Reference<lang::XServiceInfo> xServiceInfo(xShape, uno::UNO_QUERY);
250 if (!xServiceInfo->supportsService("com.sun.star.text.TextFrame"))
251 xPropertySet->setPropertyValue(
252 "RotateAngle", uno::Any(NormAngle36000(Degree100(nRotation * -1)).get()));
253 }
254
255 if (nHoriOrient != 0 && xPropertySet.is())
256 xPropertySet->setPropertyValue("HoriOrient", uno::Any(nHoriOrient));
257 if (nVertOrient != 0 && xPropertySet.is())
258 xPropertySet->setPropertyValue("VertOrient", uno::Any(nVertOrient));
259 if (obFitShapeToText.has_value() && xPropertySet.is())
260 {
261 xPropertySet->setPropertyValue(
262 "SizeType", uno::Any(*obFitShapeToText ? text::SizeType::MIN : text::SizeType::FIX));
263 xPropertySet->setPropertyValue("FrameIsAutomaticHeight", uno::Any(*obFitShapeToText));
264 }
265 if (!bFilled && xPropertySet.is())
266 {
267 if (m_bTextFrame)
268 xPropertySet->setPropertyValue("BackColorTransparency", uno::Any(sal_Int32(100)));
269 else
270 xPropertySet->setPropertyValue("FillStyle", uno::Any(drawing::FillStyle_NONE));
271 }
272}
273
275 uno::Reference<beans::XPropertySet>& o_xPropSet, bool& o_rIsCustomShape,
276 RTFShape const& rShape, bool const bClose,
277 ShapeOrPict const shapeOrPict)
278{
279 assert(!o_xShape.is());
280 assert(!o_xPropSet.is());
281 o_rIsCustomShape = false;
282 m_bFakePict = false;
283
284 // first, find the shape type
285 int nType = -1;
286 auto iter = std::find_if(rShape.getProperties().begin(), rShape.getProperties().end(),
287 [](const std::pair<OUString, OUString>& rProperty) {
288 return rProperty.first == "shapeType";
289 });
290
291 if (iter == rShape.getProperties().end())
292 {
293 if (SHAPE == shapeOrPict)
294 {
295 // The spec doesn't state what is the default for shapeType,
296 // Word seems to implement it as a rectangle.
298 }
299 else
300 {
301 // pict is picture by default but can be a rectangle too fdo#79319
303 }
304 }
305 else
306 {
307 nType = iter->second.toInt32();
308 if (PICT == shapeOrPict && ESCHER_ShpInst_PictureFrame != nType)
309 {
310 m_bFakePict = true;
311 }
312 }
313
314 switch (nType)
315 {
317 createShape("com.sun.star.drawing.GraphicObjectShape", o_xShape, o_xPropSet);
319 break;
321 createShape("com.sun.star.drawing.LineShape", o_xShape, o_xPropSet);
322 break;
325 // If we're inside a groupshape, can't use text frames.
326 if (!bClose && m_aParents.size() == 1)
327 {
328 createShape("com.sun.star.text.TextFrame", o_xShape, o_xPropSet);
329 m_bTextFrame = true;
330 std::vector<beans::PropertyValue> aDefaults = getTextFrameDefaults(true);
331 for (const beans::PropertyValue& i : aDefaults)
332 o_xPropSet->setPropertyValue(i.Name, i.Value);
333 break;
334 }
335 [[fallthrough]];
336 default:
337 createShape("com.sun.star.drawing.CustomShape", o_xShape, o_xPropSet);
338 o_rIsCustomShape = true;
339 break;
340 }
341
342 // Defaults
343 if (o_xPropSet.is() && !m_bTextFrame)
344 {
345 o_xPropSet->setPropertyValue(
346 "FillColor",
347 uno::Any(sal_uInt32(0xffffff))); // White in Word, kind of blue in Writer.
348 o_xPropSet->setPropertyValue("VertOrient", uno::Any(text::VertOrientation::NONE));
349 }
350
351 return nType;
352}
353
354void RTFSdrImport::resolve(RTFShape& rShape, bool bClose, ShapeOrPict const shapeOrPict)
355{
356 bool bPib = false;
357 m_bTextFrame = false;
358 m_bTextGraphicObject = false;
359
362 uno::Any aAny;
363 beans::PropertyValue aPropertyValue;
364 awt::Rectangle aViewBox;
365 std::vector<beans::PropertyValue> aPath;
366 // Default line color is black in Word, blue in Writer.
367 uno::Any aLineColor(COL_BLACK);
368 // Default line width is 0.75 pt (26 mm100) in Word, 0 in Writer.
369 uno::Any aLineWidth(sal_Int32(26));
370 sal_Int16 eWritingMode = text::WritingMode2::LR_TB;
371 // Groupshape support
372 std::optional<sal_Int32> oGroupLeft;
373 std::optional<sal_Int32> oGroupTop;
374 std::optional<sal_Int32> oGroupRight;
375 std::optional<sal_Int32> oGroupBottom;
376 std::optional<sal_Int32> oRelLeft;
377 std::optional<sal_Int32> oRelTop;
378 std::optional<sal_Int32> oRelRight;
379 std::optional<sal_Int32> oRelBottom;
380
381 // Importing these are not trivial, let the VML import do the hard work.
382 oox::vml::FillModel aFillModel; // Gradient.
383 oox::vml::ShadowModel aShadowModel; // Shadow.
384
385 bool bOpaque = true;
386
387 std::optional<sal_Int16> oRelativeWidth;
388 std::optional<sal_Int16> oRelativeHeight;
389 sal_Int16 nRelativeWidthRelation = text::RelOrientation::PAGE_FRAME;
390 sal_Int16 nRelativeHeightRelation = text::RelOrientation::PAGE_FRAME;
391 std::optional<bool> obRelFlipV;
392 bool obFlipH(false);
393 bool obFlipV(false);
394
395 OUString aShapeText = "";
396 OUString aFontFamily = "";
397 float nFontSize = 1.0;
398
399 sal_Int32 nContrast = 0x10000;
400 sal_Int16 nBrightness = 0;
401
402 bool bCustom(false);
403 int const nType = initShape(xShape, xPropertySet, bCustom, rShape, bClose, shapeOrPict);
404
405 for (auto& rProperty : rShape.getProperties())
406 {
407 if (rProperty.first == "shapeType")
408 {
409 continue; // ignore: already handled by initShape
410 }
411 if (rProperty.first == "wzName")
412 {
413 if (m_bTextFrame)
414 {
415 uno::Reference<container::XNamed> xNamed(xShape, uno::UNO_QUERY);
416 xNamed->setName(rProperty.second);
417 }
418 else
419 xPropertySet->setPropertyValue("Name", uno::Any(rProperty.second));
420 }
421 else if (rProperty.first == "wzDescription")
422 xPropertySet->setPropertyValue("Description", uno::Any(rProperty.second));
423 else if (rProperty.first == "gtextUNICODE")
424 aShapeText = rProperty.second;
425 else if (rProperty.first == "gtextFont")
426 aFontFamily = rProperty.second;
427 else if (rProperty.first == "gtextSize")
428 {
429 // RTF size is multiplied by 2^16
430 nFontSize = static_cast<float>(rProperty.second.toUInt32()) / RTF_MULTIPLIER;
431 }
432 else if (rProperty.first == "pib")
433 {
434 m_rImport.setDestinationText(rProperty.second);
435 bPib = true;
436 }
437 else if (rProperty.first == "fillColor" && xPropertySet.is())
438 {
439 aAny <<= msfilter::util::BGRToRGB(rProperty.second.toUInt32());
440 if (m_bTextFrame)
441 xPropertySet->setPropertyValue("BackColor", aAny);
442 else
443 xPropertySet->setPropertyValue("FillColor", aAny);
444
445 // fillType will decide, possible it'll be the start color of a gradient.
446 aFillModel.moColor
447 = "#"
448 + msfilter::util::ConvertColorOU(Color(ColorTransparency, aAny.get<sal_Int32>()));
449 }
450 else if (rProperty.first == "fillBackColor")
451 // fillType will decide, possible it'll be the end color of a gradient.
452 aFillModel.moColor2 = "#"
454 msfilter::util::BGRToRGB(rProperty.second.toInt32()));
455 else if (rProperty.first == "lineColor")
456 aLineColor <<= msfilter::util::BGRToRGB(rProperty.second.toInt32());
457 else if (rProperty.first == "lineBackColor")
458 ; // Ignore: complementer of lineColor
459 else if (rProperty.first == "txflTextFlow" && xPropertySet.is())
460 {
461 switch (rProperty.second.toInt32())
462 {
463 case 1: // Top to bottom ASCII font
464 case 3: // Top to bottom non-ASCII font
465 eWritingMode = text::WritingMode2::TB_RL;
466 break;
467 case 2: // Bottom to top non-ASCII font
468 eWritingMode = text::WritingMode2::BT_LR;
469 break;
470 }
471 }
472 else if (rProperty.first == "fLine" && xPropertySet.is())
473 resolveFLine(xPropertySet, rProperty.second.toInt32());
474 else if (rProperty.first == "fillOpacity" && xPropertySet.is())
475 {
476 int opacity = 100 - (rProperty.second.toInt32()) * 100 / RTF_MULTIPLIER;
477 xPropertySet->setPropertyValue("FillTransparence", uno::Any(sal_uInt32(opacity)));
478 }
479 else if (rProperty.first == "lineWidth")
480 aLineWidth <<= rProperty.second.toInt32() / 360;
481 else if (rProperty.first == "pVerticies")
482 {
483 std::vector<drawing::EnhancedCustomShapeParameterPair> aCoordinates;
484 sal_Int32 nSize = 0; // Size of a token (its value is hardwired in the exporter)
485 sal_Int32 nCount = 0; // Number of tokens
486 sal_Int32 nCharIndex = 0; // Character index
487 do
488 {
489 std::u16string_view aToken = o3tl::getToken(rProperty.second, 0, ';', nCharIndex);
490 if (!nSize)
491 nSize = o3tl::toInt32(aToken);
492 else if (!nCount)
493 nCount = o3tl::toInt32(aToken);
494 else if (!aToken.empty())
495 {
496 // The coordinates are in an (x,y) form.
497 aToken = aToken.substr(1, aToken.size() - 2);
498 sal_Int32 nI = 0;
499 sal_Int32 nX = o3tl::toInt32(o3tl::getToken(aToken, 0, ',', nI));
500 sal_Int32 nY
501 = (nI >= 0) ? o3tl::toInt32(o3tl::getToken(aToken, 0, ',', nI)) : 0;
502 drawing::EnhancedCustomShapeParameterPair aPair;
503 aPair.First.Value <<= nX;
504 aPair.Second.Value <<= nY;
505 aCoordinates.push_back(aPair);
506 }
507 } while (nCharIndex >= 0);
508 aPropertyValue.Name = "Coordinates";
509 aPropertyValue.Value <<= comphelper::containerToSequence(aCoordinates);
510 aPath.push_back(aPropertyValue);
511 }
512 else if (rProperty.first == "pSegmentInfo")
513 {
514 std::vector<drawing::EnhancedCustomShapeSegment> aSegments;
515 sal_Int32 nSize = 0;
516 sal_Int32 nCount = 0;
517 sal_Int32 nCharIndex = 0;
518 do
519 {
520 sal_Int32 nSeg
521 = o3tl::toInt32(o3tl::getToken(rProperty.second, 0, ';', nCharIndex));
522 if (!nSize)
523 nSize = nSeg;
524 else if (!nCount)
525 nCount = nSeg;
526 else
527 {
528 sal_Int32 nPoints = 1;
529 if (nSeg >= 0x2000 && nSeg < 0x20FF)
530 {
531 nPoints = nSeg & 0x0FFF;
532 nSeg &= 0xFF00;
533 }
534
535 drawing::EnhancedCustomShapeSegment aSegment;
536 switch (nSeg)
537 {
538 case 0x0001: // lineto
539 aSegment.Command = drawing::EnhancedCustomShapeSegmentCommand::LINETO;
540 aSegment.Count = sal_Int32(1);
541 aSegments.push_back(aSegment);
542 break;
543 case 0x4000: // moveto
544 aSegment.Command = drawing::EnhancedCustomShapeSegmentCommand::MOVETO;
545 aSegment.Count = sal_Int32(1);
546 aSegments.push_back(aSegment);
547 break;
548 case 0x2000: // curveto
549 aSegment.Command = drawing::EnhancedCustomShapeSegmentCommand::CURVETO;
550 aSegment.Count = nPoints;
551 aSegments.push_back(aSegment);
552 break;
553 case 0xb300: // arcto
554 aSegment.Command = drawing::EnhancedCustomShapeSegmentCommand::ARCTO;
555 aSegment.Count = sal_Int32(0);
556 aSegments.push_back(aSegment);
557 break;
558 case 0xac00:
559 case 0xaa00: // nofill
560 case 0xab00: // nostroke
561 case 0x6001: // close
562 break;
563 case 0x8000: // end
564 aSegment.Command
565 = drawing::EnhancedCustomShapeSegmentCommand::ENDSUBPATH;
566 aSegment.Count = sal_Int32(0);
567 aSegments.push_back(aSegment);
568 break;
569 default: // given number of lineto elements
570 aSegment.Command = drawing::EnhancedCustomShapeSegmentCommand::LINETO;
571 aSegment.Count = nSeg;
572 aSegments.push_back(aSegment);
573 break;
574 }
575 }
576 } while (nCharIndex >= 0);
577 aPropertyValue.Name = "Segments";
578 aPropertyValue.Value <<= comphelper::containerToSequence(aSegments);
579 aPath.push_back(aPropertyValue);
580 }
581 else if (rProperty.first == "geoLeft")
582 aViewBox.X = rProperty.second.toInt32();
583 else if (rProperty.first == "geoTop")
584 aViewBox.Y = rProperty.second.toInt32();
585 else if (rProperty.first == "geoRight")
586 aViewBox.Width = rProperty.second.toInt32();
587 else if (rProperty.first == "geoBottom")
588 aViewBox.Height = rProperty.second.toInt32();
589 else if (rProperty.first == "dhgt")
590 {
591 // dhgt is Word 2007, \shpz is Word 97-2003, the later has priority.
592 if (!rShape.hasZ())
593 resolveDhgt(xPropertySet, rProperty.second.toInt32(), /*bOldStyle=*/false);
594 }
595 // These are in EMU, convert to mm100.
596 else if (rProperty.first == "dxTextLeft")
597 {
598 if (xPropertySet.is())
599 xPropertySet->setPropertyValue("LeftBorderDistance",
600 uno::Any(rProperty.second.toInt32() / 360));
601 }
602 else if (rProperty.first == "dyTextTop")
603 {
604 if (xPropertySet.is())
605 xPropertySet->setPropertyValue("TopBorderDistance",
606 uno::Any(rProperty.second.toInt32() / 360));
607 }
608 else if (rProperty.first == "dxTextRight")
609 {
610 if (xPropertySet.is())
611 xPropertySet->setPropertyValue("RightBorderDistance",
612 uno::Any(rProperty.second.toInt32() / 360));
613 }
614 else if (rProperty.first == "dyTextBottom")
615 {
616 if (xPropertySet.is())
617 xPropertySet->setPropertyValue("BottomBorderDistance",
618 uno::Any(rProperty.second.toInt32() / 360));
619 }
620 else if (rProperty.first == "dxWrapDistLeft")
621 {
623 rShape.getAnchorAttributes().set(NS_ooxml::LN_CT_Anchor_distL,
624 new RTFValue(rProperty.second.toInt32()));
625 else if (xPropertySet.is())
626 xPropertySet->setPropertyValue("LeftMargin",
627 uno::Any(rProperty.second.toInt32() / 360));
628 }
629 else if (rProperty.first == "dyWrapDistTop")
630 {
632 rShape.getAnchorAttributes().set(NS_ooxml::LN_CT_Anchor_distT,
633 new RTFValue(rProperty.second.toInt32()));
634 else if (xPropertySet.is())
635 xPropertySet->setPropertyValue("TopMargin",
636 uno::Any(rProperty.second.toInt32() / 360));
637 }
638 else if (rProperty.first == "dxWrapDistRight")
639 {
641 rShape.getAnchorAttributes().set(NS_ooxml::LN_CT_Anchor_distR,
642 new RTFValue(rProperty.second.toInt32()));
643 else if (xPropertySet.is())
644 xPropertySet->setPropertyValue("RightMargin",
645 uno::Any(rProperty.second.toInt32() / 360));
646 }
647 else if (rProperty.first == "dyWrapDistBottom")
648 {
650 rShape.getAnchorAttributes().set(NS_ooxml::LN_CT_Anchor_distB,
651 new RTFValue(rProperty.second.toInt32()));
652 else if (xPropertySet.is())
653 xPropertySet->setPropertyValue("BottomMargin",
654 uno::Any(rProperty.second.toInt32() / 360));
655 }
656 else if (rProperty.first == "fillType")
657 {
658 switch (rProperty.second.toInt32())
659 {
660 case 7: // Shade using the fillAngle
661 aFillModel.moType = oox::XML_gradient;
662 break;
663 default:
664 SAL_INFO("writerfilter",
665 "TODO handle fillType value '" << rProperty.second << "'");
666 break;
667 }
668 }
669 else if (rProperty.first == "fillFocus")
670 aFillModel.moFocus = rProperty.second.toDouble() / 100; // percent
671 else if (rProperty.first == "fShadow" && xPropertySet.is())
672 {
673 if (rProperty.second.toInt32() == 1)
674 aShadowModel.mbHasShadow = true;
675 }
676 else if (rProperty.first == "shadowColor")
677 aShadowModel.moColor = "#"
679 msfilter::util::BGRToRGB(rProperty.second.toInt32()));
680 else if (rProperty.first == "shadowOffsetX")
681 // EMUs to points
682 aShadowModel.moOffset = OUString::number(rProperty.second.toDouble() / 12700) + "pt";
683 else if (rProperty.first == "posh" || rProperty.first == "posv"
684 || rProperty.first == "fFitShapeToText" || rProperty.first == "fFilled"
685 || rProperty.first == "rotation")
686 applyProperty(xShape, rProperty.first, rProperty.second);
687 else if (rProperty.first == "posrelh")
688 {
689 switch (rProperty.second.toInt32())
690 {
691 case 1:
692 rShape.setHoriOrientRelation(text::RelOrientation::PAGE_FRAME);
693 break;
694 default:
695 break;
696 }
697 }
698 else if (rProperty.first == "posrelv")
699 {
700 switch (rProperty.second.toInt32())
701 {
702 case 1:
703 rShape.setVertOrientRelation(text::RelOrientation::PAGE_FRAME);
704 break;
705 default:
706 break;
707 }
708 }
709 else if (rProperty.first == "groupLeft")
710 oGroupLeft = convertTwipToMm100(rProperty.second.toInt32());
711 else if (rProperty.first == "groupTop")
712 oGroupTop = convertTwipToMm100(rProperty.second.toInt32());
713 else if (rProperty.first == "groupRight")
714 oGroupRight = convertTwipToMm100(rProperty.second.toInt32());
715 else if (rProperty.first == "groupBottom")
716 oGroupBottom = convertTwipToMm100(rProperty.second.toInt32());
717 else if (rProperty.first == "relLeft")
718 oRelLeft = convertTwipToMm100(rProperty.second.toInt32());
719 else if (rProperty.first == "relTop")
720 oRelTop = convertTwipToMm100(rProperty.second.toInt32());
721 else if (rProperty.first == "relRight")
722 oRelRight = convertTwipToMm100(rProperty.second.toInt32());
723 else if (rProperty.first == "relBottom")
724 oRelBottom = convertTwipToMm100(rProperty.second.toInt32());
725 else if (rProperty.first == "fBehindDocument")
726 bOpaque = !rProperty.second.toInt32();
727 else if (rProperty.first == "pctHoriz" || rProperty.first == "pctVert")
728 {
729 sal_Int16 nPercentage = rtl::math::round(rProperty.second.toDouble() / 10);
730 if (nPercentage)
731 {
732 std::optional<sal_Int16>& rPercentage
733 = rProperty.first == "pctHoriz" ? oRelativeWidth : oRelativeHeight;
734 rPercentage = nPercentage;
735 }
736 }
737 else if (rProperty.first == "sizerelh")
738 {
739 if (xPropertySet.is())
740 {
741 switch (rProperty.second.toInt32())
742 {
743 case 0: // margin
744 nRelativeWidthRelation = text::RelOrientation::FRAME;
745 break;
746 case 1: // page
747 nRelativeWidthRelation = text::RelOrientation::PAGE_FRAME;
748 break;
749 default:
750 SAL_WARN("writerfilter", "RTFSdrImport::resolve: unhandled sizerelh value: "
751 << rProperty.second);
752 break;
753 }
754 }
755 }
756 else if (rProperty.first == "sizerelv")
757 {
758 if (xPropertySet.is())
759 {
760 switch (rProperty.second.toInt32())
761 {
762 case 0: // margin
763 nRelativeHeightRelation = text::RelOrientation::FRAME;
764 break;
765 case 1: // page
766 nRelativeHeightRelation = text::RelOrientation::PAGE_FRAME;
767 break;
768 default:
769 SAL_WARN("writerfilter", "RTFSdrImport::resolve: unhandled sizerelv value: "
770 << rProperty.second);
771 break;
772 }
773 }
774 }
775 else if (rProperty.first == "fHorizRule") // TODO: what does "fStandardHR" do?
776 {
777 // horizontal rule: relative width defaults to 100% of paragraph
778 // TODO: does it have a default height?
779 if (!oRelativeWidth)
780 {
781 oRelativeWidth = 100;
782 }
783 nRelativeWidthRelation = text::RelOrientation::FRAME;
784 if (xPropertySet.is())
785 {
786 sal_Int16 const nVertOrient = text::VertOrientation::CENTER;
787 xPropertySet->setPropertyValue("VertOrient", uno::Any(nVertOrient));
788 }
789 }
790 else if (rProperty.first == "pctHR")
791 {
792 // horizontal rule relative width in permille
793 oRelativeWidth = rProperty.second.toInt32() / 10;
794 }
795 else if (rProperty.first == "dxHeightHR")
796 {
797 // horizontal rule height
798 sal_uInt32 const nHeight(convertTwipToMm100(rProperty.second.toInt32()));
799 rShape.setBottom(rShape.getTop() + nHeight);
800 }
801 else if (rProperty.first == "dxWidthHR")
802 {
803 // horizontal rule width
804 sal_uInt32 const nWidth(convertTwipToMm100(rProperty.second.toInt32()));
805 rShape.setRight(rShape.getLeft() + nWidth);
806 }
807 else if (rProperty.first == "alignHR")
808 {
809 // horizontal orientation *for horizontal rule*
810 sal_Int16 nHoriOrient = text::HoriOrientation::NONE;
811 switch (rProperty.second.toInt32())
812 {
813 case 0:
814 nHoriOrient = text::HoriOrientation::LEFT;
815 break;
816 case 1:
817 nHoriOrient = text::HoriOrientation::CENTER;
818 break;
819 case 2:
820 nHoriOrient = text::HoriOrientation::RIGHT;
821 break;
822 }
823 if (xPropertySet.is() && text::HoriOrientation::NONE != nHoriOrient)
824 {
825 xPropertySet->setPropertyValue("HoriOrient", uno::Any(nHoriOrient));
826 }
827 }
828 else if (rProperty.first == "pWrapPolygonVertices")
829 {
830 RTFSprms aPolygonSprms;
831 sal_Int32 nSize = 0; // Size of a token
832 sal_Int32 nCount = 0; // Number of tokens
833 sal_Int32 nCharIndex = 0; // Character index
834 do
835 {
836 std::u16string_view aToken = o3tl::getToken(rProperty.second, 0, ';', nCharIndex);
837 if (!nSize)
838 nSize = o3tl::toInt32(aToken);
839 else if (!nCount)
840 nCount = o3tl::toInt32(aToken);
841 else if (!aToken.empty())
842 {
843 // The coordinates are in an (x,y) form.
844 aToken = aToken.substr(1, aToken.size() - 2);
845 sal_Int32 nI = 0;
846 sal_Int32 nX = o3tl::toInt32(o3tl::getToken(aToken, 0, ',', nI));
847 sal_Int32 nY
848 = (nI >= 0) ? o3tl::toInt32(o3tl::getToken(aToken, 0, ',', nI)) : 0;
849 RTFSprms aPathAttributes;
850 aPathAttributes.set(NS_ooxml::LN_CT_Point2D_x, new RTFValue(nX));
851 aPathAttributes.set(NS_ooxml::LN_CT_Point2D_y, new RTFValue(nY));
852 aPolygonSprms.set(NS_ooxml::LN_CT_WrapPath_lineTo,
853 new RTFValue(aPathAttributes), RTFOverwrite::NO_APPEND);
854 }
855 } while (nCharIndex >= 0);
856 rShape.getWrapPolygonSprms() = aPolygonSprms;
857 }
858 else if (rProperty.first == "fRelFlipV")
859 obRelFlipV = rProperty.second.toInt32() == 1;
860 else if (rProperty.first == "fFlipH")
861 obFlipH = rProperty.second.toInt32() == 1;
862 else if (rProperty.first == "fFlipV")
863 obFlipV = rProperty.second.toInt32() == 1;
864 else if (rProperty.first == "pictureContrast")
865 {
866 // Gain / contrast.
867 nContrast = rProperty.second.toInt32();
868 if (nContrast < 0x10000)
869 {
870 nContrast *= 101; // 100 + 1 to round
871 nContrast /= 0x10000;
872 nContrast -= 100;
873 }
874 }
875 else if (rProperty.first == "pictureBrightness")
876 {
877 // Blacklevel / brightness.
878 nBrightness = rProperty.second.toInt32();
879 if (nBrightness != 0)
880 {
881 nBrightness /= 327;
882 }
883 }
884 else
885 SAL_INFO("writerfilter", "TODO handle shape property '" << rProperty.first << "':'"
886 << rProperty.second << "'");
887 }
888
889 if (xPropertySet.is())
890 {
891 resolveLineColorAndWidth(m_bTextFrame, xPropertySet, aLineColor, aLineWidth);
892 if (rShape.hasZ())
893 {
894 bool bOldStyle = m_aParents.size() > 1;
895 resolveDhgt(xPropertySet, rShape.getZ(), bOldStyle);
896 }
897 if (m_bTextFrame)
898 xPropertySet->setPropertyValue("WritingMode", uno::Any(eWritingMode));
899 else
900 // Only Writer textframes implement text::WritingMode2.
901 xPropertySet->setPropertyValue("TextWritingMode",
902 uno::Any(text::WritingMode(eWritingMode)));
903 }
904
905 if (!m_aParents.empty() && m_aParents.top().is() && !m_bTextFrame)
906 m_aParents.top()->add(xShape);
907
908 if (nContrast == -70 && nBrightness == 70 && xPropertySet.is())
909 {
910 // Map MSO 'washout' to our watermark colormode.
911 xPropertySet->setPropertyValue("GraphicColorMode", uno::Any(drawing::ColorMode_WATERMARK));
912 }
913
914 if (bCustom && xShape.is() && !bPib)
915 {
916 uno::Reference<drawing::XEnhancedCustomShapeDefaulter> xDefaulter(xShape, uno::UNO_QUERY);
917 xDefaulter->createCustomShapeDefaults(OUString::number(nType));
918 }
919
920 // Set shape text
921 if (bCustom && !aShapeText.isEmpty())
922 {
923 uno::Reference<text::XTextRange> xTextRange(xShape, uno::UNO_QUERY);
924 if (xTextRange.is())
925 xTextRange->setString(aShapeText);
926
927 xPropertySet->setPropertyValue("CharFontName", uno::Any(aFontFamily));
928 xPropertySet->setPropertyValue("CharHeight", uno::Any(nFontSize));
929 }
930
931 // Creating CustomShapeGeometry property
932 if (bCustom && xPropertySet.is())
933 {
934 bool bChanged = false;
935 comphelper::SequenceAsHashMap aCustomShapeGeometry(
936 xPropertySet->getPropertyValue("CustomShapeGeometry"));
937
938 if (aViewBox.X || aViewBox.Y || aViewBox.Width || aViewBox.Height)
939 {
940 aViewBox.Width -= aViewBox.X;
941 aViewBox.Height -= aViewBox.Y;
942 aCustomShapeGeometry["ViewBox"] <<= aViewBox;
943 bChanged = true;
944 }
945
946 if (!aPath.empty())
947 {
948 aCustomShapeGeometry["Path"] <<= comphelper::containerToSequence(aPath);
949 bChanged = true;
950 }
951
952 if (!aShapeText.isEmpty())
953 {
955 { "TextPath", uno::Any(true) },
956 }));
957 aCustomShapeGeometry["TextPath"] <<= aSequence;
958 xPropertySet->setPropertyValue("TextAutoGrowHeight", uno::Any(false));
959 xPropertySet->setPropertyValue("TextAutoGrowWidth", uno::Any(false));
960 bChanged = true;
961 }
962
963 if (bChanged)
964 {
965 xPropertySet->setPropertyValue(
966 "CustomShapeGeometry",
967 uno::Any(aCustomShapeGeometry.getAsConstPropertyValueList()));
968 }
969 }
970
971 if (obRelFlipV.has_value() && xPropertySet.is())
972 {
974 {
975 // Line shape inside group shape: get the polygon sequence and transform it.
977 if ((xPropertySet->getPropertyValue("PolyPolygon") >>= aPolyPolySequence)
978 && aPolyPolySequence.hasElements())
979 {
980 uno::Sequence<awt::Point>& rPolygon = aPolyPolySequence.getArray()[0];
982 for (const awt::Point& rPoint : std::as_const(rPolygon))
983 {
984 aPoly.append(basegfx::B2DPoint(rPoint.X, rPoint.Y));
985 }
986 basegfx::B2DHomMatrix aTransformation;
987 aTransformation.scale(1.0, *obRelFlipV ? -1.0 : 1.0);
988 aPoly.transform(aTransformation);
989 auto pPolygon = rPolygon.getArray();
990 for (sal_Int32 i = 0; i < rPolygon.getLength(); ++i)
991 {
992 basegfx::B2DPoint aPoint(aPoly.getB2DPoint(i));
993 pPolygon[i] = awt::Point(static_cast<sal_Int32>(aPoint.getX()),
994 static_cast<sal_Int32>(aPoint.getY()));
995 }
996 xPropertySet->setPropertyValue("PolyPolygon", uno::Any(aPolyPolySequence));
997 }
998 }
999 }
1000
1001 // Set position and size
1002 if (xShape.is())
1003 {
1004 sal_Int32 nLeft = rShape.getLeft();
1005 sal_Int32 nTop = rShape.getTop();
1006
1007 bool bInShapeGroup = oGroupLeft && oGroupTop && oGroupRight && oGroupBottom && oRelLeft
1008 && oRelTop && oRelRight && oRelBottom;
1009 awt::Size aSize;
1010 if (bInShapeGroup)
1011 {
1012 // See lclGetAbsPoint() in the VML import: rShape is the group shape, oGroup is its coordinate system, oRel is the relative child shape.
1013 sal_Int32 nShapeWidth = rShape.getRight() - rShape.getLeft();
1014 sal_Int32 nShapeHeight = rShape.getBottom() - rShape.getTop();
1015 sal_Int32 nCoordSysWidth = *oGroupRight - *oGroupLeft;
1016 sal_Int32 nCoordSysHeight = *oGroupBottom - *oGroupTop;
1017 double fWidthRatio = static_cast<double>(nShapeWidth) / nCoordSysWidth;
1018 double fHeightRatio = static_cast<double>(nShapeHeight) / nCoordSysHeight;
1019 nLeft = static_cast<sal_Int32>(rShape.getLeft()
1020 + fWidthRatio * (*oRelLeft - *oGroupLeft));
1021 nTop = static_cast<sal_Int32>(rShape.getTop() + fHeightRatio * (*oRelTop - *oGroupTop));
1022
1023 // See lclGetAbsRect() in the VML import.
1024 aSize.Width = std::lround(fWidthRatio * (*oRelRight - *oRelLeft));
1025 aSize.Height = std::lround(fHeightRatio * (*oRelBottom - *oRelTop));
1026 }
1027
1028 if (m_bTextFrame)
1029 {
1030 xPropertySet->setPropertyValue("HoriOrientPosition", uno::Any(nLeft));
1031 xPropertySet->setPropertyValue("VertOrientPosition", uno::Any(nTop));
1032 }
1033 else
1034 xShape->setPosition(awt::Point(nLeft, nTop));
1035
1036 if (bInShapeGroup)
1037 xShape->setSize(aSize);
1038 else
1039 xShape->setSize(awt::Size(rShape.getRight() - rShape.getLeft(),
1040 rShape.getBottom() - rShape.getTop()));
1041
1042 if (obFlipH || obFlipV)
1043 {
1044 if (bCustom)
1045 {
1046 // This has to be set after position and size is set, otherwise flip will affect the position.
1047 comphelper::SequenceAsHashMap aCustomShapeGeometry(
1048 xPropertySet->getPropertyValue("CustomShapeGeometry"));
1049 if (obFlipH)
1050 aCustomShapeGeometry["MirroredX"] <<= true;
1051 if (obFlipV)
1052 aCustomShapeGeometry["MirroredY"] <<= true;
1053 xPropertySet->setPropertyValue(
1054 "CustomShapeGeometry",
1055 uno::Any(aCustomShapeGeometry.getAsConstPropertyValueList()));
1056 }
1058 {
1059 Point aRef1 = pObject->GetSnapRect().Center();
1060 Point aRef2(aRef1);
1061 if (obFlipH)
1062 {
1063 // Horizontal mirror means a vertical reference line.
1064 aRef2.AdjustY(1);
1065 }
1066 if (obFlipV)
1067 {
1068 // Vertical mirror means a horizontal reference line.
1069 aRef2.AdjustX(1);
1070 }
1071 pObject->Mirror(aRef1, aRef2);
1072 }
1073 }
1074
1075 if (rShape.getHoriOrientRelation() != 0)
1076 xPropertySet->setPropertyValue("HoriOrientRelation",
1078 if (rShape.getVertOrientRelation() != 0)
1079 xPropertySet->setPropertyValue("VertOrientRelation",
1081 if (rShape.getWrap() != text::WrapTextMode::WrapTextMode_MAKE_FIXED_SIZE)
1082 xPropertySet->setPropertyValue("Surround", uno::Any(rShape.getWrap()));
1083 oox::ModelObjectHelper aModelObjectHelper(m_rImport.getModelFactory());
1084 if (aFillModel.moType.has_value())
1085 {
1086 oox::drawingml::ShapePropertyMap aPropMap(aModelObjectHelper);
1087 aFillModel.pushToPropMap(aPropMap, m_rImport.getGraphicHelper());
1088 // Sets the FillStyle and FillGradient UNO properties.
1089 oox::PropertySet(xShape).setProperties(aPropMap);
1090 }
1091
1092 if (aShadowModel.mbHasShadow)
1093 {
1094 oox::drawingml::ShapePropertyMap aPropMap(aModelObjectHelper);
1095 aShadowModel.pushToPropMap(aPropMap, m_rImport.getGraphicHelper());
1096 // Sets the ShadowFormat UNO property.
1097 oox::PropertySet(xShape).setProperties(aPropMap);
1098 }
1099 xPropertySet->setPropertyValue("AnchorType",
1100 uno::Any(text::TextContentAnchorType_AT_CHARACTER));
1101 xPropertySet->setPropertyValue("Opaque", uno::Any(bOpaque));
1102 if (oRelativeWidth)
1103 {
1104 xPropertySet->setPropertyValue("RelativeWidth", uno::Any(*oRelativeWidth));
1105 xPropertySet->setPropertyValue("RelativeWidthRelation",
1106 uno::Any(nRelativeWidthRelation));
1107 }
1108 if (oRelativeHeight)
1109 {
1110 xPropertySet->setPropertyValue("RelativeHeight", uno::Any(*oRelativeHeight));
1111 xPropertySet->setPropertyValue("RelativeHeightRelation",
1112 uno::Any(nRelativeHeightRelation));
1113 }
1114 }
1115
1116 if (bPib)
1117 {
1118 m_rImport.resolvePict(false, xShape);
1119 }
1120
1121 if (nType == ESCHER_ShpInst_PictureFrame) // picture frame
1122 {
1123 assert(!m_bTextFrame);
1124 if (!bPib) // ??? not sure if the early return should be removed on else?
1125 {
1126 m_xShape = xShape; // store it for later resolvePict call
1127 }
1128
1129 // Handle horizontal flip.
1130 if (obFlipH && xPropertySet.is())
1131 xPropertySet->setPropertyValue("IsMirrored", uno::Any(true));
1132 return;
1133 }
1134
1136 {
1137 RTFSprms aAttributes;
1138 aAttributes.set(NS_ooxml::LN_CT_Background_color,
1139 new RTFValue(xPropertySet->getPropertyValue("FillColor").get<sal_Int32>()));
1140 m_rImport.Mapper().props(new RTFReferenceProperties(std::move(aAttributes)));
1141
1142 uno::Reference<lang::XComponent> xComponent(xShape, uno::UNO_QUERY);
1143 xComponent->dispose();
1144 return;
1145 }
1146
1147 // Send it to dmapper
1148 if (xShape.is())
1149 {
1150 m_rImport.Mapper().startShape(xShape);
1151 if (bClose)
1152 {
1154 }
1155 }
1156
1157 // If the shape has an inner shape, the inner object's properties should not be influenced by
1158 // the outer one.
1159 rShape.getProperties().clear();
1160
1161 m_xShape = xShape;
1162}
1163
1165
1166void RTFSdrImport::append(std::u16string_view aKey, std::u16string_view aValue)
1167{
1168 applyProperty(m_xShape, aKey, aValue);
1169}
1170
1171void RTFSdrImport::appendGroupProperty(std::u16string_view aKey, std::u16string_view aValue)
1172{
1173 if (m_aParents.empty())
1174 return;
1175 uno::Reference<drawing::XShape> xShape(m_aParents.top(), uno::UNO_QUERY);
1176 if (xShape.is())
1177 applyProperty(xShape, aKey, aValue);
1178}
1179
1180} // namespace writerfilter
1181
1182/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
const SvXMLImport & m_rImport
constexpr auto convertTwipToMm100(N n)
tools::Long AdjustY(tools::Long nVertMove)
tools::Long AdjustX(tools::Long nHorzMove)
static SdrObject * getSdrObjectFromXShape(const css::uno::Reference< css::uno::XInterface > &xInt)
void scale(double fX, double fY)
basegfx::B2DPoint const & getB2DPoint(sal_uInt32 nIndex) const
void transform(const basegfx::B2DHomMatrix &rMatrix)
void append(const basegfx::B2DPoint &rPoint, sal_uInt32 nCount)
TYPE getX() const
TYPE getY() const
css::uno::Sequence< css::beans::PropertyValue > getAsConstPropertyValueList() const
void setProperties(const css::uno::Sequence< OUString > &rPropNames, const css::uno::Sequence< css::uno::Any > &rValues)
virtual void props(writerfilter::Reference< Properties >::Pointer_t ref)=0
Receives properties of the current run of text.
virtual void startShape(css::uno::Reference< css::drawing::XShape > const &xShape)=0
Receives a shape.
virtual void endShape()=0
sal_Int32 findZOrder(sal_Int32 relativeHeight, bool bOldStyle=false)
void addItem(css::uno::Reference< css::beans::XPropertySet > const &props, sal_Int32 relativeHeight)
Implementation of the RTFDocument interface.
void resolvePict(bool bInline, css::uno::Reference< css::drawing::XShape > const &rShape)
Resolve a picture: If not inline, then anchored.
const css::uno::Reference< css::lang::XMultiServiceFactory > & getModelFactory() const
void setDestinationText(std::u16string_view rString)
Sends RTFSprm instances to DomainMapper.
void createShape(const OUString &rService, css::uno::Reference< css::drawing::XShape > &xShape, css::uno::Reference< css::beans::XPropertySet > &xPropertySet)
bool m_bTextGraphicObject
If m_xShape is imported as a Writer text graphic object (instead of a drawinglayer shape).
void resolve(RTFShape &rShape, bool bClose, ShapeOrPict shapeOrPict)
static void resolveFLine(css::uno::Reference< css::beans::XPropertySet > const &xPropertySet, sal_Int32 nFLine)
css::uno::Reference< css::drawing::XShape > m_xShape
void popParent()
Pop the current group shape from the parent stack.
bool m_bTextFrame
If m_xShape is imported as a Writer text frame (instead of a drawinglayer rectangle).
void pushParent(css::uno::Reference< css::drawing::XShapes > const &xParent)
Push a new group shape to the parent stack.
void append(std::u16string_view aKey, std::u16string_view aValue)
int initShape(css::uno::Reference< css::drawing::XShape > &o_xShape, css::uno::Reference< css::beans::XPropertySet > &o_xPropSet, bool &o_rIsCustomShape, RTFShape const &rShape, bool bClose, ShapeOrPict shapeOrPict)
void resolveDhgt(css::uno::Reference< css::beans::XPropertySet > const &xPropertySet, sal_Int32 nZOrder, bool bOldStyle)
RTFSdrImport(RTFDocumentImpl &rDocument, css::uno::Reference< css::lang::XComponent > const &xDstDoc)
static void resolveLineColorAndWidth(bool bTextFrame, const css::uno::Reference< css::beans::XPropertySet > &xPropertySet, css::uno::Any const &rLineColor, css::uno::Any const &rLineWidth)
Set line color and line width on the shape, using the relevant API depending on if the shape is a tex...
void appendGroupProperty(std::u16string_view aKey, std::u16string_view aValue)
Append property on the current parent.
void applyProperty(css::uno::Reference< css::drawing::XShape > const &xShape, std::u16string_view aKey, std::u16string_view aValue) const
std::stack< css::uno::Reference< css::drawing::XShapes > > m_aParents
bool m_bFakePict
if inside \pict, but actually it's a shape (not a picture)
static std::vector< css::beans::PropertyValue > getTextFrameDefaults(bool bNew)
These are the default in Word, but not in Writer.
std::stack< writerfilter::dmapper::GraphicZOrderHelper > m_aGraphicZOrderHelpers
Stores the properties of a shape.
std::vector< std::pair< OUString, OUString > > & getProperties()
sal_Int16 getVertOrientRelation() const
void setHoriOrientRelation(sal_Int16 nHoriOrientRelation)
void setBottom(sal_Int32 nBottom)
sal_Int16 getHoriOrientRelation() const
css::text::WrapTextMode getWrap() const
void setVertOrientRelation(sal_Int16 nVertOrientRelation)
void setRight(sal_Int32 nRight)
A list of RTFSprm with a copy constructor that performs a deep copy.
Definition: rtfsprm.hxx:39
void set(Id nKeyword, const RTFValue::Pointer_t &pValue, RTFOverwrite eOverwrite=RTFOverwrite::YES)
Does the same as ->push_back(), except that it can overwrite or ignore existing entries.
Definition: rtfsprm.cxx:98
Value of an RTF keyword.
Definition: rtfvalue.hxx:33
ColorTransparency
constexpr ::Color COL_BLACK(0x00, 0x00, 0x00)
int nCount
float u
EmbeddedObjectRef * pObject
#define ESCHER_ShpInst_TextBox
#define ESCHER_ShpInst_Rectangle
#define ESCHER_ShpInst_Line
#define ESCHER_ShpInst_PictureFrame
#define SAL_WARN(area, stream)
#define SAL_INFO(area, stream)
css::uno::Sequence< DstElementType > containerToSequence(const SrcType &i_Container)
css::uno::Sequence< css::beans::PropertyValue > InitPropertySequence(::std::initializer_list< ::std::pair< OUString, css::uno::Any > > vInit)
int i
::Color BGRToRGB(sal_uInt32 nColour)
OUString ConvertColorOU(const Color &rColor)
sal_Int32 toInt32(std::u16string_view str, sal_Int16 radix=10)
std::basic_string_view< charT, traits > getToken(std::basic_string_view< charT, traits > sv, charT delimiter, std::size_t &position)
css::uno::Reference< css::linguistic2::XProofreadingIterator > get(css::uno::Reference< css::uno::XComponentContext > const &context)
@ NO_APPEND
No, always append the value to the end of the list.
QPRO_FUNC_TYPE nType
#define RTF_MULTIPLIER
void pushToPropMap(::oox::drawingml::ShapePropertyMap &rPropMap, const GraphicHelper &rGraphicHelper) const
std::optional< OUString > moColor2
std::optional< sal_Int32 > moType
std::optional< double > moFocus
std::optional< OUString > moColor
std::optional< OUString > moOffset
std::optional< OUString > moColor
void pushToPropMap(oox::drawingml::ShapePropertyMap &rPropMap, const GraphicHelper &rGraphicHelper) const
bool hasValue()
SVXCORE_DLLPUBLIC Degree100 NormAngle36000(Degree100 a)
std::vector< ISegmentProgressBarRef > aSegments