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;
668 mpFS->endElementNS(XML_a, XML_gradFill);
675 mpFS->startElementNS(XML_a, XML_gsLst);
678 for(
const auto& rGradientStop : aGradientStops )
681 rGradientStop.Value >>= aGradientStop;
686 sal_Int16 nTransparency = 0;
689 for(
const auto& rProp : std::as_const(aGradientStop) )
691 if( rProp.Name ==
"SchemeClr" )
692 rProp.Value >>= sSchemeClr;
693 else if( rProp.Name ==
"RgbClr" )
694 rProp.Value >>= nRgbClr;
695 else if( rProp.Name ==
"Pos" )
696 rProp.Value >>=
nPos;
697 else if( rProp.Name ==
"Transparency" )
698 rProp.Value >>= nTransparency;
699 else if( rProp.Name ==
"Transformations" )
700 rProp.Value >>= aTransformations;
703 mpFS->startElementNS(XML_a, XML_gs, XML_pos, OString::number(
nPos * 100000.0));
704 if( sSchemeClr.isEmpty() )
714 mpFS->endElementNS( XML_a, XML_gs );
716 mpFS->endElementNS( XML_a, XML_gsLst );
722 const sal_Int16 nAngle(rBGradient.
GetAngle());
723 mpFS->singleElementNS(
724 XML_a, XML_lin, XML_ang,
725 OString::number(((3600 -
static_cast<sal_Int32
>(nAngle) + 900) * 6000) % 21600000));
728 case awt::GradientStyle_RADIAL:
730 WriteGradientPath(rBGradient,
mpFS,
true);
746 if (
nullptr != pColorGradient)
752 if (
nullptr != pTransparenceGradient)
755 if (
nullptr == pGradient)
757 pGradient = pTransparenceGradient;
769 if (aColorStops.size() != aAlphaStops.size() ||
nullptr == pGradient)
775 assert(
false &&
"oox::WriteGradientFill: non-synchronized gradients (!)");
779 bool bRadialOrEllipticalOrRectOrSquare(
false);
785 case awt::GradientStyle_LINEAR:
791 case awt::GradientStyle_AXIAL:
799 basegfx::BColorStops::const_reverse_iterator aRevCurrColor(aColorStops.rbegin());
800 basegfx::BColorStops::const_reverse_iterator aRevCurrAlpha(aAlphaStops.rbegin());
802 while (aRevCurrColor != aColorStops.rend() && aRevCurrAlpha != aAlphaStops.rend())
804 aNewColorStops.emplace_back((1.0 - aRevCurrColor->getStopOffset()) * 0.5, aRevCurrColor->getStopColor());
805 aNewAlphaStops.emplace_back((1.0 - aRevCurrAlpha->getStopOffset()) * 0.5, aRevCurrAlpha->getStopColor());
810 basegfx::BColorStops::const_iterator aCurrColor(aColorStops.begin());
811 basegfx::BColorStops::const_iterator aCurrAlpha(aAlphaStops.begin());
825 while (aCurrColor != aColorStops.end() && aCurrAlpha != aAlphaStops.end())
827 aNewColorStops.emplace_back((aCurrColor->getStopOffset() * 0.5) + 0.5, aCurrColor->getStopColor());
828 aNewAlphaStops.emplace_back((aCurrAlpha->getStopOffset() * 0.5) + 0.5, aCurrAlpha->getStopColor());
833 aColorStops = aNewColorStops;
834 aAlphaStops = aNewAlphaStops;
850 bRadialOrEllipticalOrRectOrSquare =
true;
856 mpFS->startElementNS(XML_a, XML_gsLst);
858 basegfx::BColorStops::const_iterator aCurrColor(aColorStops.begin());
859 basegfx::BColorStops::const_iterator aCurrAlpha(aAlphaStops.begin());
861 while (aCurrColor != aColorStops.end() && aCurrAlpha != aAlphaStops.end())
864 aCurrColor->getStopOffset(),
865 aCurrColor->getStopColor(),
866 aCurrAlpha->getStopColor());
871 mpFS->endElementNS( XML_a, XML_gsLst );
873 if (bLinear || bAxial)
876 const sal_Int16 nAngle(pGradient->
GetAngle());
877 mpFS->singleElementNS(
878 XML_a, XML_lin, XML_ang,
879 OString::number(((3600 -
static_cast<sal_Int32
>(nAngle) + 900) * 6000) % 21600000));
882 if (bRadialOrEllipticalOrRectOrSquare)
885 const bool bCircle(pGradient->
GetGradientStyle() == awt::GradientStyle_RADIAL ||
888 WriteGradientPath(*pGradient,
mpFS, bCircle);
895 sal_Int32 nArrowLength;
896 sal_Int32 nArrowWidth;
905 switch( nArrowLength )
942 switch( nArrowWidth )
956 mpFS->singleElementNS( XML_a, bLineStart ? XML_headEnd : XML_tailEnd,
964 drawing::LineStyle aLineStyle( drawing::LineStyle_NONE );
971 sal_uInt32 nEmuLineWidth = 0;
974 bool bColorSet =
false;
975 const char* cap =
nullptr;
976 drawing::LineDash aLineDash;
977 bool bDashSet =
false;
978 bool bNoFill =
false;
982 OUString sColorFillScheme;
983 ::Color aResolvedColorFillScheme;
987 sal_uInt32 nStyleLineWidth = 0;
992 drawing::LineStyle aStyleLineStyle(drawing::LineStyle_NONE);
993 drawing::LineJoint aStyleLineJoint(drawing::LineJoint_NONE);
1000 for (
const auto& rProp : std::as_const(aGrabBag))
1002 if( rProp.Name ==
"SpPrLnSolidFillSchemeClr" )
1003 rProp.Value >>= sColorFillScheme;
1004 if( rProp.Name ==
"SpPrLnSolidFillResolvedSchemeClr" )
1005 rProp.Value >>= aResolvedColorFillScheme;
1006 else if( rProp.Name ==
"OriginalLnSolidFillClr" )
1007 rProp.Value >>= nOriginalColor;
1008 else if( rProp.Name ==
"StyleLnRef" )
1009 rProp.Value >>= aStyleProperties;
1010 else if( rProp.Name ==
"SpPrLnSolidFillSchemeClrTransformations" )
1011 rProp.Value >>= aTransformations;
1012 else if( rProp.Name ==
"EmuLineWidth" )
1013 rProp.Value >>= nEmuLineWidth;
1015 for (
const auto& rStyleProp : std::as_const(aStyleProperties))
1017 if( rStyleProp.Name ==
"Color" )
1018 rStyleProp.Value >>= nStyleColor;
1019 else if( rStyleProp.Name ==
"LineStyle" )
1020 rStyleProp.Value >>= aStyleLineStyle;
1021 else if( rStyleProp.Name ==
"LineJoint" )
1022 rStyleProp.Value >>= aStyleLineJoint;
1023 else if( rStyleProp.Name ==
"LineWidth" )
1024 rStyleProp.Value >>= nStyleLineWidth;
1033 case drawing::LineStyle_NONE:
1036 case drawing::LineStyle_DASH:
1039 aLineDash =
mAny.get<drawing::LineDash>();
1041 if (aLineDash.Dots == 0 && aLineDash.DotLen == 0 && aLineDash.Dashes == 0 && aLineDash.DashLen == 0 && aLineDash.Distance == 0) {
1042 OUString aLineDashName;
1044 mAny >>= aLineDashName;
1045 if (!aLineDashName.isEmpty() &&
xModel) {
1054 OUString aLineDashName;
1056 mAny >>= aLineDashName;
1057 if (!aLineDashName.isEmpty() &&
xModel) {
1063 if (aLineDash.Style == DashStyle_ROUND || aLineDash.Style == DashStyle_ROUNDRELATIVE)
1068 SAL_INFO(
"oox.shape",
"dash dots: " << aLineDash.Dots <<
" dashes: " << aLineDash.Dashes
1069 <<
" dotlen: " << aLineDash.DotLen <<
" dashlen: " << aLineDash.DashLen <<
" distance: " << aLineDash.Distance);
1072 case drawing::LineStyle_SOLID:
1083 if (aLineCap == LineCap_ROUND)
1085 else if (aLineCap == LineCap_SQUARE)
1093 mpFS->startElementNS( XML_a, XML_ln,
1101 if( nColor != nOriginalColor )
1107 else if( !sColorFillScheme.isEmpty() )
1118 if( bDashSet && aStyleLineStyle != drawing::LineStyle_DASH )
1125 bool bIsConverted =
false;
1127 bool bIsRelative(aLineDash.Style == DashStyle_RECTRELATIVE || aLineDash.Style == DashStyle_ROUNDRELATIVE);
1128 if ( bIsRelative && aLineDash.Dots == 1)
1130 sal_uInt32 nDotLen = aLineDash.DotLen;
1131 sal_uInt32 nDashLen = aLineDash.DashLen;
1132 sal_uInt32 nDistance = aLineDash.Distance;
1133 if (aLineCap != LineCap_BUTT && nDistance >= 99)
1144 if (nDashLen == 0 && aLineDash.Dashes > 0)
1146 bIsConverted =
true;
1147 if (nDotLen == 100 && aLineDash.Dashes == 0 && nDashLen == 0 && nDistance == 300)
1149 mpFS->singleElementNS(XML_a, XML_prstDash, XML_val,
"dot");
1151 else if (nDotLen == 400 && aLineDash.Dashes == 0 && nDashLen == 0 && nDistance == 300)
1153 mpFS->singleElementNS(XML_a, XML_prstDash, XML_val,
"dash");
1155 else if (nDotLen == 400 && aLineDash.Dashes == 1 && nDashLen == 100 && nDistance == 300)
1157 mpFS->singleElementNS(XML_a, XML_prstDash, XML_val,
"dashDot");
1159 else if (nDotLen == 800 && aLineDash.Dashes == 0 && nDashLen == 0 && nDistance == 300)
1161 mpFS->singleElementNS(XML_a, XML_prstDash, XML_val,
"lgDash");
1163 else if (nDotLen == 800 && aLineDash.Dashes == 1 && nDashLen == 100 && nDistance == 300)
1165 mpFS->singleElementNS(XML_a, XML_prstDash, XML_val,
"lgDashDot");
1167 else if (nDotLen == 800 && aLineDash.Dashes == 2 && nDashLen == 100 && nDistance == 300)
1169 mpFS->singleElementNS(XML_a, XML_prstDash, XML_val,
"lgDashDotDot");
1171 else if (nDotLen == 100 && aLineDash.Dashes == 0 && nDashLen == 0 && nDistance == 100)
1173 mpFS->singleElementNS(XML_a, XML_prstDash, XML_val,
"sysDot");
1175 else if (nDotLen == 300 && aLineDash.Dashes == 0 && nDashLen == 0 && nDistance == 100)
1177 mpFS->singleElementNS(XML_a, XML_prstDash, XML_val,
"sysDash");
1179 else if (nDotLen == 300 && aLineDash.Dashes == 1 && nDashLen == 100 && nDistance == 100)
1181 mpFS->singleElementNS(XML_a, XML_prstDash, XML_val,
"sysDashDot");
1183 else if (nDotLen == 300 && aLineDash.Dashes == 2 && nDashLen == 100 && nDistance == 100)
1185 mpFS->singleElementNS(XML_a, XML_prstDash, XML_val,
"sysDashDotDot");
1188 bIsConverted =
false;
1193 mpFS->startElementNS(XML_a, XML_custDash);
1199 double fSp = bIsRelative ? aLineDash.Distance : aLineDash.Distance * 100.0 / fLineWidth;
1202 if (aLineDash.Distance <= 0)
1206 if (aLineCap == LineCap_ROUND && fSp > 99.0)
1209 if (aLineDash.Dots > 0)
1211 double fD = bIsRelative ? aLineDash.DotLen : aLineDash.DotLen * 100.0 / fLineWidth;
1213 if (aLineDash.DotLen == 0)
1216 if (aLineCap == LineCap_ROUND && fSp > 99.0)
1219 for(
i = 0;
i < aLineDash.Dots;
i ++ )
1221 mpFS->singleElementNS( XML_a, XML_ds,
1226 if ( aLineDash.Dashes > 0 )
1228 double fD = bIsRelative ? aLineDash.DashLen : aLineDash.DashLen * 100.0 / fLineWidth;
1230 if (aLineDash.DashLen == 0)
1233 if (aLineCap == LineCap_ROUND && fSp > 99.0)
1236 for(
i = 0;
i < aLineDash.Dashes;
i ++ )
1238 mpFS->singleElementNS( XML_a , XML_ds,
1245 "oox.shape",
"while writing outline - custom dash - line width was < 0 : " <<
nLineWidth);
1247 "oox.shape",
"while writing outline - custom dash - number of dashes was < 0 : " << aLineDash.Dashes);
1248 SAL_WARN_IF(aLineDash.Dashes > 0 && aLineDash.DashLen <= 0,
1249 "oox.shape",
"while writing outline - custom dash - dash length was < 0 : " << aLineDash.DashLen);
1251 "oox.shape",
"while writing outline - custom dash - number of dots was < 0 : " << aLineDash.Dots);
1252 SAL_WARN_IF(aLineDash.Dots > 0 && aLineDash.DotLen <= 0,
1253 "oox.shape",
"while writing outline - custom dash - dot length was < 0 : " << aLineDash.DotLen);
1255 "oox.shape",
"while writing outline - custom dash - distance was < 0 : " << aLineDash.Distance);
1257 mpFS->endElementNS( XML_a, XML_custDash );
1267 || aStyleLineJoint != eLineJoint)
1270 switch( eLineJoint )
1272 case LineJoint_NONE:
1273 case LineJoint_BEVEL:
1274 mpFS->singleElementNS(XML_a, XML_bevel);
1277 case LineJoint_MIDDLE:
1278 case LineJoint_MITER:
1279 mpFS->singleElementNS(XML_a, XML_miter);
1281 case LineJoint_ROUND:
1282 mpFS->singleElementNS(XML_a, XML_round);
1295 mpFS->singleElementNS(XML_a, XML_noFill);
1298 mpFS->endElementNS( XML_a, XML_ln );
1317 mpFS->startElementNS(XML_a, XML_blip,
FSNS(XML_r, XML_embed), sRelId);
1319 for (
auto const& rEffect : rEffects)
1321 switch (rEffect.meType)
1325 mpFS->singleElementNS(XML_a, XML_alphaBiLevel, XML_thresh, OString::number(rEffect.mnThreshold));
1330 mpFS->singleElementNS(XML_a, XML_alphaCeiling);
1335 mpFS->singleElementNS(XML_a, XML_alphaFloor);
1340 mpFS->singleElementNS(XML_a, XML_alphaInv);
1346 mpFS->singleElementNS(XML_a, XML_alphaMod);
1352 mpFS->singleElementNS(XML_a, XML_alphaModFix, XML_amt, OString::number(rEffect.mnAmount));
1357 mpFS->singleElementNS(XML_a, XML_alphaRepl, XML_a, OString::number(rEffect.mnAlpha));
1362 mpFS->singleElementNS(XML_a, XML_biLevel, XML_thresh, OString::number(rEffect.mnThreshold));
1367 mpFS->singleElementNS(XML_a, XML_blur,
1368 XML_rad, OString::number(rEffect.mnRadius),
1369 XML_grow, rEffect.mbGrow ?
"1" :
"0");
1374 mpFS->startElementNS(XML_a, XML_clrChange, XML_useA, rEffect.mbUseAlpha ?
"1" :
"0");
1375 mpFS->endElementNS(XML_a, XML_clrChange);
1380 mpFS->startElementNS(XML_a, XML_clrRepl);
1381 mpFS->endElementNS(XML_a, XML_clrRepl);
1386 mpFS->startElementNS(XML_a, XML_duotone);
1387 mpFS->endElementNS(XML_a, XML_duotone);
1392 mpFS->singleElementNS(XML_a, XML_fillOverlay);
1397 mpFS->singleElementNS(XML_a, XML_grayscl);
1402 mpFS->singleElementNS(XML_a, XML_hsl,
1403 XML_hue, OString::number(rEffect.mnHue),
1404 XML_sat, OString::number(rEffect.mnSaturation),
1405 XML_lum, OString::number(rEffect.mnLuminance));
1410 mpFS->singleElementNS(XML_a, XML_lum,
1411 XML_bright, OString::number(rEffect.mnBrightness),
1412 XML_contrast, OString::number(rEffect.mnContrast));
1417 mpFS->singleElementNS(XML_a, XML_tint,
1418 XML_hue, OString::number(rEffect.mnHue),
1419 XML_amt, OString::number(rEffect.mnAmount));
1428 mpFS->endElementNS(XML_a, XML_blip);
1438 const char* pExtension =
"";
1446 if (sPath.isEmpty())
1454 case GfxLinkType::NativeGif:
1456 pExtension =
".gif";
1461 case GfxLinkType::NativeBmp:
1463 pExtension =
".bmp";
1466 case GfxLinkType::NativeJpg:
1468 pExtension =
".jpeg";
1470 case GfxLinkType::NativePng:
1472 pExtension =
".png";
1474 case GfxLinkType::NativeTif:
1476 pExtension =
".tif";
1478 case GfxLinkType::NativeWmf:
1480 pExtension =
".wmf";
1482 case GfxLinkType::NativeMet:
1484 pExtension =
".met";
1486 case GfxLinkType::NativePct:
1488 pExtension =
".pct";
1490 case GfxLinkType::NativeMov:
1492 pExtension =
".MOV";
1497 if (aType == GraphicType::Bitmap || aType == GraphicType::GdiMetafile)
1499 if (aType == GraphicType::Bitmap)
1503 pExtension =
".png";
1509 pExtension =
".emf";
1514 SAL_WARN(
"oox.shape",
"unhandled graphic type " <<
static_cast<int>(aType));
1533 .append(
"/media/image" + OUString::number(nImageCount))
1534 .appendAscii(pExtension)
1535 .makeStringAndClear(),
1538 xOutStream->closeOutput();
1540 const OString sRelPathToMedia =
"media/image";
1541 OString sRelationCompPrefix;
1542 if (bRelPathToMedia)
1543 sRelationCompPrefix =
"../";
1546 sPath = OUStringBuffer()
1547 .appendAscii(sRelationCompPrefix.getStr())
1548 .appendAscii(sRelPathToMedia.getStr())
1549 .append(nImageCount)
1550 .appendAscii(pExtension)
1551 .makeStringAndClear();
1576 OUString aExtension;
1577 const OUString& rURL(pMediaObj->
getURL());
1578 int nLastDot = rURL.lastIndexOf(
'.');
1580 aExtension = rURL.copy(nLastDot);
1582 bool bEmbed = rURL.startsWith(
"vnd.sun.star.Package:");
1586#if HAVE_FEATURE_AVMEDIA
1596 if (
aMimeType ==
"application/vnd.sun.star.media")
1600 if (aExtension.equalsIgnoreAsciiCase(
".avi"))
1602 else if (aExtension.equalsIgnoreAsciiCase(
".flv"))
1604 else if (aExtension.equalsIgnoreAsciiCase(
".mp4"))
1606 else if (aExtension.equalsIgnoreAsciiCase(
".mov"))
1608 else if (aExtension.equalsIgnoreAsciiCase(
".ogv"))
1610 else if (aExtension.equalsIgnoreAsciiCase(
".wmv"))
1612 else if (aExtension.equalsIgnoreAsciiCase(
".wav"))
1617 else if (aExtension.equalsIgnoreAsciiCase(
".m4a"))
1622 else if (aExtension.equalsIgnoreAsciiCase(
".mp3"))
1629 OUString aVideoFileRelId;
1630 OUString aMediaRelId;
1636 OUString sFileName = OUStringBuffer()
1638 .append(
"/media/media" + OUString::number(nImageCount) + aExtension)
1639 .makeStringAndClear();
1644 uno::Reference<io::XInputStream> xInputStream(pMediaObj->
GetInputStream());
1647 xOutStream->closeOutput();
1651 .append(
"media/media" + OUString::number(nImageCount) + aExtension)
1652 .makeStringAndClear();
1662 GetFS()->startElementNS(XML_p, XML_nvPr);
1665 FSNS(XML_r, XML_link), aVideoFileRelId);
1667 GetFS()->startElementNS(XML_p, XML_extLst);
1669 GetFS()->startElementNS(XML_p, XML_ext, XML_uri,
"{DAA4B4D4-6D71-4841-9C94-3DE7FCFB9230}");
1671 GetFS()->singleElementNS(XML_p14, XML_media,
1672 bEmbed?
FSNS(XML_r, XML_embed):
FSNS(XML_r, XML_link), aMediaRelId);
1674 GetFS()->endElementNS(XML_p, XML_ext);
1675 GetFS()->endElementNS(XML_p, XML_extLst);
1677 GetFS()->endElementNS(XML_p, XML_nvPr);
1682 sal_Int16 nBright = 0;
1683 sal_Int32 nContrast = 0;
1684 sal_Int32 nTransparence = 0;
1687 nBright =
mAny.get<sal_Int16>();
1689 nContrast =
mAny.get<sal_Int32>();
1692 nTransparence =
mAny.get<sal_Int32>();
1694 if (nTransparence == 0 &&
GetProperty(rXPropSet,
"Transparency"))
1695 nTransparence =
static_cast<sal_Int32
>(
mAny.get<sal_Int16>());
1699 drawing::ColorMode aColorMode;
1700 mAny >>= aColorMode;
1701 if (aColorMode == drawing::ColorMode_GREYS)
1702 mpFS->singleElementNS(XML_a, XML_grayscl);
1703 else if (aColorMode == drawing::ColorMode_MONO)
1705 mpFS->singleElementNS(XML_a, XML_biLevel, XML_thresh, OString::number(50000));
1706 else if (aColorMode == drawing::ColorMode_WATERMARK)
1715 if (nBright || nContrast)
1717 mpFS->singleElementNS(XML_a, XML_lum,
1724 sal_Int32 nAlphaMod = (100 - nTransparence ) *
PER_PERCENT;
1725 mpFS->singleElementNS(XML_a, XML_alphaModFix, XML_amt, OString::number(nAlphaMod));
1730 uno::Reference<graphic::XGraphic>
const & rxGraphic,
1731 bool bRelPathToMedia)
1735 if (!rxGraphic.is())
1739 sRelId =
WriteImage(aGraphic, bRelPathToMedia);
1741 mpFS->startElementNS(XML_a, XML_blip,
FSNS(XML_r, XML_embed), sRelId);
1747 mpFS->endElementNS(XML_a, XML_blip);
1753 uno::Reference<graphic::XGraphic>
const & rxGraphic,
1754 css::awt::Size
const& rSize)
1756 BitmapMode eBitmapMode(BitmapMode_NO_REPEAT);
1758 mAny >>= eBitmapMode;
1760 SAL_INFO(
"oox.shape",
"fill bitmap mode: " <<
int(eBitmapMode));
1762 switch (eBitmapMode)
1764 case BitmapMode_REPEAT:
1767 case BitmapMode_STRETCH:
1770 case BitmapMode_NO_REPEAT:
1779 const OUString& rURLPropName,
const awt::Size& rSize)
1791 const OUString& sURLPropName,
const awt::Size& rSize)
1797 const OUString& sURLPropName, sal_Int32 nXmlNamespace)
1802 uno::Reference<graphic::XGraphic> xGraphic;
1803 if (
mAny.has<uno::Reference<awt::XBitmap>>())
1805 uno::Reference<awt::XBitmap> xBitmap =
mAny.get<uno::Reference<awt::XBitmap>>();
1807 xGraphic.set(xBitmap, uno::UNO_QUERY);
1809 else if (
mAny.has<uno::Reference<graphic::XGraphic>>())
1811 xGraphic =
mAny.get<uno::Reference<graphic::XGraphic>>();
1816 bool bWriteMode =
false;
1817 if (sURLPropName ==
"FillBitmap" || sURLPropName ==
"BackGraphic")
1824 uno::Reference<graphic::XGraphic>
const & rxGraphic,
1825 sal_Int32 nXmlNamespace,
bool bWriteMode,
1826 bool bRelPathToMedia, css::awt::Size
const& rSize)
1828 if (!rxGraphic.is() )
1831 mpFS->startElementNS(nXmlNamespace , XML_blipFill, XML_rotWithShape,
"0");
1845 else if(
GetProperty(rXPropSet,
"FillBitmapStretch"))
1847 bool bStretch =
mAny.get<
bool>();
1854 mpFS->endElementNS(nXmlNamespace, XML_blipFill);
1861 drawing::Hatch aHatch;
1874 sal_Int32 nTransparency = 0;
1875 mAny >>= nTransparency;
1879 mpFS->startElementNS(XML_a, XML_fgClr);
1881 mpFS->endElementNS( XML_a , XML_fgClr );
1887 bool isBackgroundFilled =
false;
1888 mAny >>= isBackgroundFilled;
1889 if( isBackgroundFilled )
1900 mpFS->startElementNS(XML_a, XML_bgClr);
1902 mpFS->endElementNS( XML_a , XML_bgClr );
1904 mpFS->endElementNS( XML_a , XML_pattFill );
1908 Size const & rOriginalSize,
1914 css::text::GraphicCrop aGraphicCropStruct;
1915 mAny >>= aGraphicCropStruct;
1923 mpFS->singleElementNS( XML_a, XML_srcRect);
1927 Size aOriginalSize(rOriginalSize);
1930 if (rMapMode.
GetMapUnit() == MapUnit::MapPixel)
1933 if ( (0 != aGraphicCropStruct.Left) || (0 != aGraphicCropStruct.Top) || (0 != aGraphicCropStruct.Right) || (0 != aGraphicCropStruct.Bottom) )
1935 mpFS->singleElementNS( XML_a, XML_srcRect,
1936 XML_l, OString::number(rtl::math::round(aGraphicCropStruct.Left * 100000.0 / aOriginalSize.
Width())),
1937 XML_t, OString::number(rtl::math::round(aGraphicCropStruct.Top * 100000.0 / aOriginalSize.
Height())),
1938 XML_r, OString::number(rtl::math::round(aGraphicCropStruct.Right * 100000.0 / aOriginalSize.
Width())),
1939 XML_b, OString::number(rtl::math::round(aGraphicCropStruct.Bottom * 100000.0 / aOriginalSize.
Height())) );
1945 uno::Reference<graphic::XGraphic>
const & rxGraphic)
1954 uno::Reference<graphic::XGraphic>
const & rxGraphic)
1959 mpFS->singleElementNS(XML_a, XML_stretch);
1963 mpFS->startElementNS(XML_a, XML_stretch);
1968 css::text::GraphicCrop aGraphicCropStruct;
1969 mAny >>= aGraphicCropStruct;
1971 if ((0 != aGraphicCropStruct.Left)
1972 || (0 != aGraphicCropStruct.Top)
1973 || (0 != aGraphicCropStruct.Right)
1974 || (0 != aGraphicCropStruct.Bottom))
1978 mpFS->singleElementNS(XML_a, XML_fillRect,
1979 XML_l, OString::number(((aGraphicCropStruct.Left) * 100000) / aOriginalSize.
Width()),
1980 XML_t, OString::number(((aGraphicCropStruct.Top) * 100000) / aOriginalSize.
Height()),
1981 XML_r, OString::number(((aGraphicCropStruct.Right) * 100000) / aOriginalSize.
Width()),
1982 XML_b, OString::number(((aGraphicCropStruct.Bottom) * 100000) / aOriginalSize.
Height()));
1989 mpFS->singleElementNS(XML_a, XML_fillRect);
1992 mpFS->endElementNS(XML_a, XML_stretch);
1997 OUString sAlignment;
1998 switch (eRectanglePoint)
2000 case RectanglePoint_LEFT_TOP:
2003 case RectanglePoint_MIDDLE_TOP:
2006 case RectanglePoint_RIGHT_TOP:
2009 case RectanglePoint_LEFT_MIDDLE:
2012 case RectanglePoint_MIDDLE_MIDDLE:
2015 case RectanglePoint_RIGHT_MIDDLE:
2018 case RectanglePoint_LEFT_BOTTOM:
2021 case RectanglePoint_MIDDLE_BOTTOM:
2024 case RectanglePoint_RIGHT_BOTTOM:
2034 uno::Reference<graphic::XGraphic>
const& rxGraphic,
2035 css::awt::Size
const& rSize)
2041 if (rMapMode.
GetMapUnit() == MapUnit::MapPixel)
2043 MapMode(MapUnit::Map100thMM));
2044 sal_Int32 nSizeX = 0;
2045 sal_Int32 nOffsetX = 0;
2049 if (
GetProperty(rXPropSet,
"FillBitmapPositionOffsetX"))
2051 sal_Int32 nX = (nSizeX != 0) ? nSizeX : aOriginalSize.
Width();
2052 if (nX < 0 && rSize.Width > 0)
2053 nX = rSize.Width * std::abs(nX) / 100;
2054 nOffsetX = (*o3tl::doAccess<sal_Int32>(
mAny)) * nX * 3.6;
2059 nSizeX = double(nSizeX) / aOriginalSize.
Width() * 100000;
2060 else if (nSizeX < 0)
2066 sal_Int32 nSizeY = 0;
2067 sal_Int32 nOffsetY = 0;
2071 if (
GetProperty(rXPropSet,
"FillBitmapPositionOffsetY"))
2073 sal_Int32 nY = (nSizeY != 0) ? nSizeY : aOriginalSize.
Height();
2074 if (nY < 0 && rSize.Height > 0)
2075 nY = rSize.Height * std::abs(nY) / 100;
2076 nOffsetY = (*o3tl::doAccess<sal_Int32>(
mAny)) * nY * 3.6;
2081 nSizeY = double(nSizeY) / aOriginalSize.
Height() * 100000;
2082 else if (nSizeY < 0)
2089 if (nSizeX < 0 && nSizeY < 0)
2091 if (rSize.Width != 0 && rSize.Height != 0)
2093 nSizeX = rSize.Width / double(aOriginalSize.
Width()) * std::abs(nSizeX);
2094 nSizeY = rSize.Height / double(aOriginalSize.
Height()) * std::abs(nSizeY);
2098 nSizeX = std::abs(nSizeX);
2099 nSizeY = std::abs(nSizeY);
2103 OUString sRectanglePoint;
2104 if (
GetProperty(rXPropSet,
"FillBitmapRectanglePoint"))
2107 mpFS->singleElementNS(XML_a, XML_tile, XML_tx, OUString::number(nOffsetX), XML_ty,
2108 OUString::number(nOffsetY), XML_sx, OUString::number(nSizeX), XML_sy,
2109 OUString::number(nSizeY), XML_algn, sRectanglePoint);
2113 uno::Reference<graphic::XGraphic>
const& rxGraphic,
2114 css::awt::Size
const& rSize)
2120 if (rMapMode.
GetMapUnit() == MapUnit::MapPixel)
2122 MapMode(MapUnit::Map100thMM));
2130 nSizeX = aOriginalSize.
Width();
2143 nSizeY = aOriginalSize.
Height();
2149 if (nSizeX < 0 && nSizeY < 0 && rSize.Width != 0 && rSize.Height != 0)
2151 nSizeX = rSize.Width * std::abs(nSizeX);
2152 nSizeY = rSize.Height * std::abs(nSizeY);
2155 sal_Int32 nL = 0, nT = 0, nR = 0, nB = 0;
2156 if (
GetProperty(rXPropSet,
"FillBitmapRectanglePoint") && rSize.Width != 0 && rSize.Height != 0)
2158 sal_Int32 nWidth = (1 - (nSizeX / rSize.Width)) * 100000;
2159 sal_Int32 nHeight = (1 - (nSizeY / rSize.Height)) * 100000;
2161 switch (*o3tl::doAccess<RectanglePoint>(
mAny))
2163 case RectanglePoint_LEFT_TOP: nR = nWidth; nB = nHeight;
break;
2164 case RectanglePoint_RIGHT_TOP: nL = nWidth; nB = nHeight;
break;
2165 case RectanglePoint_LEFT_BOTTOM: nR = nWidth; nT = nHeight;
break;
2166 case RectanglePoint_RIGHT_BOTTOM: nL = nWidth; nT = nHeight;
break;
2167 case RectanglePoint_LEFT_MIDDLE: nR = nWidth; nT = nB = nHeight / 2;
break;
2168 case RectanglePoint_RIGHT_MIDDLE: nL = nWidth; nT = nB = nHeight / 2;
break;
2169 case RectanglePoint_MIDDLE_TOP: nB = nHeight; nL = nR = nWidth / 2;
break;
2170 case RectanglePoint_MIDDLE_BOTTOM: nT = nHeight; nL = nR = nWidth / 2;
break;
2171 case RectanglePoint_MIDDLE_MIDDLE: nL = nR = nWidth / 2; nT = nB = nHeight / 2;
break;
2176 mpFS->startElementNS(XML_a, XML_stretch);
2178 mpFS->singleElementNS(XML_a, XML_fillRect, XML_l,
2184 mpFS->endElementNS(XML_a, XML_stretch);
2189bool IsTopGroupObj(
const uno::Reference<drawing::XShape>& xShape)
2195 if (
pObject->getParentSdrObjectFromSdrObject())
2198 return pObject->IsGroupObject();
2203 sal_Int32 nXmlNamespace,
bool bFlipH,
bool bFlipV, sal_Int32 nRotation,
bool bIsGroupShape)
2206 mpFS->startElementNS( nXmlNamespace, XML_xfrm,
2211 sal_Int32 nLeft = rRect.
Left();
2212 sal_Int32 nTop = rRect.
Top();
2218 sal_Int32 nChildLeft = nLeft;
2219 sal_Int32 nChildTop = nTop;
2221 mpFS->singleElementNS(XML_a, XML_off,
2224 mpFS->singleElementNS(XML_a, XML_ext,
2230 mpFS->singleElementNS(XML_a, XML_chOff,
2233 mpFS->singleElementNS(XML_a, XML_chExt,
2238 mpFS->endElementNS( nXmlNamespace, XML_xfrm );
2243 SAL_INFO(
"oox.shape",
"write shape transformation");
2247 awt::Point aPos = rXShape->getPosition();
2248 awt::Size aSize = rXShape->getSize();
2250 bool bFlipHWrite = bFlipH && !bSuppressFlipping;
2251 bool bFlipVWrite = bFlipV && !bSuppressFlipping;
2252 bFlipH = bFlipH && !bFlippedBeforeRotation;
2253 bFlipV = bFlipV && !bFlippedBeforeRotation;
2257 awt::Point aParentPos =
m_xParent->getPosition();
2258 aPos.X -= aParentPos.X;
2259 aPos.Y -= aParentPos.Y;
2262 if ( aSize.Width < 0 )
2264 if ( aSize.Height < 0 )
2265 aSize.Height = 1000;
2266 if (!bSuppressRotation)
2272 int faccos=bFlipV ? -1 : 1;
2273 int facsin=bFlipH ? -1 : 1;
2274 aPos.X-=(1-faccos*cos(
toRadians(nRotation)))*aSize.Width/2-facsin*sin(
toRadians(nRotation))*aSize.Height/2;
2275 aPos.Y-=(1-faccos*cos(
toRadians(nRotation)))*aSize.Height/2+facsin*sin(
toRadians(nRotation))*aSize.Width/2;
2277 else if (
m_xParent.is() && nRotation != 0_deg100)
2280 basegfx::B2DRange aRect(-aSize.Width / 2.0, -aSize.Height / 2.0, aSize.Width / 2.0,
2281 aSize.Height / 2.0);
2285 aPos.X += -aSize.Width / 2.0 - aRect.
getMinX();
2286 aPos.Y += -aSize.Height / 2.0 - aRect.
getMinY();
2290 uno::Reference<beans::XPropertySet> xPropertySet(rXShape, uno::UNO_QUERY);
2291 uno::Reference<beans::XPropertySetInfo> xPropertySetInfo = xPropertySet->getPropertySetInfo();
2292 if (xPropertySetInfo->hasPropertyByName(
"RotateAngle"))
2295 if (xPropertySet->getPropertyValue(
"RotateAngle") >>= nTmp)
2301 uno::Sequence<beans::PropertyValue> aGrabBagProps;
2303 auto p3DEffectProps = std::find_if(std::cbegin(aGrabBagProps), std::cend(aGrabBagProps),
2304 [](
const PropertyValue& rProp) {
return rProp.Name ==
"3DEffectProperties"; });
2305 if (p3DEffectProps != std::cend(aGrabBagProps))
2307 uno::Sequence<beans::PropertyValue> a3DEffectProps;
2308 p3DEffectProps->Value >>= a3DEffectProps;
2309 auto pCameraProps = std::find_if(std::cbegin(a3DEffectProps), std::cend(a3DEffectProps),
2310 [](
const PropertyValue& rProp) {
return rProp.Name ==
"Camera"; });
2311 if (pCameraProps != std::cend(a3DEffectProps))
2313 uno::Sequence<beans::PropertyValue> aCameraProps;
2314 pCameraProps->Value >>= aCameraProps;
2315 auto pZRotationProp = std::find_if(std::cbegin(aCameraProps), std::cend(aCameraProps),
2316 [](
const PropertyValue& rProp) {
return rProp.Name ==
"rotRev"; });
2317 if (pZRotationProp != std::cend(aCameraProps))
2320 pZRotationProp->Value >>= nTmp;
2329 if(bFlipH != bFlipV)
2330 nRotation = 36000_deg100 - nRotation;
2336static OUString
lcl_GetTarget(
const css::uno::Reference<css::frame::XModel>& xModel, OUString& rURL)
2340 sal_uInt32 nPageCount = xDrawPages->getCount();
2343 for (sal_uInt32
i = 0;
i < nPageCount; ++
i)
2346 xDrawPages->getByIndex(
i) >>= xDrawPage;
2350 OUString sSlideName =
"#" + xNamed->getName();
2351 if (rURL == sSlideName)
2353 sTarget =
"slide" + OUString::number(
i + 1) +
".xml";
2357 if (sTarget.isEmpty())
2359 sal_Int32 nSplit = rURL.lastIndexOf(
' ');
2361 sTarget = OUString::Concat(
"slide") + rURL.subView(nSplit + 1) +
".xml";
2368 bool bCheckDirect,
bool& rbOverridingCharHeight, sal_Int32& rnCharHeight,
2373 OUString usLanguage;
2374 PropertyState eState;
2375 bool bComplex = ( nScriptType == css::i18n::ScriptType::COMPLEX );
2376 const char*
bold =
"0";
2377 const char*
italic =
nullptr;
2379 const char* strikeout =
nullptr;
2380 const char* cap =
nullptr;
2381 sal_Int32 nSize = 1800;
2382 sal_Int32 nCharEscapement = 0;
2383 sal_Int32 nCharKerning = 0;
2384 sal_Int32 nCharEscapementHeight = 0;
2386 if ( nElement == XML_endParaRPr && rbOverridingCharHeight )
2388 nSize = rnCharHeight;
2392 nSize =
static_cast<sal_Int32
>(100*(*o3tl::doAccess<float>(
mAny)));
2393 if ( nElement == XML_rPr || nElement == XML_defRPr )
2395 rbOverridingCharHeight =
true;
2396 rnCharHeight = nSize;
2401 nCharKerning =
static_cast<sal_Int32
>(*o3tl::doAccess<sal_Int16>(
mAny));
2408 nCharKerning = ((nCharKerning * 720)-360) / 254;
2410 if ((bComplex &&
GetProperty(rXPropSet,
"CharWeightComplex"))
2413 if ( *o3tl::doAccess<float>(
mAny) >= awt::FontWeight::SEMIBOLD )
2417 if ((bComplex &&
GetProperty(rXPropSet,
"CharPostureComplex"))
2419 switch ( *o3tl::doAccess<awt::FontSlant>(
mAny) )
2421 case awt::FontSlant_OBLIQUE :
2422 case awt::FontSlant_ITALIC :
2430 && eState == beans::PropertyState_DIRECT_VALUE)
2433 switch ( *o3tl::doAccess<sal_Int16>(
mAny) )
2435 case awt::FontUnderline::SINGLE :
2438 case awt::FontUnderline::DOUBLE :
2441 case awt::FontUnderline::DOTTED :
2444 case awt::FontUnderline::DASH :
2447 case awt::FontUnderline::LONGDASH :
2450 case awt::FontUnderline::DASHDOT :
2453 case awt::FontUnderline::DASHDOTDOT :
2456 case awt::FontUnderline::WAVE :
2459 case awt::FontUnderline::DOUBLEWAVE :
2462 case awt::FontUnderline::BOLD :
2465 case awt::FontUnderline::BOLDDOTTED :
2468 case awt::FontUnderline::BOLDDASH :
2471 case awt::FontUnderline::BOLDLONGDASH :
2474 case awt::FontUnderline::BOLDDASHDOT :
2477 case awt::FontUnderline::BOLDDASHDOTDOT :
2480 case awt::FontUnderline::BOLDWAVE :
2487 && eState == beans::PropertyState_DIRECT_VALUE)
2490 switch ( *o3tl::doAccess<sal_Int16>(
mAny) )
2492 case awt::FontStrikeout::NONE :
2493 strikeout =
"noStrike";
2495 case awt::FontStrikeout::SINGLE :
2503 case awt::FontStrikeout::BOLD :
2504 case awt::FontStrikeout::SLASH :
2505 case awt::FontStrikeout::X :
2506 strikeout =
"sngStrike";
2508 case awt::FontStrikeout::DOUBLE :
2509 strikeout =
"dblStrike";
2517 case css::i18n::ScriptType::ASIAN:
2518 bLang =
GetProperty(rXPropSet,
"CharLocaleAsian");
break;
2519 case css::i18n::ScriptType::COMPLEX:
2520 bLang =
GetProperty(rXPropSet,
"CharLocaleComplex");
break;
2522 bLang =
GetProperty(rXPropSet,
"CharLocale");
break;
2527 css::lang::Locale aLocale;
2535 && eState == beans::PropertyState_DIRECT_VALUE)
2536 mAny >>= nCharEscapement;
2539 && eState == beans::PropertyState_DIRECT_VALUE)
2540 mAny >>= nCharEscapementHeight;
2547 nCharEscapement = .8 * (100 - nCharEscapementHeight);
2554 nCharEscapement = .2 * -(100 - nCharEscapementHeight);
2557 if (nCharEscapement && nCharEscapementHeight)
2559 nSize = (nSize * nCharEscapementHeight) / 100;
2561 nSize = (nSize / 0.58);
2566 switch ( *o3tl::doAccess<sal_Int16>(
mAny) )
2568 case CaseMap::UPPERCASE :
2571 case CaseMap::SMALLCAPS :
2577 mpFS->startElementNS( XML_a, nElement,
2581 XML_sz, OString::number(nSize),
2584 XML_strike, strikeout,
2601 && eState == beans::PropertyState_DIRECT_VALUE)
2609 if (rXPropSet->getPropertySetInfo()->hasPropertyByName(
"CharTransparence"))
2611 rXPropSet->getPropertyValue(
"CharTransparence") >>= nTransparency;
2617 bool bContoured =
false;
2619 bContoured = *o3tl::doAccess<bool>(
mAny);
2624 mpFS->startElementNS(XML_a, XML_ln);
2631 color.SetAlpha(255);
2635 mpFS->endElementNS(XML_a, XML_ln);
2643 color.SetAlpha(255);
2654 if (rXShapePropSet.is() &&
GetProperty(rXShapePropSet,
"FillStyle")
2659 bIsTextBackgroundDark = aShapeFillColor.
IsDark();
2662 if (bIsTextBackgroundDark)
2679 mpFS->startElementNS(XML_a, XML_highlight);
2681 mpFS->endElementNS( XML_a, XML_highlight );
2689 && eState == beans::PropertyState_DIRECT_VALUE)
2696 mpFS->startElementNS(XML_a, XML_uFill);
2698 mpFS->endElementNS( XML_a, XML_uFill );
2702 mpFS->singleElementNS(XML_a, XML_uFillTx);
2708 const char*
const pitch =
nullptr;
2709 const char*
const charset =
nullptr;
2710 OUString usTypeface;
2712 mAny >>= usTypeface;
2713 OUString aSubstName(
GetSubsFontName( usTypeface, SubsFontFlags::ONLYONE | SubsFontFlags::MS ) );
2714 if (!aSubstName.isEmpty())
2715 usTypeface = aSubstName;
2717 mpFS->singleElementNS( XML_a, XML_latin,
2718 XML_typeface, usTypeface,
2719 XML_pitchFamily, pitch,
2720 XML_charset, charset );
2725 && eState == beans::PropertyState_DIRECT_VALUE))
2728 && eState == beans::PropertyState_DIRECT_VALUE)))
2730 const char*
const pitch =
nullptr;
2731 const char*
const charset =
nullptr;
2732 OUString usTypeface;
2734 mAny >>= usTypeface;
2735 OUString aSubstName(
GetSubsFontName( usTypeface, SubsFontFlags::ONLYONE | SubsFontFlags::MS ) );
2736 if (!aSubstName.isEmpty())
2737 usTypeface = aSubstName;
2739 mpFS->singleElementNS( XML_a, bComplex ? XML_cs : XML_ea,
2740 XML_typeface, usTypeface,
2741 XML_pitchFamily, pitch,
2742 XML_charset, charset );
2749 mAny >>= rXTextField;
2750 if( rXTextField.is() )
2751 rXPropSet.set( rXTextField, UNO_QUERY );
2760 if (!sURL.isEmpty())
2762 if (!sURL.match(
"#action?jump="))
2774 mpFS->singleElementNS(XML_a, XML_hlinkClick,
FSNS(XML_r, XML_id), sRelId);
2776 mpFS->singleElementNS(XML_a, XML_hlinkClick,
FSNS(XML_r, XML_id), sRelId,
2777 XML_action,
"ppaction://hlinksldjump");
2781 sal_Int32
nIndex = sURL.indexOf(
'=');
2782 std::u16string_view aDestination(sURL.subView(
nIndex + 1));
2783 mpFS->singleElementNS(XML_a, XML_hlinkClick,
FSNS(XML_r, XML_id),
"", XML_action,
2784 OUString::Concat(
"ppaction://hlinkshowjump?jump=") + aDestination);
2788 mpFS->endElementNS( XML_a, nElement );
2794 OUString aFieldType, aFieldValue;
2798 aFieldType = *o3tl::doAccess<OUString>(
mAny);
2799 SAL_INFO(
"oox.shape",
"field type: " << aFieldType);
2802 if( aFieldType ==
"TextField" )
2806 mAny >>= rXTextField;
2807 if( rXTextField.is() )
2809 rXPropSet.set( rXTextField, UNO_QUERY );
2810 if( rXPropSet.is() )
2812 OUString aFieldKind( rXTextField->getPresentation(
true ) );
2813 SAL_INFO(
"oox.shape",
"field kind: " << aFieldKind);
2814 if( aFieldKind ==
"Page" )
2816 aFieldValue =
"slidenum";
2818 else if( aFieldKind ==
"Pages" )
2820 aFieldValue =
"slidecount";
2822 else if( aFieldKind ==
"PageName" )
2824 aFieldValue =
"slidename";
2826 else if( aFieldKind ==
"URL" )
2830 mAny >>= aFieldValue;
2833 else if(aFieldKind ==
"Date")
2835 sal_Int32 nNumFmt = -1;
2839 else if(aFieldKind ==
"ExtTime")
2841 sal_Int32 nNumFmt = -1;
2845 else if(aFieldKind ==
"ExtFile")
2847 sal_Int32 nNumFmt = -1;
2851 case 0: aFieldValue =
"file";
2853 case 1: aFieldValue =
"file1";
2855 case 2: aFieldValue =
"file2";
2857 case 3: aFieldValue =
"file3";
2860 else if(aFieldKind ==
"Author")
2862 aFieldValue =
"author";
2882 OUString aDateField;
2885 case SvxDateFormat::StdSmall:
2886 case SvxDateFormat::A:
2887 aDateField =
"datetime";
2889 case SvxDateFormat::B:
2890 aDateField =
"datetime1";
2892 case SvxDateFormat::C:
2893 aDateField =
"datetime5";
2895 case SvxDateFormat::D:
2896 aDateField =
"datetime3";
2898 case SvxDateFormat::StdBig:
2899 case SvxDateFormat::E:
2900 case SvxDateFormat::F:
2901 aDateField =
"datetime2";
2907 OUString aTimeField;
2910 case SvxTimeFormat::Standard:
2911 case SvxTimeFormat::HH24_MM_SS:
2912 case SvxTimeFormat::HH24_MM_SS_00:
2913 aTimeField =
"datetime11";
2915 case SvxTimeFormat::HH24_MM:
2916 aTimeField =
"datetime10";
2918 case SvxTimeFormat::HH12_MM:
2919 case SvxTimeFormat::HH12_MM_AMPM:
2920 aTimeField =
"datetime12";
2922 case SvxTimeFormat::HH12_MM_SS:
2923 case SvxTimeFormat::HH12_MM_SS_AMPM:
2924 case SvxTimeFormat::HH12_MM_SS_00:
2925 case SvxTimeFormat::HH12_MM_SS_00_AMPM:
2926 aTimeField =
"datetime13";
2932 if (!aDateField.isEmpty() && aTimeField.isEmpty())
2934 else if (!aTimeField.isEmpty() && aDateField.isEmpty())
2936 else if (!aDateField.isEmpty() && !aTimeField.isEmpty())
2938 if (aTimeField ==
"datetime11" || aTimeField ==
"datetime13")
2950 bool& rbOverridingCharHeight, sal_Int32& rnCharHeight,
2951 const css::uno::Reference< css::beans::XPropertySet >& rXShapePropSet)
2954 sal_Int16 nLevel = -1;
2958 bool bNumberingIsNumber =
true;
2960 mAny >>= bNumberingIsNumber;
2962 float nFontSize = -1;
2966 bool bIsURLField =
false;
2968 bool bWriteField = !( sFieldValue.isEmpty() || bIsURLField );
2970 OUString sText = rRun->getString();
2973 if (nLevel !=-1 && bNumberingIsNumber && sText.isEmpty() )
2977 sText = sFieldValue;
2979 if( sText.isEmpty())
2985 if( !xPropSet.is() || !( xPropSet->getPropertyValue(
"PlaceholderText" ) >>= sText ) )
2987 if( sText.isEmpty() )
3001 mpFS->startElementNS(XML_a, XML_br);
3002 mpFS->singleElementNS(XML_a, XML_rPr, XML_sz,
3003 OString::number(nFontSize * 100));
3004 mpFS->endElementNS(XML_a, XML_br);
3007 mpFS->singleElementNS(XML_a, XML_br);
3014 mpFS->startElementNS( XML_a, XML_fld,
3015 XML_id, sUUID.getStr(),
3020 mpFS->startElementNS(XML_a, XML_r);
3026 mpFS->startElementNS(XML_a, XML_t);
3027 mpFS->writeEscaped( sText );
3028 mpFS->endElementNS( XML_a, XML_t );
3031 mpFS->endElementNS( XML_a, XML_fld );
3033 mpFS->endElementNS( XML_a, XML_r );
3039 OUString sPrefixSuffix;
3042 sPrefixSuffix =
"ParenBoth";
3044 sPrefixSuffix =
"ParenR";
3046 sPrefixSuffix =
"Period";
3048 switch( nNumberingType )
3052 return "alphaUc" + sPrefixSuffix;
3056 return "alphaLc" + sPrefixSuffix;
3059 return "romanUc" + sPrefixSuffix;
3062 return "romanLc" + sPrefixSuffix;
3066 if (sPrefixSuffix.isEmpty())
3067 return "arabicPlain";
3069 return "arabic" + sPrefixSuffix;
3080 if (nLevel < 0 || !
GetProperty(rXPropSet,
"NumberingRules"))
3085 if (!(
mAny >>= rXIndexAccess) || nLevel >= rXIndexAccess->getCount())
3088 SAL_INFO(
"oox.shape",
"numbering rules");
3091 rXIndexAccess->getByIndex(nLevel) >>= aPropertySequence;
3093 if (!aPropertySequence.hasElements())
3098 bool bPBehind =
false;
3099 bool bPBoth =
false;
3101 awt::FontDescriptor aFontDesc;
3102 bool bHasFontDesc =
false;
3103 uno::Reference<graphic::XGraphic> xGraphic;
3104 sal_Int16 nBulletRelSize = 0;
3105 sal_Int16 nStartWith = 1;
3107 bool bHasBulletColor =
false;
3108 awt::Size aGraphicSize;
3110 for (
const PropertyValue& rPropValue : std::as_const(aPropertySequence) )
3116 nNumberingType =
static_cast<SvxNumType>(*o3tl::doAccess<sal_Int16>(rPropValue.Value));
3120 if( *o3tl::doAccess<OUString>(rPropValue.Value) ==
")")
3125 auto s = o3tl::doAccess<OUString>(rPropValue.Value);
3134 bHasBulletColor =
true;
3138 aBulletChar = (*o3tl::doAccess<OUString>(rPropValue.Value))[ 0 ];
3142 aFontDesc = *o3tl::doAccess<awt::FontDescriptor>(rPropValue.Value);
3143 bHasFontDesc =
true;
3149 if ( aFontDesc.Name.equalsIgnoreAsciiCase(
"StarSymbol") )
3150 aFontDesc.CharSet = RTL_TEXTENCODING_MS_1252;
3153 else if (
aPropName ==
"BulletRelSize" )
3155 nBulletRelSize = *o3tl::doAccess<sal_Int16>(rPropValue.Value);
3159 nStartWith = *o3tl::doAccess<sal_Int16>(rPropValue.Value);
3163 auto xBitmap = rPropValue.Value.get<uno::Reference<awt::XBitmap>>();
3164 xGraphic.set(xBitmap, uno::UNO_QUERY);
3168 aGraphicSize = *o3tl::doAccess<awt::Size>(rPropValue.Value);
3169 SAL_INFO(
"oox.shape",
"graphic size: " << aGraphicSize.Width <<
"x" << aGraphicSize.Height);
3177 if (xGraphic.is() && aGraphic.
GetType() != GraphicType::NONE)
3182 OUString sRelationId;
3184 if (fBulletSizeRel < 1.0f)
3187 Size aDestSize(64, 64);
3188 float fBulletSizeRelX = fBulletSizeRel / aGraphicSize.Height * aGraphicSize.Width;
3189 tools::Long nPaddingX = std::max<tools::Long>(0, std::lround((aDestSize.
Width() - fBulletSizeRelX * aDestSize.
Width()) / 2.f));
3199 aDestBitmap.
CopyPixel(aDestRect, aSourceRect, &aSourceBitmap);
3200 Graphic aDestGraphic(aDestBitmap);
3202 fBulletSizeRel = 1.0f;
3209 mpFS->singleElementNS( XML_a, XML_buSzPct,
3210 XML_val, OString::number(std::min<sal_Int32>(std::lround(100000.f * fBulletSizeRel), 400000)));
3211 mpFS->startElementNS(XML_a, XML_buBlip);
3212 mpFS->singleElementNS(XML_a, XML_blip,
FSNS(XML_r, XML_embed), sRelationId);
3213 mpFS->endElementNS( XML_a, XML_buBlip );
3223 mpFS->startElementNS(XML_a, XML_buClr);
3225 mpFS->endElementNS( XML_a, XML_buClr );
3228 if( nBulletRelSize && nBulletRelSize != 100 )
3229 mpFS->singleElementNS( XML_a, XML_buSzPct,
3230 XML_val, OString::number(std::clamp<sal_Int32>(1000*nBulletRelSize, 25000, 400000)));
3235 mpFS->singleElementNS( XML_a, XML_buFont,
3236 XML_typeface, aFontDesc.Name,
3240 OUString aAutoNumType =
GetAutoNumType( nNumberingType, bSDot, bPBehind, bPBoth );
3242 if (!aAutoNumType.isEmpty())
3244 mpFS->singleElementNS(XML_a, XML_buAutoNum,
3250 mpFS->singleElementNS(XML_a, XML_buChar, XML_char, OUString(aBulletChar));
3257 css::uno::Sequence<css::style::TabStop> aTabStops;
3259 aTabStops = *o3tl::doAccess<css::uno::Sequence<css::style::TabStop>>(
mAny);
3261 if (aTabStops.getLength() > 0)
3262 mpFS->startElementNS(XML_a, XML_tabLst);
3264 for (
const css::style::TabStop& rTabStop : std::as_const(aTabStops))
3268 switch (rTabStop.Alignment)
3270 case css::style::TabAlign_DECIMAL:
3273 case css::style::TabAlign_RIGHT:
3276 case css::style::TabAlign_CENTER:
3279 case css::style::TabAlign_LEFT:
3283 mpFS->singleElementNS(XML_a, XML_tab, XML_algn, sAlignment, XML_pos, sPosition);
3285 if (aTabStops.getLength() > 0)
3286 mpFS->endElementNS(XML_a, XML_tabLst);
3294 uno::Reference<lang::XServiceInfo> xServiceInfo(rXShape, uno::UNO_QUERY_THROW);
3295 bRet = xServiceInfo->supportsService(
"com.sun.star.drawing.GroupShape");
3302 if (nLevel < 0 || !
GetProperty(rXPropSet,
"NumberingRules"))
3307 if (!(
mAny >>= rXIndexAccess) || nLevel >= rXIndexAccess->getCount())
3310 SAL_INFO(
"oox.shape",
"numbering rules");
3313 rXIndexAccess->getByIndex(nLevel) >>= aPropertySequence;
3315 if (!aPropertySequence.hasElements())
3318 for (
const PropertyValue& rPropValue : std::as_const(aPropertySequence) )
3323 return *o3tl::doAccess<sal_Int32>(rPropValue.Value);
3331 const char* sAlignment =
nullptr;
3333 switch( nAlignment )
3335 case style::ParagraphAdjust_CENTER:
3338 case style::ParagraphAdjust_RIGHT:
3341 case style::ParagraphAdjust_BLOCK:
3342 sAlignment =
"just";
3353 if( rSpacing.Mode == LineSpacingMode::PROP )
3355 mpFS->singleElementNS( XML_a, XML_spcPct,
3356 XML_val, OString::number(
static_cast<sal_Int32
>(rSpacing.Height)*1000));
3358 else if (rSpacing.Mode == LineSpacingMode::MINIMUM
3359 && fFirstCharHeight >
static_cast<float>(rSpacing.Height) * 0.001 * 72.0 / 2.54)
3362 mpFS->singleElementNS(XML_a, XML_spcPct, XML_val,
3363 OString::number(
static_cast<sal_Int32
>(100000)));
3367 mpFS->singleElementNS( XML_a, XML_spcPts,
3368 XML_val, OString::number(std::lround(rSpacing.Height / 25.4 * 72)));
3376 PropertyState eState;
3378 if( !rXPropSet.is() || !rXPropState.is() )
3381 sal_Int16 nLevel = -1;
3385 bool bWriteNumbering =
true;
3386 bool bForceZeroIndent =
false;
3392 bool bNumberingOnThisLevel =
false;
3397 for (
const PropertyValue& rRule : rNumRuleOfLevel)
3398 if (rRule.Name ==
"NumberingType" && rRule.Value.hasValue())
3399 bNumberingOnThisLevel = rRule.Value.get<sal_uInt16>() != style::NumberingType::NUMBER_NONE;
3402 const bool bIsNumberingVisible = rXPropSet->getPropertyValue(
"NumberingIsNumber").get<
bool>();
3403 const bool bIsLineEmpty = !xParaText->getString().getLength();
3405 bWriteNumbering = !bIsLineEmpty && bIsNumberingVisible && (nLevel != -1);
3406 bForceZeroIndent = (!bIsNumberingVisible || bIsLineEmpty || !bNumberingOnThisLevel);
3411 sal_Int16 nTmp = sal_Int16(style::ParagraphAdjust_LEFT);
3414 style::ParagraphAdjust nAlignment =
static_cast<style::ParagraphAdjust
>(nTmp);
3416 bool bHasLinespacing =
false;
3417 LineSpacing aLineSpacing;
3419 && (
mAny >>= aLineSpacing)
3420 && (eState == beans::PropertyState_DIRECT_VALUE ||
3422 aLineSpacing.Mode != LineSpacingMode::PROP || aLineSpacing.Height != 100))
3423 bHasLinespacing =
true;
3428 sal_Int16 nWritingMode;
3429 if( (
mAny >>= nWritingMode ) && nWritingMode == text::WritingMode2::RL_TB )
3435 sal_Int32 nParaLeftMargin = 0;
3436 sal_Int32 nParaFirstLineIndent = 0;
3439 mAny >>= nParaLeftMargin;
3440 if (
GetProperty(rXPropSet,
"ParaFirstLineIndent"))
3441 mAny >>= nParaFirstLineIndent;
3443 sal_Int32 nParaTopMargin = 0;
3444 sal_Int32 nParaBottomMargin = 0;
3447 mAny >>= nParaTopMargin;
3449 mAny >>= nParaBottomMargin;
3454 if (bWriteNumbering && !bForceZeroIndent)
3457 || nAlignment != style::ParagraphAdjust_LEFT
3458 || bHasLinespacing))
3462 sal_Int32 nParaDefaultTabSize = 0;
3463 if (
GetProperty(rXPropSet,
"ParaTabStopDefaultDistance"))
3464 mAny >>= nParaDefaultTabSize;
3466 if (nParaLeftMargin)
3467 mpFS->startElementNS( XML_a, nElement,
3475 mpFS->startElementNS( XML_a, nElement,
3484 if( bHasLinespacing )
3486 mpFS->startElementNS(XML_a, XML_lnSpc);
3488 mpFS->endElementNS( XML_a, XML_lnSpc );
3491 if( nParaTopMargin != 0 )
3493 mpFS->startElementNS(XML_a, XML_spcBef);
3495 mpFS->singleElementNS( XML_a, XML_spcPts,
3496 XML_val, OString::number(std::lround(nParaTopMargin / 25.4 * 72)));
3498 mpFS->endElementNS( XML_a, XML_spcBef );
3501 if( nParaBottomMargin != 0 )
3503 mpFS->startElementNS(XML_a, XML_spcAft);
3505 mpFS->singleElementNS( XML_a, XML_spcPts,
3506 XML_val, OString::number(std::lround(nParaBottomMargin / 25.4 * 72)));
3508 mpFS->endElementNS( XML_a, XML_spcAft );
3511 if (!bWriteNumbering)
3512 mpFS->singleElementNS(XML_a, XML_buNone);
3519 if( nElement != XML_lvl1pPr )
3520 mpFS->endElementNS( XML_a, nElement );
3526 bool& rbOverridingCharHeight, sal_Int32& rnCharHeight,
3527 const css::uno::Reference<css::beans::XPropertySet>& rXShapePropSet)
3534 if (!xEnumeration.is())
3540 if (!xEnumeration->hasMoreElements())
3543 Any aAny(xEnumeration->nextElement());
3546 float fFirstCharHeight = rnCharHeight / 1000.;
3549 = xFirstRunPropSet->getPropertySetInfo();
3551 if (xFirstRunPropSetInfo->hasPropertyByName(
"CharHeight"))
3552 fFirstCharHeight = xFirstRunPropSet->getPropertyValue(
"CharHeight").get<
float>();
3554 mpFS->startElementNS(XML_a, XML_lstStyle);
3556 mpFS->startElementNS(XML_a, XML_lvl1pPr);
3557 WriteRunProperties(xFirstRunPropSet,
false, XML_defRPr,
true, rbOverridingCharHeight,
3558 rnCharHeight,
GetScriptType(rRun->getString()), rXShapePropSet);
3559 mpFS->endElementNS(XML_a, XML_lvl1pPr);
3560 mpFS->endElementNS(XML_a, XML_lstStyle);
3565 bool& rbOverridingCharHeight, sal_Int32& rnCharHeight,
3566 const css::uno::Reference< css::beans::XPropertySet >& rXShapePropSet)
3573 if( !enumeration.is() )
3576 mpFS->startElementNS(XML_a, XML_p);
3578 bool bPropertiesWritten =
false;
3579 while( enumeration->hasMoreElements() )
3582 Any any ( enumeration->nextElement() );
3586 if( !bPropertiesWritten )
3588 float fFirstCharHeight = rnCharHeight / 1000.;
3591 if( xFirstRunPropSetInfo->hasPropertyByName(
"CharHeight") )
3593 fFirstCharHeight = xFirstRunPropSet->getPropertyValue(
"CharHeight").get<
float>();
3594 rnCharHeight = 100 * fFirstCharHeight;
3595 rbOverridingCharHeight =
true;
3598 bPropertiesWritten =
true;
3600 WriteRun(
run, rbOverridingCharHeight, rnCharHeight, rXShapePropSet);
3604 sal_Int16 nDummy = -1;
3606 rnCharHeight, nDummy, rXShapePropSet);
3608 mpFS->endElementNS( XML_a, XML_p );
3613 bool bResult(
false);
3614 if (rXShapePropSet.is())
3617 if (
GetProperty(rXShapePropSet,
"CustomShapeGeometry"))
3619 mAny >>= aCustomShapeGeometryProps;
3620 uno::Sequence<beans::PropertyValue> aTextPathSeq;
3621 for (
const auto& rProp : std::as_const(aCustomShapeGeometryProps))
3623 if (rProp.Name ==
"TextPath")
3625 rProp.Value >>= aTextPathSeq;
3626 for (
const auto& rTextPathItem : std::as_const(aTextPathSeq))
3628 if (rTextPathItem.Name ==
"TextPath")
3630 rTextPathItem.Value >>= bResult;
3643 sal_Int32 nXmlNamespace,
bool bWritePropertiesAsLstStyles)
3646 uno::Reference<XText> xXText(rXIface, UNO_QUERY);
3650 uno::Reference<drawing::XShape> xShape(rXIface, UNO_QUERY);
3651 uno::Reference<XPropertySet> rXPropSet(rXIface, UNO_QUERY);
3653 constexpr const sal_Int32 constDefaultLeftRightInset = 254;
3654 constexpr const sal_Int32 constDefaultTopBottomInset = 127;
3655 sal_Int32 nLeft = constDefaultLeftRightInset;
3656 sal_Int32 nRight = constDefaultLeftRightInset;
3657 sal_Int32 nTop = constDefaultTopBottomInset;
3658 sal_Int32 nBottom = constDefaultTopBottomInset;
3674 sal_Int32 nTextHeight = xShape->getSize().Height;
3687 if (nTop + nBottom >= nTextHeight)
3692 std::swap(nTop, nBottom);
3693 nTop = nTextHeight - nTop;
3694 nBottom = nTextHeight - nBottom;
3698 std::optional<OString> sWritingMode;
3703 sWritingMode =
"eaVert";
3707 sal_Int16 nWritingMode;
3708 if (
mAny >>= nWritingMode)
3710 if (nWritingMode == text::WritingMode2::TB_RL)
3711 sWritingMode =
"eaVert";
3712 else if (nWritingMode == text::WritingMode2::BT_LR)
3713 sWritingMode =
"vert270";
3714 else if (nWritingMode == text::WritingMode2::TB_RL90)
3715 sWritingMode =
"vert";
3716 else if (nWritingMode == text::WritingMode2::TB_LR)
3717 sWritingMode =
"mongolianVert";
3723 uno::Sequence<beans::PropertyValue> aTextPathSeq;
3724 bool bScaleX(
false);
3725 OUString sShapeType(
"non-primitive");
3726 OUString sMSWordPresetTextWarp;
3727 sal_Int32 nTextPreRotateAngle = 0;
3728 std::optional<Degree100> nTextRotateAngleDeg100;
3730 if (
GetProperty(rXPropSet,
"CustomShapeGeometry"))
3733 if (
mAny >>= aProps )
3735 for (
const auto& rProp : std::as_const(aProps) )
3737 if (rProp.Name ==
"TextPreRotateAngle")
3738 rProp.Value >>= nTextPreRotateAngle;
3739 else if (rProp.Name ==
"AdjustmentValues")
3740 rProp.Value >>= aAdjustmentSeq;
3741 else if (rProp.Name ==
"TextRotateAngle")
3743 double fTextRotateAngle = 0;
3744 rProp.Value >>= fTextRotateAngle;
3745 nTextRotateAngleDeg100 =
Degree100(std::lround(fTextRotateAngle * 100.0));
3747 else if (rProp.Name ==
"Type")
3748 rProp.Value >>= sShapeType;
3749 else if (rProp.Name ==
"TextPath")
3751 rProp.Value >>= aTextPathSeq;
3752 for (
const auto& rTextPathItem : std::as_const(aTextPathSeq))
3754 if (rTextPathItem.Name ==
"ScaleX")
3755 rTextPathItem.Value >>= bScaleX;
3758 else if (rProp.Name ==
"PresetTextWarp")
3759 rProp.Value >>= sMSWordPresetTextWarp;
3772 uno::Reference<beans::XPropertySet> xPropSet(xTextFrame, uno::UNO_QUERY);
3773 auto aAny = xPropSet->getPropertyValue(
"WritingMode");
3774 sal_Int16 nWritingMode;
3775 if (aAny >>= nWritingMode)
3777 switch (nWritingMode)
3779 case WritingMode2::TB_RL:
3780 sWritingMode =
"eaVert";
3782 case WritingMode2::BT_LR:
3783 sWritingMode =
"vert270";
3785 case WritingMode2::TB_RL90:
3786 sWritingMode =
"vert";
3788 case WritingMode2::TB_LR:
3789 sWritingMode =
"mongolianVert";
3801 std::optional<OUString> sHorzOverflow;
3802 std::optional<OUString> sVertOverflow;
3803 bool bUpright =
false;
3804 std::optional<OString> isUpright;
3805 if (rXPropSet->getPropertySetInfo()->hasPropertyByName(
"InteropGrabBag"))
3807 uno::Sequence<beans::PropertyValue> aGrabBag;
3808 rXPropSet->getPropertyValue(
"InteropGrabBag") >>= aGrabBag;
3809 for (
const auto& aProp : std::as_const(aGrabBag))
3811 if (aProp.Name ==
"Upright")
3813 aProp.Value >>= bUpright;
3814 isUpright = OString(bUpright ?
"1" :
"0");
3816 else if (aProp.Name ==
"horzOverflow")
3819 aProp.Value >>= sValue;
3820 sHorzOverflow = sValue;
3822 else if (aProp.Name ==
"vertOverflow")
3825 aProp.Value >>= sValue;
3826 sVertOverflow = sValue;
3834 if (sPresetWarp.isEmpty())
3835 sPresetWarp = bIsFontworkShape ? std::u16string_view(
u"textPlain") : std::u16string_view(
u"textNoShape");
3837 bool bFromWordArt = !bScaleX
3838 && ( sPresetWarp ==
"textArchDown" || sPresetWarp ==
"textArchUp"
3839 || sPresetWarp ==
"textButton" || sPresetWarp ==
"textCircle");
3852 Degree100 nShapeRotateAngleDeg100(0_deg100);
3857 bool bWasAngleChanged
3858 = (nShapeRotateAngleDeg100 > 4500_deg100 && nShapeRotateAngleDeg100 <= 13500_deg100)
3859 || (nShapeRotateAngleDeg100 > 22500_deg100
3860 && nShapeRotateAngleDeg100 <= 31500_deg100);
3861 if (bWasAngleChanged)
3863 nTextRotateAngleDeg100 = nTextRotateAngleDeg100.value_or(0_deg100) + 9000_deg100;
3864 nTextPreRotateAngle -= 90;
3870 Degree100 nAngleSum = nShapeRotateAngleDeg100 + nTextRotateAngleDeg100.value_or(0_deg100);
3873 nTextRotateAngleDeg100.reset();
3879 if (bWasAngleChanged)
3881 nTextPreRotateAngle += 90;
3882 nTextRotateAngleDeg100 = nTextRotateAngleDeg100.value_or(0_deg100) - 9000_deg100;
3889 if (nTextPreRotateAngle != 0 && !sWritingMode)
3891 if (nTextPreRotateAngle == -90 || nTextPreRotateAngle == 270)
3892 sWritingMode =
"vert";
3893 else if (nTextPreRotateAngle == -270 || nTextPreRotateAngle == 90)
3894 sWritingMode =
"vert270";
3895 else if (nTextPreRotateAngle == -180 || nTextPreRotateAngle == 180)
3897#if defined __GNUC__ && !defined __clang__ && __GNUC__ == 12
3898#pragma GCC diagnostic push
3899#pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
3901 nTextRotateAngleDeg100
3902 =
NormAngle18000(nTextRotateAngleDeg100.value_or(0_deg100) + 18000_deg100);
3903#if defined __GNUC__ && !defined __clang__ && __GNUC__ == 12
3904#pragma GCC diagnostic pop
3909 SAL_WARN(
"oox",
"unsuitable value for TextPreRotateAngle:" << nTextPreRotateAngle);
3911 else if (nTextPreRotateAngle != 0 && sWritingMode && sWritingMode.value() ==
"eaVert")
3922 if (sWritingMode.value() ==
"vert" || sWritingMode.value() ==
"eaVert")
3924 sal_Int32 nHelp = nLeft;
3930 else if (sWritingMode.value() ==
"vert270")
3932 sal_Int32 nHelp = nLeft;
3938 else if (sWritingMode.value() ==
"mongolianVert")
3945 std::optional<OString> sTextRotateAngleMSUnit;
3946 if (nTextRotateAngleDeg100.has_value())
3947#if defined __GNUC__ && !defined __clang__ && __GNUC__ == 12
3948#pragma GCC diagnostic push
3949#pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
3951 sTextRotateAngleMSUnit
3953#if defined __GNUC__ && !defined __clang__ && __GNUC__ == 12
3954#pragma GCC diagnostic pop
3960 TextVerticalAdjust eVerticalAlignment(TextVerticalAdjust_TOP);
3962 mAny >>= eVerticalAlignment;
3963 TextHorizontalAdjust eHorizontalAlignment(TextHorizontalAdjust_CENTER);
3964 if (
GetProperty(rXPropSet,
"TextHorizontalAdjust"))
3965 mAny >>= eHorizontalAlignment;
3967 const char* sAnchor =
nullptr;
3968 bool bAnchorCtr =
false;
3969 if (sWritingMode.has_value()
3970 && (sWritingMode.value() ==
"eaVert" || sWritingMode.value() ==
"mongolianVert"))
3972 bAnchorCtr = eVerticalAlignment == TextVerticalAdjust_CENTER
3973 || eVerticalAlignment == TextVerticalAdjust_BOTTOM
3974 || eVerticalAlignment == TextVerticalAdjust_BLOCK;
3975 switch (eHorizontalAlignment)
3977 case TextHorizontalAdjust_CENTER:
3980 case TextHorizontalAdjust_LEFT:
3981 sAnchor = sWritingMode.value() ==
"eaVert" ?
"b" :
"t";
3983 case TextHorizontalAdjust_RIGHT:
3985 sAnchor = sWritingMode.value() ==
"eaVert" ?
"t" :
"b";
3991 bAnchorCtr = eHorizontalAlignment == TextHorizontalAdjust_CENTER
3992 || eHorizontalAlignment == TextHorizontalAdjust_RIGHT;
3996 bool bHasWrap =
false;
4007 const char* pWrap = (bHasWrap && !bWrap) || bIsFontworkShape ?
"none" :
nullptr;
4013 uno::Reference<lang::XServiceInfo> xServiceInfo(rXIface, uno::UNO_QUERY);
4014 if ((xServiceInfo.is() && xServiceInfo->supportsService(
"com.sun.star.drawing.TextShape"))
4015 || bIsFontworkShape)
4019 sal_Int16 nCols = 0;
4020 sal_Int32 nColSpacing = -1;
4023 if (css::uno::Reference<css::text::XTextColumns> xCols{
mAny, css::uno::UNO_QUERY })
4025 nCols = xCols->getColumnCount();
4026 if (css::uno::Reference<css::beans::XPropertySet> xProps{
mAny,
4027 css::uno::UNO_QUERY })
4030 mAny >>= nColSpacing;
4035 if (!sVertOverflow &&
GetProperty(rXPropSet,
"TextClipVerticalOverflow") &&
mAny.get<
bool>())
4037 sVertOverflow =
"clip";
4040 mpFS->startElementNS( (nXmlNamespace ? nXmlNamespace : XML_a), XML_bodyPr,
4044 XML_horzOverflow, sHorzOverflow,
4045 XML_vertOverflow, sVertOverflow,
4051 XML_anchor, sAnchor,
4053 XML_vert, sWritingMode,
4054 XML_upright, isUpright,
4055 XML_rot, sTextRotateAngleMSUnit);
4057 if (bIsFontworkShape)
4059 if (aAdjustmentSeq.hasElements())
4061 mpFS->startElementNS(XML_a, XML_prstTxWarp, XML_prst, sPresetWarp);
4062 mpFS->startElementNS(XML_a, XML_avLst);
4063 bool bHasTwoHandles(
4064 sPresetWarp ==
"textArchDownPour" || sPresetWarp ==
"textArchUpPour"
4065 || sPresetWarp ==
"textButtonPour" || sPresetWarp ==
"textCirclePour"
4066 || sPresetWarp ==
"textDoubleWave1" || sPresetWarp ==
"textWave1"
4067 || sPresetWarp ==
"textWave2" || sPresetWarp ==
"textWave4");
4068 for (sal_Int32
i = 0, nElems = aAdjustmentSeq.getLength();
i < nElems; ++
i )
4070 OString
sName =
"adj" + (bHasTwoHandles ? OString::number(
i + 1) : OString());
4072 if (aAdjustmentSeq[
i].
Value.getValueTypeClass() == TypeClass_DOUBLE)
4073 aAdjustmentSeq[
i].Value >>= fValue;
4076 sal_Int32 nNumber(0);
4077 aAdjustmentSeq[
i].Value >>= nNumber;
4078 fValue =
static_cast<double>(nNumber);
4083 if (sPresetWarp ==
"textArchDown" || sPresetWarp ==
"textArchUp"
4084 || sPresetWarp ==
"textButton" || sPresetWarp ==
"textCircle"
4086 && (sPresetWarp ==
"textArchDownPour" || sPresetWarp ==
"textArchUpPour"
4087 || sPresetWarp ==
"textButtonPour" || sPresetWarp ==
"textCirclePour")))
4094 && (sPresetWarp ==
"textDoubleWave1" || sPresetWarp ==
"textWave1"
4095 || sPresetWarp ==
"textWave2" || sPresetWarp ==
"textWave4"))
4097 fValue = fValue / 0.216 - 50000.0;
4100 && (sPresetWarp ==
"textArchDownPour"
4101 || sPresetWarp ==
"textArchUpPour"
4102 || sPresetWarp ==
"textButtonPour"
4103 || sPresetWarp ==
"textCirclePour"))
4111 OString sFmla =
"val " + OString::number(std::lround(fValue));
4112 mpFS->singleElementNS(XML_a, XML_gd, XML_name,
sName, XML_fmla, sFmla);
4114 if (!bHasTwoHandles)
4117 mpFS->endElementNS(XML_a, XML_avLst);
4118 mpFS->endElementNS(XML_a, XML_prstTxWarp);
4122 mpFS->singleElementNS(XML_a, XML_prstTxWarp, XML_prst, sPresetWarp);
4128 if (!sMSWordPresetTextWarp.isEmpty())
4129 mpFS->singleElementNS(XML_a, XML_prstTxWarp, XML_prst, sMSWordPresetTextWarp);
4135 bool bTextAutoGrowHeight =
false;
4137 if (pSdrObjCustomShape &&
GetProperty(rXPropSet,
"TextAutoGrowHeight"))
4139 mAny >>= bTextAutoGrowHeight;
4141 mpFS->singleElementNS(XML_a, (bTextAutoGrowHeight ? XML_spAutoFit : XML_noAutofit));
4145 TextFitToSizeType eFit = TextFitToSizeType_NONE;
4149 if (eFit == TextFitToSizeType_AUTOFIT)
4151 const sal_Int32 MAX_SCALE_VAL = 100000;
4152 sal_Int32 nFontScale = MAX_SCALE_VAL;
4153 sal_Int32 nSpacingReduction = 0;
4160 nFontScale = sal_Int32(pTextObject->
GetFontScale() * 1000.0);
4161 nSpacingReduction = sal_Int32((100.0 - pTextObject->
GetSpacingScale()) * 1000.0);
4165 bool bExportFontScale =
false;
4166 if (nFontScale < MAX_SCALE_VAL && nFontScale > 0)
4167 bExportFontScale =
true;
4169 bool bExportSpaceReduction =
false;
4170 if (nSpacingReduction < MAX_SCALE_VAL && nSpacingReduction > 0)
4171 bExportSpaceReduction =
true;
4173 mpFS->singleElementNS(XML_a, XML_normAutofit,
4175 XML_lnSpcReduction,
sax_fastparser::UseIf(OString::number(nSpacingReduction), bExportSpaceReduction));
4180 bool bTextAutoGrowHeight =
false;
4182 mAny >>= bTextAutoGrowHeight;
4183 mpFS->singleElementNS(XML_a, (bTextAutoGrowHeight ? XML_spAutoFit : XML_noAutofit));
4189 mpFS->endElementNS((nXmlNamespace ? nXmlNamespace : XML_a), XML_bodyPr);
4193 if( !access.is() || !bText )
4197 if( !enumeration.is() )
4204 std::vector<beans::PropertyValue> aOldCharFillPropVec;
4205 if (bIsFontworkShape)
4214 std::vector<beans::PropertyValue> aExportCharFillPropVec;
4220 std::vector<beans::PropertyValue> aUpdatePropVec;
4245 if (bIsFontworkShape)
4250 bool bOverridingCharHeight =
false;
4251 sal_Int32 nCharHeight = -1;
4252 bool bFirstParagraph =
true;
4256 if(xXText->getString().isEmpty() && enumeration->hasMoreElements())
4258 Any aAny (enumeration->nextElement());
4260 if( aAny >>= xParagraph )
4262 mpFS->startElementNS(XML_a, XML_p);
4264 sal_Int16 nDummy = -1;
4266 bOverridingCharHeight, nCharHeight, nDummy, rXPropSet);
4267 mpFS->endElementNS(XML_a, XML_p);
4272 while( enumeration->hasMoreElements() )
4275 Any any ( enumeration->nextElement() );
4279 if (bFirstParagraph && bWritePropertiesAsLstStyles)
4283 bFirstParagraph =
false;
4290 mpFS->startElementNS(XML_a, XML_prstGeom, XML_prst, pShape);
4291 if ( !rAvList.empty() )
4294 mpFS->startElementNS(XML_a, XML_avLst);
4295 for (
auto const& elem : rAvList)
4297 OString
sName =
"adj" + ( ( elem.first > 0 ) ? OString::number(elem.first) : OString() );
4298 OString sFmla =
"val " + OString::number( elem.second );
4300 mpFS->singleElementNS(XML_a, XML_gd, XML_name,
sName, XML_fmla, sFmla);
4302 mpFS->endElementNS( XML_a, XML_avLst );
4305 mpFS->singleElementNS(XML_a, XML_avLst);
4307 mpFS->endElementNS( XML_a, XML_prstGeom );
4312 mpFS->startElementNS(XML_a, XML_prstGeom, XML_prst, pShape);
4313 mpFS->singleElementNS(XML_a, XML_avLst);
4314 mpFS->endElementNS( XML_a, XML_prstGeom );
4319 std::map< OString, std::vector<OString> > aRet;
4321 OUString aPath(
"$BRAND_BASE_DIR/" LIBO_SHARE_FOLDER
"/filter/oox-drawingml-adj-names");
4322 rtl::Bootstrap::expandMacros(aPath);
4325 SAL_WARN(
"oox.shape",
"failed to open oox-drawingml-adj-names");
4326 OStringBuffer aLine;
4327 bool bNotDone = aStream.
ReadLine(aLine);
4333 OString aValue( std::string_view(aLine).substr(
nIndex) );
4334 aRet[aKey].push_back(aValue);
4335 bNotDone = aStream.
ReadLine(aLine);
4342 static std::map< OString, std::vector<OString> > aAdjMap =
lcl_getAdjNames();
4344 std::vector<OString> aAdjustments;
4345 if (aAdjMap.find(pShape) != aAdjMap.end())
4346 aAdjustments = aAdjMap[pShape];
4348 mpFS->startElementNS(XML_a, XML_prstGeom, XML_prst, pShape);
4349 mpFS->startElementNS(XML_a, XML_avLst);
4351 Sequence< drawing::EnhancedCustomShapeAdjustmentValue > aAdjustmentSeq;
4352 if ( ( rProp.Value >>= aAdjustmentSeq )
4353 && eShapeType != mso_sptActionButtonForwardNext
4354 && eShapeType != mso_sptActionButtonBackPrevious
4358 SAL_INFO(
"oox.shape",
"adj seq len: " << aAdjustmentSeq.getLength());
4359 sal_Int32 nAdjustmentsWhichNeedsToBeConverted = 0;
4360 if ( bPredefinedHandlesUsed )
4368 for (sal_Int32
i = 0; i < static_cast<sal_Int32>(aAdjustments.size());
i++)
4373 OString aAdjName = aAdjustmentSeq[
i].Name.isEmpty()
4375 : aAdjustmentSeq[
i].Name.toUtf8();
4377 mpFS->singleElementNS( XML_a, XML_gd,
4379 XML_fmla,
"val " + OString::number(nValue));
4385 mpFS->endElementNS( XML_a, XML_avLst );
4386 mpFS->endElementNS( XML_a, XML_prstGeom );
4392FindNextCommandEndSubpath(
const sal_Int32 nStart,
4393 const uno::Sequence<drawing::EnhancedCustomShapeSegment>& rSegments)
4395 sal_Int32
i = nStart < 0 ? 0 : nStart;
4396 while (
i < rSegments.getLength() && rSegments[
i].Command != ENDSUBPATH)
4401bool HasCommandInSubPath(
const sal_Int16 nCommand,
const sal_Int32 nFirst,
const sal_Int32 nLast,
4402 const uno::Sequence<drawing::EnhancedCustomShapeSegment>& rSegments)
4404 for (sal_Int32
i = nFirst < 0 ? 0 : nFirst;
i <= nLast &&
i < rSegments.getLength();
i++)
4406 if (rSegments[
i].Command == nCommand)
4414void getEllipsePointAndAngleFromRayPoint(
double& rfAngleDeg,
double& rfSx,
double& rfSy,
4415 const double fWR,
const double fHR,
const double fCx,
4416 const double fCy,
const double fRayPx,
const double fRayPy)
4427 double fCircleMathAngle = atan2(-fWR / fHR * (fRayPy - fCy), fRayPx - fCx);
4429 double fPointMathEllipse_x = fWR * cos(fCircleMathAngle);
4430 double fPointMathEllipse_y = fHR * sin(fCircleMathAngle);
4432 double fEllipseMathAngle = atan2(fPointMathEllipse_y, fPointMathEllipse_x);
4435 rfSx = fPointMathEllipse_x + fCx;
4436 rfSy = -fPointMathEllipse_y + fCy;
4440void getEllipsePointFromViewAngle(
double& rfSx,
double& rfSy,
const double fWR,
const double fHR,
4441 const double fCx,
const double fCy,
const double fViewAngleDeg)
4452 double fRadius = 1.0 / std::hypot(fX, fY);
4458sal_Int32 GetCustomGeometryPointValue(
const css::drawing::EnhancedCustomShapeParameter& rParam,
4460 const bool bReplaceGeoWidth,
const bool bReplaceGeoHeight)
4462 double fValue = 0.0;
4463 rCustomShape2d.
GetParameter(fValue, rParam, bReplaceGeoWidth, bReplaceGeoHeight);
4464 sal_Int32
nValue(std::lround(fValue));
4484 std::vector<Guide>& rGuideList, TextAreaRect& rTextAreaRect)
4488 if (aTextAreaLO == aLogicRectLO)
4490 rTextAreaRect.left =
"l";
4491 rTextAreaRect.top =
"t";
4492 rTextAreaRect.right =
"r";
4493 rTextAreaRect.bottom =
"b";
4498 aTextAreaLO.
Move((aLogicRectLO.
Center().X() - aTextAreaLO.
Center().X()) * 2, 0);
4500 aTextAreaLO.
Move(0, (aLogicRectLO.
Center().Y() - aTextAreaLO.
Center().Y()) * 2);
4504 const sal_Int32 nWidth = aLogicRectLO.
Right() - aLogicRectLO.
Left();
4508 aGuide.sName =
"textAreaLeft";
4509 sal_Int32 nHelp = aTextAreaLO.
Left() - aLogicRectLO.
Left();
4511 aGuide.sFormula =
"*/ " + sLeft +
" w " + sWidth;
4512 rTextAreaRect.left = aGuide.sName;
4513 rGuideList.push_back(aGuide);
4516 aGuide.sName =
"textAreaRight";
4517 nHelp = aTextAreaLO.
Right() - aLogicRectLO.
Left();
4519 aGuide.sFormula =
"*/ " + sRight +
" w " + sWidth;
4520 rTextAreaRect.right = aGuide.sName;
4521 rGuideList.push_back(aGuide);
4524 const sal_Int32 nHeight = aLogicRectLO.
Bottom() - aLogicRectLO.
Top();
4528 aGuide.sName =
"textAreaTop";
4529 nHelp = aTextAreaLO.
Top() - aLogicRectLO.
Top();
4531 aGuide.sFormula =
"*/ " + sTop +
" h " + sHeight;
4532 rTextAreaRect.top = aGuide.sName;
4533 rGuideList.push_back(aGuide);
4536 aGuide.sName =
"textAreaBottom";
4537 nHelp = aTextAreaLO.
Bottom() - aLogicRectLO.
Top();
4539 aGuide.sFormula =
"*/ " + sBottom +
" h " + sHeight;
4540 rTextAreaRect.bottom = aGuide.sName;
4541 rGuideList.push_back(aGuide);
4551 uno::Reference< beans::XPropertySet > aXPropSet;
4554 if ( ! (aAny >>= aXPropSet) )
4559 aAny = aXPropSet->getPropertyValue(
"CustomShapeGeometry" );
4563 catch( const ::uno::Exception& )
4568 auto pGeometrySeq = o3tl::tryAccess<uno::Sequence<beans::PropertyValue>>(aAny);
4572 auto pPathProp = std::find_if(std::cbegin(*pGeometrySeq), std::cend(*pGeometrySeq),
4573 [](
const PropertyValue& rProp) {
return rProp.Name ==
"Path"; });
4574 if (pPathProp == std::cend(*pGeometrySeq))
4577 uno::Sequence<beans::PropertyValue> aPathProp;
4578 pPathProp->
Value >>= aPathProp;
4580 uno::Sequence<drawing::EnhancedCustomShapeParameterPair> aPairs;
4581 uno::Sequence<drawing::EnhancedCustomShapeSegment>
aSegments;
4582 uno::Sequence<awt::Size> aPathSize;
4583 bool bReplaceGeoWidth =
false;
4584 bool bReplaceGeoHeight =
false;
4585 for (
const beans::PropertyValue& rPathProp : std::as_const(aPathProp))
4587 if (rPathProp.Name ==
"Coordinates")
4588 rPathProp.Value >>= aPairs;
4589 else if (rPathProp.Name ==
"Segments")
4591 else if (rPathProp.Name ==
"SubViewSize")
4592 rPathProp.Value >>= aPathSize;
4593 else if (rPathProp.Name ==
"StretchX")
4594 bReplaceGeoWidth =
true;
4595 else if (rPathProp.Name ==
"StretchY")
4596 bReplaceGeoHeight =
true;
4599 if ( !aPairs.hasElements() )
4604 aSegments = uno::Sequence<drawing::EnhancedCustomShapeSegment>
4608 static_cast<sal_Int16
>(std::min( aPairs.getLength() - 1, sal_Int32(32767) )) },
4609 { CLOSESUBPATH, 0 },
4614 int nExpectedPairCount = std::accumulate(std::cbegin(
aSegments), std::cend(
aSegments), 0,
4615 [](
const int nSum,
const drawing::EnhancedCustomShapeSegment& rSegment) {
return nSum + rSegment.Count; });
4617 if ( nExpectedPairCount > aPairs.getLength() )
4619 SAL_WARN(
"oox.shape",
"Segments need " << nExpectedPairCount <<
" coordinates, but Coordinates have only " << aPairs.getLength() <<
" pairs.");
4627 TextAreaRect aTextAreaRect;
4628 std::vector<Guide> aGuideList;
4629 prepareTextArea(aCustomShape2d, aGuideList, aTextAreaRect);
4630 mpFS->startElementNS(XML_a, XML_custGeom);
4631 mpFS->singleElementNS(XML_a, XML_avLst);
4632 if (aGuideList.empty())
4634 mpFS->singleElementNS(XML_a, XML_gdLst);
4638 mpFS->startElementNS(XML_a, XML_gdLst);
4639 for (
auto const& elem : aGuideList)
4641 mpFS->singleElementNS(XML_a, XML_gd, XML_name, elem.sName, XML_fmla, elem.sFormula);
4643 mpFS->endElementNS(XML_a, XML_gdLst);
4645 mpFS->singleElementNS(XML_a, XML_ahLst);
4646 mpFS->singleElementNS(XML_a, XML_rect, XML_l, aTextAreaRect.left, XML_t, aTextAreaRect.top,
4647 XML_r, aTextAreaRect.right, XML_b, aTextAreaRect.bottom);
4648 mpFS->startElementNS(XML_a, XML_pathLst);
4651 bool bUseGlobalViewBox(
false);
4655 sal_Int32 nViewBoxWidth(0);
4656 sal_Int32 nViewBoxHeight(0);
4657 if (!aPathSize.hasElements())
4659 bUseGlobalViewBox =
true;
4663 auto pProp = std::find_if(
4664 std::cbegin(*pGeometrySeq), std::cend(*pGeometrySeq),
4665 [](
const beans::PropertyValue& rGeomProp) {
return rGeomProp.Name ==
"ViewBox"; });
4666 if (pProp != std::cend(*pGeometrySeq))
4668 css::awt::Rectangle aViewBox;
4669 if (pProp->Value >>= aViewBox)
4671 nViewBoxWidth = aViewBox.Width;
4672 nViewBoxHeight = aViewBox.Height;
4673 css::drawing::EnhancedCustomShapeParameter aECSP;
4674 aECSP.Type = css::drawing::EnhancedCustomShapeParameterType::NORMAL;
4675 aECSP.Value <<= nViewBoxWidth;
4677 aCustomShape2d.
GetParameter(fRetValue, aECSP,
true,
false);
4679 aECSP.Value <<= nViewBoxHeight;
4680 aCustomShape2d.
GetParameter(fRetValue, aECSP,
false,
true);
4687 if ((nViewBoxWidth == 0 && nViewBoxHeight == 0) || pProp == std::cend(*pGeometrySeq))
4691 aPairs[0].First.Value >>= nXMin;
4692 sal_Int32 nXMax = nXMin;
4694 aPairs[0].Second.Value >>= nYMin;
4695 sal_Int32 nYMax = nYMin;
4697 for (
const auto& rPair : std::as_const(aPairs))
4699 sal_Int32 nX = GetCustomGeometryPointValue(rPair.First, aCustomShape2d,
4700 bReplaceGeoWidth,
false);
4701 sal_Int32 nY = GetCustomGeometryPointValue(rPair.Second, aCustomShape2d,
false,
4712 nViewBoxWidth = std::max(nXMax, nXMax - nXMin);
4713 nViewBoxHeight = std::max(nYMax, nYMax - nYMin);
4720 sal_Int32 nPairIndex = 0;
4721 sal_Int32 nPathSizeIndex = 0;
4722 sal_Int32 nSubpathStartIndex(0);
4723 sal_Int32 nSubPathIndex(0);
4728 sal_Int32 nNextNcommandIndex = FindNextCommandEndSubpath(nSubpathStartIndex,
aSegments);
4732 std::optional<OString> sFill;
4733 if (HasCommandInSubPath(NOFILL, nSubpathStartIndex, nNextNcommandIndex - 1,
aSegments))
4735 else if (HasCommandInSubPath(DARKEN, nSubpathStartIndex, nNextNcommandIndex - 1,
aSegments))
4737 else if (HasCommandInSubPath(DARKENLESS, nSubpathStartIndex, nNextNcommandIndex - 1,
4739 sFill =
"darkenLess";
4740 else if (HasCommandInSubPath(LIGHTEN, nSubpathStartIndex, nNextNcommandIndex - 1,
4743 else if (HasCommandInSubPath(LIGHTENLESS, nSubpathStartIndex, nNextNcommandIndex - 1,
4745 sFill =
"lightenLess";
4750 if (nLuminanceChange <= -40)
4752 else if (nLuminanceChange <= -10)
4753 sFill =
"darkenLess";
4754 else if (nLuminanceChange >= 40)
4756 else if (nLuminanceChange >= 10)
4757 sFill =
"lightenLess";
4760 std::optional<OString> sStroke;
4761 if (HasCommandInSubPath(NOSTROKE, nSubpathStartIndex, nNextNcommandIndex - 1,
aSegments))
4765 mpFS->startElementNS(
4766 XML_a, XML_path, XML_fill, sFill, XML_stroke, sStroke, XML_w,
4767 OString::number(bUseGlobalViewBox ? nViewBoxWidth : aPathSize[nPathSizeIndex].
Width),
4769 OString::number(bUseGlobalViewBox ? nViewBoxHeight : aPathSize[nPathSizeIndex].
Height));
4774 double fCurrentX(0.0);
4775 double fCurrentY(0.0);
4776 bool bCurrentValid(
false);
4778 for (sal_Int32 nSegmentIndex = nSubpathStartIndex; nSegmentIndex < nNextNcommandIndex;
4781 const auto& rSegment(
aSegments[nSegmentIndex]);
4782 if (rSegment.Command == CLOSESUBPATH)
4784 mpFS->singleElementNS(XML_a, XML_close);
4788 for (sal_Int32 k = 0; k < rSegment.Count && bOK; ++k)
4791 fCurrentY, bCurrentValid, aCustomShape2d,
4792 bReplaceGeoWidth, bReplaceGeoHeight);
4796 mpFS->endElementNS(XML_a, XML_path);
4802 nSubpathStartIndex = nNextNcommandIndex + 1;
4805 }
while (nSubpathStartIndex <
aSegments.getLength());
4807 mpFS->endElementNS(XML_a, XML_pathLst);
4808 mpFS->endElementNS(XML_a, XML_custGeom);
4813 const sal_Int16 eCommand,
const sal_Int32
nCount,
4814 const uno::Sequence<css::drawing::EnhancedCustomShapeParameterPair>& rPairs,
4815 sal_Int32& rnPairIndex,
double& rfCurrentX,
double& rfCurrentY,
bool& rbCurrentValid,
4817 const bool bReplaceGeoHeight)
4823 if (rnPairIndex >= rPairs.getLength())
4826 mpFS->startElementNS(XML_a, XML_moveTo);
4829 mpFS->endElementNS(XML_a, XML_moveTo);
4830 rCustomShape2d.
GetParameter(rfCurrentX, rPairs[rnPairIndex].
First, bReplaceGeoWidth,
4832 rCustomShape2d.
GetParameter(rfCurrentY, rPairs[rnPairIndex].Second,
false,
4834 rbCurrentValid =
true;
4840 if (rnPairIndex >= rPairs.getLength())
4847 mpFS->startElementNS(XML_a, XML_lnTo);
4850 mpFS->endElementNS(XML_a, XML_lnTo);
4854 mpFS->startElementNS(XML_a, XML_moveTo);
4857 mpFS->endElementNS(XML_a, XML_moveTo);
4859 rCustomShape2d.
GetParameter(rfCurrentX, rPairs[rnPairIndex].
First, bReplaceGeoWidth,
4861 rCustomShape2d.
GetParameter(rfCurrentY, rPairs[rnPairIndex].Second,
false,
4863 rbCurrentValid =
true;
4869 if (rnPairIndex + 2 >= rPairs.getLength())
4872 mpFS->startElementNS(XML_a, XML_cubicBezTo);
4878 mpFS->endElementNS(XML_a, XML_cubicBezTo);
4879 rCustomShape2d.
GetParameter(rfCurrentX, rPairs[rnPairIndex + 2].
First, bReplaceGeoWidth,
4881 rCustomShape2d.
GetParameter(rfCurrentY, rPairs[rnPairIndex + 2].Second,
false,
4883 rbCurrentValid =
true;
4887 case ANGLEELLIPSETO:
4890 if (rnPairIndex + 2 >= rPairs.getLength())
4895 rCustomShape2d.
GetParameter(fCx, rPairs[rnPairIndex].
First, bReplaceGeoWidth,
false);
4897 rCustomShape2d.
GetParameter(fCy, rPairs[rnPairIndex].Second,
false, bReplaceGeoHeight);
4901 rCustomShape2d.
GetParameter(fHR, rPairs[rnPairIndex + 1].Second,
false,
false);
4902 double fStartAngle = 0.0;
4903 rCustomShape2d.
GetParameter(fStartAngle, rPairs[rnPairIndex + 2].
First,
false,
false);
4904 double fEndAngle = 0.0;
4905 rCustomShape2d.
GetParameter(fEndAngle, rPairs[rnPairIndex + 2].Second,
false,
false);
4908 sal_Int32 nStartAng(std::lround(fStartAngle * 60000));
4909 sal_Int32 nSwingAng = 0;
4912 nSwingAng = 360 * 60000;
4915 nSwingAng = std::lround((fEndAngle - fStartAngle) * 60000);
4917 nSwingAng += 360 * 60000;
4923 getEllipsePointFromViewAngle(fSx, fSy, fWR, fHR, fCx, fCy, fStartAngle);
4927 if (eCommand == ANGLEELLIPSETO && rbCurrentValid)
4929 mpFS->startElementNS(XML_a, XML_lnTo);
4930 mpFS->singleElementNS(XML_a, XML_pt, XML_x, OString::number(std::lround(fSx)),
4931 XML_y, OString::number(std::lround(fSy)));
4932 mpFS->endElementNS(XML_a, XML_lnTo);
4936 mpFS->startElementNS(XML_a, XML_moveTo);
4937 mpFS->singleElementNS(XML_a, XML_pt, XML_x, OString::number(std::lround(fSx)),
4938 XML_y, OString::number(std::lround(fSy)));
4939 mpFS->endElementNS(XML_a, XML_moveTo);
4943 mpFS->singleElement(
4944 FSNS(XML_a, XML_arcTo), XML_wR, OString::number(std::lround(fWR)), XML_hR,
4945 OString::number(std::lround(fHR)), XML_stAng, OString::number(nStartAng),
4946 XML_swAng, OString::number(nSwingAng));
4948 getEllipsePointFromViewAngle(rfCurrentX, rfCurrentY, fWR, fHR, fCx, fCy, fEndAngle);
4949 rbCurrentValid =
true;
4955 case CLOCKWISEARCTO:
4958 if (rnPairIndex + 3 >= rPairs.getLength())
4963 rCustomShape2d.
GetParameter(fX1, rPairs[rnPairIndex].
First, bReplaceGeoWidth,
false);
4965 rCustomShape2d.
GetParameter(fY1, rPairs[rnPairIndex].Second,
false, bReplaceGeoHeight);
4967 rCustomShape2d.
GetParameter(fX2, rPairs[rnPairIndex + 1].
First, bReplaceGeoWidth,
4970 rCustomShape2d.
GetParameter(fY2, rPairs[rnPairIndex + 1].Second,
false,
4973 rCustomShape2d.
GetParameter(fX3, rPairs[rnPairIndex + 2].
First, bReplaceGeoWidth,
4976 rCustomShape2d.
GetParameter(fY3, rPairs[rnPairIndex + 2].Second,
false,
4979 rCustomShape2d.
GetParameter(fX4, rPairs[rnPairIndex + 3].
First, bReplaceGeoWidth,
4982 rCustomShape2d.
GetParameter(fY4, rPairs[rnPairIndex + 3].Second,
false,
4985 const double fWR = (fX2 - fX1) / 2.0;
4986 const double fHR = (fY2 - fY1) / 2.0;
4987 const double fCx = (fX1 + fX2) / 2.0;
4988 const double fCy = (fY1 + fY2) / 2.0;
4990 double fStartAngle = 0.0;
4993 getEllipsePointAndAngleFromRayPoint(fStartAngle, fPx, fPy, fWR, fHR, fCx, fCy, fX3,
4997 if ((eCommand == ARCTO || eCommand == CLOCKWISEARCTO) && rbCurrentValid)
4999 mpFS->startElementNS(XML_a, XML_lnTo);
5000 mpFS->singleElementNS(XML_a, XML_pt, XML_x, OString::number(std::lround(fPx)),
5001 XML_y, OString::number(std::lround(fPy)));
5002 mpFS->endElementNS(XML_a, XML_lnTo);
5006 mpFS->startElementNS(XML_a, XML_moveTo);
5007 mpFS->singleElementNS(XML_a, XML_pt, XML_x, OString::number(std::lround(fPx)),
5008 XML_y, OString::number(std::lround(fPy)));
5009 mpFS->endElementNS(XML_a, XML_moveTo);
5012 double fEndAngle = 0.0;
5013 getEllipsePointAndAngleFromRayPoint(fEndAngle, fPx, fPy, fWR, fHR, fCx, fCy, fX4, fY4);
5014 double fSwingAngle(fEndAngle - fStartAngle);
5015 const bool bIsClockwise(eCommand == CLOCKWISEARCTO || eCommand == CLOCKWISEARC);
5016 if (bIsClockwise && fSwingAngle < 0)
5017 fSwingAngle += 360.0;
5018 else if (!bIsClockwise && fSwingAngle > 0)
5019 fSwingAngle -= 360.0;
5022 const sal_Int32 nStartAng(std::lround(fStartAngle * 60000));
5023 const sal_Int32 nSwingAng(std::lround(fSwingAngle * 60000));
5024 mpFS->singleElement(
FSNS(XML_a, XML_arcTo), XML_wR, OString::number(std::lround(fWR)),
5025 XML_hR, OString::number(std::lround(fHR)), XML_stAng,
5026 OString::number(nStartAng), XML_swAng, OString::number(nSwingAng));
5029 rbCurrentValid =
true;
5033 case ELLIPTICALQUADRANTX:
5034 case ELLIPTICALQUADRANTY:
5036 if (rnPairIndex >= rPairs.getLength())
5041 rCustomShape2d.
GetParameter(fX, rPairs[rnPairIndex].
First, bReplaceGeoWidth,
false);
5043 rCustomShape2d.
GetParameter(fY, rPairs[rnPairIndex].Second,
false, bReplaceGeoHeight);
5048 double fWR = std::abs(rfCurrentX - fX);
5049 double fHR = std::abs(rfCurrentY - fY);
5050 double fStartAngle(0.0);
5051 double fSwingAngle(0.0);
5053 if ((eCommand == ELLIPTICALQUADRANTX && !(
nCount % 2))
5054 || (eCommand == ELLIPTICALQUADRANTY && (
nCount % 2)))
5057 fStartAngle = fY < rfCurrentY ? 90.0 : 270.0;
5058 const bool bClockwise = (fX < rfCurrentX && fY < rfCurrentY)
5059 || (fX > rfCurrentX && fY > rfCurrentY);
5060 fSwingAngle = bClockwise ? 90.0 : -90.0;
5065 fStartAngle = fX < rfCurrentX ? 0.0 : 180.0;
5066 const bool bClockwise = (fX < rfCurrentX && fY > rfCurrentY)
5067 || (fX > rfCurrentX && fY < rfCurrentY);
5068 fSwingAngle = bClockwise ? 90.0 : -90.0;
5070 sal_Int32 nStartAng(std::lround(fStartAngle * 60000));
5071 sal_Int32 nSwingAng(std::lround(fSwingAngle * 60000));
5072 mpFS->singleElement(
5073 FSNS(XML_a, XML_arcTo), XML_wR, OString::number(std::lround(fWR)), XML_hR,
5074 OString::number(std::lround(fHR)), XML_stAng, OString::number(nStartAng),
5075 XML_swAng, OString::number(nSwingAng));
5080 mpFS->startElementNS(XML_a, XML_moveTo);
5083 mpFS->endElementNS(XML_a, XML_moveTo);
5087 rbCurrentValid =
true;
5091 case QUADRATICCURVETO:
5093 if (rnPairIndex + 1 >= rPairs.getLength())
5096 mpFS->startElementNS(XML_a, XML_quadBezTo);
5102 mpFS->endElementNS(XML_a, XML_quadBezTo);
5103 rCustomShape2d.
GetParameter(rfCurrentX, rPairs[rnPairIndex + 1].
First, bReplaceGeoWidth,
5105 rCustomShape2d.
GetParameter(rfCurrentY, rPairs[rnPairIndex + 1].Second,
false,
5107 rbCurrentValid =
true;
5113 if (rnPairIndex + 1 >= rPairs.getLength())
5119 rCustomShape2d.
GetParameter(fHR, rPairs[rnPairIndex].Second,
false,
false);
5120 double fStartAngle = 0.0;
5121 rCustomShape2d.
GetParameter(fStartAngle, rPairs[rnPairIndex + 1].
First,
false,
false);
5122 sal_Int32 nStartAng(std::lround(fStartAngle * 60000));
5123 double fSwingAng = 0.0;
5124 rCustomShape2d.
GetParameter(fSwingAng, rPairs[rnPairIndex + 1].Second,
false,
false);
5125 sal_Int32 nSwingAng(std::lround(fSwingAng * 60000));
5126 mpFS->singleElement(
FSNS(XML_a, XML_arcTo), XML_wR, OString::number(fWR), XML_hR,
5127 OString::number(fHR), XML_stAng, OString::number(nStartAng),
5128 XML_swAng, OString::number(nSwingAng));
5131 getEllipsePointFromViewAngle(fPx, fPy, fWR, fHR, 0.0, 0.0, fStartAngle);
5132 double fCx = rfCurrentX - fPx;
5133 double fCy = rfCurrentY - fPy;
5134 getEllipsePointFromViewAngle(rfCurrentX, rfCurrentY, fWR, fHR, fCx, fCy,
5135 fStartAngle + fSwingAng);
5136 rbCurrentValid =
true;
5148 const drawing::EnhancedCustomShapeParameterPair& rParamPair,
5150 const bool bReplaceGeoHeight)
5153 = GetCustomGeometryPointValue(rParamPair.First, rCustomShape2d, bReplaceGeoWidth,
false);
5155 = GetCustomGeometryPointValue(rParamPair.Second, rCustomShape2d,
false, bReplaceGeoHeight);
5157 mpFS->singleElementNS(XML_a, XML_pt, XML_x, OString::number(nX), XML_y, OString::number(nY));
5163 mpFS->startElementNS(XML_a, XML_custGeom);
5164 mpFS->singleElementNS(XML_a, XML_avLst);
5165 mpFS->singleElementNS(XML_a, XML_gdLst);
5166 mpFS->singleElementNS(XML_a, XML_ahLst);
5167 mpFS->singleElementNS(XML_a, XML_rect, XML_l,
"0", XML_t,
"0", XML_r,
"r", XML_b,
"b");
5168 mpFS->singleElementNS(XML_a, XML_pathLst);
5169 mpFS->endElementNS(XML_a, XML_custGeom);
5182 mpFS->startElementNS(XML_a, XML_custGeom);
5183 mpFS->singleElementNS(XML_a, XML_avLst);
5184 mpFS->singleElementNS(XML_a, XML_gdLst);
5185 mpFS->singleElementNS(XML_a, XML_ahLst);
5186 mpFS->singleElementNS(XML_a, XML_rect, XML_l,
"0", XML_t,
"0", XML_r,
"r", XML_b,
"b");
5188 mpFS->startElementNS(XML_a, XML_pathLst);
5190 awt::Size aSize = rXShape->getSize();
5191 awt::Point aPos = rXShape->getPosition();
5193 uno::Reference<XPropertySetInfo> xPropertySetInfo = xPropertySet->getPropertySetInfo();
5194 if (xPropertySetInfo->hasPropertyByName(
"AnchorPosition"))
5196 awt::Point aAnchorPosition;
5197 xPropertySet->getPropertyValue(
"AnchorPosition") >>= aAnchorPosition;
5198 aPos.X += aAnchorPosition.X;
5199 aPos.Y += aAnchorPosition.Y;
5203 std::optional<OString> sFill;
5209 mpFS->startElementNS(XML_a, XML_path, XML_fill, sFill, XML_w, OString::number(aSize.Width),
5210 XML_h, OString::number(aSize.Height));
5212 for (sal_uInt16
i = 0;
i < aPolyPolygon.
Count();
i++)
5218 mpFS->startElementNS(XML_a, XML_moveTo);
5220 mpFS->singleElementNS(XML_a, XML_pt, XML_x, OString::number(aPoly[0].
X() - aPos.X),
5221 XML_y, OString::number(aPoly[0].Y() - aPos.Y));
5223 mpFS->endElementNS(XML_a, XML_moveTo);
5226 for (sal_uInt16 j = 1; j < aPoly.
GetSize(); j++)
5229 if (flags == PolyFlags::Control)
5232 if (j + 2 < aPoly.
GetSize() && aPoly.
GetFlags(j + 1) == PolyFlags::Control
5233 && aPoly.
GetFlags(j + 2) != PolyFlags::Control)
5235 mpFS->startElementNS(XML_a, XML_cubicBezTo);
5238 mpFS->singleElementNS(XML_a, XML_pt, XML_x,
5239 OString::number(aPoly[j + k].
X() - aPos.X), XML_y,
5240 OString::number(aPoly[j + k].Y() - aPos.Y));
5242 mpFS->endElementNS(XML_a, XML_cubicBezTo);
5246 else if (flags == PolyFlags::Normal)
5248 mpFS->startElementNS(XML_a, XML_lnTo);
5249 mpFS->singleElementNS(XML_a, XML_pt, XML_x, OString::number(aPoly[j].
X() - aPos.X),
5250 XML_y, OString::number(aPoly[j].Y() - aPos.Y));
5251 mpFS->endElementNS(XML_a, XML_lnTo);
5256 mpFS->singleElementNS(XML_a, XML_close);
5257 mpFS->endElementNS(XML_a, XML_path);
5259 mpFS->endElementNS(XML_a, XML_pathLst);
5261 mpFS->endElementNS(XML_a, XML_custGeom);
5266 if( nStartID != -1 )
5268 mpFS->singleElementNS( XML_a, XML_stCxn,
5269 XML_id, OString::number(nStartID),
5270 XML_idx, OString::number(nStartGlueId) );
5274 mpFS->singleElementNS( XML_a, XML_endCxn,
5275 XML_id, OString::number(nEndID),
5276 XML_idx, OString::number(nEndGlueId) );
5284 rtl_TextEncoding eCharSet = rFontDesc.CharSet;
5286 rFontDesc.CharSet = eCharSet;
5293 const OUString& sFullStream,
5294 std::u16string_view sRelativeStream,
5296 const OUString& sContentType,
5297 const OUString& sRelationshipType,
5298 OUString* pRelationshipId )
5300 OUString sRelationshipId;
5301 if (xParentRelation.is())
5302 sRelationshipId =
GetFB()->
addRelation( xParentRelation, sRelationshipType, sRelativeStream );
5304 sRelationshipId =
GetFB()->
addRelation( sRelationshipType, sRelativeStream );
5306 if( pRelationshipId )
5307 *pRelationshipId = sRelationshipId;
5319 xPropSet->getPropertyValue(
"FillStyle" ) >>= aFillStyle;
5322 if (aFillStyle == FillStyle_SOLID)
5324 OUString sFillTransparenceGradientName;
5326 if (
GetProperty(xPropSet,
"FillTransparenceGradientName")
5327 && (
mAny >>= sFillTransparenceGradientName)
5328 && !sFillTransparenceGradientName.isEmpty()
5329 &&
GetProperty(xPropSet,
"FillTransparenceGradient"))
5338 if (bCompletelyTransparent)
5340 aFillStyle = FillStyle_NONE;
5343 else if (
GetProperty( xPropSet,
"FillTransparence" ) )
5347 xPropSet->getPropertyValue(
"FillTransparence" ) >>= nVal;
5349 aFillStyle = FillStyle_NONE;
5353 bool bUseBackground(
false);
5354 if (
GetProperty(xPropSet,
"FillUseSlideBackground"))
5355 xPropSet->getPropertyValue(
"FillUseSlideBackground") >>= bUseBackground;
5357 switch( aFillStyle )
5359 case FillStyle_SOLID :
5362 case FillStyle_GRADIENT :
5365 case FillStyle_BITMAP :
5368 case FillStyle_HATCH :
5371 case FillStyle_NONE:
5372 if (!bUseBackground)
5373 mpFS->singleElementNS(XML_a, XML_noFill);
5384 OUString sSchemeClr;
5385 sal_uInt32 nIdx = 0;
5389 if( rProp.Name ==
"SchemeClr" )
5390 rProp.Value >>= sSchemeClr;
5391 else if( rProp.Name ==
"Idx" )
5392 rProp.Value >>= nIdx;
5393 else if( rProp.Name ==
"Transformations" )
5394 rProp.Value >>= aTransformations;
5396 mpFS->startElementNS(XML_a, nTokenId, XML_idx, OString::number(nIdx));
5398 mpFS->endElementNS( XML_a, nTokenId );
5403 mpFS->singleElementNS(XML_a, nTokenId, XML_idx, OString::number(0));
5417 for(
const auto& rProp : std::as_const(aGrabBag))
5419 if( rProp.Name ==
"StyleFillRef" )
5420 rProp.Value >>= aFillRefProperties;
5421 else if( rProp.Name ==
"StyleLnRef" )
5422 rProp.Value >>= aLnRefProperties;
5423 else if( rProp.Name ==
"StyleEffectRef" )
5424 rProp.Value >>= aEffectRefProperties;
5432 mpFS->singleElementNS(XML_a, XML_fontRef, XML_idx,
"minor");
5437 if( !aEffectProps.hasElements() )
5441 sal_Int32 nEffectToken = 0;
5442 bool bContainsColor =
false;
5443 if(
sName ==
u"outerShdw" )
5445 nEffectToken =
FSNS( XML_a, XML_outerShdw );
5446 bContainsColor =
true;
5448 else if(
sName ==
u"innerShdw" )
5450 nEffectToken =
FSNS( XML_a, XML_innerShdw );
5451 bContainsColor =
true;
5453 else if(
sName ==
u"glow" )
5455 nEffectToken =
FSNS( XML_a, XML_glow );
5456 bContainsColor =
true;
5458 else if(
sName ==
u"softEdge" )
5459 nEffectToken =
FSNS( XML_a, XML_softEdge );
5460 else if(
sName ==
u"reflection" )
5461 nEffectToken =
FSNS( XML_a, XML_reflection );
5462 else if(
sName ==
u"blur" )
5463 nEffectToken =
FSNS( XML_a, XML_blur );
5465 OUString sSchemeClr;
5470 for(
const auto& rEffectProp : aEffectProps )
5472 if( rEffectProp.Name ==
"Attribs" )
5475 uno::Sequence< beans::PropertyValue > aOuterShdwProps;
5476 rEffectProp.Value >>= aOuterShdwProps;
5477 for(
const auto& rOuterShdwProp : std::as_const(aOuterShdwProps) )
5479 if( rOuterShdwProp.Name ==
"algn" )
5482 rOuterShdwProp.Value >>= sVal;
5483 aOuterShdwAttrList->add( XML_algn, sVal );
5485 else if( rOuterShdwProp.Name ==
"blurRad" )
5488 rOuterShdwProp.Value >>= nVal;
5489 aOuterShdwAttrList->add( XML_blurRad, OString::number( nVal ) );
5491 else if( rOuterShdwProp.Name ==
"dir" )
5494 rOuterShdwProp.Value >>= nVal;
5495 aOuterShdwAttrList->add( XML_dir, OString::number( nVal ) );
5497 else if( rOuterShdwProp.Name ==
"dist" )