20#include <config_features.h>
22#include <config_folders.h>
23#include <rtl/bootstrap.hxx>
33#include <oox/token/namespaces.hxx>
34#include <oox/token/properties.hxx>
36#include <oox/token/tokens.hxx>
50#include <com/sun/star/awt/CharSet.hpp>
51#include <com/sun/star/awt/FontDescriptor.hpp>
52#include <com/sun/star/awt/FontSlant.hpp>
53#include <com/sun/star/awt/FontStrikeout.hpp>
54#include <com/sun/star/awt/FontWeight.hpp>
55#include <com/sun/star/awt/FontUnderline.hpp>
56#include <com/sun/star/awt/Gradient.hpp>
57#include <com/sun/star/awt/Gradient2.hpp>
58#include <com/sun/star/beans/XPropertySet.hpp>
59#include <com/sun/star/beans/XPropertyState.hpp>
60#include <com/sun/star/beans/XPropertySetInfo.hpp>
61#include <com/sun/star/container/XEnumerationAccess.hpp>
62#include <com/sun/star/container/XIndexAccess.hpp>
63#include <com/sun/star/container/XNameAccess.hpp>
64#include <com/sun/star/drawing/BitmapMode.hpp>
65#include <com/sun/star/drawing/ColorMode.hpp>
66#include <com/sun/star/drawing/EnhancedCustomShapeAdjustmentValue.hpp>
67#include <com/sun/star/drawing/EnhancedCustomShapeParameterPair.hpp>
68#include <com/sun/star/drawing/EnhancedCustomShapeParameterType.hpp>
69#include <com/sun/star/drawing/EnhancedCustomShapeSegment.hpp>
70#include <com/sun/star/drawing/EnhancedCustomShapeSegmentCommand.hpp>
71#include <com/sun/star/drawing/FillStyle.hpp>
72#include <com/sun/star/drawing/Hatch.hpp>
73#include <com/sun/star/drawing/LineDash.hpp>
74#include <com/sun/star/drawing/LineJoint.hpp>
75#include <com/sun/star/drawing/LineStyle.hpp>
76#include <com/sun/star/drawing/TextFitToSizeType.hpp>
77#include <com/sun/star/drawing/TextHorizontalAdjust.hpp>
78#include <com/sun/star/drawing/TextVerticalAdjust.hpp>
79#include <com/sun/star/drawing/XShape.hpp>
80#include <com/sun/star/drawing/XShapes.hpp>
81#include <com/sun/star/frame/XModel.hpp>
82#include <com/sun/star/graphic/XGraphic.hpp>
83#include <com/sun/star/i18n/ScriptType.hpp>
84#include <com/sun/star/i18n/BreakIterator.hpp>
85#include <com/sun/star/i18n/XBreakIterator.hpp>
86#include <com/sun/star/io/XOutputStream.hpp>
87#include <com/sun/star/lang/XMultiServiceFactory.hpp>
88#include <com/sun/star/style/LineSpacing.hpp>
89#include <com/sun/star/style/LineSpacingMode.hpp>
90#include <com/sun/star/text/WritingMode.hpp>
91#include <com/sun/star/text/WritingMode2.hpp>
92#include <com/sun/star/text/GraphicCrop.hpp>
93#include <com/sun/star/text/XText.hpp>
94#include <com/sun/star/text/XTextColumns.hpp>
95#include <com/sun/star/text/XTextContent.hpp>
96#include <com/sun/star/text/XTextField.hpp>
97#include <com/sun/star/text/XTextRange.hpp>
98#include <com/sun/star/text/XTextFrame.hpp>
99#include <com/sun/star/style/CaseMap.hpp>
100#include <com/sun/star/xml/dom/XNodeList.hpp>
101#include <com/sun/star/xml/sax/Writer.hpp>
102#include <com/sun/star/xml/sax/XSAXSerializable.hpp>
103#include <com/sun/star/container/XNamed.hpp>
104#include <com/sun/star/drawing/XDrawPages.hpp>
105#include <com/sun/star/drawing/XDrawPagesSupplier.hpp>
106#include <com/sun/star/drawing/RectanglePoint.hpp>
121#include <rtl/strbuf.hxx>
139using namespace ::css;
140using namespace ::css::beans;
141using namespace ::css::drawing;
142using namespace ::css::i18n;
143using namespace ::css::style;
144using namespace ::css::text;
145using namespace ::css::uno;
146using namespace ::css::container;
147using namespace ::com::sun::star::drawing::EnhancedCustomShapeSegmentCommand;
149using ::css::io::XOutputStream;
150using ::sax_fastparser::FSHelperPtr;
151using ::sax_fastparser::FastSerializerHelper;
155const char* g_aPredefinedClrNames[] = {
184 bool bExternal =
true;
185 if (rURL.startsWith(
"#"))
193 return staticGraphicExportCache;
196static css::uno::Any
getLineDash(
const css::uno::Reference<css::frame::XModel>& xModel,
const OUString& rDashName )
198 css::uno::Reference<css::lang::XMultiServiceFactory> xFact(
xModel, css::uno::UNO_QUERY);
199 css::uno::Reference<css::container::XNameAccess> xNameAccess(
200 xFact->createInstance(
"com.sun.star.drawing.DashTable"),
201 css::uno::UNO_QUERY );
204 if (!xNameAccess->hasByName(rDashName))
205 return css::uno::Any();
207 return xNameAccess->getByName(rDashName);
210 return css::uno::Any();
217 pFS->startElementNS(XML_a, XML_path, XML_path, bCircle ?
"circle" :
"rect");
225 sal_Int32 nLeftPercent = rBGradient.
GetXOffset();
226 pAttributeList->add(XML_l, OString::number(nLeftPercent *
PER_PERCENT));
227 sal_Int32 nTopPercent = rBGradient.
GetYOffset();
228 pAttributeList->add(XML_t, OString::number(nTopPercent *
PER_PERCENT));
229 sal_Int32 nRightPercent = 100 - rBGradient.
GetXOffset();
230 pAttributeList->add(XML_r, OString::number(nRightPercent *
PER_PERCENT));
231 sal_Int32 nBottomPercent = 100 - rBGradient.
GetYOffset();
232 pAttributeList->add(XML_b, OString::number(nBottomPercent *
PER_PERCENT));
233 pFS->singleElementNS(XML_a, XML_fillToRect, pAttributeList);
235 pFS->endElementNS(XML_a, XML_path);
246 if (rStr.getLength() > 0)
251 sal_Int16 nScriptType = xBreakIterator->getScriptType(rStr, 0);
253 if (nScriptType == css::i18n::ScriptType::WEAK)
255 sal_Int32
nPos = xBreakIterator->nextScript(rStr, 0, nScriptType);
256 if (
nPos < rStr.getLength())
257 nScriptType = xBreakIterator->getScriptType(rStr,
nPos);
261 if (nScriptType != css::i18n::ScriptType::WEAK)
265 return css::i18n::ScriptType::LATIN;
279 mAny = rXPropertySet->getPropertyValue(
aName);
294 mAny = rXPropertySet->getPropertyValue(
aName);
297 eState = rXPropertyState->getPropertyState(
aName);
311OString getColorStr(const ::Color nColor)
314 OString
sColor = OString::number(sal_uInt32(nColor) & 0x00FFFFFF, 16);
315 if (
sColor.getLength() < 6)
317 OStringBuffer sBuf(
"0");
318 int remains = 5 -
sColor.getLength();
336 const auto sColor = getColorStr(nColor);
339 mpFS->startElementNS(XML_a, XML_srgbClr, XML_val,
sColor);
340 mpFS->singleElementNS(XML_a, XML_alpha, XML_val, OString::number(nAlpha));
341 mpFS->endElementNS( XML_a, XML_srgbClr );
346 mpFS->singleElementNS(XML_a, XML_srgbClr, XML_val,
sColor);
353 if( sColorSchemeName.isEmpty() )
356 if( aTransformations.hasElements() )
358 mpFS->startElementNS(XML_a, XML_schemeClr, XML_val, sColorSchemeName);
360 mpFS->endElementNS( XML_a, XML_schemeClr );
364 mpFS->startElementNS(XML_a, XML_schemeClr, XML_val, sColorSchemeName);
365 mpFS->singleElementNS(XML_a, XML_alpha, XML_val, OString::number(nAlpha));
366 mpFS->endElementNS( XML_a, XML_schemeClr );
370 mpFS->singleElementNS(XML_a, XML_schemeClr, XML_val, sColorSchemeName);
374void DrawingML::WriteColor( const ::Color nColor,
const Sequence< PropertyValue >& aTransformations, sal_Int32 nAlpha )
376 const auto sColor = getColorStr(nColor);
377 if( aTransformations.hasElements() )
379 mpFS->startElementNS(XML_a, XML_srgbClr, XML_val, sColor);
381 mpFS->endElementNS(XML_a, XML_srgbClr);
385 mpFS->startElementNS(XML_a, XML_srgbClr, XML_val, sColor);
386 mpFS->singleElementNS(XML_a, XML_alpha, XML_val, OString::number(nAlpha));
387 mpFS->endElementNS(XML_a, XML_srgbClr);
391 mpFS->singleElementNS(XML_a, XML_srgbClr, XML_val, sColor);
397 for(
const auto& rTransformation : aTransformations )
404 mpFS->singleElementNS(XML_a,
nToken, XML_val, OString::number(nAlpha));
408 sal_Int32
nValue = rTransformation.Value.get<sal_Int32>();
417 mpFS->startElementNS(XML_a, XML_solidFill);
419 mpFS->endElementNS( XML_a, XML_solidFill );
424 mpFS->startElementNS(XML_a, XML_solidFill);
425 WriteColor( sSchemeName, aTransformations, nAlpha );
426 mpFS->endElementNS( XML_a, XML_solidFill );
429void DrawingML::WriteSolidFill( const ::Color nColor,
const Sequence< PropertyValue >& aTransformations, sal_Int32 nAlpha )
431 mpFS->startElementNS(XML_a, XML_solidFill);
433 mpFS->endElementNS(XML_a, XML_solidFill);
441 sal_uInt32 nFillColor =
mAny.get<sal_uInt32>();
444 OUString sColorFillScheme;
445 sal_uInt32 nOriginalColor = 0;
446 Sequence< PropertyValue > aStyleProperties, aTransformations;
449 Sequence< PropertyValue > aGrabBag;
451 for(
const auto& rProp : std::as_const(aGrabBag) )
453 if( rProp.Name ==
"SpPrSolidFillSchemeClr" )
454 rProp.Value >>= sColorFillScheme;
455 else if( rProp.Name ==
"OriginalSolidFillClr" )
456 rProp.Value >>= nOriginalColor;
457 else if( rProp.Name ==
"StyleFillRef" )
458 rProp.Value >>= aStyleProperties;
459 else if( rProp.Name ==
"SpPrSolidFillSchemeClrTransformations" )
460 rProp.Value >>= aTransformations;
467 sal_Int32 nTransparency = 0;
468 mAny >>= nTransparency;
476 OUString sFillTransparenceGradientName;
477 bool bNeedGradientFill(
false);
479 if (
GetProperty(rXPropSet,
"FillTransparenceGradientName")
480 && (
mAny >>= sFillTransparenceGradientName)
481 && !sFillTransparenceGradientName.isEmpty()
482 &&
GetProperty(rXPropSet,
"FillTransparenceGradient"))
491 if (!bNeedGradientFill)
502 if (bNeedGradientFill)
506 mpFS->startElementNS(XML_a, XML_gradFill, XML_rotWithShape,
"0");
508 mpFS->endElementNS( XML_a, XML_gradFill );
510 else if ( nFillColor != nOriginalColor )
534 if (!xPropertySet->getPropertySetInfo()->hasPropertyByName(rPropertyName))
537 uno::Reference<util::XComplexColor> xComplexColor;
538 xPropertySet->getPropertyValue(rPropertyName) >>= xComplexColor;
539 if (!xComplexColor.is())
545 const char* pColorName = g_aPredefinedClrNames[sal_Int16(aComplexColor.getSchemeType())];
546 mpFS->startElementNS(XML_a, XML_solidFill);
547 mpFS->startElementNS(XML_a, XML_schemeClr, XML_val, pColorName);
548 for (
auto const& rTransform : aComplexColor.getTransformations())
550 switch (rTransform.meType)
553 mpFS->singleElementNS(XML_a, XML_lumMod, XML_val, OString::number(rTransform.mnValue * 10));
556 mpFS->singleElementNS(XML_a, XML_lumOff, XML_val, OString::number(rTransform.mnValue * 10));
559 mpFS->singleElementNS(XML_a, XML_tint, XML_val, OString::number(rTransform.mnValue * 10));
562 mpFS->singleElementNS(XML_a, XML_shade, XML_val, OString::number(rTransform.mnValue * 10));
569 sal_Int16 nAPITransparency(0);
570 if ((rPropertyName ==
u"FillComplexColor" &&
GetProperty(xPropertySet,
"FillTransparence"))
571 || (rPropertyName ==
u"LineComplexColor" &&
GetProperty(xPropertySet,
"LineTransparence"))
572 || (rPropertyName ==
u"CharComplexColor" &&
GetProperty(xPropertySet,
"CharTransparence")))
574 mAny >>= nAPITransparency;
576 if (nAPITransparency != 0)
577 mpFS->singleElementNS(XML_a, XML_alpha, XML_val,
580 mpFS->endElementNS(XML_a, XML_schemeClr);
581 mpFS->endElementNS(XML_a, XML_solidFill);
588 mpFS->startElementNS(XML_a, XML_gs, XML_pos, OString::number(
basegfx::fround(fOffset * 100000)));
592 mpFS->endElementNS( XML_a, XML_gs );
598 | ( ( ( ( ( nColor & 0xff00 ) >> 8 ) * nIntensity ) / 100 ) << 8 )
599 | ( ( ( ( ( nColor & 0xff0000 ) >> 8 ) * nIntensity ) / 100 ) << 8 ));
617 for(
const auto& rProp : std::as_const(aGrabBag) )
618 if( rProp.Name ==
"GradFillDefinition" )
619 rProp.Value >>= aGradientStops;
620 else if( rProp.Name ==
"OriginalGradFill" )
631 if( aGradientStops.hasElements() )
633 mpFS->startElementNS(XML_a, XML_gradFill, XML_rotWithShape,
"0");
635 mpFS->endElementNS( XML_a, XML_gradFill );
640 mpFS->startElementNS(XML_a, XML_gradFill, XML_rotWithShape,
"0");
644 double fTransparency(0.0);
645 OUString sFillTransparenceGradientName;
647 if (
GetProperty(rXPropSet,
"FillTransparenceGradientName")
648 && (
mAny >>= sFillTransparenceGradientName)
649 && !sFillTransparenceGradientName.isEmpty()
650 &&
GetProperty(rXPropSet,
"FillTransparenceGradient"))
654 pTransparenceGradient = &aTransparenceGradient;
656 else if (
GetProperty(rXPropSet,
"FillTransparence"))
660 sal_Int32 nTransparency(0);
661 mAny >>= nTransparency;
663 fTransparency = nTransparency * 0.01;
669 if (
GetProperty(rXPropSet,
"FillGradientStepCount"))
671 sal_Int16 nStepCount = 0;
673 aGradient.SetSteps(nStepCount);
678 mpFS->endElementNS(XML_a, XML_gradFill);
685 mpFS->startElementNS(XML_a, XML_gsLst);
688 for(
const auto& rGradientStop : aGradientStops )
691 rGradientStop.Value >>= aGradientStop;
696 sal_Int16 nTransparency = 0;
699 for(
const auto& rProp : std::as_const(aGradientStop) )
701 if( rProp.Name ==
"SchemeClr" )
702 rProp.Value >>= sSchemeClr;
703 else if( rProp.Name ==
"RgbClr" )
704 rProp.Value >>= nRgbClr;
705 else if( rProp.Name ==
"Pos" )
706 rProp.Value >>=
nPos;
707 else if( rProp.Name ==
"Transparency" )
708 rProp.Value >>= nTransparency;
709 else if( rProp.Name ==
"Transformations" )
710 rProp.Value >>= aTransformations;
713 mpFS->startElementNS(XML_a, XML_gs, XML_pos, OString::number(
nPos * 100000.0));
714 if( sSchemeClr.isEmpty() )
724 mpFS->endElementNS( XML_a, XML_gs );
726 mpFS->endElementNS( XML_a, XML_gsLst );
732 const sal_Int16 nAngle(rBGradient.
GetAngle());
733 mpFS->singleElementNS(
734 XML_a, XML_lin, XML_ang,
735 OString::number(((3600 -
static_cast<sal_Int32
>(nAngle) + 900) * 6000) % 21600000));
738 case awt::GradientStyle_RADIAL:
740 WriteGradientPath(rBGradient,
mpFS,
true);
756 if (
nullptr != pColorGradient)
762 if (aColorStops.size() > 0 && awt::GradientStyle_AXIAL == pColorGradient->
GetGradientStyle())
765 if (
nullptr != pTransparenceGradient)
769 if (
nullptr == pGradient)
771 pGradient = pTransparenceGradient;
776 if (aAlphaStops.size() > 0
783 if (
nullptr == pGradient)
787 assert(
false &&
"pColorGradient or pTransparenceGradient should be set");
804 if (aColorStops.size() != aAlphaStops.size())
808 assert(
false &&
"oox::WriteGradientFill: non-synchronized gradients (!)");
812 bool bLinearOrAxial(awt::GradientStyle_LINEAR == pGradient->
GetGradientStyle()
831 mpFS->startElementNS(XML_a, XML_gsLst);
833 basegfx::BColorStops::const_iterator aCurrColor(aColorStops.begin());
834 basegfx::BColorStops::const_iterator aCurrAlpha(aAlphaStops.begin());
836 while (aCurrColor != aColorStops.end() && aCurrAlpha != aAlphaStops.end())
839 aCurrColor->getStopOffset(),
840 aCurrColor->getStopColor(),
841 aCurrAlpha->getStopColor());
846 mpFS->endElementNS( XML_a, XML_gsLst );
852 const sal_Int16 nAngle(pGradient->
GetAngle());
853 mpFS->singleElementNS(
854 XML_a, XML_lin, XML_ang,
855 OString::number(((3600 -
static_cast<sal_Int32
>(nAngle) + 900) * 6000) % 21600000));
861 const bool bCircle(pGradient->
GetGradientStyle() == awt::GradientStyle_RADIAL ||
863 WriteGradientPath(*pGradient,
mpFS, bCircle);
870 sal_Int32 nArrowLength;
871 sal_Int32 nArrowWidth;
880 switch( nArrowLength )
917 switch( nArrowWidth )
931 mpFS->singleElementNS( XML_a, bLineStart ? XML_headEnd : XML_tailEnd,
939 drawing::LineStyle aLineStyle( drawing::LineStyle_NONE );
946 sal_uInt32 nEmuLineWidth = 0;
949 bool bColorSet =
false;
950 const char* cap =
nullptr;
951 drawing::LineDash aLineDash;
952 bool bDashSet =
false;
953 bool bNoFill =
false;
957 OUString sColorFillScheme;
958 ::Color aResolvedColorFillScheme;
962 sal_uInt32 nStyleLineWidth = 0;
967 drawing::LineStyle aStyleLineStyle(drawing::LineStyle_NONE);
968 drawing::LineJoint aStyleLineJoint(drawing::LineJoint_NONE);
975 for (
const auto& rProp : std::as_const(aGrabBag))
977 if( rProp.Name ==
"SpPrLnSolidFillSchemeClr" )
978 rProp.Value >>= sColorFillScheme;
979 if( rProp.Name ==
"SpPrLnSolidFillResolvedSchemeClr" )
980 rProp.Value >>= aResolvedColorFillScheme;
981 else if( rProp.Name ==
"OriginalLnSolidFillClr" )
982 rProp.Value >>= nOriginalColor;
983 else if( rProp.Name ==
"StyleLnRef" )
984 rProp.Value >>= aStyleProperties;
985 else if( rProp.Name ==
"SpPrLnSolidFillSchemeClrTransformations" )
986 rProp.Value >>= aTransformations;
987 else if( rProp.Name ==
"EmuLineWidth" )
988 rProp.Value >>= nEmuLineWidth;
990 for (
const auto& rStyleProp : std::as_const(aStyleProperties))
992 if( rStyleProp.Name ==
"Color" )
993 rStyleProp.Value >>= nStyleColor;
994 else if( rStyleProp.Name ==
"LineStyle" )
995 rStyleProp.Value >>= aStyleLineStyle;
996 else if( rStyleProp.Name ==
"LineJoint" )
997 rStyleProp.Value >>= aStyleLineJoint;
998 else if( rStyleProp.Name ==
"LineWidth" )
999 rStyleProp.Value >>= nStyleLineWidth;
1008 case drawing::LineStyle_NONE:
1011 case drawing::LineStyle_DASH:
1014 aLineDash =
mAny.get<drawing::LineDash>();
1016 if (aLineDash.Dots == 0 && aLineDash.DotLen == 0 && aLineDash.Dashes == 0 && aLineDash.DashLen == 0 && aLineDash.Distance == 0) {
1017 OUString aLineDashName;
1019 mAny >>= aLineDashName;
1020 if (!aLineDashName.isEmpty() &&
xModel) {
1029 OUString aLineDashName;
1031 mAny >>= aLineDashName;
1032 if (!aLineDashName.isEmpty() &&
xModel) {
1038 if (aLineDash.Style == DashStyle_ROUND || aLineDash.Style == DashStyle_ROUNDRELATIVE)
1043 SAL_INFO(
"oox.shape",
"dash dots: " << aLineDash.Dots <<
" dashes: " << aLineDash.Dashes
1044 <<
" dotlen: " << aLineDash.DotLen <<
" dashlen: " << aLineDash.DashLen <<
" distance: " << aLineDash.Distance);
1047 case drawing::LineStyle_SOLID:
1058 if (aLineCap == LineCap_ROUND)
1060 else if (aLineCap == LineCap_SQUARE)
1068 mpFS->startElementNS( XML_a, XML_ln,
1076 if( nColor != nOriginalColor )
1082 else if( !sColorFillScheme.isEmpty() )
1093 if( bDashSet && aStyleLineStyle != drawing::LineStyle_DASH )
1100 bool bIsConverted =
false;
1102 bool bIsRelative(aLineDash.Style == DashStyle_RECTRELATIVE || aLineDash.Style == DashStyle_ROUNDRELATIVE);
1103 if ( bIsRelative && aLineDash.Dots == 1)
1105 sal_uInt32 nDotLen = aLineDash.DotLen;
1106 sal_uInt32 nDashLen = aLineDash.DashLen;
1107 sal_uInt32 nDistance = aLineDash.Distance;
1108 if (aLineCap != LineCap_BUTT && nDistance >= 99)
1119 if (nDashLen == 0 && aLineDash.Dashes > 0)
1121 bIsConverted =
true;
1122 if (nDotLen == 100 && aLineDash.Dashes == 0 && nDashLen == 0 && nDistance == 300)
1124 mpFS->singleElementNS(XML_a, XML_prstDash, XML_val,
"dot");
1126 else if (nDotLen == 400 && aLineDash.Dashes == 0 && nDashLen == 0 && nDistance == 300)
1128 mpFS->singleElementNS(XML_a, XML_prstDash, XML_val,
"dash");
1130 else if (nDotLen == 400 && aLineDash.Dashes == 1 && nDashLen == 100 && nDistance == 300)
1132 mpFS->singleElementNS(XML_a, XML_prstDash, XML_val,
"dashDot");
1134 else if (nDotLen == 800 && aLineDash.Dashes == 0 && nDashLen == 0 && nDistance == 300)
1136 mpFS->singleElementNS(XML_a, XML_prstDash, XML_val,
"lgDash");
1138 else if (nDotLen == 800 && aLineDash.Dashes == 1 && nDashLen == 100 && nDistance == 300)
1140 mpFS->singleElementNS(XML_a, XML_prstDash, XML_val,
"lgDashDot");
1142 else if (nDotLen == 800 && aLineDash.Dashes == 2 && nDashLen == 100 && nDistance == 300)
1144 mpFS->singleElementNS(XML_a, XML_prstDash, XML_val,
"lgDashDotDot");
1146 else if (nDotLen == 100 && aLineDash.Dashes == 0 && nDashLen == 0 && nDistance == 100)
1148 mpFS->singleElementNS(XML_a, XML_prstDash, XML_val,
"sysDot");
1150 else if (nDotLen == 300 && aLineDash.Dashes == 0 && nDashLen == 0 && nDistance == 100)
1152 mpFS->singleElementNS(XML_a, XML_prstDash, XML_val,
"sysDash");
1154 else if (nDotLen == 300 && aLineDash.Dashes == 1 && nDashLen == 100 && nDistance == 100)
1156 mpFS->singleElementNS(XML_a, XML_prstDash, XML_val,
"sysDashDot");
1158 else if (nDotLen == 300 && aLineDash.Dashes == 2 && nDashLen == 100 && nDistance == 100)
1160 mpFS->singleElementNS(XML_a, XML_prstDash, XML_val,
"sysDashDotDot");
1163 bIsConverted =
false;
1168 mpFS->startElementNS(XML_a, XML_custDash);
1174 double fSp = bIsRelative ? aLineDash.Distance : aLineDash.Distance * 100.0 / fLineWidth;
1177 if (aLineDash.Distance <= 0)
1181 if (aLineCap == LineCap_ROUND && fSp > 99.0)
1184 if (aLineDash.Dots > 0)
1186 double fD = bIsRelative ? aLineDash.DotLen : aLineDash.DotLen * 100.0 / fLineWidth;
1188 if (aLineDash.DotLen == 0)
1191 if (aLineCap == LineCap_ROUND && fSp > 99.0)
1194 for(
i = 0;
i < aLineDash.Dots;
i ++ )
1196 mpFS->singleElementNS( XML_a, XML_ds,
1201 if ( aLineDash.Dashes > 0 )
1203 double fD = bIsRelative ? aLineDash.DashLen : aLineDash.DashLen * 100.0 / fLineWidth;
1205 if (aLineDash.DashLen == 0)
1208 if (aLineCap == LineCap_ROUND && fSp > 99.0)
1211 for(
i = 0;
i < aLineDash.Dashes;
i ++ )
1213 mpFS->singleElementNS( XML_a , XML_ds,
1220 "oox.shape",
"while writing outline - custom dash - line width was < 0 : " <<
nLineWidth);
1222 "oox.shape",
"while writing outline - custom dash - number of dashes was < 0 : " << aLineDash.Dashes);
1223 SAL_WARN_IF(aLineDash.Dashes > 0 && aLineDash.DashLen <= 0,
1224 "oox.shape",
"while writing outline - custom dash - dash length was < 0 : " << aLineDash.DashLen);
1226 "oox.shape",
"while writing outline - custom dash - number of dots was < 0 : " << aLineDash.Dots);
1227 SAL_WARN_IF(aLineDash.Dots > 0 && aLineDash.DotLen <= 0,
1228 "oox.shape",
"while writing outline - custom dash - dot length was < 0 : " << aLineDash.DotLen);
1230 "oox.shape",
"while writing outline - custom dash - distance was < 0 : " << aLineDash.Distance);
1232 mpFS->endElementNS( XML_a, XML_custDash );
1242 || aStyleLineJoint != eLineJoint)
1245 switch( eLineJoint )
1247 case LineJoint_NONE:
1248 case LineJoint_BEVEL:
1249 mpFS->singleElementNS(XML_a, XML_bevel);
1252 case LineJoint_MIDDLE:
1253 case LineJoint_MITER:
1254 mpFS->singleElementNS(XML_a, XML_miter);
1256 case LineJoint_ROUND:
1257 mpFS->singleElementNS(XML_a, XML_round);
1270 mpFS->singleElementNS(XML_a, XML_noFill);
1273 mpFS->endElementNS( XML_a, XML_ln );
1292 mpFS->startElementNS(XML_a, XML_blip,
FSNS(XML_r, XML_embed), sRelId);
1294 for (
auto const& rEffect : rEffects)
1296 switch (rEffect.meType)
1300 mpFS->singleElementNS(XML_a, XML_alphaBiLevel, XML_thresh, OString::number(rEffect.mnThreshold));
1305 mpFS->singleElementNS(XML_a, XML_alphaCeiling);
1310 mpFS->singleElementNS(XML_a, XML_alphaFloor);
1315 mpFS->singleElementNS(XML_a, XML_alphaInv);
1321 mpFS->singleElementNS(XML_a, XML_alphaMod);
1327 mpFS->singleElementNS(XML_a, XML_alphaModFix, XML_amt, OString::number(rEffect.mnAmount));
1332 mpFS->singleElementNS(XML_a, XML_alphaRepl, XML_a, OString::number(rEffect.mnAlpha));
1337 mpFS->singleElementNS(XML_a, XML_biLevel, XML_thresh, OString::number(rEffect.mnThreshold));
1342 mpFS->singleElementNS(XML_a, XML_blur,
1343 XML_rad, OString::number(rEffect.mnRadius),
1344 XML_grow, rEffect.mbGrow ?
"1" :
"0");
1349 mpFS->startElementNS(XML_a, XML_clrChange, XML_useA, rEffect.mbUseAlpha ?
"1" :
"0");
1350 mpFS->endElementNS(XML_a, XML_clrChange);
1355 mpFS->startElementNS(XML_a, XML_clrRepl);
1356 mpFS->endElementNS(XML_a, XML_clrRepl);
1361 mpFS->startElementNS(XML_a, XML_duotone);
1362 mpFS->endElementNS(XML_a, XML_duotone);
1367 mpFS->singleElementNS(XML_a, XML_fillOverlay);
1372 mpFS->singleElementNS(XML_a, XML_grayscl);
1377 mpFS->singleElementNS(XML_a, XML_hsl,
1378 XML_hue, OString::number(rEffect.mnHue),
1379 XML_sat, OString::number(rEffect.mnSaturation),
1380 XML_lum, OString::number(rEffect.mnLuminance));
1385 mpFS->singleElementNS(XML_a, XML_lum,
1386 XML_bright, OString::number(rEffect.mnBrightness),
1387 XML_contrast, OString::number(rEffect.mnContrast));
1392 mpFS->singleElementNS(XML_a, XML_tint,
1393 XML_hue, OString::number(rEffect.mnHue),
1394 XML_amt, OString::number(rEffect.mnAmount));
1403 mpFS->endElementNS(XML_a, XML_blip);
1413 const char* pExtension =
"";
1421 if (sPath.isEmpty())
1429 case GfxLinkType::NativeGif:
1431 pExtension =
".gif";
1436 case GfxLinkType::NativeBmp:
1438 pExtension =
".bmp";
1441 case GfxLinkType::NativeJpg:
1443 pExtension =
".jpeg";
1445 case GfxLinkType::NativePng:
1447 pExtension =
".png";
1449 case GfxLinkType::NativeTif:
1451 pExtension =
".tif";
1453 case GfxLinkType::NativeWmf:
1455 pExtension =
".wmf";
1457 case GfxLinkType::NativeMet:
1459 pExtension =
".met";
1461 case GfxLinkType::NativePct:
1463 pExtension =
".pct";
1465 case GfxLinkType::NativeMov:
1467 pExtension =
".MOV";
1472 if (aType == GraphicType::Bitmap || aType == GraphicType::GdiMetafile)
1474 if (aType == GraphicType::Bitmap)
1478 pExtension =
".png";
1484 pExtension =
".emf";
1489 SAL_WARN(
"oox.shape",
"unhandled graphic type " <<
static_cast<int>(aType));
1508 .append(
"/media/image" + OUString::number(nImageCount))
1509 .appendAscii(pExtension)
1510 .makeStringAndClear(),
1513 xOutStream->closeOutput();
1515 const char* sRelationCompPrefix;
1516 if (bRelPathToMedia)
1517 sRelationCompPrefix =
"../";
1520 sPath = OUStringBuffer()
1521 .appendAscii(sRelationCompPrefix)
1522 .append(
"media/image" + OUString::number(nImageCount))
1523 .appendAscii(pExtension)
1524 .makeStringAndClear();
1549 OUString aExtension;
1550 const OUString& rURL(pMediaObj->
getURL());
1551 int nLastDot = rURL.lastIndexOf(
'.');
1553 aExtension = rURL.copy(nLastDot);
1555 bool bEmbed = rURL.startsWith(
"vnd.sun.star.Package:");
1559#if HAVE_FEATURE_AVMEDIA
1569 if (
aMimeType ==
"application/vnd.sun.star.media")
1573 if (aExtension.equalsIgnoreAsciiCase(
".avi"))
1575 else if (aExtension.equalsIgnoreAsciiCase(
".flv"))
1577 else if (aExtension.equalsIgnoreAsciiCase(
".mp4"))
1579 else if (aExtension.equalsIgnoreAsciiCase(
".mov"))
1581 else if (aExtension.equalsIgnoreAsciiCase(
".ogv"))
1583 else if (aExtension.equalsIgnoreAsciiCase(
".wmv"))
1585 else if (aExtension.equalsIgnoreAsciiCase(
".wav"))
1590 else if (aExtension.equalsIgnoreAsciiCase(
".m4a"))
1595 else if (aExtension.equalsIgnoreAsciiCase(
".mp3"))
1602 OUString aVideoFileRelId;
1603 OUString aMediaRelId;
1609 OUString sFileName = OUStringBuffer()
1611 .append(
"/media/media" + OUString::number(nImageCount) + aExtension)
1612 .makeStringAndClear();
1617 uno::Reference<io::XInputStream> xInputStream(pMediaObj->
GetInputStream());
1620 xOutStream->closeOutput();
1624 .append(
"media/media" + OUString::number(nImageCount) + aExtension)
1625 .makeStringAndClear();
1635 GetFS()->startElementNS(XML_p, XML_nvPr);
1638 FSNS(XML_r, XML_link), aVideoFileRelId);
1640 GetFS()->startElementNS(XML_p, XML_extLst);
1642 GetFS()->startElementNS(XML_p, XML_ext, XML_uri,
"{DAA4B4D4-6D71-4841-9C94-3DE7FCFB9230}");
1644 GetFS()->singleElementNS(XML_p14, XML_media,
1645 bEmbed?
FSNS(XML_r, XML_embed):
FSNS(XML_r, XML_link), aMediaRelId);
1647 GetFS()->endElementNS(XML_p, XML_ext);
1648 GetFS()->endElementNS(XML_p, XML_extLst);
1650 GetFS()->endElementNS(XML_p, XML_nvPr);
1655 sal_Int16 nBright = 0;
1656 sal_Int32 nContrast = 0;
1657 sal_Int32 nTransparence = 0;
1660 nBright =
mAny.get<sal_Int16>();
1662 nContrast =
mAny.get<sal_Int32>();
1665 nTransparence =
mAny.get<sal_Int32>();
1667 if (nTransparence == 0 &&
GetProperty(rXPropSet,
"Transparency"))
1668 nTransparence =
static_cast<sal_Int32
>(
mAny.get<sal_Int16>());
1672 drawing::ColorMode aColorMode;
1673 mAny >>= aColorMode;
1674 if (aColorMode == drawing::ColorMode_GREYS)
1675 mpFS->singleElementNS(XML_a, XML_grayscl);
1676 else if (aColorMode == drawing::ColorMode_MONO)
1678 mpFS->singleElementNS(XML_a, XML_biLevel, XML_thresh, OString::number(50000));
1679 else if (aColorMode == drawing::ColorMode_WATERMARK)
1688 if (nBright || nContrast)
1690 mpFS->singleElementNS(XML_a, XML_lum,
1697 sal_Int32 nAlphaMod = (100 - nTransparence ) *
PER_PERCENT;
1698 mpFS->singleElementNS(XML_a, XML_alphaModFix, XML_amt, OString::number(nAlphaMod));
1703 uno::Reference<graphic::XGraphic>
const & rxGraphic,
1704 bool bRelPathToMedia)
1708 if (!rxGraphic.is())
1712 sRelId =
WriteImage(aGraphic, bRelPathToMedia);
1714 mpFS->startElementNS(XML_a, XML_blip,
FSNS(XML_r, XML_embed), sRelId);
1720 mpFS->endElementNS(XML_a, XML_blip);
1726 uno::Reference<graphic::XGraphic>
const & rxGraphic,
1727 css::awt::Size
const& rSize)
1729 BitmapMode eBitmapMode(BitmapMode_NO_REPEAT);
1731 mAny >>= eBitmapMode;
1733 SAL_INFO(
"oox.shape",
"fill bitmap mode: " <<
int(eBitmapMode));
1735 switch (eBitmapMode)
1737 case BitmapMode_REPEAT:
1740 case BitmapMode_STRETCH:
1743 case BitmapMode_NO_REPEAT:
1752 const OUString& rURLPropName,
const awt::Size& rSize)
1764 const OUString& sURLPropName,
const awt::Size& rSize)
1770 const OUString& sURLPropName, sal_Int32 nXmlNamespace)
1775 uno::Reference<graphic::XGraphic> xGraphic;
1776 if (
mAny.has<uno::Reference<awt::XBitmap>>())
1778 uno::Reference<awt::XBitmap> xBitmap =
mAny.get<uno::Reference<awt::XBitmap>>();
1780 xGraphic.set(xBitmap, uno::UNO_QUERY);
1782 else if (
mAny.has<uno::Reference<graphic::XGraphic>>())
1784 xGraphic =
mAny.get<uno::Reference<graphic::XGraphic>>();
1789 bool bWriteMode =
false;
1790 if (sURLPropName ==
"FillBitmap" || sURLPropName ==
"BackGraphic")
1797 uno::Reference<graphic::XGraphic>
const & rxGraphic,
1798 sal_Int32 nXmlNamespace,
bool bWriteMode,
1799 bool bRelPathToMedia, css::awt::Size
const& rSize)
1801 if (!rxGraphic.is() )
1804 mpFS->startElementNS(nXmlNamespace , XML_blipFill, XML_rotWithShape,
"0");
1818 else if(
GetProperty(rXPropSet,
"FillBitmapStretch"))
1820 bool bStretch =
mAny.get<
bool>();
1827 mpFS->endElementNS(nXmlNamespace, XML_blipFill);
1834 drawing::Hatch aHatch;
1847 sal_Int32 nTransparency = 0;
1848 mAny >>= nTransparency;
1852 mpFS->startElementNS(XML_a, XML_fgClr);
1854 mpFS->endElementNS( XML_a , XML_fgClr );
1860 bool isBackgroundFilled =
false;
1861 mAny >>= isBackgroundFilled;
1862 if( isBackgroundFilled )
1873 mpFS->startElementNS(XML_a, XML_bgClr);
1875 mpFS->endElementNS( XML_a , XML_bgClr );
1877 mpFS->endElementNS( XML_a , XML_pattFill );
1881 Size const & rOriginalSize,
1887 css::text::GraphicCrop aGraphicCropStruct;
1888 mAny >>= aGraphicCropStruct;
1896 mpFS->singleElementNS( XML_a, XML_srcRect);
1900 Size aOriginalSize(rOriginalSize);
1903 if (rMapMode.
GetMapUnit() == MapUnit::MapPixel)
1906 if ( (0 != aGraphicCropStruct.Left) || (0 != aGraphicCropStruct.Top) || (0 != aGraphicCropStruct.Right) || (0 != aGraphicCropStruct.Bottom) )
1908 mpFS->singleElementNS( XML_a, XML_srcRect,
1909 XML_l, OString::number(rtl::math::round(aGraphicCropStruct.Left * 100000.0 / aOriginalSize.
Width())),
1910 XML_t, OString::number(rtl::math::round(aGraphicCropStruct.Top * 100000.0 / aOriginalSize.
Height())),
1911 XML_r, OString::number(rtl::math::round(aGraphicCropStruct.Right * 100000.0 / aOriginalSize.
Width())),
1912 XML_b, OString::number(rtl::math::round(aGraphicCropStruct.Bottom * 100000.0 / aOriginalSize.
Height())) );
1918 uno::Reference<graphic::XGraphic>
const & rxGraphic)
1927 uno::Reference<graphic::XGraphic>
const & rxGraphic)
1932 mpFS->singleElementNS(XML_a, XML_stretch);
1936 mpFS->startElementNS(XML_a, XML_stretch);
1941 css::text::GraphicCrop aGraphicCropStruct;
1942 mAny >>= aGraphicCropStruct;
1944 if ((0 != aGraphicCropStruct.Left)
1945 || (0 != aGraphicCropStruct.Top)
1946 || (0 != aGraphicCropStruct.Right)
1947 || (0 != aGraphicCropStruct.Bottom))
1951 mpFS->singleElementNS(XML_a, XML_fillRect,
1952 XML_l, OString::number(((aGraphicCropStruct.Left) * 100000) / aOriginalSize.
Width()),
1953 XML_t, OString::number(((aGraphicCropStruct.Top) * 100000) / aOriginalSize.
Height()),
1954 XML_r, OString::number(((aGraphicCropStruct.Right) * 100000) / aOriginalSize.
Width()),
1955 XML_b, OString::number(((aGraphicCropStruct.Bottom) * 100000) / aOriginalSize.
Height()));
1962 mpFS->singleElementNS(XML_a, XML_fillRect);
1965 mpFS->endElementNS(XML_a, XML_stretch);
1970 OUString sAlignment;
1971 switch (eRectanglePoint)
1973 case RectanglePoint_LEFT_TOP:
1976 case RectanglePoint_MIDDLE_TOP:
1979 case RectanglePoint_RIGHT_TOP:
1982 case RectanglePoint_LEFT_MIDDLE:
1985 case RectanglePoint_MIDDLE_MIDDLE:
1988 case RectanglePoint_RIGHT_MIDDLE:
1991 case RectanglePoint_LEFT_BOTTOM:
1994 case RectanglePoint_MIDDLE_BOTTOM:
1997 case RectanglePoint_RIGHT_BOTTOM:
2007 uno::Reference<graphic::XGraphic>
const& rxGraphic,
2008 css::awt::Size
const& rSize)
2014 if (rMapMode.
GetMapUnit() == MapUnit::MapPixel)
2016 MapMode(MapUnit::Map100thMM));
2017 sal_Int32 nSizeX = 0;
2018 sal_Int32 nOffsetX = 0;
2022 if (
GetProperty(rXPropSet,
"FillBitmapPositionOffsetX"))
2024 sal_Int32 nX = (nSizeX != 0) ? nSizeX : aOriginalSize.
Width();
2025 if (nX < 0 && rSize.Width > 0)
2026 nX = rSize.Width * std::abs(nX) / 100;
2027 nOffsetX = (*o3tl::doAccess<sal_Int32>(
mAny)) * nX * 3.6;
2032 nSizeX = double(nSizeX) / aOriginalSize.
Width() * 100000;
2033 else if (nSizeX < 0)
2039 sal_Int32 nSizeY = 0;
2040 sal_Int32 nOffsetY = 0;
2044 if (
GetProperty(rXPropSet,
"FillBitmapPositionOffsetY"))
2046 sal_Int32 nY = (nSizeY != 0) ? nSizeY : aOriginalSize.
Height();
2047 if (nY < 0 && rSize.Height > 0)
2048 nY = rSize.Height * std::abs(nY) / 100;
2049 nOffsetY = (*o3tl::doAccess<sal_Int32>(
mAny)) * nY * 3.6;
2054 nSizeY = double(nSizeY) / aOriginalSize.
Height() * 100000;
2055 else if (nSizeY < 0)
2062 if (nSizeX < 0 && nSizeY < 0)
2064 if (rSize.Width != 0 && rSize.Height != 0)
2066 nSizeX = rSize.Width / double(aOriginalSize.
Width()) * std::abs(nSizeX);
2067 nSizeY = rSize.Height / double(aOriginalSize.
Height()) * std::abs(nSizeY);
2071 nSizeX = std::abs(nSizeX);
2072 nSizeY = std::abs(nSizeY);
2076 OUString sRectanglePoint;
2077 if (
GetProperty(rXPropSet,
"FillBitmapRectanglePoint"))
2080 mpFS->singleElementNS(XML_a, XML_tile, XML_tx, OUString::number(nOffsetX), XML_ty,
2081 OUString::number(nOffsetY), XML_sx, OUString::number(nSizeX), XML_sy,
2082 OUString::number(nSizeY), XML_algn, sRectanglePoint);
2086 uno::Reference<graphic::XGraphic>
const& rxGraphic,
2087 css::awt::Size
const& rSize)
2093 if (rMapMode.
GetMapUnit() == MapUnit::MapPixel)
2095 MapMode(MapUnit::Map100thMM));
2103 nSizeX = aOriginalSize.
Width();
2116 nSizeY = aOriginalSize.
Height();
2122 if (nSizeX < 0 && nSizeY < 0 && rSize.Width != 0 && rSize.Height != 0)
2124 nSizeX = rSize.Width * std::abs(nSizeX);
2125 nSizeY = rSize.Height * std::abs(nSizeY);
2128 sal_Int32 nL = 0, nT = 0, nR = 0, nB = 0;
2129 if (
GetProperty(rXPropSet,
"FillBitmapRectanglePoint") && rSize.Width != 0 && rSize.Height != 0)
2131 sal_Int32 nWidth = (1 - (nSizeX / rSize.Width)) * 100000;
2132 sal_Int32 nHeight = (1 - (nSizeY / rSize.Height)) * 100000;
2134 switch (*o3tl::doAccess<RectanglePoint>(
mAny))
2136 case RectanglePoint_LEFT_TOP: nR = nWidth; nB = nHeight;
break;
2137 case RectanglePoint_RIGHT_TOP: nL = nWidth; nB = nHeight;
break;
2138 case RectanglePoint_LEFT_BOTTOM: nR = nWidth; nT = nHeight;
break;
2139 case RectanglePoint_RIGHT_BOTTOM: nL = nWidth; nT = nHeight;
break;
2140 case RectanglePoint_LEFT_MIDDLE: nR = nWidth; nT = nB = nHeight / 2;
break;
2141 case RectanglePoint_RIGHT_MIDDLE: nL = nWidth; nT = nB = nHeight / 2;
break;
2142 case RectanglePoint_MIDDLE_TOP: nB = nHeight; nL = nR = nWidth / 2;
break;
2143 case RectanglePoint_MIDDLE_BOTTOM: nT = nHeight; nL = nR = nWidth / 2;
break;
2144 case RectanglePoint_MIDDLE_MIDDLE: nL = nR = nWidth / 2; nT = nB = nHeight / 2;
break;
2149 mpFS->startElementNS(XML_a, XML_stretch);
2151 mpFS->singleElementNS(XML_a, XML_fillRect, XML_l,
2157 mpFS->endElementNS(XML_a, XML_stretch);
2162bool IsTopGroupObj(
const uno::Reference<drawing::XShape>& xShape)
2168 if (
pObject->getParentSdrObjectFromSdrObject())
2171 return pObject->IsGroupObject();
2176 sal_Int32 nXmlNamespace,
bool bFlipH,
bool bFlipV, sal_Int32 nRotation,
bool bIsGroupShape)
2179 mpFS->startElementNS( nXmlNamespace, XML_xfrm,
2184 sal_Int32 nLeft = rRect.
Left();
2185 sal_Int32 nTop = rRect.
Top();
2191 sal_Int32 nChildLeft = nLeft;
2192 sal_Int32 nChildTop = nTop;
2194 mpFS->singleElementNS(XML_a, XML_off,
2197 mpFS->singleElementNS(XML_a, XML_ext,
2203 mpFS->singleElementNS(XML_a, XML_chOff,
2206 mpFS->singleElementNS(XML_a, XML_chExt,
2211 mpFS->endElementNS( nXmlNamespace, XML_xfrm );
2216 SAL_INFO(
"oox.shape",
"write shape transformation");
2220 awt::Point aPos = rXShape->getPosition();
2221 awt::Size aSize = rXShape->getSize();
2223 bool bFlipHWrite = bFlipH && !bSuppressFlipping;
2224 bool bFlipVWrite = bFlipV && !bSuppressFlipping;
2225 bFlipH = bFlipH && !bFlippedBeforeRotation;
2226 bFlipV = bFlipV && !bFlippedBeforeRotation;
2230 awt::Point aParentPos =
m_xParent->getPosition();
2231 aPos.X -= aParentPos.X;
2232 aPos.Y -= aParentPos.Y;
2235 if ( aSize.Width < 0 )
2237 if ( aSize.Height < 0 )
2238 aSize.Height = 1000;
2239 if (!bSuppressRotation)
2245 int faccos=bFlipV ? -1 : 1;
2246 int facsin=bFlipH ? -1 : 1;
2247 aPos.X-=(1-faccos*cos(
toRadians(nRotation)))*aSize.Width/2-facsin*sin(
toRadians(nRotation))*aSize.Height/2;
2248 aPos.Y-=(1-faccos*cos(
toRadians(nRotation)))*aSize.Height/2+facsin*sin(
toRadians(nRotation))*aSize.Width/2;
2250 else if (
m_xParent.is() && nRotation != 0_deg100)
2253 basegfx::B2DRange aRect(-aSize.Width / 2.0, -aSize.Height / 2.0, aSize.Width / 2.0,
2254 aSize.Height / 2.0);
2258 aPos.X += -aSize.Width / 2.0 - aRect.
getMinX();
2259 aPos.Y += -aSize.Height / 2.0 - aRect.
getMinY();
2263 uno::Reference<beans::XPropertySet> xPropertySet(rXShape, uno::UNO_QUERY);
2264 uno::Reference<beans::XPropertySetInfo> xPropertySetInfo = xPropertySet->getPropertySetInfo();
2265 if (xPropertySetInfo->hasPropertyByName(
"RotateAngle"))
2268 if (xPropertySet->getPropertyValue(
"RotateAngle") >>= nTmp)
2274 uno::Sequence<beans::PropertyValue> aGrabBagProps;
2276 auto p3DEffectProps = std::find_if(std::cbegin(aGrabBagProps), std::cend(aGrabBagProps),
2277 [](
const PropertyValue& rProp) {
return rProp.Name ==
"3DEffectProperties"; });
2278 if (p3DEffectProps != std::cend(aGrabBagProps))
2280 uno::Sequence<beans::PropertyValue> a3DEffectProps;
2281 p3DEffectProps->Value >>= a3DEffectProps;
2282 auto pCameraProps = std::find_if(std::cbegin(a3DEffectProps), std::cend(a3DEffectProps),
2283 [](
const PropertyValue& rProp) {
return rProp.Name ==
"Camera"; });
2284 if (pCameraProps != std::cend(a3DEffectProps))
2286 uno::Sequence<beans::PropertyValue> aCameraProps;
2287 pCameraProps->Value >>= aCameraProps;
2288 auto pZRotationProp = std::find_if(std::cbegin(aCameraProps), std::cend(aCameraProps),
2289 [](
const PropertyValue& rProp) {
return rProp.Name ==
"rotRev"; });
2290 if (pZRotationProp != std::cend(aCameraProps))
2293 pZRotationProp->Value >>= nTmp;
2302 if(bFlipH != bFlipV)
2303 nRotation = 36000_deg100 - nRotation;
2309static OUString
lcl_GetTarget(
const css::uno::Reference<css::frame::XModel>& xModel, OUString& rURL)
2313 sal_uInt32 nPageCount = xDrawPages->getCount();
2316 for (sal_uInt32
i = 0;
i < nPageCount; ++
i)
2319 xDrawPages->getByIndex(
i) >>= xDrawPage;
2323 OUString sSlideName =
"#" + xNamed->getName();
2324 if (rURL == sSlideName)
2326 sTarget =
"slide" + OUString::number(
i + 1) +
".xml";
2330 if (sTarget.isEmpty())
2332 sal_Int32 nSplit = rURL.lastIndexOf(
' ');
2334 sTarget = OUString::Concat(
"slide") + rURL.subView(nSplit + 1) +
".xml";
2341 bool bCheckDirect,
bool& rbOverridingCharHeight, sal_Int32& rnCharHeight,
2346 OUString usLanguage;
2347 PropertyState eState;
2348 bool bComplex = ( nScriptType == css::i18n::ScriptType::COMPLEX );
2349 const char*
bold =
"0";
2350 const char*
italic =
nullptr;
2352 const char* strikeout =
nullptr;
2353 const char* cap =
nullptr;
2354 sal_Int32 nSize = 1800;
2355 sal_Int32 nCharEscapement = 0;
2356 sal_Int32 nCharKerning = 0;
2357 sal_Int32 nCharEscapementHeight = 0;
2359 if ( nElement == XML_endParaRPr && rbOverridingCharHeight )
2361 nSize = rnCharHeight;
2365 nSize =
static_cast<sal_Int32
>(100*(*o3tl::doAccess<float>(
mAny)));
2366 if ( nElement == XML_rPr || nElement == XML_defRPr )
2368 rbOverridingCharHeight =
true;
2369 rnCharHeight = nSize;
2374 nCharKerning =
static_cast<sal_Int32
>(*o3tl::doAccess<sal_Int16>(
mAny));
2381 nCharKerning = ((nCharKerning * 720)-360) / 254;
2383 if ((bComplex &&
GetProperty(rXPropSet,
"CharWeightComplex"))
2386 if ( *o3tl::doAccess<float>(
mAny) >= awt::FontWeight::SEMIBOLD )
2390 if ((bComplex &&
GetProperty(rXPropSet,
"CharPostureComplex"))
2392 switch ( *o3tl::doAccess<awt::FontSlant>(
mAny) )
2394 case awt::FontSlant_OBLIQUE :
2395 case awt::FontSlant_ITALIC :
2403 && eState == beans::PropertyState_DIRECT_VALUE)
2406 switch ( *o3tl::doAccess<sal_Int16>(
mAny) )
2408 case awt::FontUnderline::SINGLE :
2411 case awt::FontUnderline::DOUBLE :
2414 case awt::FontUnderline::DOTTED :
2417 case awt::FontUnderline::DASH :
2420 case awt::FontUnderline::LONGDASH :
2423 case awt::FontUnderline::DASHDOT :
2426 case awt::FontUnderline::DASHDOTDOT :
2429 case awt::FontUnderline::WAVE :
2432 case awt::FontUnderline::DOUBLEWAVE :
2435 case awt::FontUnderline::BOLD :
2438 case awt::FontUnderline::BOLDDOTTED :
2441 case awt::FontUnderline::BOLDDASH :
2444 case awt::FontUnderline::BOLDLONGDASH :
2447 case awt::FontUnderline::BOLDDASHDOT :
2450 case awt::FontUnderline::BOLDDASHDOTDOT :
2453 case awt::FontUnderline::BOLDWAVE :
2460 && eState == beans::PropertyState_DIRECT_VALUE)
2463 switch ( *o3tl::doAccess<sal_Int16>(
mAny) )
2465 case awt::FontStrikeout::NONE :
2466 strikeout =
"noStrike";
2468 case awt::FontStrikeout::SINGLE :
2476 case awt::FontStrikeout::BOLD :
2477 case awt::FontStrikeout::SLASH :
2478 case awt::FontStrikeout::X :
2479 strikeout =
"sngStrike";
2481 case awt::FontStrikeout::DOUBLE :
2482 strikeout =
"dblStrike";
2490 case css::i18n::ScriptType::ASIAN:
2491 bLang =
GetProperty(rXPropSet,
"CharLocaleAsian");
break;
2492 case css::i18n::ScriptType::COMPLEX:
2493 bLang =
GetProperty(rXPropSet,
"CharLocaleComplex");
break;
2495 bLang =
GetProperty(rXPropSet,
"CharLocale");
break;
2500 css::lang::Locale aLocale;
2508 && eState == beans::PropertyState_DIRECT_VALUE)
2509 mAny >>= nCharEscapement;
2512 && eState == beans::PropertyState_DIRECT_VALUE)
2513 mAny >>= nCharEscapementHeight;
2520 nCharEscapement = .8 * (100 - nCharEscapementHeight);
2527 nCharEscapement = .2 * -(100 - nCharEscapementHeight);
2530 if (nCharEscapement && nCharEscapementHeight)
2532 nSize = (nSize * nCharEscapementHeight) / 100;
2534 nSize = (nSize / 0.58);
2539 switch ( *o3tl::doAccess<sal_Int16>(
mAny) )
2541 case CaseMap::UPPERCASE :
2544 case CaseMap::SMALLCAPS :
2550 mpFS->startElementNS( XML_a, nElement,
2554 XML_sz, OString::number(nSize),
2557 XML_strike, strikeout,
2574 && eState == beans::PropertyState_DIRECT_VALUE)
2582 if (rXPropSet->getPropertySetInfo()->hasPropertyByName(
"CharTransparence"))
2584 rXPropSet->getPropertyValue(
"CharTransparence") >>= nTransparency;
2590 bool bContoured =
false;
2592 bContoured = *o3tl::doAccess<bool>(
mAny);
2597 mpFS->startElementNS(XML_a, XML_ln);
2604 color.SetAlpha(255);
2608 mpFS->endElementNS(XML_a, XML_ln);
2616 color.SetAlpha(255);
2627 if (rXShapePropSet.is() &&
GetProperty(rXShapePropSet,
"FillStyle")
2632 bIsTextBackgroundDark = aShapeFillColor.
IsDark();
2635 if (bIsTextBackgroundDark)
2652 mpFS->startElementNS(XML_a, XML_highlight);
2654 mpFS->endElementNS( XML_a, XML_highlight );
2662 && eState == beans::PropertyState_DIRECT_VALUE)
2669 mpFS->startElementNS(XML_a, XML_uFill);
2671 mpFS->endElementNS( XML_a, XML_uFill );
2675 mpFS->singleElementNS(XML_a, XML_uFillTx);
2681 const char*
const pitch =
nullptr;
2682 const char*
const charset =
nullptr;
2683 OUString usTypeface;
2685 mAny >>= usTypeface;
2686 OUString aSubstName(
GetSubsFontName( usTypeface, SubsFontFlags::ONLYONE | SubsFontFlags::MS ) );
2687 if (!aSubstName.isEmpty())
2688 usTypeface = aSubstName;
2690 mpFS->singleElementNS( XML_a, XML_latin,
2691 XML_typeface, usTypeface,
2692 XML_pitchFamily, pitch,
2693 XML_charset, charset );
2698 && eState == beans::PropertyState_DIRECT_VALUE))
2701 && eState == beans::PropertyState_DIRECT_VALUE)))
2703 const char*
const pitch =
nullptr;
2704 const char*
const charset =
nullptr;
2705 OUString usTypeface;
2707 mAny >>= usTypeface;
2708 OUString aSubstName(
GetSubsFontName( usTypeface, SubsFontFlags::ONLYONE | SubsFontFlags::MS ) );
2709 if (!aSubstName.isEmpty())
2710 usTypeface = aSubstName;
2712 mpFS->singleElementNS( XML_a, bComplex ? XML_cs : XML_ea,
2713 XML_typeface, usTypeface,
2714 XML_pitchFamily, pitch,
2715 XML_charset, charset );
2722 mAny >>= rXTextField;
2723 if( rXTextField.is() )
2724 rXPropSet.set( rXTextField, UNO_QUERY );
2733 if (!sURL.isEmpty())
2735 if (!sURL.match(
"#action?jump="))
2747 mpFS->singleElementNS(XML_a, XML_hlinkClick,
FSNS(XML_r, XML_id), sRelId);
2749 mpFS->singleElementNS(XML_a, XML_hlinkClick,
FSNS(XML_r, XML_id), sRelId,
2750 XML_action,
"ppaction://hlinksldjump");
2754 sal_Int32
nIndex = sURL.indexOf(
'=');
2755 std::u16string_view aDestination(sURL.subView(
nIndex + 1));
2756 mpFS->singleElementNS(XML_a, XML_hlinkClick,
FSNS(XML_r, XML_id),
"", XML_action,
2757 OUString::Concat(
"ppaction://hlinkshowjump?jump=") + aDestination);
2761 mpFS->endElementNS( XML_a, nElement );
2767 OUString aFieldType, aFieldValue;
2771 aFieldType = *o3tl::doAccess<OUString>(
mAny);
2772 SAL_INFO(
"oox.shape",
"field type: " << aFieldType);
2775 if( aFieldType ==
"TextField" )
2779 mAny >>= rXTextField;
2780 if( rXTextField.is() )
2782 rXPropSet.set( rXTextField, UNO_QUERY );
2783 if( rXPropSet.is() )
2785 OUString aFieldKind( rXTextField->getPresentation(
true ) );
2786 SAL_INFO(
"oox.shape",
"field kind: " << aFieldKind);
2787 if( aFieldKind ==
"Page" )
2789 aFieldValue =
"slidenum";
2791 else if( aFieldKind ==
"Pages" )
2793 aFieldValue =
"slidecount";
2795 else if( aFieldKind ==
"PageName" )
2797 aFieldValue =
"slidename";
2799 else if( aFieldKind ==
"URL" )
2803 mAny >>= aFieldValue;
2806 else if(aFieldKind ==
"Date")
2808 sal_Int32 nNumFmt = -1;
2812 else if(aFieldKind ==
"ExtTime")
2814 sal_Int32 nNumFmt = -1;
2818 else if(aFieldKind ==
"ExtFile")
2820 sal_Int32 nNumFmt = -1;
2824 case 0: aFieldValue =
"file";
2826 case 1: aFieldValue =
"file1";
2828 case 2: aFieldValue =
"file2";
2830 case 3: aFieldValue =
"file3";
2833 else if(aFieldKind ==
"Author")
2835 aFieldValue =
"author";
2855 OUString aDateField;
2858 case SvxDateFormat::StdSmall:
2859 case SvxDateFormat::A:
2860 aDateField =
"datetime";
2862 case SvxDateFormat::B:
2863 aDateField =
"datetime1";
2865 case SvxDateFormat::C:
2866 aDateField =
"datetime5";
2868 case SvxDateFormat::D:
2869 aDateField =
"datetime3";
2871 case SvxDateFormat::StdBig:
2872 case SvxDateFormat::E:
2873 case SvxDateFormat::F:
2874 aDateField =
"datetime2";
2880 OUString aTimeField;
2883 case SvxTimeFormat::Standard:
2884 case SvxTimeFormat::HH24_MM_SS:
2885 case SvxTimeFormat::HH24_MM_SS_00:
2886 aTimeField =
"datetime11";
2888 case SvxTimeFormat::HH24_MM:
2889 aTimeField =
"datetime10";
2891 case SvxTimeFormat::HH12_MM:
2892 case SvxTimeFormat::HH12_MM_AMPM:
2893 aTimeField =
"datetime12";
2895 case SvxTimeFormat::HH12_MM_SS:
2896 case SvxTimeFormat::HH12_MM_SS_AMPM:
2897 case SvxTimeFormat::HH12_MM_SS_00:
2898 case SvxTimeFormat::HH12_MM_SS_00_AMPM:
2899 aTimeField =
"datetime13";
2905 if (!aDateField.isEmpty() && aTimeField.isEmpty())
2907 else if (!aTimeField.isEmpty() && aDateField.isEmpty())
2909 else if (!aDateField.isEmpty() && !aTimeField.isEmpty())
2911 if (aTimeField ==
"datetime11" || aTimeField ==
"datetime13")
2923 bool& rbOverridingCharHeight, sal_Int32& rnCharHeight,
2924 const css::uno::Reference< css::beans::XPropertySet >& rXShapePropSet)
2927 sal_Int16 nLevel = -1;
2931 bool bNumberingIsNumber =
true;
2933 mAny >>= bNumberingIsNumber;
2935 float nFontSize = -1;
2939 bool bIsURLField =
false;
2941 bool bWriteField = !( sFieldValue.isEmpty() || bIsURLField );
2943 OUString sText = rRun->getString();
2946 if (nLevel !=-1 && bNumberingIsNumber && sText.isEmpty() )
2950 sText = sFieldValue;
2952 if( sText.isEmpty())
2958 if( !xPropSet.is() || !( xPropSet->getPropertyValue(
"PlaceholderText" ) >>= sText ) )
2960 if( sText.isEmpty() )
2974 mpFS->startElementNS(XML_a, XML_br);
2975 mpFS->singleElementNS(XML_a, XML_rPr, XML_sz,
2976 OString::number(nFontSize * 100));
2977 mpFS->endElementNS(XML_a, XML_br);
2980 mpFS->singleElementNS(XML_a, XML_br);
2987 mpFS->startElementNS( XML_a, XML_fld,
2988 XML_id, sUUID.getStr(),
2993 mpFS->startElementNS(XML_a, XML_r);
2999 mpFS->startElementNS(XML_a, XML_t);
3000 mpFS->writeEscaped( sText );
3001 mpFS->endElementNS( XML_a, XML_t );
3004 mpFS->endElementNS( XML_a, XML_fld );
3006 mpFS->endElementNS( XML_a, XML_r );
3012 OUString sPrefixSuffix;
3015 sPrefixSuffix =
"ParenBoth";
3017 sPrefixSuffix =
"ParenR";
3019 sPrefixSuffix =
"Period";
3021 switch( nNumberingType )
3025 return "alphaUc" + sPrefixSuffix;
3029 return "alphaLc" + sPrefixSuffix;
3032 return "romanUc" + sPrefixSuffix;
3035 return "romanLc" + sPrefixSuffix;
3039 if (sPrefixSuffix.isEmpty())
3040 return "arabicPlain";
3042 return "arabic" + sPrefixSuffix;
3053 if (nLevel < 0 || !
GetProperty(rXPropSet,
"NumberingRules"))
3058 if (!(
mAny >>= rXIndexAccess) || nLevel >= rXIndexAccess->getCount())
3061 SAL_INFO(
"oox.shape",
"numbering rules");
3064 rXIndexAccess->getByIndex(nLevel) >>= aPropertySequence;
3066 if (!aPropertySequence.hasElements())
3071 bool bPBehind =
false;
3072 bool bPBoth =
false;
3074 awt::FontDescriptor aFontDesc;
3075 bool bHasFontDesc =
false;
3076 uno::Reference<graphic::XGraphic> xGraphic;
3077 sal_Int16 nBulletRelSize = 0;
3078 sal_Int16 nStartWith = 1;
3080 bool bHasBulletColor =
false;
3081 awt::Size aGraphicSize;
3083 for (
const PropertyValue& rPropValue : std::as_const(aPropertySequence) )
3089 nNumberingType =
static_cast<SvxNumType>(*o3tl::doAccess<sal_Int16>(rPropValue.Value));
3093 if( *o3tl::doAccess<OUString>(rPropValue.Value) ==
")")
3098 auto s = o3tl::doAccess<OUString>(rPropValue.Value);
3107 bHasBulletColor =
true;
3111 aBulletChar = (*o3tl::doAccess<OUString>(rPropValue.Value))[ 0 ];
3115 aFontDesc = *o3tl::doAccess<awt::FontDescriptor>(rPropValue.Value);
3116 bHasFontDesc =
true;
3122 if ( aFontDesc.Name.equalsIgnoreAsciiCase(
"StarSymbol") )
3123 aFontDesc.CharSet = RTL_TEXTENCODING_MS_1252;
3126 else if (
aPropName ==
"BulletRelSize" )
3128 nBulletRelSize = *o3tl::doAccess<sal_Int16>(rPropValue.Value);
3132 nStartWith = *o3tl::doAccess<sal_Int16>(rPropValue.Value);
3136 auto xBitmap = rPropValue.Value.get<uno::Reference<awt::XBitmap>>();
3137 xGraphic.set(xBitmap, uno::UNO_QUERY);
3141 aGraphicSize = *o3tl::doAccess<awt::Size>(rPropValue.Value);
3142 SAL_INFO(
"oox.shape",
"graphic size: " << aGraphicSize.Width <<
"x" << aGraphicSize.Height);
3150 if (xGraphic.is() && aGraphic.
GetType() != GraphicType::NONE)
3155 OUString sRelationId;
3157 if (fBulletSizeRel < 1.0f)
3160 Size aDestSize(64, 64);
3161 float fBulletSizeRelX = fBulletSizeRel / aGraphicSize.Height * aGraphicSize.Width;
3162 tools::Long nPaddingX = std::max<tools::Long>(0, std::lround((aDestSize.
Width() - fBulletSizeRelX * aDestSize.
Width()) / 2.f));
3172 aDestBitmap.
CopyPixel(aDestRect, aSourceRect, &aSourceBitmap);
3173 Graphic aDestGraphic(aDestBitmap);
3175 fBulletSizeRel = 1.0f;
3182 mpFS->singleElementNS( XML_a, XML_buSzPct,
3183 XML_val, OString::number(std::min<sal_Int32>(std::lround(100000.f * fBulletSizeRel), 400000)));
3184 mpFS->startElementNS(XML_a, XML_buBlip);
3185 mpFS->singleElementNS(XML_a, XML_blip,
FSNS(XML_r, XML_embed), sRelationId);
3186 mpFS->endElementNS( XML_a, XML_buBlip );
3196 mpFS->startElementNS(XML_a, XML_buClr);
3198 mpFS->endElementNS( XML_a, XML_buClr );
3201 if( nBulletRelSize && nBulletRelSize != 100 )
3202 mpFS->singleElementNS( XML_a, XML_buSzPct,
3203 XML_val, OString::number(std::clamp<sal_Int32>(1000*nBulletRelSize, 25000, 400000)));
3208 mpFS->singleElementNS( XML_a, XML_buFont,
3209 XML_typeface, aFontDesc.Name,
3213 OUString aAutoNumType =
GetAutoNumType( nNumberingType, bSDot, bPBehind, bPBoth );
3215 if (!aAutoNumType.isEmpty())
3217 mpFS->singleElementNS(XML_a, XML_buAutoNum,
3223 mpFS->singleElementNS(XML_a, XML_buChar, XML_char, OUString(aBulletChar));
3230 css::uno::Sequence<css::style::TabStop> aTabStops;
3232 aTabStops = *o3tl::doAccess<css::uno::Sequence<css::style::TabStop>>(
mAny);
3234 if (aTabStops.getLength() > 0)
3235 mpFS->startElementNS(XML_a, XML_tabLst);
3237 for (
const css::style::TabStop& rTabStop : std::as_const(aTabStops))
3241 switch (rTabStop.Alignment)
3243 case css::style::TabAlign_DECIMAL:
3246 case css::style::TabAlign_RIGHT:
3249 case css::style::TabAlign_CENTER:
3252 case css::style::TabAlign_LEFT:
3256 mpFS->singleElementNS(XML_a, XML_tab, XML_algn, sAlignment, XML_pos, sPosition);
3258 if (aTabStops.getLength() > 0)
3259 mpFS->endElementNS(XML_a, XML_tabLst);
3267 uno::Reference<lang::XServiceInfo> xServiceInfo(rXShape, uno::UNO_QUERY_THROW);
3268 bRet = xServiceInfo->supportsService(
"com.sun.star.drawing.GroupShape");
3275 if (nLevel < 0 || !
GetProperty(rXPropSet,
"NumberingRules"))
3280 if (!(
mAny >>= rXIndexAccess) || nLevel >= rXIndexAccess->getCount())
3283 SAL_INFO(
"oox.shape",
"numbering rules");
3286 rXIndexAccess->getByIndex(nLevel) >>= aPropertySequence;
3288 if (!aPropertySequence.hasElements())
3291 for (
const PropertyValue& rPropValue : std::as_const(aPropertySequence) )
3296 return *o3tl::doAccess<sal_Int32>(rPropValue.Value);
3304 const char* sAlignment =
nullptr;
3306 switch( nAlignment )
3308 case style::ParagraphAdjust_CENTER:
3311 case style::ParagraphAdjust_RIGHT:
3314 case style::ParagraphAdjust_BLOCK:
3315 sAlignment =
"just";
3326 if( rSpacing.Mode == LineSpacingMode::PROP )
3328 mpFS->singleElementNS( XML_a, XML_spcPct,
3329 XML_val, OString::number(
static_cast<sal_Int32
>(rSpacing.Height)*1000));
3331 else if (rSpacing.Mode == LineSpacingMode::MINIMUM
3332 && fFirstCharHeight >
static_cast<float>(rSpacing.Height) * 0.001 * 72.0 / 2.54)
3335 mpFS->singleElementNS(XML_a, XML_spcPct, XML_val,
3336 OString::number(
static_cast<sal_Int32
>(100000)));
3340 mpFS->singleElementNS( XML_a, XML_spcPts,
3341 XML_val, OString::number(std::lround(rSpacing.Height / 25.4 * 72)));
3349 PropertyState eState;
3351 if( !rXPropSet.is() || !rXPropState.is() )
3354 sal_Int16 nLevel = -1;
3358 bool bWriteNumbering =
true;
3359 bool bForceZeroIndent =
false;
3365 bool bNumberingOnThisLevel =
false;
3370 for (
const PropertyValue& rRule : rNumRuleOfLevel)
3371 if (rRule.Name ==
"NumberingType" && rRule.Value.hasValue())
3372 bNumberingOnThisLevel = rRule.Value.get<sal_uInt16>() != style::NumberingType::NUMBER_NONE;
3375 const bool bIsNumberingVisible = rXPropSet->getPropertyValue(
"NumberingIsNumber").get<
bool>();
3376 const bool bIsLineEmpty = !xParaText->getString().getLength();
3378 bWriteNumbering = !bIsLineEmpty && bIsNumberingVisible && (nLevel != -1);
3379 bForceZeroIndent = (!bIsNumberingVisible || bIsLineEmpty || !bNumberingOnThisLevel);
3384 sal_Int16 nTmp = sal_Int16(style::ParagraphAdjust_LEFT);
3387 style::ParagraphAdjust nAlignment =
static_cast<style::ParagraphAdjust
>(nTmp);
3389 bool bHasLinespacing =
false;
3390 LineSpacing aLineSpacing;
3392 && (
mAny >>= aLineSpacing)
3393 && (eState == beans::PropertyState_DIRECT_VALUE ||
3395 aLineSpacing.Mode != LineSpacingMode::PROP || aLineSpacing.Height != 100))
3396 bHasLinespacing =
true;
3401 sal_Int16 nWritingMode;
3402 if( (
mAny >>= nWritingMode ) && nWritingMode == text::WritingMode2::RL_TB )
3408 sal_Int32 nParaLeftMargin = 0;
3409 sal_Int32 nParaFirstLineIndent = 0;
3412 mAny >>= nParaLeftMargin;
3413 if (
GetProperty(rXPropSet,
"ParaFirstLineIndent"))
3414 mAny >>= nParaFirstLineIndent;
3416 sal_Int32 nParaTopMargin = 0;
3417 sal_Int32 nParaBottomMargin = 0;
3420 mAny >>= nParaTopMargin;
3422 mAny >>= nParaBottomMargin;
3427 if (bWriteNumbering && !bForceZeroIndent)
3430 || nAlignment != style::ParagraphAdjust_LEFT
3431 || bHasLinespacing))
3435 sal_Int32 nParaDefaultTabSize = 0;
3436 if (
GetProperty(rXPropSet,
"ParaTabStopDefaultDistance"))
3437 mAny >>= nParaDefaultTabSize;
3439 if (nParaLeftMargin)
3440 mpFS->startElementNS( XML_a, nElement,
3448 mpFS->startElementNS( XML_a, nElement,
3457 if( bHasLinespacing )
3459 mpFS->startElementNS(XML_a, XML_lnSpc);
3461 mpFS->endElementNS( XML_a, XML_lnSpc );
3464 if( nParaTopMargin != 0 )
3466 mpFS->startElementNS(XML_a, XML_spcBef);
3468 mpFS->singleElementNS( XML_a, XML_spcPts,
3469 XML_val, OString::number(std::lround(nParaTopMargin / 25.4 * 72)));
3471 mpFS->endElementNS( XML_a, XML_spcBef );
3474 if( nParaBottomMargin != 0 )
3476 mpFS->startElementNS(XML_a, XML_spcAft);
3478 mpFS->singleElementNS( XML_a, XML_spcPts,
3479 XML_val, OString::number(std::lround(nParaBottomMargin / 25.4 * 72)));
3481 mpFS->endElementNS( XML_a, XML_spcAft );
3484 if (!bWriteNumbering)
3485 mpFS->singleElementNS(XML_a, XML_buNone);
3492 if( nElement != XML_lvl1pPr )
3493 mpFS->endElementNS( XML_a, nElement );
3499 bool& rbOverridingCharHeight, sal_Int32& rnCharHeight,
3500 const css::uno::Reference<css::beans::XPropertySet>& rXShapePropSet)
3507 if (!xEnumeration.is())
3513 if (!xEnumeration->hasMoreElements())
3516 Any aAny(xEnumeration->nextElement());
3519 float fFirstCharHeight = rnCharHeight / 1000.;
3522 = xFirstRunPropSet->getPropertySetInfo();
3524 if (xFirstRunPropSetInfo->hasPropertyByName(
"CharHeight"))
3525 fFirstCharHeight = xFirstRunPropSet->getPropertyValue(
"CharHeight").get<
float>();
3527 mpFS->startElementNS(XML_a, XML_lstStyle);
3529 mpFS->startElementNS(XML_a, XML_lvl1pPr);
3530 WriteRunProperties(xFirstRunPropSet,
false, XML_defRPr,
true, rbOverridingCharHeight,
3531 rnCharHeight,
GetScriptType(rRun->getString()), rXShapePropSet);
3532 mpFS->endElementNS(XML_a, XML_lvl1pPr);
3533 mpFS->endElementNS(XML_a, XML_lstStyle);
3538 bool& rbOverridingCharHeight, sal_Int32& rnCharHeight,
3539 const css::uno::Reference< css::beans::XPropertySet >& rXShapePropSet)
3546 if( !enumeration.is() )
3549 mpFS->startElementNS(XML_a, XML_p);
3551 bool bPropertiesWritten =
false;
3552 while( enumeration->hasMoreElements() )
3555 Any any ( enumeration->nextElement() );
3559 if( !bPropertiesWritten )
3561 float fFirstCharHeight = rnCharHeight / 1000.;
3564 if( xFirstRunPropSetInfo->hasPropertyByName(
"CharHeight") )
3566 fFirstCharHeight = xFirstRunPropSet->getPropertyValue(
"CharHeight").get<
float>();
3567 rnCharHeight = 100 * fFirstCharHeight;
3568 rbOverridingCharHeight =
true;
3571 bPropertiesWritten =
true;
3573 WriteRun(
run, rbOverridingCharHeight, rnCharHeight, rXShapePropSet);
3577 sal_Int16 nDummy = -1;
3579 rnCharHeight, nDummy, rXShapePropSet);
3581 mpFS->endElementNS( XML_a, XML_p );
3586 bool bResult(
false);
3587 if (rXShapePropSet.is())
3590 if (
GetProperty(rXShapePropSet,
"CustomShapeGeometry"))
3592 mAny >>= aCustomShapeGeometryProps;
3593 uno::Sequence<beans::PropertyValue> aTextPathSeq;
3594 for (
const auto& rProp : std::as_const(aCustomShapeGeometryProps))
3596 if (rProp.Name ==
"TextPath")
3598 rProp.Value >>= aTextPathSeq;
3599 for (
const auto& rTextPathItem : std::as_const(aTextPathSeq))
3601 if (rTextPathItem.Name ==
"TextPath")
3603 rTextPathItem.Value >>= bResult;
3616 sal_Int32 nXmlNamespace,
bool bWritePropertiesAsLstStyles)
3619 uno::Reference<XText> xXText(rXIface, UNO_QUERY);
3623 uno::Reference<drawing::XShape> xShape(rXIface, UNO_QUERY);
3624 uno::Reference<XPropertySet> rXPropSet(rXIface, UNO_QUERY);
3626 constexpr const sal_Int32 constDefaultLeftRightInset = 254;
3627 constexpr const sal_Int32 constDefaultTopBottomInset = 127;
3628 sal_Int32 nLeft = constDefaultLeftRightInset;
3629 sal_Int32 nRight = constDefaultLeftRightInset;
3630 sal_Int32 nTop = constDefaultTopBottomInset;
3631 sal_Int32 nBottom = constDefaultTopBottomInset;
3647 sal_Int32 nTextHeight = xShape->getSize().Height;
3660 if (nTop + nBottom >= nTextHeight)
3665 std::swap(nTop, nBottom);
3666 nTop = nTextHeight - nTop;
3667 nBottom = nTextHeight - nBottom;
3671 std::optional<OString> sWritingMode;
3676 sWritingMode =
"eaVert";
3680 sal_Int16 nWritingMode;
3681 if (
mAny >>= nWritingMode)
3683 if (nWritingMode == text::WritingMode2::TB_RL)
3684 sWritingMode =
"eaVert";
3685 else if (nWritingMode == text::WritingMode2::BT_LR)
3686 sWritingMode =
"vert270";
3687 else if (nWritingMode == text::WritingMode2::TB_RL90)
3688 sWritingMode =
"vert";
3689 else if (nWritingMode == text::WritingMode2::TB_LR)
3690 sWritingMode =
"mongolianVert";
3696 uno::Sequence<beans::PropertyValue> aTextPathSeq;
3697 bool bScaleX(
false);
3698 OUString sShapeType(
"non-primitive");
3699 OUString sMSWordPresetTextWarp;
3700 sal_Int32 nTextPreRotateAngle = 0;
3701 std::optional<Degree100> nTextRotateAngleDeg100;
3703 if (
GetProperty(rXPropSet,
"CustomShapeGeometry"))
3706 if (
mAny >>= aProps )
3708 for (
const auto& rProp : std::as_const(aProps) )
3710 if (rProp.Name ==
"TextPreRotateAngle")
3711 rProp.Value >>= nTextPreRotateAngle;
3712 else if (rProp.Name ==
"AdjustmentValues")
3713 rProp.Value >>= aAdjustmentSeq;
3714 else if (rProp.Name ==
"TextRotateAngle")
3716 double fTextRotateAngle = 0;
3717 rProp.Value >>= fTextRotateAngle;
3718 nTextRotateAngleDeg100 =
Degree100(std::lround(fTextRotateAngle * 100.0));
3720 else if (rProp.Name ==
"Type")
3721 rProp.Value >>= sShapeType;
3722 else if (rProp.Name ==
"TextPath")
3724 rProp.Value >>= aTextPathSeq;
3725 for (
const auto& rTextPathItem : std::as_const(aTextPathSeq))
3727 if (rTextPathItem.Name ==
"ScaleX")
3728 rTextPathItem.Value >>= bScaleX;
3731 else if (rProp.Name ==
"PresetTextWarp")
3732 rProp.Value >>= sMSWordPresetTextWarp;
3745 uno::Reference<beans::XPropertySet> xPropSet(xTextFrame, uno::UNO_QUERY);
3746 auto aAny = xPropSet->getPropertyValue(
"WritingMode");
3747 sal_Int16 nWritingMode;
3748 if (aAny >>= nWritingMode)
3750 switch (nWritingMode)
3752 case WritingMode2::TB_RL:
3753 sWritingMode =
"eaVert";
3755 case WritingMode2::BT_LR:
3756 sWritingMode =
"vert270";
3758 case WritingMode2::TB_RL90:
3759 sWritingMode =
"vert";
3761 case WritingMode2::TB_LR:
3762 sWritingMode =
"mongolianVert";
3774 std::optional<OUString> sHorzOverflow;
3775 std::optional<OUString> sVertOverflow;
3776 bool bUpright =
false;
3777 std::optional<OString> isUpright;
3778 if (rXPropSet->getPropertySetInfo()->hasPropertyByName(
"InteropGrabBag"))
3780 uno::Sequence<beans::PropertyValue> aGrabBag;
3781 rXPropSet->getPropertyValue(
"InteropGrabBag") >>= aGrabBag;
3782 for (
const auto& aProp : std::as_const(aGrabBag))
3784 if (aProp.Name ==
"Upright")
3786 aProp.Value >>= bUpright;
3787 isUpright = OString(bUpright ?
"1" :
"0");
3789 else if (aProp.Name ==
"horzOverflow")
3792 aProp.Value >>= sValue;
3793 sHorzOverflow = sValue;
3795 else if (aProp.Name ==
"vertOverflow")
3798 aProp.Value >>= sValue;
3799 sVertOverflow = sValue;
3807 if (sPresetWarp.isEmpty())
3808 sPresetWarp = bIsFontworkShape ? std::u16string_view(
u"textPlain") : std::u16string_view(
u"textNoShape");
3810 bool bFromWordArt = !bScaleX
3811 && ( sPresetWarp ==
"textArchDown" || sPresetWarp ==
"textArchUp"
3812 || sPresetWarp ==
"textButton" || sPresetWarp ==
"textCircle");
3825 Degree100 nShapeRotateAngleDeg100(0_deg100);
3830 bool bWasAngleChanged
3831 = (nShapeRotateAngleDeg100 > 4500_deg100 && nShapeRotateAngleDeg100 <= 13500_deg100)
3832 || (nShapeRotateAngleDeg100 > 22500_deg100
3833 && nShapeRotateAngleDeg100 <= 31500_deg100);
3834 if (bWasAngleChanged)
3836 nTextRotateAngleDeg100 = nTextRotateAngleDeg100.value_or(0_deg100) + 9000_deg100;
3837 nTextPreRotateAngle -= 90;
3843 Degree100 nAngleSum = nShapeRotateAngleDeg100 + nTextRotateAngleDeg100.value_or(0_deg100);
3846 nTextRotateAngleDeg100.reset();
3852 if (bWasAngleChanged)
3854 nTextPreRotateAngle += 90;
3855 nTextRotateAngleDeg100 = nTextRotateAngleDeg100.value_or(0_deg100) - 9000_deg100;
3862 if (nTextPreRotateAngle != 0 && !sWritingMode)
3864 if (nTextPreRotateAngle == -90 || nTextPreRotateAngle == 270)
3865 sWritingMode =
"vert";
3866 else if (nTextPreRotateAngle == -270 || nTextPreRotateAngle == 90)
3867 sWritingMode =
"vert270";
3868 else if (nTextPreRotateAngle == -180 || nTextPreRotateAngle == 180)
3870#if defined __GNUC__ && !defined __clang__ && __GNUC__ == 12
3871#pragma GCC diagnostic push
3872#pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
3874 nTextRotateAngleDeg100
3875 =
NormAngle18000(nTextRotateAngleDeg100.value_or(0_deg100) + 18000_deg100);
3876#if defined __GNUC__ && !defined __clang__ && __GNUC__ == 12
3877#pragma GCC diagnostic pop
3882 SAL_WARN(
"oox",
"unsuitable value for TextPreRotateAngle:" << nTextPreRotateAngle);
3884 else if (nTextPreRotateAngle != 0 && sWritingMode && sWritingMode.value() ==
"eaVert")
3895 if (sWritingMode.value() ==
"vert" || sWritingMode.value() ==
"eaVert")
3897 sal_Int32 nHelp = nLeft;
3903 else if (sWritingMode.value() ==
"vert270")
3905 sal_Int32 nHelp = nLeft;
3911 else if (sWritingMode.value() ==
"mongolianVert")
3918 std::optional<OString> sTextRotateAngleMSUnit;
3919 if (nTextRotateAngleDeg100.has_value())
3920#if defined __GNUC__ && !defined __clang__ && __GNUC__ == 12
3921#pragma GCC diagnostic push
3922#pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
3924 sTextRotateAngleMSUnit
3926#if defined __GNUC__ && !defined __clang__ && __GNUC__ == 12
3927#pragma GCC diagnostic pop
3933 TextVerticalAdjust eVerticalAlignment(TextVerticalAdjust_TOP);
3935 mAny >>= eVerticalAlignment;
3936 TextHorizontalAdjust eHorizontalAlignment(TextHorizontalAdjust_CENTER);
3937 if (
GetProperty(rXPropSet,
"TextHorizontalAdjust"))
3938 mAny >>= eHorizontalAlignment;
3940 const char* sAnchor =
nullptr;
3941 bool bAnchorCtr =
false;
3942 if (sWritingMode.has_value()
3943 && (sWritingMode.value() ==
"eaVert" || sWritingMode.value() ==
"mongolianVert"))
3945 bAnchorCtr = eVerticalAlignment == TextVerticalAdjust_CENTER
3946 || eVerticalAlignment == TextVerticalAdjust_BOTTOM
3947 || eVerticalAlignment == TextVerticalAdjust_BLOCK;
3948 switch (eHorizontalAlignment)
3950 case TextHorizontalAdjust_CENTER:
3953 case TextHorizontalAdjust_LEFT:
3954 sAnchor = sWritingMode.value() ==
"eaVert" ?
"b" :
"t";
3956 case TextHorizontalAdjust_RIGHT:
3958 sAnchor = sWritingMode.value() ==
"eaVert" ?
"t" :
"b";
3964 bAnchorCtr = eHorizontalAlignment == TextHorizontalAdjust_CENTER
3965 || eHorizontalAlignment == TextHorizontalAdjust_RIGHT;
3969 bool bHasWrap =
false;
3980 const char* pWrap = (bHasWrap && !bWrap) || bIsFontworkShape ?
"none" :
nullptr;
3986 uno::Reference<lang::XServiceInfo> xServiceInfo(rXIface, uno::UNO_QUERY);
3987 if ((xServiceInfo.is() && xServiceInfo->supportsService(
"com.sun.star.drawing.TextShape"))
3988 || bIsFontworkShape)
3992 sal_Int16 nCols = 0;
3993 sal_Int32 nColSpacing = -1;
3996 if (css::uno::Reference<css::text::XTextColumns> xCols{
mAny, css::uno::UNO_QUERY })
3998 nCols = xCols->getColumnCount();
3999 if (css::uno::Reference<css::beans::XPropertySet> xProps{
mAny,
4000 css::uno::UNO_QUERY })
4003 mAny >>= nColSpacing;
4008 if (!sVertOverflow &&
GetProperty(rXPropSet,
"TextClipVerticalOverflow") &&
mAny.get<
bool>())
4010 sVertOverflow =
"clip";
4013 mpFS->startElementNS( (nXmlNamespace ? nXmlNamespace : XML_a), XML_bodyPr,
4017 XML_horzOverflow, sHorzOverflow,
4018 XML_vertOverflow, sVertOverflow,
4024 XML_anchor, sAnchor,
4026 XML_vert, sWritingMode,
4027 XML_upright, isUpright,
4028 XML_rot, sTextRotateAngleMSUnit);
4030 if (bIsFontworkShape)
4032 if (aAdjustmentSeq.hasElements())
4034 mpFS->startElementNS(XML_a, XML_prstTxWarp, XML_prst, sPresetWarp);
4035 mpFS->startElementNS(XML_a, XML_avLst);
4036 bool bHasTwoHandles(
4037 sPresetWarp ==
"textArchDownPour" || sPresetWarp ==
"textArchUpPour"
4038 || sPresetWarp ==
"textButtonPour" || sPresetWarp ==
"textCirclePour"
4039 || sPresetWarp ==
"textDoubleWave1" || sPresetWarp ==
"textWave1"
4040 || sPresetWarp ==
"textWave2" || sPresetWarp ==
"textWave4");
4041 for (sal_Int32
i = 0, nElems = aAdjustmentSeq.getLength();
i < nElems; ++
i )
4043 OString
sName =
"adj" + (bHasTwoHandles ? OString::number(
i + 1) : OString());
4045 if (aAdjustmentSeq[
i].
Value.getValueTypeClass() == TypeClass_DOUBLE)
4046 aAdjustmentSeq[
i].Value >>= fValue;
4049 sal_Int32 nNumber(0);
4050 aAdjustmentSeq[
i].Value >>= nNumber;
4051 fValue =
static_cast<double>(nNumber);
4056 if (sPresetWarp ==
"textArchDown" || sPresetWarp ==
"textArchUp"
4057 || sPresetWarp ==
"textButton" || sPresetWarp ==
"textCircle"
4059 && (sPresetWarp ==
"textArchDownPour" || sPresetWarp ==
"textArchUpPour"
4060 || sPresetWarp ==
"textButtonPour" || sPresetWarp ==
"textCirclePour")))
4067 && (sPresetWarp ==
"textDoubleWave1" || sPresetWarp ==
"textWave1"
4068 || sPresetWarp ==
"textWave2" || sPresetWarp ==
"textWave4"))
4070 fValue = fValue / 0.216 - 50000.0;
4073 && (sPresetWarp ==
"textArchDownPour"
4074 || sPresetWarp ==
"textArchUpPour"
4075 || sPresetWarp ==
"textButtonPour"
4076 || sPresetWarp ==
"textCirclePour"))
4084 OString sFmla =
"val " + OString::number(std::lround(fValue));
4085 mpFS->singleElementNS(XML_a, XML_gd, XML_name,
sName, XML_fmla, sFmla);
4087 if (!bHasTwoHandles)
4090 mpFS->endElementNS(XML_a, XML_avLst);
4091 mpFS->endElementNS(XML_a, XML_prstTxWarp);
4095 mpFS->singleElementNS(XML_a, XML_prstTxWarp, XML_prst, sPresetWarp);
4101 if (!sMSWordPresetTextWarp.isEmpty())
4102 mpFS->singleElementNS(XML_a, XML_prstTxWarp, XML_prst, sMSWordPresetTextWarp);
4108 bool bTextAutoGrowHeight =
false;
4110 if (pSdrObjCustomShape &&
GetProperty(rXPropSet,
"TextAutoGrowHeight"))
4112 mAny >>= bTextAutoGrowHeight;
4114 mpFS->singleElementNS(XML_a, (bTextAutoGrowHeight ? XML_spAutoFit : XML_noAutofit));
4118 TextFitToSizeType eFit = TextFitToSizeType_NONE;
4122 if (eFit == TextFitToSizeType_AUTOFIT)
4124 const sal_Int32 MAX_SCALE_VAL = 100000;
4125 sal_Int32 nFontScale = MAX_SCALE_VAL;
4126 sal_Int32 nSpacingReduction = 0;
4133 nFontScale = sal_Int32(pTextObject->
GetFontScale() * 1000.0);
4134 nSpacingReduction = sal_Int32((100.0 - pTextObject->
GetSpacingScale()) * 1000.0);
4138 bool bExportFontScale =
false;
4139 if (nFontScale < MAX_SCALE_VAL && nFontScale > 0)
4140 bExportFontScale =
true;
4142 bool bExportSpaceReduction =
false;
4143 if (nSpacingReduction < MAX_SCALE_VAL && nSpacingReduction > 0)
4144 bExportSpaceReduction =
true;
4146 mpFS->singleElementNS(XML_a, XML_normAutofit,
4148 XML_lnSpcReduction,
sax_fastparser::UseIf(OString::number(nSpacingReduction), bExportSpaceReduction));
4153 bool bTextAutoGrowHeight =
false;
4155 mAny >>= bTextAutoGrowHeight;
4156 mpFS->singleElementNS(XML_a, (bTextAutoGrowHeight ? XML_spAutoFit : XML_noAutofit));
4162 mpFS->endElementNS((nXmlNamespace ? nXmlNamespace : XML_a), XML_bodyPr);
4166 if( !access.is() || !bText )
4170 if( !enumeration.is() )
4177 std::vector<beans::PropertyValue> aOldCharFillPropVec;
4178 if (bIsFontworkShape)
4187 std::vector<beans::PropertyValue> aExportCharFillPropVec;
4193 std::vector<beans::PropertyValue> aUpdatePropVec;
4218 if (bIsFontworkShape)
4223 bool bOverridingCharHeight =
false;
4224 sal_Int32 nCharHeight = -1;
4225 bool bFirstParagraph =
true;
4229 if(xXText->getString().isEmpty() && enumeration->hasMoreElements())
4231 Any aAny (enumeration->nextElement());
4233 if( aAny >>= xParagraph )
4235 mpFS->startElementNS(XML_a, XML_p);
4237 sal_Int16 nDummy = -1;
4239 bOverridingCharHeight, nCharHeight, nDummy, rXPropSet);
4240 mpFS->endElementNS(XML_a, XML_p);
4245 while( enumeration->hasMoreElements() )
4248 Any any ( enumeration->nextElement() );
4252 if (bFirstParagraph && bWritePropertiesAsLstStyles)
4256 bFirstParagraph =
false;
4263 mpFS->startElementNS(XML_a, XML_prstGeom, XML_prst, pShape);
4264 if ( !rAvList.empty() )
4267 mpFS->startElementNS(XML_a, XML_avLst);
4268 for (
auto const& elem : rAvList)
4270 OString
sName =
"adj" + ( ( elem.first > 0 ) ? OString::number(elem.first) : OString() );
4271 OString sFmla =
"val " + OString::number( elem.second );
4273 mpFS->singleElementNS(XML_a, XML_gd, XML_name,
sName, XML_fmla, sFmla);
4275 mpFS->endElementNS( XML_a, XML_avLst );
4278 mpFS->singleElementNS(XML_a, XML_avLst);
4280 mpFS->endElementNS( XML_a, XML_prstGeom );
4285 mpFS->startElementNS(XML_a, XML_prstGeom, XML_prst, pShape);
4286 mpFS->singleElementNS(XML_a, XML_avLst);
4287 mpFS->endElementNS( XML_a, XML_prstGeom );
4292 std::map< OString, std::vector<OString> > aRet;
4294 OUString aPath(
"$BRAND_BASE_DIR/" LIBO_SHARE_FOLDER
"/filter/oox-drawingml-adj-names");
4295 rtl::Bootstrap::expandMacros(aPath);
4298 SAL_WARN(
"oox.shape",
"failed to open oox-drawingml-adj-names");
4299 OStringBuffer aLine;
4300 bool bNotDone = aStream.
ReadLine(aLine);
4306 OString aValue( std::string_view(aLine).substr(
nIndex) );
4307 aRet[aKey].push_back(aValue);
4308 bNotDone = aStream.
ReadLine(aLine);
4315 static std::map< OString, std::vector<OString> > aAdjMap =
lcl_getAdjNames();
4317 std::vector<OString> aAdjustments;
4318 if (aAdjMap.find(pShape) != aAdjMap.end())
4319 aAdjustments = aAdjMap[pShape];
4321 mpFS->startElementNS(XML_a, XML_prstGeom, XML_prst, pShape);
4322 mpFS->startElementNS(XML_a, XML_avLst);
4324 Sequence< drawing::EnhancedCustomShapeAdjustmentValue > aAdjustmentSeq;
4325 if ( ( rProp.Value >>= aAdjustmentSeq )
4326 && eShapeType != mso_sptActionButtonForwardNext
4327 && eShapeType != mso_sptActionButtonBackPrevious
4331 SAL_INFO(
"oox.shape",
"adj seq len: " << aAdjustmentSeq.getLength());
4332 sal_Int32 nAdjustmentsWhichNeedsToBeConverted = 0;
4333 if ( bPredefinedHandlesUsed )
4341 for (sal_Int32
i = 0; i < static_cast<sal_Int32>(aAdjustments.size());
i++)
4346 OString aAdjName = aAdjustmentSeq[
i].Name.isEmpty()
4348 : aAdjustmentSeq[
i].Name.toUtf8();
4350 mpFS->singleElementNS( XML_a, XML_gd,
4352 XML_fmla,
"val " + OString::number(nValue));
4358 mpFS->endElementNS( XML_a, XML_avLst );
4359 mpFS->endElementNS( XML_a, XML_prstGeom );
4365FindNextCommandEndSubpath(
const sal_Int32 nStart,
4366 const uno::Sequence<drawing::EnhancedCustomShapeSegment>& rSegments)
4368 sal_Int32
i = nStart < 0 ? 0 : nStart;
4369 while (
i < rSegments.getLength() && rSegments[
i].Command != ENDSUBPATH)
4374bool HasCommandInSubPath(
const sal_Int16 nCommand,
const sal_Int32 nFirst,
const sal_Int32 nLast,
4375 const uno::Sequence<drawing::EnhancedCustomShapeSegment>& rSegments)
4377 for (sal_Int32
i = nFirst < 0 ? 0 : nFirst;
i <= nLast &&
i < rSegments.getLength();
i++)
4379 if (rSegments[
i].Command == nCommand)
4387void getEllipsePointAndAngleFromRayPoint(
double& rfAngleDeg,
double& rfSx,
double& rfSy,
4388 const double fWR,
const double fHR,
const double fCx,
4389 const double fCy,
const double fRayPx,
const double fRayPy)
4400 double fCircleMathAngle = atan2(-fWR / fHR * (fRayPy - fCy), fRayPx - fCx);
4402 double fPointMathEllipse_x = fWR * cos(fCircleMathAngle);
4403 double fPointMathEllipse_y = fHR * sin(fCircleMathAngle);
4405 double fEllipseMathAngle = atan2(fPointMathEllipse_y, fPointMathEllipse_x);
4408 rfSx = fPointMathEllipse_x + fCx;
4409 rfSy = -fPointMathEllipse_y + fCy;
4413void getEllipsePointFromViewAngle(
double& rfSx,
double& rfSy,
const double fWR,
const double fHR,
4414 const double fCx,
const double fCy,
const double fViewAngleDeg)
4425 double fRadius = 1.0 / std::hypot(fX, fY);
4431sal_Int32 GetCustomGeometryPointValue(
const css::drawing::EnhancedCustomShapeParameter& rParam,
4433 const bool bReplaceGeoWidth,
const bool bReplaceGeoHeight)
4435 double fValue = 0.0;
4436 rCustomShape2d.
GetParameter(fValue, rParam, bReplaceGeoWidth, bReplaceGeoHeight);
4437 sal_Int32
nValue(std::lround(fValue));
4457 std::vector<Guide>& rGuideList, TextAreaRect& rTextAreaRect)
4461 if (aTextAreaLO == aLogicRectLO)
4463 rTextAreaRect.left =
"l";
4464 rTextAreaRect.top =
"t";
4465 rTextAreaRect.right =
"r";
4466 rTextAreaRect.bottom =
"b";
4477 const sal_Int32 nWidth = aLogicRectLO.
Right() - aLogicRectLO.
Left();
4481 aGuide.sName =
"textAreaLeft";
4482 sal_Int32 nHelp = aTextAreaLO.
Left() - aLogicRectLO.
Left();
4484 aGuide.sFormula =
"*/ " + sLeft +
" w " + sWidth;
4485 rTextAreaRect.left = aGuide.sName;
4486 rGuideList.push_back(aGuide);
4489 aGuide.sName =
"textAreaRight";
4490 nHelp = aTextAreaLO.
Right() - aLogicRectLO.
Left();
4492 aGuide.sFormula =
"*/ " + sRight +
" w " + sWidth;
4493 rTextAreaRect.right = aGuide.sName;
4494 rGuideList.push_back(aGuide);
4497 const sal_Int32 nHeight = aLogicRectLO.
Bottom() - aLogicRectLO.
Top();
4501 aGuide.sName =
"textAreaTop";
4502 nHelp = aTextAreaLO.
Top() - aLogicRectLO.
Top();
4504 aGuide.sFormula =
"*/ " + sTop +
" h " + sHeight;
4505 rTextAreaRect.top = aGuide.sName;
4506 rGuideList.push_back(aGuide);
4509 aGuide.sName =
"textAreaBottom";
4510 nHelp = aTextAreaLO.
Bottom() - aLogicRectLO.
Top();
4512 aGuide.sFormula =
"*/ " + sBottom +
" h " + sHeight;
4513 rTextAreaRect.bottom = aGuide.sName;
4514 rGuideList.push_back(aGuide);
4524 uno::Reference< beans::XPropertySet > aXPropSet;
4527 if ( ! (aAny >>= aXPropSet) )
4532 aAny = aXPropSet->getPropertyValue(
"CustomShapeGeometry" );
4536 catch( const ::uno::Exception& )
4541 auto pGeometrySeq = o3tl::tryAccess<uno::Sequence<beans::PropertyValue>>(aAny);
4545 auto pPathProp = std::find_if(std::cbegin(*pGeometrySeq), std::cend(*pGeometrySeq),
4546 [](
const PropertyValue& rProp) {
return rProp.Name ==
"Path"; });
4547 if (pPathProp == std::cend(*pGeometrySeq))
4550 uno::Sequence<beans::PropertyValue> aPathProp;
4551 pPathProp->
Value >>= aPathProp;
4553 uno::Sequence<drawing::EnhancedCustomShapeParameterPair> aPairs;
4554 uno::Sequence<drawing::EnhancedCustomShapeSegment>
aSegments;
4555 uno::Sequence<awt::Size> aPathSize;
4556 bool bReplaceGeoWidth =
false;
4557 bool bReplaceGeoHeight =
false;
4558 for (
const beans::PropertyValue& rPathProp : std::as_const(aPathProp))
4560 if (rPathProp.Name ==
"Coordinates")
4561 rPathProp.Value >>= aPairs;
4562 else if (rPathProp.Name ==
"Segments")
4564 else if (rPathProp.Name ==
"SubViewSize")
4565 rPathProp.Value >>= aPathSize;
4566 else if (rPathProp.Name ==
"StretchX")
4567 bReplaceGeoWidth =
true;
4568 else if (rPathProp.Name ==
"StretchY")
4569 bReplaceGeoHeight =
true;
4572 if ( !aPairs.hasElements() )
4577 aSegments = uno::Sequence<drawing::EnhancedCustomShapeSegment>
4581 static_cast<sal_Int16
>(std::min( aPairs.getLength() - 1, sal_Int32(32767) )) },
4582 { CLOSESUBPATH, 0 },
4587 int nExpectedPairCount = std::accumulate(std::cbegin(
aSegments), std::cend(
aSegments), 0,
4588 [](
const int nSum,
const drawing::EnhancedCustomShapeSegment& rSegment) {
return nSum + rSegment.Count; });
4590 if ( nExpectedPairCount > aPairs.getLength() )
4592 SAL_WARN(
"oox.shape",
"Segments need " << nExpectedPairCount <<
" coordinates, but Coordinates have only " << aPairs.getLength() <<
" pairs.");
4600 TextAreaRect aTextAreaRect;
4601 std::vector<Guide> aGuideList;
4602 prepareTextArea(aCustomShape2d, aGuideList, aTextAreaRect);
4603 mpFS->startElementNS(XML_a, XML_custGeom);
4604 mpFS->singleElementNS(XML_a, XML_avLst);
4605 if (aGuideList.empty())
4607 mpFS->singleElementNS(XML_a, XML_gdLst);
4611 mpFS->startElementNS(XML_a, XML_gdLst);
4612 for (
auto const& elem : aGuideList)
4614 mpFS->singleElementNS(XML_a, XML_gd, XML_name, elem.sName, XML_fmla, elem.sFormula);
4616 mpFS->endElementNS(XML_a, XML_gdLst);
4618 mpFS->singleElementNS(XML_a, XML_ahLst);
4619 mpFS->singleElementNS(XML_a, XML_rect, XML_l, aTextAreaRect.left, XML_t, aTextAreaRect.top,
4620 XML_r, aTextAreaRect.right, XML_b, aTextAreaRect.bottom);
4621 mpFS->startElementNS(XML_a, XML_pathLst);
4624 bool bUseGlobalViewBox(
false);
4628 sal_Int32 nViewBoxWidth(0);
4629 sal_Int32 nViewBoxHeight(0);
4630 if (!aPathSize.hasElements())
4632 bUseGlobalViewBox =
true;
4636 auto pProp = std::find_if(
4637 std::cbegin(*pGeometrySeq), std::cend(*pGeometrySeq),
4638 [](
const beans::PropertyValue& rGeomProp) {
return rGeomProp.Name ==
"ViewBox"; });
4639 if (pProp != std::cend(*pGeometrySeq))
4641 css::awt::Rectangle aViewBox;
4642 if (pProp->Value >>= aViewBox)
4644 nViewBoxWidth = aViewBox.Width;
4645 nViewBoxHeight = aViewBox.Height;
4646 css::drawing::EnhancedCustomShapeParameter aECSP;
4647 aECSP.Type = css::drawing::EnhancedCustomShapeParameterType::NORMAL;
4648 aECSP.Value <<= nViewBoxWidth;
4650 aCustomShape2d.
GetParameter(fRetValue, aECSP,
true,
false);
4652 aECSP.Value <<= nViewBoxHeight;
4653 aCustomShape2d.
GetParameter(fRetValue, aECSP,
false,
true);
4660 if ((nViewBoxWidth == 0 && nViewBoxHeight == 0) || pProp == std::cend(*pGeometrySeq))
4664 aPairs[0].First.Value >>= nXMin;
4665 sal_Int32 nXMax = nXMin;
4667 aPairs[0].Second.Value >>= nYMin;
4668 sal_Int32 nYMax = nYMin;
4670 for (
const auto& rPair : std::as_const(aPairs))
4672 sal_Int32 nX = GetCustomGeometryPointValue(rPair.First, aCustomShape2d,
4673 bReplaceGeoWidth,
false);
4674 sal_Int32 nY = GetCustomGeometryPointValue(rPair.Second, aCustomShape2d,
false,
4685 nViewBoxWidth = std::max(nXMax, nXMax - nXMin);
4686 nViewBoxHeight = std::max(nYMax, nYMax - nYMin);
4693 sal_Int32 nPairIndex = 0;
4694 sal_Int32 nPathSizeIndex = 0;
4695 sal_Int32 nSubpathStartIndex(0);
4696 sal_Int32 nSubPathIndex(0);
4701 sal_Int32 nNextNcommandIndex = FindNextCommandEndSubpath(nSubpathStartIndex,
aSegments);
4705 std::optional<OString> sFill;
4706 if (HasCommandInSubPath(NOFILL, nSubpathStartIndex, nNextNcommandIndex - 1,
aSegments))
4708 else if (HasCommandInSubPath(DARKEN, nSubpathStartIndex, nNextNcommandIndex - 1,
aSegments))
4710 else if (HasCommandInSubPath(DARKENLESS, nSubpathStartIndex, nNextNcommandIndex - 1,
4712 sFill =
"darkenLess";
4713 else if (HasCommandInSubPath(LIGHTEN, nSubpathStartIndex, nNextNcommandIndex - 1,
4716 else if (HasCommandInSubPath(LIGHTENLESS, nSubpathStartIndex, nNextNcommandIndex - 1,
4718 sFill =
"lightenLess";
4723 if (nLuminanceChange <= -40)
4725 else if (nLuminanceChange <= -10)
4726 sFill =
"darkenLess";
4727 else if (nLuminanceChange >= 40)
4729 else if (nLuminanceChange >= 10)
4730 sFill =
"lightenLess";
4733 std::optional<OString> sStroke;
4734 if (HasCommandInSubPath(NOSTROKE, nSubpathStartIndex, nNextNcommandIndex - 1,
aSegments))
4738 mpFS->startElementNS(
4739 XML_a, XML_path, XML_fill, sFill, XML_stroke, sStroke, XML_w,
4740 OString::number(bUseGlobalViewBox ? nViewBoxWidth : aPathSize[nPathSizeIndex].
Width),
4742 OString::number(bUseGlobalViewBox ? nViewBoxHeight : aPathSize[nPathSizeIndex].
Height));
4747 double fCurrentX(0.0);
4748 double fCurrentY(0.0);
4749 bool bCurrentValid(
false);
4751 for (sal_Int32 nSegmentIndex = nSubpathStartIndex; nSegmentIndex < nNextNcommandIndex;
4754 const auto& rSegment(
aSegments[nSegmentIndex]);
4755 if (rSegment.Command == CLOSESUBPATH)
4757 mpFS->singleElementNS(XML_a, XML_close);
4761 for (sal_Int32 k = 0; k < rSegment.Count && bOK; ++k)
4764 fCurrentY, bCurrentValid, aCustomShape2d,
4765 bReplaceGeoWidth, bReplaceGeoHeight);
4769 mpFS->endElementNS(XML_a, XML_path);
4775 nSubpathStartIndex = nNextNcommandIndex + 1;
4778 }
while (nSubpathStartIndex <
aSegments.getLength());
4780 mpFS->endElementNS(XML_a, XML_pathLst);
4781 mpFS->endElementNS(XML_a, XML_custGeom);
4786 const sal_Int16 eCommand,
const sal_Int32
nCount,
4787 const uno::Sequence<css::drawing::EnhancedCustomShapeParameterPair>& rPairs,
4788 sal_Int32& rnPairIndex,
double& rfCurrentX,
double& rfCurrentY,
bool& rbCurrentValid,
4790 const bool bReplaceGeoHeight)
4796 if (rnPairIndex >= rPairs.getLength())
4799 mpFS->startElementNS(XML_a, XML_moveTo);
4802 mpFS->endElementNS(XML_a, XML_moveTo);
4803 rCustomShape2d.
GetParameter(rfCurrentX, rPairs[rnPairIndex].
First, bReplaceGeoWidth,
4805 rCustomShape2d.
GetParameter(rfCurrentY, rPairs[rnPairIndex].Second,
false,
4807 rbCurrentValid =
true;
4813 if (rnPairIndex >= rPairs.getLength())
4820 mpFS->startElementNS(XML_a, XML_lnTo);
4823 mpFS->endElementNS(XML_a, XML_lnTo);
4827 mpFS->startElementNS(XML_a, XML_moveTo);
4830 mpFS->endElementNS(XML_a, XML_moveTo);
4832 rCustomShape2d.
GetParameter(rfCurrentX, rPairs[rnPairIndex].
First, bReplaceGeoWidth,
4834 rCustomShape2d.
GetParameter(rfCurrentY, rPairs[rnPairIndex].Second,
false,
4836 rbCurrentValid =
true;
4842 if (rnPairIndex + 2 >= rPairs.getLength())
4845 mpFS->startElementNS(XML_a, XML_cubicBezTo);
4851 mpFS->endElementNS(XML_a, XML_cubicBezTo);
4852 rCustomShape2d.
GetParameter(rfCurrentX, rPairs[rnPairIndex + 2].
First, bReplaceGeoWidth,
4854 rCustomShape2d.
GetParameter(rfCurrentY, rPairs[rnPairIndex + 2].Second,
false,
4856 rbCurrentValid =
true;
4860 case ANGLEELLIPSETO:
4863 if (rnPairIndex + 2 >= rPairs.getLength())
4868 rCustomShape2d.
GetParameter(fCx, rPairs[rnPairIndex].
First, bReplaceGeoWidth,
false);
4870 rCustomShape2d.
GetParameter(fCy, rPairs[rnPairIndex].Second,
false, bReplaceGeoHeight);
4874 rCustomShape2d.
GetParameter(fHR, rPairs[rnPairIndex + 1].Second,
false,
false);
4875 double fStartAngle = 0.0;
4876 rCustomShape2d.
GetParameter(fStartAngle, rPairs[rnPairIndex + 2].
First,
false,
false);
4877 double fEndAngle = 0.0;
4878 rCustomShape2d.
GetParameter(fEndAngle, rPairs[rnPairIndex + 2].Second,
false,
false);
4881 sal_Int32 nStartAng(std::lround(fStartAngle * 60000));
4882 sal_Int32 nSwingAng = 0;
4885 nSwingAng = 360 * 60000;
4888 nSwingAng = std::lround((fEndAngle - fStartAngle) * 60000);
4890 nSwingAng += 360 * 60000;
4896 getEllipsePointFromViewAngle(fSx, fSy, fWR, fHR, fCx, fCy, fStartAngle);
4900 if (eCommand == ANGLEELLIPSETO && rbCurrentValid)
4902 mpFS->startElementNS(XML_a, XML_lnTo);
4903 mpFS->singleElementNS(XML_a, XML_pt, XML_x, OString::number(std::lround(fSx)),
4904 XML_y, OString::number(std::lround(fSy)));
4905 mpFS->endElementNS(XML_a, XML_lnTo);
4909 mpFS->startElementNS(XML_a, XML_moveTo);
4910 mpFS->singleElementNS(XML_a, XML_pt, XML_x, OString::number(std::lround(fSx)),
4911 XML_y, OString::number(std::lround(fSy)));
4912 mpFS->endElementNS(XML_a, XML_moveTo);
4916 mpFS->singleElement(
4917 FSNS(XML_a, XML_arcTo), XML_wR, OString::number(std::lround(fWR)), XML_hR,
4918 OString::number(std::lround(fHR)), XML_stAng, OString::number(nStartAng),
4919 XML_swAng, OString::number(nSwingAng));
4921 getEllipsePointFromViewAngle(rfCurrentX, rfCurrentY, fWR, fHR, fCx, fCy, fEndAngle);
4922 rbCurrentValid =
true;
4928 case CLOCKWISEARCTO:
4931 if (rnPairIndex + 3 >= rPairs.getLength())
4936 rCustomShape2d.
GetParameter(fX1, rPairs[rnPairIndex].
First, bReplaceGeoWidth,
false);
4938 rCustomShape2d.
GetParameter(fY1, rPairs[rnPairIndex].Second,
false, bReplaceGeoHeight);
4940 rCustomShape2d.
GetParameter(fX2, rPairs[rnPairIndex + 1].
First, bReplaceGeoWidth,
4943 rCustomShape2d.
GetParameter(fY2, rPairs[rnPairIndex + 1].Second,
false,
4946 rCustomShape2d.
GetParameter(fX3, rPairs[rnPairIndex + 2].
First, bReplaceGeoWidth,
4949 rCustomShape2d.
GetParameter(fY3, rPairs[rnPairIndex + 2].Second,
false,
4952 rCustomShape2d.
GetParameter(fX4, rPairs[rnPairIndex + 3].
First, bReplaceGeoWidth,
4955 rCustomShape2d.
GetParameter(fY4, rPairs[rnPairIndex + 3].Second,
false,
4958 const double fWR = (fX2 - fX1) / 2.0;
4959 const double fHR = (fY2 - fY1) / 2.0;
4960 const double fCx = (fX1 + fX2) / 2.0;
4961 const double fCy = (fY1 + fY2) / 2.0;
4963 double fStartAngle = 0.0;
4966 getEllipsePointAndAngleFromRayPoint(fStartAngle, fPx, fPy, fWR, fHR, fCx, fCy, fX3,
4970 if ((eCommand == ARCTO || eCommand == CLOCKWISEARCTO) && rbCurrentValid)
4972 mpFS->startElementNS(XML_a, XML_lnTo);
4973 mpFS->singleElementNS(XML_a, XML_pt, XML_x, OString::number(std::lround(fPx)),
4974 XML_y, OString::number(std::lround(fPy)));
4975 mpFS->endElementNS(XML_a, XML_lnTo);
4979 mpFS->startElementNS(XML_a, XML_moveTo);
4980 mpFS->singleElementNS(XML_a, XML_pt, XML_x, OString::number(std::lround(fPx)),
4981 XML_y, OString::number(std::lround(fPy)));
4982 mpFS->endElementNS(XML_a, XML_moveTo);
4985 double fEndAngle = 0.0;
4986 getEllipsePointAndAngleFromRayPoint(fEndAngle, fPx, fPy, fWR, fHR, fCx, fCy, fX4, fY4);
4987 double fSwingAngle(fEndAngle - fStartAngle);
4988 const bool bIsClockwise(eCommand == CLOCKWISEARCTO || eCommand == CLOCKWISEARC);
4989 if (bIsClockwise && fSwingAngle < 0)
4990 fSwingAngle += 360.0;
4991 else if (!bIsClockwise && fSwingAngle > 0)
4992 fSwingAngle -= 360.0;
4995 const sal_Int32 nStartAng(std::lround(fStartAngle * 60000));
4996 const sal_Int32 nSwingAng(std::lround(fSwingAngle * 60000));
4997 mpFS->singleElement(
FSNS(XML_a, XML_arcTo), XML_wR, OString::number(std::lround(fWR)),
4998 XML_hR, OString::number(std::lround(fHR)), XML_stAng,
4999 OString::number(nStartAng), XML_swAng, OString::number(nSwingAng));
5002 rbCurrentValid =
true;
5006 case ELLIPTICALQUADRANTX:
5007 case ELLIPTICALQUADRANTY:
5009 if (rnPairIndex >= rPairs.getLength())
5014 rCustomShape2d.
GetParameter(fX, rPairs[rnPairIndex].
First, bReplaceGeoWidth,
false);
5016 rCustomShape2d.
GetParameter(fY, rPairs[rnPairIndex].Second,
false, bReplaceGeoHeight);
5021 double fWR = std::abs(rfCurrentX - fX);
5022 double fHR = std::abs(rfCurrentY - fY);
5023 double fStartAngle(0.0);
5024 double fSwingAngle(0.0);
5026 if ((eCommand == ELLIPTICALQUADRANTX && !(
nCount % 2))
5027 || (eCommand == ELLIPTICALQUADRANTY && (
nCount % 2)))
5030 fStartAngle = fY < rfCurrentY ? 90.0 : 270.0;
5031 const bool bClockwise = (fX < rfCurrentX && fY < rfCurrentY)
5032 || (fX > rfCurrentX && fY > rfCurrentY);
5033 fSwingAngle = bClockwise ? 90.0 : -90.0;
5038 fStartAngle = fX < rfCurrentX ? 0.0 : 180.0;
5039 const bool bClockwise = (fX < rfCurrentX && fY > rfCurrentY)
5040 || (fX > rfCurrentX && fY < rfCurrentY);
5041 fSwingAngle = bClockwise ? 90.0 : -90.0;
5043 sal_Int32 nStartAng(std::lround(fStartAngle * 60000));
5044 sal_Int32 nSwingAng(std::lround(fSwingAngle * 60000));
5045 mpFS->singleElement(
5046 FSNS(XML_a, XML_arcTo), XML_wR, OString::number(std::lround(fWR)), XML_hR,
5047 OString::number(std::lround(fHR)), XML_stAng, OString::number(nStartAng),
5048 XML_swAng, OString::number(nSwingAng));
5053 mpFS->startElementNS(XML_a, XML_moveTo);
5056 mpFS->endElementNS(XML_a, XML_moveTo);
5060 rbCurrentValid =
true;
5064 case QUADRATICCURVETO:
5066 if (rnPairIndex + 1 >= rPairs.getLength())
5069 mpFS->startElementNS(XML_a, XML_quadBezTo);
5075 mpFS->endElementNS(XML_a, XML_quadBezTo);
5076 rCustomShape2d.
GetParameter(rfCurrentX, rPairs[rnPairIndex + 1].
First, bReplaceGeoWidth,
5078 rCustomShape2d.
GetParameter(rfCurrentY, rPairs[rnPairIndex + 1].Second,
false,
5080 rbCurrentValid =
true;
5086 if (rnPairIndex + 1 >= rPairs.getLength())
5092 rCustomShape2d.
GetParameter(fHR, rPairs[rnPairIndex].Second,
false,
false);
5093 double fStartAngle = 0.0;
5094 rCustomShape2d.
GetParameter(fStartAngle, rPairs[rnPairIndex + 1].
First,
false,
false);
5095 sal_Int32 nStartAng(std::lround(fStartAngle * 60000));
5096 double fSwingAng = 0.0;
5097 rCustomShape2d.
GetParameter(fSwingAng, rPairs[rnPairIndex + 1].Second,
false,
false);
5098 sal_Int32 nSwingAng(std::lround(fSwingAng * 60000));
5099 mpFS->singleElement(
FSNS(XML_a, XML_arcTo), XML_wR, OString::number(fWR), XML_hR,
5100 OString::number(fHR), XML_stAng, OString::number(nStartAng),
5101 XML_swAng, OString::number(nSwingAng));
5104 getEllipsePointFromViewAngle(fPx, fPy, fWR, fHR, 0.0, 0.0, fStartAngle);
5105 double fCx = rfCurrentX - fPx;
5106 double fCy = rfCurrentY - fPy;
5107 getEllipsePointFromViewAngle(rfCurrentX, rfCurrentY, fWR, fHR, fCx, fCy,
5108 fStartAngle + fSwingAng);
5109 rbCurrentValid =
true;
5121 const drawing::EnhancedCustomShapeParameterPair& rParamPair,
5123 const bool bReplaceGeoHeight)
5126 = GetCustomGeometryPointValue(rParamPair.First, rCustomShape2d, bReplaceGeoWidth,
false);
5128 = GetCustomGeometryPointValue(rParamPair.Second, rCustomShape2d,
false, bReplaceGeoHeight);
5130 mpFS->singleElementNS(XML_a, XML_pt, XML_x, OString::number(nX), XML_y, OString::number(nY));
5136 mpFS->startElementNS(XML_a, XML_custGeom);
5137 mpFS->singleElementNS(XML_a, XML_avLst);
5138 mpFS->singleElementNS(XML_a, XML_gdLst);
5139 mpFS->singleElementNS(XML_a, XML_ahLst);
5140 mpFS->singleElementNS(XML_a, XML_rect, XML_l,
"0", XML_t,
"0", XML_r,
"r", XML_b,
"b");
5141 mpFS->singleElementNS(XML_a, XML_pathLst);
5142 mpFS->endElementNS(XML_a, XML_custGeom);
5155 mpFS->startElementNS(XML_a, XML_custGeom);
5156 mpFS->singleElementNS(XML_a, XML_avLst);
5157 mpFS->singleElementNS(XML_a, XML_gdLst);
5158 mpFS->singleElementNS(XML_a, XML_ahLst);
5159 mpFS->singleElementNS(XML_a, XML_rect, XML_l,
"0", XML_t,
"0", XML_r,
"r", XML_b,
"b");
5161 mpFS->startElementNS(XML_a, XML_pathLst);
5163 awt::Size aSize = rXShape->getSize();
5164 awt::Point aPos = rXShape->getPosition();
5166 uno::Reference<XPropertySetInfo> xPropertySetInfo = xPropertySet->getPropertySetInfo();
5167 if (xPropertySetInfo->hasPropertyByName(
"AnchorPosition"))
5169 awt::Point aAnchorPosition;
5170 xPropertySet->getPropertyValue(
"AnchorPosition") >>= aAnchorPosition;
5171 aPos.X += aAnchorPosition.X;
5172 aPos.Y += aAnchorPosition.Y;
5176 std::optional<OString> sFill;
5182 mpFS->startElementNS(XML_a, XML_path, XML_fill, sFill, XML_w, OString::number(aSize.Width),
5183 XML_h, OString::number(aSize.Height));
5185 for (sal_uInt16
i = 0;
i < aPolyPolygon.
Count();
i++)
5191 mpFS->startElementNS(XML_a, XML_moveTo);
5193 mpFS->singleElementNS(XML_a, XML_pt, XML_x, OString::number(aPoly[0].
X() - aPos.X),
5194 XML_y, OString::number(aPoly[0].Y() - aPos.Y));
5196 mpFS->endElementNS(XML_a, XML_moveTo);
5199 for (sal_uInt16 j = 1; j < aPoly.
GetSize(); j++)
5202 if (flags == PolyFlags::Control)
5205 if (j + 2 < aPoly.
GetSize() && aPoly.
GetFlags(j + 1) == PolyFlags::Control
5206 && aPoly.
GetFlags(j + 2) != PolyFlags::Control)
5208 mpFS->startElementNS(XML_a, XML_cubicBezTo);
5211 mpFS->singleElementNS(XML_a, XML_pt, XML_x,
5212 OString::number(aPoly[j + k].
X() - aPos.X), XML_y,
5213 OString::number(aPoly[j + k].Y() - aPos.Y));
5215 mpFS->endElementNS(XML_a, XML_cubicBezTo);
5219 else if (flags == PolyFlags::Normal)
5221 mpFS->startElementNS(XML_a, XML_lnTo);
5222 mpFS->singleElementNS(XML_a, XML_pt, XML_x, OString::number(aPoly[j].
X() - aPos.X),
5223 XML_y, OString::number(aPoly[j].Y() - aPos.Y));
5224 mpFS->endElementNS(XML_a, XML_lnTo);
5229 mpFS->singleElementNS(XML_a, XML_close);
5230 mpFS->endElementNS(XML_a, XML_path);
5232 mpFS->endElementNS(XML_a, XML_pathLst);
5234 mpFS->endElementNS(XML_a, XML_custGeom);
5239 if( nStartID != -1 )
5241 mpFS->singleElementNS( XML_a, XML_stCxn,
5242 XML_id, OString::number(nStartID),
5243 XML_idx, OString::number(nStartGlueId) );
5247 mpFS->singleElementNS( XML_a, XML_endCxn,
5248 XML_id, OString::number(nEndID),
5249 XML_idx, OString::number(nEndGlueId) );
5257 rtl_TextEncoding eCharSet = rFontDesc.CharSet;
5259 rFontDesc.CharSet = eCharSet;
5266 const OUString& sFullStream,
5267 std::u16string_view sRelativeStream,
5269 const OUString& sContentType,
5270 const OUString& sRelationshipType,
5271 OUString* pRelationshipId )
5273 OUString sRelationshipId;
5274 if (xParentRelation.is())
5275 sRelationshipId =
GetFB()->
addRelation( xParentRelation, sRelationshipType, sRelativeStream );
5277 sRelationshipId =
GetFB()->
addRelation( sRelationshipType, sRelativeStream );
5279 if( pRelationshipId )
5280 *pRelationshipId = sRelationshipId;
5292 xPropSet->getPropertyValue(
"FillStyle" ) >>= aFillStyle;
5295 if (aFillStyle == FillStyle_SOLID)
5297 OUString sFillTransparenceGradientName;
5299 if (
GetProperty(xPropSet,
"FillTransparenceGradientName")
5300 && (
mAny >>= sFillTransparenceGradientName)
5301 && !sFillTransparenceGradientName.isEmpty()
5302 &&
GetProperty(xPropSet,
"FillTransparenceGradient"))
5311 if (bCompletelyTransparent)
5313 aFillStyle = FillStyle_NONE;
5316 else if (
GetProperty( xPropSet,
"FillTransparence" ) )
5320 xPropSet->getPropertyValue(
"FillTransparence" ) >>= nVal;
5322 aFillStyle = FillStyle_NONE;
5326 bool bUseBackground(
false);
5327 if (
GetProperty(xPropSet,
"FillUseSlideBackground"))
5328 xPropSet->getPropertyValue(
"FillUseSlideBackground") >>= bUseBackground;
5330 switch( aFillStyle )
5332 case FillStyle_SOLID :
5335 case FillStyle_GRADIENT :
5338 case FillStyle_BITMAP :
5341 case FillStyle_HATCH :
5344 case FillStyle_NONE:
5345 if (!bUseBackground)
5346 mpFS->singleElementNS(XML_a, XML_noFill);
5357 OUString sSchemeClr;
5358 sal_uInt32 nIdx = 0;
5362 if( rProp.Name ==
"SchemeClr" )
5363 rProp.Value >>= sSchemeClr;
5364 else if( rProp.Name ==
"Idx" )
5365 rProp.Value >>= nIdx;
5366 else if( rProp.Name ==
"Transformations" )
5367 rProp.Value >>= aTransformations;
5369 mpFS->startElementNS(XML_a, nTokenId, XML_idx, OString::number(nIdx));
5371 mpFS->endElementNS( XML_a, nTokenId );
5376 mpFS->singleElementNS(XML_a, nTokenId, XML_idx, OString::number(0));
5390 for(
const auto& rProp : std::as_const(aGrabBag))
5392 if( rProp.Name ==
"StyleFillRef" )
5393 rProp.Value >>= aFillRefProperties;
5394 else if( rProp.Name ==
"StyleLnRef" )
5395 rProp.Value >>= aLnRefProperties;
5396 else if( rProp.Name ==
"StyleEffectRef" )
5397 rProp.Value >>= aEffectRefProperties;
5405 mpFS->singleElementNS(XML_a, XML_fontRef, XML_idx,
"minor");
5410 if( !aEffectProps.hasElements() )
5414 sal_Int32 nEffectToken = 0;
5415 bool bContainsColor =
false;
5416 if(
sName ==
u"outerShdw" )
5418 nEffectToken =
FSNS( XML_a, XML_outerShdw );
5419 bContainsColor =
true;
5421 else if(
sName ==
u"innerShdw" )
5423 nEffectToken =
FSNS( XML_a, XML_innerShdw );
5424 bContainsColor =
true;
5426 else if(
sName ==
u"glow" )
5428 nEffectToken =
FSNS( XML_a, XML_glow );
5429 bContainsColor =
true;
5431 else if(
sName ==
u"softEdge" )
5432 nEffectToken =
FSNS( XML_a, XML_softEdge );
5433 else if(
sName ==
u"reflection" )
5434 nEffectToken =
FSNS( XML_a, XML_reflection );
5435 else if(
sName ==
u"blur" )
5436 nEffectToken =
FSNS( XML_a, XML_blur );
5438 OUString sSchemeClr;
5443 for(
const auto& rEffectProp : aEffectProps )
5445 if( rEffectProp.Name ==
"Attribs" )
5448 uno::Sequence< beans::PropertyValue > aOuterShdwProps;
5449 rEffectProp.Value >>= aOuterShdwProps;
5450 for(
const auto& rOuterShdwProp : std::as_const(aOuterShdwProps) )
5452 if( rOuterShdwProp.Name ==
"algn" )
5455 rOuterShdwProp.Value >>= sVal;
5456 aOuterShdwAttrList->add( XML_algn, sVal );
5458 else if( rOuterShdwProp.Name ==
"blurRad" )
5461 rOuterShdwProp.Value >>= nVal;
5462 aOuterShdwAttrList->add( XML_blurRad, OString::number( nVal ) );
5464 else if( rOuterShdwProp.Name ==
"dir" )
5467 rOuterShdwProp.Value >>= nVal;
5468 aOuterShdwAttrList->add( XML_dir, OString::number( nVal ) );
5470 else if( rOuterShdwProp.Name ==
"dist" )
5473 rOuterShdwProp.Value >>= nVal;
5474 aOuterShdwAttrList->add( XML_dist, OString::number( nVal ) );
5476 else if( rOuterShdwProp.Name ==
"kx" )
5479 rOuterShdwProp.Value >>= nVal;
5480 aOuterShdwAttrList->add( XML_kx, OString::number( nVal ) );
5482 else if( rOuterShdwProp.Name ==
"ky" )
5485 rOuterShdwProp.Value >>= nVal;