20#include <config_features.h>
22#include <config_folders.h>
23#include <rtl/bootstrap.hxx>
32#include <oox/token/namespaces.hxx>
33#include <oox/token/properties.hxx>
35#include <oox/token/tokens.hxx>
48#include <com/sun/star/awt/CharSet.hpp>
49#include <com/sun/star/awt/FontDescriptor.hpp>
50#include <com/sun/star/awt/FontSlant.hpp>
51#include <com/sun/star/awt/FontStrikeout.hpp>
52#include <com/sun/star/awt/FontWeight.hpp>
53#include <com/sun/star/awt/FontUnderline.hpp>
54#include <com/sun/star/awt/Gradient.hpp>
55#include <com/sun/star/beans/XPropertySet.hpp>
56#include <com/sun/star/beans/XPropertyState.hpp>
57#include <com/sun/star/beans/XPropertySetInfo.hpp>
58#include <com/sun/star/container/XEnumerationAccess.hpp>
59#include <com/sun/star/container/XIndexAccess.hpp>
60#include <com/sun/star/container/XNameAccess.hpp>
61#include <com/sun/star/drawing/BitmapMode.hpp>
62#include <com/sun/star/drawing/ColorMode.hpp>
63#include <com/sun/star/drawing/EnhancedCustomShapeAdjustmentValue.hpp>
64#include <com/sun/star/drawing/EnhancedCustomShapeParameterPair.hpp>
65#include <com/sun/star/drawing/EnhancedCustomShapeParameterType.hpp>
66#include <com/sun/star/drawing/EnhancedCustomShapeSegment.hpp>
67#include <com/sun/star/drawing/EnhancedCustomShapeSegmentCommand.hpp>
68#include <com/sun/star/drawing/Hatch.hpp>
69#include <com/sun/star/drawing/LineDash.hpp>
70#include <com/sun/star/drawing/LineJoint.hpp>
71#include <com/sun/star/drawing/LineStyle.hpp>
72#include <com/sun/star/drawing/TextFitToSizeType.hpp>
73#include <com/sun/star/drawing/TextHorizontalAdjust.hpp>
74#include <com/sun/star/drawing/TextVerticalAdjust.hpp>
75#include <com/sun/star/drawing/XShape.hpp>
76#include <com/sun/star/drawing/XShapes.hpp>
77#include <com/sun/star/drawing/FillStyle.hpp>
78#include <com/sun/star/frame/XModel.hpp>
79#include <com/sun/star/graphic/XGraphic.hpp>
80#include <com/sun/star/i18n/ScriptType.hpp>
81#include <com/sun/star/i18n/BreakIterator.hpp>
82#include <com/sun/star/i18n/XBreakIterator.hpp>
83#include <com/sun/star/io/XOutputStream.hpp>
84#include <com/sun/star/lang/XMultiServiceFactory.hpp>
85#include <com/sun/star/style/LineSpacing.hpp>
86#include <com/sun/star/style/LineSpacingMode.hpp>
87#include <com/sun/star/text/WritingMode.hpp>
88#include <com/sun/star/text/WritingMode2.hpp>
89#include <com/sun/star/text/GraphicCrop.hpp>
90#include <com/sun/star/text/XText.hpp>
91#include <com/sun/star/text/XTextColumns.hpp>
92#include <com/sun/star/text/XTextContent.hpp>
93#include <com/sun/star/text/XTextField.hpp>
94#include <com/sun/star/text/XTextRange.hpp>
95#include <com/sun/star/text/XTextFrame.hpp>
96#include <com/sun/star/style/CaseMap.hpp>
97#include <com/sun/star/xml/dom/XNodeList.hpp>
98#include <com/sun/star/xml/sax/Writer.hpp>
99#include <com/sun/star/xml/sax/XSAXSerializable.hpp>
100#include <com/sun/star/container/XNamed.hpp>
101#include <com/sun/star/drawing/XDrawPages.hpp>
102#include <com/sun/star/drawing/XDrawPagesSupplier.hpp>
103#include <com/sun/star/drawing/RectanglePoint.hpp>
118#include <rtl/strbuf.hxx>
136using namespace ::css;
137using namespace ::css::beans;
138using namespace ::css::drawing;
139using namespace ::css::i18n;
140using namespace ::css::style;
141using namespace ::css::text;
142using namespace ::css::uno;
143using namespace ::css::container;
144using namespace ::com::sun::star::drawing::EnhancedCustomShapeSegmentCommand;
146using ::css::io::XOutputStream;
147using ::sax_fastparser::FSHelperPtr;
148using ::sax_fastparser::FastSerializerHelper;
153sal_Int32 GetAlphaFromTransparenceGradient(
const awt::Gradient& rGradient,
bool bStart)
161const char* g_aPredefinedClrNames[] = {
190 bool bExternal =
true;
191 if (rURL.startsWith(
"#"))
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();
215void WriteGradientPath(
const awt::Gradient& rGradient,
const FSHelperPtr& pFS,
const bool bCircle)
217 pFS->startElementNS(XML_a, XML_path, XML_path, bCircle ?
"circle" :
"rect");
225 sal_Int32 nLeftPercent = rGradient.XOffset;
226 pAttributeList->add(XML_l, OString::number(nLeftPercent *
PER_PERCENT));
227 sal_Int32 nTopPercent = rGradient.YOffset;
228 pAttributeList->add(XML_t, OString::number(nTopPercent *
PER_PERCENT));
229 sal_Int32 nRightPercent = 100 - rGradient.XOffset;
230 pAttributeList->add(XML_r, OString::number(nRightPercent *
PER_PERCENT));
231 sal_Int32 nBottomPercent = 100 - rGradient.YOffset;
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);
249 if (rStr.getLength() > 0)
254 sal_Int16 nScriptType = xBreakIterator->getScriptType(rStr, 0);
256 if (nScriptType == css::i18n::ScriptType::WEAK)
258 sal_Int32
nPos = xBreakIterator->nextScript(rStr, 0, nScriptType);
259 if (
nPos < rStr.getLength())
260 nScriptType = xBreakIterator->getScriptType(rStr,
nPos);
264 if (nScriptType != css::i18n::ScriptType::WEAK)
268 return css::i18n::ScriptType::LATIN;
299 mAny = rXPropertySet->getPropertyValue(
aName);
314 mAny = rXPropertySet->getPropertyValue(
aName);
317 eState = rXPropertyState->getPropertyState(
aName);
331OString getColorStr(const ::Color nColor)
334 OString
sColor = OString::number(sal_uInt32(nColor) & 0x00FFFFFF, 16);
335 if (
sColor.getLength() < 6)
337 OStringBuffer sBuf(
"0");
338 int remains = 5 -
sColor.getLength();
356 const auto sColor = getColorStr(nColor);
359 mpFS->startElementNS(XML_a, XML_srgbClr, XML_val,
sColor);
360 mpFS->singleElementNS(XML_a, XML_alpha, XML_val, OString::number(nAlpha));
361 mpFS->endElementNS( XML_a, XML_srgbClr );
366 mpFS->singleElementNS(XML_a, XML_srgbClr, XML_val,
sColor);
373 if( sColorSchemeName.isEmpty() )
376 if( aTransformations.hasElements() )
378 mpFS->startElementNS(XML_a, XML_schemeClr, XML_val, sColorSchemeName);
380 mpFS->endElementNS( XML_a, XML_schemeClr );
384 mpFS->startElementNS(XML_a, XML_schemeClr, XML_val, sColorSchemeName);
385 mpFS->singleElementNS(XML_a, XML_alpha, XML_val, OString::number(nAlpha));
386 mpFS->endElementNS( XML_a, XML_schemeClr );
390 mpFS->singleElementNS(XML_a, XML_schemeClr, XML_val, sColorSchemeName);
394void DrawingML::WriteColor( const ::Color nColor,
const Sequence< PropertyValue >& aTransformations, sal_Int32 nAlpha )
396 const auto sColor = getColorStr(nColor);
397 if( aTransformations.hasElements() )
399 mpFS->startElementNS(XML_a, XML_srgbClr, XML_val, sColor);
401 mpFS->endElementNS(XML_a, XML_srgbClr);
405 mpFS->startElementNS(XML_a, XML_srgbClr, XML_val, sColor);
406 mpFS->singleElementNS(XML_a, XML_alpha, XML_val, OString::number(nAlpha));
407 mpFS->endElementNS(XML_a, XML_srgbClr);
411 mpFS->singleElementNS(XML_a, XML_srgbClr, XML_val, sColor);
417 for(
const auto& rTransformation : aTransformations )
424 mpFS->singleElementNS(XML_a,
nToken, XML_val, OString::number(nAlpha));
428 sal_Int32
nValue = rTransformation.Value.get<sal_Int32>();
437 mpFS->startElementNS(XML_a, XML_solidFill);
439 mpFS->endElementNS( XML_a, XML_solidFill );
444 mpFS->startElementNS(XML_a, XML_solidFill);
445 WriteColor( sSchemeName, aTransformations, nAlpha );
446 mpFS->endElementNS( XML_a, XML_solidFill );
449void DrawingML::WriteSolidFill( const ::Color nColor,
const Sequence< PropertyValue >& aTransformations, sal_Int32 nAlpha )
451 mpFS->startElementNS(XML_a, XML_solidFill);
453 mpFS->endElementNS(XML_a, XML_solidFill);
461 sal_uInt32 nFillColor =
mAny.get<sal_uInt32>();
464 OUString sColorFillScheme;
465 sal_uInt32 nOriginalColor = 0;
466 Sequence< PropertyValue > aStyleProperties, aTransformations;
469 Sequence< PropertyValue > aGrabBag;
471 for(
const auto& rProp : std::as_const(aGrabBag) )
473 if( rProp.Name ==
"SpPrSolidFillSchemeClr" )
474 rProp.Value >>= sColorFillScheme;
475 else if( rProp.Name ==
"OriginalSolidFillClr" )
476 rProp.Value >>= nOriginalColor;
477 else if( rProp.Name ==
"StyleFillRef" )
478 rProp.Value >>= aStyleProperties;
479 else if( rProp.Name ==
"SpPrSolidFillSchemeClrTransformations" )
480 rProp.Value >>= aTransformations;
487 sal_Int32 nTransparency = 0;
488 mAny >>= nTransparency;
495 awt::Gradient aTransparenceGradient;
496 bool bNeedGradientFill(
false);
497 if (
GetProperty(rXPropSet,
"FillTransparenceGradient"))
499 mAny >>= aTransparenceGradient;
500 if (aTransparenceGradient.StartColor != aTransparenceGradient.EndColor)
501 bNeedGradientFill =
true;
502 else if (aTransparenceGradient.StartColor != 0)
503 nAlpha = GetAlphaFromTransparenceGradient(aTransparenceGradient,
true);
507 if (bNeedGradientFill)
509 awt::Gradient aPseudoColorGradient;
510 aPseudoColorGradient.XOffset = aTransparenceGradient.XOffset;
511 aPseudoColorGradient.YOffset = aTransparenceGradient.YOffset;
512 aPseudoColorGradient.StartIntensity = 100;
513 aPseudoColorGradient.EndIntensity = 100;
514 aPseudoColorGradient.Angle = aTransparenceGradient.Angle;
515 aPseudoColorGradient.Border = aTransparenceGradient.Border;
516 aPseudoColorGradient.Style = aTransparenceGradient.Style;
517 aPseudoColorGradient.StartColor = nFillColor;
518 aPseudoColorGradient.EndColor = nFillColor;
519 aPseudoColorGradient.StepCount = aTransparenceGradient.StepCount;
520 mpFS->startElementNS(XML_a, XML_gradFill, XML_rotWithShape,
"0");
522 mpFS->endElementNS( XML_a, XML_gradFill );
524 else if ( nFillColor != nOriginalColor )
532 else if ( !sColorFillScheme.isEmpty() )
547 if (!xPropertySet->getPropertySetInfo()->hasPropertyByName(rPropertyName))
550 uno::Reference<util::XThemeColor> xThemeColor;
551 xPropertySet->getPropertyValue(rPropertyName) >>= xThemeColor;
552 if (!xThemeColor.is())
559 const char* pColorName = g_aPredefinedClrNames[sal_Int16(aThemeColor.
getType())];
560 mpFS->startElementNS(XML_a, XML_solidFill);
561 mpFS->startElementNS(XML_a, XML_schemeClr, XML_val, pColorName);
564 switch (rTransform.meType)
567 mpFS->singleElementNS(XML_a, XML_lumMod, XML_val, OString::number(rTransform.mnValue * 10));
570 mpFS->singleElementNS(XML_a, XML_lumOff, XML_val, OString::number(rTransform.mnValue * 10));
573 mpFS->singleElementNS(XML_a, XML_tint, XML_val, OString::number(rTransform.mnValue * 10));
576 mpFS->singleElementNS(XML_a, XML_shade, XML_val, OString::number(rTransform.mnValue * 10));
583 mpFS->endElementNS(XML_a, XML_schemeClr);
584 mpFS->endElementNS(XML_a, XML_solidFill);
591 mpFS->startElementNS(XML_a, XML_gs, XML_pos, OString::number(nStop * 1000));
593 mpFS->endElementNS( XML_a, XML_gs );
599 | ( ( ( ( ( nColor & 0xff00 ) >> 8 ) * nIntensity ) / 100 ) << 8 )
600 | ( ( ( ( ( nColor & 0xff0000 ) >> 8 ) * nIntensity ) / 100 ) << 8 ));
605 return aGradient1.Style == aGradient2.Style &&
606 aGradient1.StartColor == aGradient2.StartColor &&
607 aGradient1.EndColor == aGradient2.EndColor &&
608 aGradient1.Angle == aGradient2.Angle &&
609 aGradient1.Border == aGradient2.Border &&
610 aGradient1.XOffset == aGradient2.XOffset &&
611 aGradient1.YOffset == aGradient2.YOffset &&
612 aGradient1.StartIntensity == aGradient2.StartIntensity &&
613 aGradient1.EndIntensity == aGradient2.EndIntensity &&
614 aGradient1.StepCount == aGradient2.StepCount;
619 awt::Gradient aGradient;
623 aGradient = *o3tl::doAccess<awt::Gradient>(
mAny);
626 awt::Gradient aOriginalGradient;
632 for(
const auto& rProp : std::as_const(aGrabBag) )
633 if( rProp.Name ==
"GradFillDefinition" )
634 rProp.Value >>= aGradientStops;
635 else if( rProp.Name ==
"OriginalGradFill" )
636 rProp.Value >>= aOriginalGradient;
645 if( aGradientStops.hasElements() )
647 mpFS->startElementNS(XML_a, XML_gradFill, XML_rotWithShape,
"0");
649 mpFS->endElementNS( XML_a, XML_gradFill );
654 awt::Gradient aTransparenceGradient;
655 mpFS->startElementNS(XML_a, XML_gradFill, XML_rotWithShape,
"0");
656 OUString sFillTransparenceGradientName;
657 if (
GetProperty(rXPropSet,
"FillTransparenceGradientName")
658 && (
mAny >>= sFillTransparenceGradientName)
659 && !sFillTransparenceGradientName.isEmpty())
661 if (
GetProperty(rXPropSet,
"FillTransparenceGradient"))
662 aTransparenceGradient = *o3tl::doAccess<awt::Gradient>(
mAny);
664 else if (
GetProperty(rXPropSet,
"FillTransparence"))
667 sal_Int32 nTransparency = 0;
668 mAny >>= nTransparency;
670 nTransparency = nTransparency * 255/100;
671 const sal_Int32 aGrayColor =
static_cast<sal_Int32
>( nTransparency | nTransparency << 8 | nTransparency << 16 );
672 aTransparenceGradient.StartColor = aGrayColor;
673 aTransparenceGradient.EndColor = aGrayColor;
676 mpFS->endElementNS(XML_a, XML_gradFill);
683 mpFS->startElementNS(XML_a, XML_gsLst);
686 for(
const auto& rGradientStop : aGradientStops )
689 rGradientStop.Value >>= aGradientStop;
694 sal_Int16 nTransparency = 0;
697 for(
const auto& rProp : std::as_const(aGradientStop) )
699 if( rProp.Name ==
"SchemeClr" )
700 rProp.Value >>= sSchemeClr;
701 else if( rProp.Name ==
"RgbClr" )
702 rProp.Value >>= nRgbClr;
703 else if( rProp.Name ==
"Pos" )
704 rProp.Value >>=
nPos;
705 else if( rProp.Name ==
"Transparency" )
706 rProp.Value >>= nTransparency;
707 else if( rProp.Name ==
"Transformations" )
708 rProp.Value >>= aTransformations;
711 mpFS->startElementNS(XML_a, XML_gs, XML_pos, OString::number(
nPos * 100000.0).getStr());
712 if( sSchemeClr.isEmpty() )
722 mpFS->endElementNS( XML_a, XML_gs );
724 mpFS->endElementNS( XML_a, XML_gsLst );
726 switch (rGradient.Style)
729 mpFS->singleElementNS(
730 XML_a, XML_lin, XML_ang,
731 OString::number(((3600 - rGradient.Angle + 900) * 6000) % 21600000));
733 case awt::GradientStyle_RADIAL:
734 WriteGradientPath(rGradient,
mpFS,
true);
740 const uno::Reference<beans::XPropertySet>& rXPropSet)
742 sal_Int32 nStartAlpha;
744 if( rXPropSet.is() &&
GetProperty(rXPropSet,
"FillTransparence") )
746 sal_Int32 nTransparency = 0;
747 mAny >>= nTransparency;
752 nStartAlpha = GetAlphaFromTransparenceGradient(rTransparenceGradient,
true);
753 nEndAlpha = GetAlphaFromTransparenceGradient(rTransparenceGradient,
false);
755 switch( rGradient.Style )
758 case awt::GradientStyle_LINEAR:
760 mpFS->startElementNS(XML_a, XML_gsLst);
765 mpFS->endElementNS( XML_a, XML_gsLst );
766 mpFS->singleElementNS(
767 XML_a, XML_lin, XML_ang,
768 OString::number(((3600 - rGradient.Angle + 900) * 6000) % 21600000));
772 case awt::GradientStyle_AXIAL:
774 mpFS->startElementNS(XML_a, XML_gsLst);
777 if (rGradient.Border > 0 && rGradient.Border < 100)
785 if (rGradient.Border > 0 && rGradient.Border < 100)
793 mpFS->endElementNS(XML_a, XML_gsLst);
794 mpFS->singleElementNS(
795 XML_a, XML_lin, XML_ang,
796 OString::number(((3600 - rGradient.Angle + 900) * 6000) % 21600000));
800 case awt::GradientStyle_RADIAL:
801 case awt::GradientStyle_ELLIPTICAL:
802 case awt::GradientStyle_RECT:
803 case awt::GradientStyle_SQUARE:
805 mpFS->startElementNS(XML_a, XML_gsLst);
808 if (rGradient.Border > 0 && rGradient.Border < 100)
819 mpFS->endElementNS(XML_a, XML_gsLst);
821 WriteGradientPath(rGradient,
mpFS, rGradient.Style == awt::GradientStyle_RADIAL || rGradient.Style == awt::GradientStyle_ELLIPTICAL);
830 sal_Int32 nArrowLength;
831 sal_Int32 nArrowWidth;
840 switch( nArrowLength )
877 switch( nArrowWidth )
891 mpFS->singleElementNS( XML_a, bLineStart ? XML_headEnd : XML_tailEnd,
899 drawing::LineStyle aLineStyle( drawing::LineStyle_NONE );
906 sal_uInt32 nEmuLineWidth = 0;
909 bool bColorSet =
false;
910 const char* cap =
nullptr;
911 drawing::LineDash aLineDash;
912 bool bDashSet =
false;
913 bool bNoFill =
false;
917 OUString sColorFillScheme;
918 ::Color aResolvedColorFillScheme;
922 sal_uInt32 nStyleLineWidth = 0;
927 drawing::LineStyle aStyleLineStyle(drawing::LineStyle_NONE);
928 drawing::LineJoint aStyleLineJoint(drawing::LineJoint_NONE);
935 for (
const auto& rProp : std::as_const(aGrabBag))
937 if( rProp.Name ==
"SpPrLnSolidFillSchemeClr" )
938 rProp.Value >>= sColorFillScheme;
939 if( rProp.Name ==
"SpPrLnSolidFillResolvedSchemeClr" )
940 rProp.Value >>= aResolvedColorFillScheme;
941 else if( rProp.Name ==
"OriginalLnSolidFillClr" )
942 rProp.Value >>= nOriginalColor;
943 else if( rProp.Name ==
"StyleLnRef" )
944 rProp.Value >>= aStyleProperties;
945 else if( rProp.Name ==
"SpPrLnSolidFillSchemeClrTransformations" )
946 rProp.Value >>= aTransformations;
947 else if( rProp.Name ==
"EmuLineWidth" )
948 rProp.Value >>= nEmuLineWidth;
950 for (
const auto& rStyleProp : std::as_const(aStyleProperties))
952 if( rStyleProp.Name ==
"Color" )
953 rStyleProp.Value >>= nStyleColor;
954 else if( rStyleProp.Name ==
"LineStyle" )
955 rStyleProp.Value >>= aStyleLineStyle;
956 else if( rStyleProp.Name ==
"LineJoint" )
957 rStyleProp.Value >>= aStyleLineJoint;
958 else if( rStyleProp.Name ==
"LineWidth" )
959 rStyleProp.Value >>= nStyleLineWidth;
968 case drawing::LineStyle_NONE:
971 case drawing::LineStyle_DASH:
974 aLineDash =
mAny.get<drawing::LineDash>();
976 if (aLineDash.Dots == 0 && aLineDash.DotLen == 0 && aLineDash.Dashes == 0 && aLineDash.DashLen == 0 && aLineDash.Distance == 0) {
977 OUString aLineDashName;
979 mAny >>= aLineDashName;
980 if (!aLineDashName.isEmpty() &&
xModel) {
989 OUString aLineDashName;
991 mAny >>= aLineDashName;
992 if (!aLineDashName.isEmpty() &&
xModel) {
998 if (aLineDash.Style == DashStyle_ROUND || aLineDash.Style == DashStyle_ROUNDRELATIVE)
1003 SAL_INFO(
"oox.shape",
"dash dots: " << aLineDash.Dots <<
" dashes: " << aLineDash.Dashes
1004 <<
" dotlen: " << aLineDash.DotLen <<
" dashlen: " << aLineDash.DashLen <<
" distance: " << aLineDash.Distance);
1007 case drawing::LineStyle_SOLID:
1018 if (aLineCap == LineCap_ROUND)
1020 else if (aLineCap == LineCap_SQUARE)
1028 mpFS->startElementNS( XML_a, XML_ln,
1035 if( nColor != nOriginalColor )
1041 else if( !sColorFillScheme.isEmpty() )
1052 if( bDashSet && aStyleLineStyle != drawing::LineStyle_DASH )
1059 bool bIsConverted =
false;
1061 bool bIsRelative(aLineDash.Style == DashStyle_RECTRELATIVE || aLineDash.Style == DashStyle_ROUNDRELATIVE);
1062 if ( bIsRelative && aLineDash.Dots == 1)
1064 sal_uInt32 nDotLen = aLineDash.DotLen;
1065 sal_uInt32 nDashLen = aLineDash.DashLen;
1066 sal_uInt32 nDistance = aLineDash.Distance;
1067 if (aLineCap != LineCap_BUTT && nDistance >= 99)
1078 if (nDashLen == 0 && aLineDash.Dashes > 0)
1080 bIsConverted =
true;
1081 if (nDotLen == 100 && aLineDash.Dashes == 0 && nDashLen == 0 && nDistance == 300)
1083 mpFS->singleElementNS(XML_a, XML_prstDash, XML_val,
"dot");
1085 else if (nDotLen == 400 && aLineDash.Dashes == 0 && nDashLen == 0 && nDistance == 300)
1087 mpFS->singleElementNS(XML_a, XML_prstDash, XML_val,
"dash");
1089 else if (nDotLen == 400 && aLineDash.Dashes == 1 && nDashLen == 100 && nDistance == 300)
1091 mpFS->singleElementNS(XML_a, XML_prstDash, XML_val,
"dashDot");
1093 else if (nDotLen == 800 && aLineDash.Dashes == 0 && nDashLen == 0 && nDistance == 300)
1095 mpFS->singleElementNS(XML_a, XML_prstDash, XML_val,
"lgDash");
1097 else if (nDotLen == 800 && aLineDash.Dashes == 1 && nDashLen == 100 && nDistance == 300)
1099 mpFS->singleElementNS(XML_a, XML_prstDash, XML_val,
"lgDashDot");
1101 else if (nDotLen == 800 && aLineDash.Dashes == 2 && nDashLen == 100 && nDistance == 300)
1103 mpFS->singleElementNS(XML_a, XML_prstDash, XML_val,
"lgDashDotDot");
1105 else if (nDotLen == 100 && aLineDash.Dashes == 0 && nDashLen == 0 && nDistance == 100)
1107 mpFS->singleElementNS(XML_a, XML_prstDash, XML_val,
"sysDot");
1109 else if (nDotLen == 300 && aLineDash.Dashes == 0 && nDashLen == 0 && nDistance == 100)
1111 mpFS->singleElementNS(XML_a, XML_prstDash, XML_val,
"sysDash");
1113 else if (nDotLen == 300 && aLineDash.Dashes == 1 && nDashLen == 100 && nDistance == 100)
1115 mpFS->singleElementNS(XML_a, XML_prstDash, XML_val,
"sysDashDot");
1117 else if (nDotLen == 300 && aLineDash.Dashes == 2 && nDashLen == 100 && nDistance == 100)
1119 mpFS->singleElementNS(XML_a, XML_prstDash, XML_val,
"sysDashDotDot");
1122 bIsConverted =
false;
1127 mpFS->startElementNS(XML_a, XML_custDash);
1133 double fSp = bIsRelative ? aLineDash.Distance : aLineDash.Distance * 100.0 / fLineWidth;
1136 if (aLineDash.Distance <= 0)
1140 if (aLineCap == LineCap_ROUND && fSp > 99.0)
1143 if (aLineDash.Dots > 0)
1145 double fD = bIsRelative ? aLineDash.DotLen : aLineDash.DotLen * 100.0 / fLineWidth;
1147 if (aLineDash.DotLen == 0)
1150 if (aLineCap == LineCap_ROUND && fSp > 99.0)
1153 for(
i = 0;
i < aLineDash.Dots;
i ++ )
1155 mpFS->singleElementNS( XML_a, XML_ds,
1160 if ( aLineDash.Dashes > 0 )
1162 double fD = bIsRelative ? aLineDash.DashLen : aLineDash.DashLen * 100.0 / fLineWidth;
1164 if (aLineDash.DashLen == 0)
1167 if (aLineCap == LineCap_ROUND && fSp > 99.0)
1170 for(
i = 0;
i < aLineDash.Dashes;
i ++ )
1172 mpFS->singleElementNS( XML_a , XML_ds,
1179 "oox.shape",
"while writing outline - custom dash - line width was < 0 : " <<
nLineWidth);
1181 "oox.shape",
"while writing outline - custom dash - number of dashes was < 0 : " << aLineDash.Dashes);
1182 SAL_WARN_IF(aLineDash.Dashes > 0 && aLineDash.DashLen <= 0,
1183 "oox.shape",
"while writing outline - custom dash - dash length was < 0 : " << aLineDash.DashLen);
1185 "oox.shape",
"while writing outline - custom dash - number of dots was < 0 : " << aLineDash.Dots);
1186 SAL_WARN_IF(aLineDash.Dots > 0 && aLineDash.DotLen <= 0,
1187 "oox.shape",
"while writing outline - custom dash - dot length was < 0 : " << aLineDash.DotLen);
1189 "oox.shape",
"while writing outline - custom dash - distance was < 0 : " << aLineDash.Distance);
1191 mpFS->endElementNS( XML_a, XML_custDash );
1199 if( aStyleLineJoint == LineJoint_NONE || aStyleLineJoint != eLineJoint )
1202 switch( eLineJoint )
1204 case LineJoint_NONE:
1205 case LineJoint_BEVEL:
1206 mpFS->singleElementNS(XML_a, XML_bevel);
1209 case LineJoint_MIDDLE:
1210 case LineJoint_MITER:
1211 mpFS->singleElementNS(XML_a, XML_miter);
1213 case LineJoint_ROUND:
1214 mpFS->singleElementNS(XML_a, XML_round);
1227 mpFS->singleElementNS(XML_a, XML_noFill);
1230 mpFS->endElementNS( XML_a, XML_ln );
1262 const char* pExtension =
"";
1271 sPath = aIterator->second;
1274 if (sPath.isEmpty())
1282 case GfxLinkType::NativeGif:
1284 pExtension =
".gif";
1289 case GfxLinkType::NativeBmp:
1291 pExtension =
".bmp";
1294 case GfxLinkType::NativeJpg:
1296 pExtension =
".jpeg";
1298 case GfxLinkType::NativePng:
1300 pExtension =
".png";
1302 case GfxLinkType::NativeTif:
1304 pExtension =
".tif";
1306 case GfxLinkType::NativeWmf:
1308 pExtension =
".wmf";
1310 case GfxLinkType::NativeMet:
1312 pExtension =
".met";
1314 case GfxLinkType::NativePct:
1316 pExtension =
".pct";
1318 case GfxLinkType::NativeMov:
1320 pExtension =
".MOV";
1325 if (aType == GraphicType::Bitmap || aType == GraphicType::GdiMetafile)
1327 if (aType == GraphicType::Bitmap)
1331 pExtension =
".png";
1337 pExtension =
".emf";
1342 SAL_WARN(
"oox.shape",
"unhandled graphic type " <<
static_cast<int>(aType));
1361 .appendAscii(pExtension)
1362 .makeStringAndClear(),
1365 xOutStream->closeOutput();
1367 const OString sRelPathToMedia =
"media/image";
1368 OString sRelationCompPrefix;
1369 if (bRelPathToMedia)
1370 sRelationCompPrefix =
"../";
1373 sPath = OUStringBuffer()
1374 .appendAscii(sRelationCompPrefix.getStr())
1375 .appendAscii(sRelPathToMedia.getStr())
1377 .appendAscii(pExtension)
1378 .makeStringAndClear();
1398 OUString aExtension;
1399 const OUString& rURL(pMediaObj->
getURL());
1400 int nLastDot = rURL.lastIndexOf(
'.');
1402 aExtension = rURL.copy(nLastDot);
1404 bool bEmbed = rURL.startsWith(
"vnd.sun.star.Package:");
1408#if HAVE_FEATURE_AVMEDIA
1413 if (
aMimeType ==
"application/vnd.sun.star.media")
1417 if (aExtension.equalsIgnoreAsciiCase(
".avi"))
1419 else if (aExtension.equalsIgnoreAsciiCase(
".flv"))
1421 else if (aExtension.equalsIgnoreAsciiCase(
".mp4"))
1423 else if (aExtension.equalsIgnoreAsciiCase(
".mov"))
1425 else if (aExtension.equalsIgnoreAsciiCase(
".ogv"))
1427 else if (aExtension.equalsIgnoreAsciiCase(
".wmv"))
1429 else if (aExtension.equalsIgnoreAsciiCase(
".wav"))
1434 else if (aExtension.equalsIgnoreAsciiCase(
".m4a"))
1439 else if (aExtension.equalsIgnoreAsciiCase(
".mp3"))
1446 OUString aVideoFileRelId;
1447 OUString aMediaRelId;
1454 .append(
"/media/media" +
1457 .makeStringAndClear(),
1460 uno::Reference<io::XInputStream> xInputStream(pMediaObj->
GetInputStream());
1463 xOutStream->closeOutput();
1467 .append(
"media/media" + OUString::number(
mnImageCounter.top()++) + aExtension)
1468 .makeStringAndClear();
1478 GetFS()->startElementNS(XML_p, XML_nvPr);
1481 FSNS(XML_r, XML_link), aVideoFileRelId);
1483 GetFS()->startElementNS(XML_p, XML_extLst);
1485 GetFS()->startElementNS(XML_p, XML_ext, XML_uri,
"{DAA4B4D4-6D71-4841-9C94-3DE7FCFB9230}");
1487 GetFS()->singleElementNS(XML_p14, XML_media,
1488 bEmbed?
FSNS(XML_r, XML_embed):
FSNS(XML_r, XML_link), aMediaRelId);
1490 GetFS()->endElementNS(XML_p, XML_ext);
1491 GetFS()->endElementNS(XML_p, XML_extLst);
1493 GetFS()->endElementNS(XML_p, XML_nvPr);
1498 sal_Int16 nBright = 0;
1499 sal_Int32 nContrast = 0;
1500 sal_Int32 nTransparence = 0;
1503 nBright =
mAny.get<sal_Int16>();
1505 nContrast =
mAny.get<sal_Int32>();
1508 nTransparence =
mAny.get<sal_Int32>();
1510 if (nTransparence == 0 &&
GetProperty(rXPropSet,
"Transparency"))
1511 nTransparence =
static_cast<sal_Int32
>(
mAny.get<sal_Int16>());
1515 drawing::ColorMode aColorMode;
1516 mAny >>= aColorMode;
1517 if (aColorMode == drawing::ColorMode_GREYS)
1518 mpFS->singleElementNS(XML_a, XML_grayscl);
1519 else if (aColorMode == drawing::ColorMode_MONO)
1521 mpFS->singleElementNS(XML_a, XML_biLevel, XML_thresh, OString::number(50000));
1522 else if (aColorMode == drawing::ColorMode_WATERMARK)
1531 if (nBright || nContrast)
1533 mpFS->singleElementNS(XML_a, XML_lum,
1540 sal_Int32 nAlphaMod = (100 - nTransparence ) *
PER_PERCENT;
1541 mpFS->singleElementNS(XML_a, XML_alphaModFix, XML_amt, OString::number(nAlphaMod));
1546 uno::Reference<graphic::XGraphic>
const & rxGraphic,
1547 bool bRelPathToMedia)
1551 if (!rxGraphic.is())
1555 sRelId =
WriteImage(aGraphic, bRelPathToMedia);
1557 mpFS->startElementNS(XML_a, XML_blip,
FSNS(XML_r, XML_embed), sRelId);
1563 mpFS->endElementNS(XML_a, XML_blip);
1569 uno::Reference<graphic::XGraphic>
const & rxGraphic)
1571 BitmapMode eBitmapMode(BitmapMode_NO_REPEAT);
1573 mAny >>= eBitmapMode;
1575 SAL_INFO(
"oox.shape",
"fill bitmap mode: " <<
int(eBitmapMode));
1577 switch (eBitmapMode)
1579 case BitmapMode_REPEAT:
1582 case BitmapMode_STRETCH:
1606void DrawingML::WriteBlipFill(
const Reference< XPropertySet >& rXPropSet,
const OUString& sURLPropName, sal_Int32 nXmlNamespace )
1611 uno::Reference<graphic::XGraphic> xGraphic;
1612 if (
mAny.has<uno::Reference<awt::XBitmap>>())
1614 uno::Reference<awt::XBitmap> xBitmap =
mAny.get<uno::Reference<awt::XBitmap>>();
1616 xGraphic.set(xBitmap, uno::UNO_QUERY);
1618 else if (
mAny.has<uno::Reference<graphic::XGraphic>>())
1620 xGraphic =
mAny.get<uno::Reference<graphic::XGraphic>>();
1625 bool bWriteMode =
false;
1626 if (sURLPropName ==
"FillBitmap" || sURLPropName ==
"BackGraphic")
1633 uno::Reference<graphic::XGraphic>
const & rxGraphic,
1634 sal_Int32 nXmlNamespace,
bool bWriteMode,
bool bRelPathToMedia)
1636 if (!rxGraphic.is() )
1639 mpFS->startElementNS(nXmlNamespace , XML_blipFill, XML_rotWithShape,
"0");
1653 else if(
GetProperty(rXPropSet,
"FillBitmapStretch"))
1655 bool bStretch =
mAny.get<
bool>();
1662 mpFS->endElementNS(nXmlNamespace, XML_blipFill);
1669 drawing::Hatch aHatch;
1682 sal_Int32 nTransparency = 0;
1683 mAny >>= nTransparency;
1687 mpFS->startElementNS(XML_a, XML_fgClr);
1689 mpFS->endElementNS( XML_a , XML_fgClr );
1695 bool isBackgroundFilled =
false;
1696 mAny >>= isBackgroundFilled;
1697 if( isBackgroundFilled )
1708 mpFS->startElementNS(XML_a, XML_bgClr);
1710 mpFS->endElementNS( XML_a , XML_bgClr );
1712 mpFS->endElementNS( XML_a , XML_pattFill );
1716 Size const & rOriginalSize,
1722 css::text::GraphicCrop aGraphicCropStruct;
1723 mAny >>= aGraphicCropStruct;
1731 mpFS->singleElementNS( XML_a, XML_srcRect);
1735 Size aOriginalSize(rOriginalSize);
1738 if (rMapMode.
GetMapUnit() == MapUnit::MapPixel)
1741 if ( (0 != aGraphicCropStruct.Left) || (0 != aGraphicCropStruct.Top) || (0 != aGraphicCropStruct.Right) || (0 != aGraphicCropStruct.Bottom) )
1743 mpFS->singleElementNS( XML_a, XML_srcRect,
1744 XML_l, OString::number(rtl::math::round(aGraphicCropStruct.Left * 100000.0 / aOriginalSize.
Width())),
1745 XML_t, OString::number(rtl::math::round(aGraphicCropStruct.Top * 100000.0 / aOriginalSize.
Height())),
1746 XML_r, OString::number(rtl::math::round(aGraphicCropStruct.Right * 100000.0 / aOriginalSize.
Width())),
1747 XML_b, OString::number(rtl::math::round(aGraphicCropStruct.Bottom * 100000.0 / aOriginalSize.
Height())) );
1753 uno::Reference<graphic::XGraphic>
const & rxGraphic)
1762 uno::Reference<graphic::XGraphic>
const & rxGraphic)
1767 mpFS->singleElementNS(XML_a, XML_stretch);
1771 mpFS->startElementNS(XML_a, XML_stretch);
1776 css::text::GraphicCrop aGraphicCropStruct;
1777 mAny >>= aGraphicCropStruct;
1779 if ((0 != aGraphicCropStruct.Left)
1780 || (0 != aGraphicCropStruct.Top)
1781 || (0 != aGraphicCropStruct.Right)
1782 || (0 != aGraphicCropStruct.Bottom))
1786 mpFS->singleElementNS(XML_a, XML_fillRect,
1787 XML_l, OString::number(((aGraphicCropStruct.Left) * 100000) / aOriginalSize.
Width()),
1788 XML_t, OString::number(((aGraphicCropStruct.Top) * 100000) / aOriginalSize.
Height()),
1789 XML_r, OString::number(((aGraphicCropStruct.Right) * 100000) / aOriginalSize.
Width()),
1790 XML_b, OString::number(((aGraphicCropStruct.Bottom) * 100000) / aOriginalSize.
Height()));
1797 mpFS->singleElementNS(XML_a, XML_fillRect);
1800 mpFS->endElementNS(XML_a, XML_stretch);
1805 OUString sAlignment;
1806 switch (eRectanglePoint)
1808 case RectanglePoint_LEFT_TOP:
1811 case RectanglePoint_MIDDLE_TOP:
1814 case RectanglePoint_RIGHT_TOP:
1817 case RectanglePoint_LEFT_MIDDLE:
1820 case RectanglePoint_MIDDLE_MIDDLE:
1823 case RectanglePoint_RIGHT_MIDDLE:
1826 case RectanglePoint_LEFT_BOTTOM:
1829 case RectanglePoint_MIDDLE_BOTTOM:
1832 case RectanglePoint_RIGHT_BOTTOM:
1842 uno::Reference<graphic::XGraphic>
const& rxGraphic)
1848 if (rMapMode.
GetMapUnit() == MapUnit::MapPixel)
1850 MapMode(MapUnit::Map100thMM));
1851 sal_Int32 nSizeX = 0;
1852 sal_Int32 nOffsetX = 0;
1856 if (
GetProperty(rXPropSet,
"FillBitmapPositionOffsetX"))
1858 sal_Int32 nX = (nSizeX != 0) ? nSizeX : aOriginalSize.
Width();
1859 nOffsetX = (*o3tl::doAccess<sal_Int32>(
mAny)) * nX * 3.6;
1864 nSizeX = double(nSizeX) / aOriginalSize.
Width() * 100000;
1865 else if (nSizeX < 0)
1871 sal_Int32 nSizeY = 0;
1872 sal_Int32 nOffsetY = 0;
1876 if (
GetProperty(rXPropSet,
"FillBitmapPositionOffsetY"))
1878 sal_Int32 nY = (nSizeY != 0) ? nSizeY : aOriginalSize.
Height();
1879 nOffsetY = (*o3tl::doAccess<sal_Int32>(
mAny)) * nY * 3.6;
1884 nSizeY = double(nSizeY) / aOriginalSize.
Height() * 100000;
1885 else if (nSizeY < 0)
1892 if (nSizeX < 0 && nSizeY < 0)
1898 css::uno::Reference<css::beans::XPropertySet> xPagePropSet(xDrawPage, UNO_QUERY);
1901 double nPageWidth, nPageHeight;
1902 xPagePropSet->getPropertyValue(
"Width") >>= nPageWidth;
1903 xPagePropSet->getPropertyValue(
"Height") >>= nPageHeight;
1904 nSizeX = nPageWidth / aOriginalSize.
Width() * std::abs(nSizeX);
1905 nSizeY = nPageHeight / aOriginalSize.
Height() * std::abs(nSizeY);
1909 OUString sRectanglePoint;
1910 if (
GetProperty(rXPropSet,
"FillBitmapRectanglePoint"))
1913 mpFS->singleElementNS(XML_a, XML_tile, XML_tx, OUString::number(nOffsetX), XML_ty,
1914 OUString::number(nOffsetY), XML_sx, OUString::number(nSizeX), XML_sy,
1915 OUString::number(nSizeY), XML_algn, sRectanglePoint);
1920bool IsTopGroupObj(
const uno::Reference<drawing::XShape>& xShape)
1926 if (
pObject->getParentSdrObjectFromSdrObject())
1929 return pObject->IsGroupObject();
1934 sal_Int32 nXmlNamespace,
bool bFlipH,
bool bFlipV, sal_Int32 nRotation,
bool bIsGroupShape)
1937 mpFS->startElementNS( nXmlNamespace, XML_xfrm,
1942 sal_Int32 nLeft = rRect.
Left();
1943 sal_Int32 nTop = rRect.
Top();
1949 sal_Int32 nChildLeft = nLeft;
1950 sal_Int32 nChildTop = nTop;
1952 mpFS->singleElementNS(XML_a, XML_off,
1955 mpFS->singleElementNS(XML_a, XML_ext,
1961 mpFS->singleElementNS(XML_a, XML_chOff,
1964 mpFS->singleElementNS(XML_a, XML_chExt,
1969 mpFS->endElementNS( nXmlNamespace, XML_xfrm );
1974 SAL_INFO(
"oox.shape",
"write shape transformation");
1978 awt::Point aPos = rXShape->getPosition();
1979 awt::Size aSize = rXShape->getSize();
1981 bool bFlipHWrite = bFlipH && !bSuppressFlipping;
1982 bool bFlipVWrite = bFlipV && !bSuppressFlipping;
1983 bFlipH = bFlipH && !bFlippedBeforeRotation;
1984 bFlipV = bFlipV && !bFlippedBeforeRotation;
1988 awt::Point aParentPos =
m_xParent->getPosition();
1989 aPos.X -= aParentPos.X;
1990 aPos.Y -= aParentPos.Y;
1993 if ( aSize.Width < 0 )
1995 if ( aSize.Height < 0 )
1996 aSize.Height = 1000;
1997 if (!bSuppressRotation)
2003 int faccos=bFlipV ? -1 : 1;
2004 int facsin=bFlipH ? -1 : 1;
2005 aPos.X-=(1-faccos*cos(
toRadians(nRotation)))*aSize.Width/2-facsin*sin(
toRadians(nRotation))*aSize.Height/2;
2006 aPos.Y-=(1-faccos*cos(
toRadians(nRotation)))*aSize.Height/2+facsin*sin(
toRadians(nRotation))*aSize.Width/2;
2008 else if (
m_xParent.is() && nRotation != 0_deg100)
2011 basegfx::B2DRange aRect(-aSize.Width / 2.0, -aSize.Height / 2.0, aSize.Width / 2.0,
2012 aSize.Height / 2.0);
2016 aPos.X += -aSize.Width / 2.0 - aRect.
getMinX();
2017 aPos.Y += -aSize.Height / 2.0 - aRect.
getMinY();
2021 uno::Reference<beans::XPropertySet> xPropertySet(rXShape, uno::UNO_QUERY);
2022 uno::Reference<beans::XPropertySetInfo> xPropertySetInfo = xPropertySet->getPropertySetInfo();
2023 if (xPropertySetInfo->hasPropertyByName(
"RotateAngle"))
2026 if (xPropertySet->getPropertyValue(
"RotateAngle") >>= nTmp)
2032 uno::Sequence<beans::PropertyValue> aGrabBagProps;
2034 auto p3DEffectProps = std::find_if(std::cbegin(aGrabBagProps), std::cend(aGrabBagProps),
2035 [](
const PropertyValue& rProp) {
return rProp.Name ==
"3DEffectProperties"; });
2036 if (p3DEffectProps != std::cend(aGrabBagProps))
2038 uno::Sequence<beans::PropertyValue> a3DEffectProps;
2039 p3DEffectProps->Value >>= a3DEffectProps;
2040 auto pCameraProps = std::find_if(std::cbegin(a3DEffectProps), std::cend(a3DEffectProps),
2041 [](
const PropertyValue& rProp) {
return rProp.Name ==
"Camera"; });
2042 if (pCameraProps != std::cend(a3DEffectProps))
2044 uno::Sequence<beans::PropertyValue> aCameraProps;
2045 pCameraProps->Value >>= aCameraProps;
2046 auto pZRotationProp = std::find_if(std::cbegin(aCameraProps), std::cend(aCameraProps),
2047 [](
const PropertyValue& rProp) {
return rProp.Name ==
"rotRev"; });
2048 if (pZRotationProp != std::cend(aCameraProps))
2051 pZRotationProp->Value >>= nTmp;
2060 if(bFlipH != bFlipV)
2061 nRotation = 36000_deg100 - nRotation;
2067static OUString
lcl_GetTarget(
const css::uno::Reference<css::frame::XModel>& xModel, OUString& rURL)
2071 sal_uInt32 nPageCount = xDrawPages->getCount();
2074 for (sal_uInt32
i = 0;
i < nPageCount; ++
i)
2077 xDrawPages->getByIndex(
i) >>= xDrawPage;
2081 OUString sSlideName =
"#" + xNamed->getName();
2082 if (rURL == sSlideName)
2084 sTarget =
"slide" + OUString::number(
i + 1) +
".xml";
2088 if (sTarget.isEmpty())
2090 sal_Int32 nSplit = rURL.lastIndexOf(
' ');
2092 sTarget = OUString::Concat(
"slide") + rURL.subView(nSplit + 1) +
".xml";
2099 bool bCheckDirect,
bool& rbOverridingCharHeight, sal_Int32& rnCharHeight,
2104 OUString usLanguage;
2105 PropertyState eState;
2106 bool bComplex = ( nScriptType == css::i18n::ScriptType::COMPLEX );
2107 const char*
bold =
"0";
2108 const char*
italic =
nullptr;
2110 const char* strikeout =
nullptr;
2111 const char* cap =
nullptr;
2112 sal_Int32 nSize = 1800;
2113 sal_Int32 nCharEscapement = 0;
2114 sal_Int32 nCharKerning = 0;
2115 sal_Int32 nCharEscapementHeight = 0;
2117 if ( nElement == XML_endParaRPr && rbOverridingCharHeight )
2119 nSize = rnCharHeight;
2123 nSize =
static_cast<sal_Int32
>(100*(*o3tl::doAccess<float>(
mAny)));
2124 if ( nElement == XML_rPr || nElement == XML_defRPr )
2126 rbOverridingCharHeight =
true;
2127 rnCharHeight = nSize;
2132 nCharKerning =
static_cast<sal_Int32
>(*o3tl::doAccess<sal_Int16>(
mAny));
2139 nCharKerning = ((nCharKerning * 720)-360) / 254;
2141 if ((bComplex &&
GetProperty(rXPropSet,
"CharWeightComplex"))
2144 if ( *o3tl::doAccess<float>(
mAny) >= awt::FontWeight::SEMIBOLD )
2148 if ((bComplex &&
GetProperty(rXPropSet,
"CharPostureComplex"))
2150 switch ( *o3tl::doAccess<awt::FontSlant>(
mAny) )
2152 case awt::FontSlant_OBLIQUE :
2153 case awt::FontSlant_ITALIC :
2161 && eState == beans::PropertyState_DIRECT_VALUE)
2164 switch ( *o3tl::doAccess<sal_Int16>(
mAny) )
2166 case awt::FontUnderline::SINGLE :
2169 case awt::FontUnderline::DOUBLE :
2172 case awt::FontUnderline::DOTTED :
2175 case awt::FontUnderline::DASH :
2178 case awt::FontUnderline::LONGDASH :
2181 case awt::FontUnderline::DASHDOT :
2184 case awt::FontUnderline::DASHDOTDOT :
2187 case awt::FontUnderline::WAVE :
2190 case awt::FontUnderline::DOUBLEWAVE :
2193 case awt::FontUnderline::BOLD :
2196 case awt::FontUnderline::BOLDDOTTED :
2199 case awt::FontUnderline::BOLDDASH :
2202 case awt::FontUnderline::BOLDLONGDASH :
2205 case awt::FontUnderline::BOLDDASHDOT :
2208 case awt::FontUnderline::BOLDDASHDOTDOT :
2211 case awt::FontUnderline::BOLDWAVE :
2218 && eState == beans::PropertyState_DIRECT_VALUE)
2221 switch ( *o3tl::doAccess<sal_Int16>(
mAny) )
2223 case awt::FontStrikeout::NONE :
2224 strikeout =
"noStrike";
2226 case awt::FontStrikeout::SINGLE :
2234 case awt::FontStrikeout::BOLD :
2235 case awt::FontStrikeout::SLASH :
2236 case awt::FontStrikeout::X :
2237 strikeout =
"sngStrike";
2239 case awt::FontStrikeout::DOUBLE :
2240 strikeout =
"dblStrike";
2248 case css::i18n::ScriptType::ASIAN:
2249 bLang =
GetProperty(rXPropSet,
"CharLocaleAsian");
break;
2250 case css::i18n::ScriptType::COMPLEX:
2251 bLang =
GetProperty(rXPropSet,
"CharLocaleComplex");
break;
2253 bLang =
GetProperty(rXPropSet,
"CharLocale");
break;
2258 css::lang::Locale aLocale;
2266 && eState == beans::PropertyState_DIRECT_VALUE)
2267 mAny >>= nCharEscapement;
2270 && eState == beans::PropertyState_DIRECT_VALUE)
2271 mAny >>= nCharEscapementHeight;
2278 nCharEscapement = .8 * (100 - nCharEscapementHeight);
2285 nCharEscapement = .2 * -(100 - nCharEscapementHeight);
2288 if (nCharEscapement && nCharEscapementHeight)
2290 nSize = (nSize * nCharEscapementHeight) / 100;
2292 nSize = (nSize / 0.58);
2297 switch ( *o3tl::doAccess<sal_Int16>(
mAny) )
2299 case CaseMap::UPPERCASE :
2302 case CaseMap::SMALLCAPS :
2308 mpFS->startElementNS( XML_a, nElement,
2312 XML_sz, OString::number(nSize),
2315 XML_strike, strikeout,
2332 && eState == beans::PropertyState_DIRECT_VALUE)
2340 if (rXPropSet->getPropertySetInfo()->hasPropertyByName(
"CharTransparence"))
2342 rXPropSet->getPropertyValue(
"CharTransparence") >>= nTransparency;
2348 bool bContoured =
false;
2350 bContoured = *o3tl::doAccess<bool>(
mAny);
2355 mpFS->startElementNS(XML_a, XML_ln);
2362 color.SetAlpha(255);
2366 mpFS->endElementNS(XML_a, XML_ln);
2374 color.SetAlpha(255);
2385 if (rXShapePropSet.is() &&
GetProperty(rXShapePropSet,
"FillStyle")
2390 bIsTextBackgroundDark = aShapeFillColor.
IsDark();
2393 if (bIsTextBackgroundDark)
2410 mpFS->startElementNS(XML_a, XML_highlight);
2412 mpFS->endElementNS( XML_a, XML_highlight );
2420 && eState == beans::PropertyState_DIRECT_VALUE)
2427 mpFS->startElementNS(XML_a, XML_uFill);
2429 mpFS->endElementNS( XML_a, XML_uFill );
2433 mpFS->singleElementNS(XML_a, XML_uFillTx);
2439 const char*
const pitch =
nullptr;
2440 const char*
const charset =
nullptr;
2441 OUString usTypeface;
2443 mAny >>= usTypeface;
2444 OUString aSubstName(
GetSubsFontName( usTypeface, SubsFontFlags::ONLYONE | SubsFontFlags::MS ) );
2445 if (!aSubstName.isEmpty())
2446 usTypeface = aSubstName;
2448 mpFS->singleElementNS( XML_a, XML_latin,
2449 XML_typeface, usTypeface,
2450 XML_pitchFamily, pitch,
2451 XML_charset, charset );
2456 && eState == beans::PropertyState_DIRECT_VALUE))
2459 && eState == beans::PropertyState_DIRECT_VALUE)))
2461 const char*
const pitch =
nullptr;
2462 const char*
const charset =
nullptr;
2463 OUString usTypeface;
2465 mAny >>= usTypeface;
2466 OUString aSubstName(
GetSubsFontName( usTypeface, SubsFontFlags::ONLYONE | SubsFontFlags::MS ) );
2467 if (!aSubstName.isEmpty())
2468 usTypeface = aSubstName;
2470 mpFS->singleElementNS( XML_a, bComplex ? XML_cs : XML_ea,
2471 XML_typeface, usTypeface,
2472 XML_pitchFamily, pitch,
2473 XML_charset, charset );
2480 mAny >>= rXTextField;
2481 if( rXTextField.is() )
2482 rXPropSet.set( rXTextField, UNO_QUERY );
2491 if (!sURL.isEmpty())
2493 if (!sURL.match(
"#action?jump="))
2505 mpFS->singleElementNS(XML_a, XML_hlinkClick,
FSNS(XML_r, XML_id), sRelId);
2507 mpFS->singleElementNS(XML_a, XML_hlinkClick,
FSNS(XML_r, XML_id), sRelId,
2508 XML_action,
"ppaction://hlinksldjump");
2512 sal_Int32
nIndex = sURL.indexOf(
'=');
2513 std::u16string_view aDestination(sURL.subView(
nIndex + 1));
2514 mpFS->singleElementNS(XML_a, XML_hlinkClick,
FSNS(XML_r, XML_id),
"", XML_action,
2515 OUString::Concat(
"ppaction://hlinkshowjump?jump=") + aDestination);
2519 mpFS->endElementNS( XML_a, nElement );
2525 OUString aFieldType, aFieldValue;
2529 aFieldType = *o3tl::doAccess<OUString>(
mAny);
2530 SAL_INFO(
"oox.shape",
"field type: " << aFieldType);
2533 if( aFieldType ==
"TextField" )
2537 mAny >>= rXTextField;
2538 if( rXTextField.is() )
2540 rXPropSet.set( rXTextField, UNO_QUERY );
2541 if( rXPropSet.is() )
2543 OUString aFieldKind( rXTextField->getPresentation(
true ) );
2544 SAL_INFO(
"oox.shape",
"field kind: " << aFieldKind);
2545 if( aFieldKind ==
"Page" )
2547 aFieldValue =
"slidenum";
2549 else if( aFieldKind ==
"Pages" )
2551 aFieldValue =
"slidecount";
2553 else if( aFieldKind ==
"PageName" )
2555 aFieldValue =
"slidename";
2557 else if( aFieldKind ==
"URL" )
2561 mAny >>= aFieldValue;
2564 else if(aFieldKind ==
"Date")
2566 sal_Int32 nNumFmt = -1;
2570 else if(aFieldKind ==
"ExtTime")
2572 sal_Int32 nNumFmt = -1;
2576 else if(aFieldKind ==
"ExtFile")
2578 sal_Int32 nNumFmt = -1;
2582 case 0: aFieldValue =
"file";
2584 case 1: aFieldValue =
"file1";
2586 case 2: aFieldValue =
"file2";
2588 case 3: aFieldValue =
"file3";
2591 else if(aFieldKind ==
"Author")
2593 aFieldValue =
"author";
2613 OUString aDateField;
2616 case SvxDateFormat::StdSmall:
2617 case SvxDateFormat::A:
2618 aDateField =
"datetime";
2620 case SvxDateFormat::B:
2621 aDateField =
"datetime1";
2623 case SvxDateFormat::C:
2624 aDateField =
"datetime5";
2626 case SvxDateFormat::D:
2627 aDateField =
"datetime3";
2629 case SvxDateFormat::StdBig:
2630 case SvxDateFormat::E:
2631 case SvxDateFormat::F:
2632 aDateField =
"datetime2";
2638 OUString aTimeField;
2641 case SvxTimeFormat::Standard:
2642 case SvxTimeFormat::HH24_MM_SS:
2643 case SvxTimeFormat::HH24_MM_SS_00:
2644 aTimeField =
"datetime11";
2646 case SvxTimeFormat::HH24_MM:
2647 aTimeField =
"datetime10";
2649 case SvxTimeFormat::HH12_MM:
2650 case SvxTimeFormat::HH12_MM_AMPM:
2651 aTimeField =
"datetime12";
2653 case SvxTimeFormat::HH12_MM_SS:
2654 case SvxTimeFormat::HH12_MM_SS_AMPM:
2655 case SvxTimeFormat::HH12_MM_SS_00:
2656 case SvxTimeFormat::HH12_MM_SS_00_AMPM:
2657 aTimeField =
"datetime13";
2663 if (!aDateField.isEmpty() && aTimeField.isEmpty())
2665 else if (!aTimeField.isEmpty() && aDateField.isEmpty())
2667 else if (!aDateField.isEmpty() && !aTimeField.isEmpty())
2669 if (aTimeField ==
"datetime11" || aTimeField ==
"datetime13")
2681 bool& rbOverridingCharHeight, sal_Int32& rnCharHeight,
2682 const css::uno::Reference< css::beans::XPropertySet >& rXShapePropSet)
2685 sal_Int16 nLevel = -1;
2689 bool bNumberingIsNumber =
true;
2691 mAny >>= bNumberingIsNumber;
2693 float nFontSize = -1;
2697 bool bIsURLField =
false;
2699 bool bWriteField = !( sFieldValue.isEmpty() || bIsURLField );
2701 OUString sText = rRun->getString();
2704 if (nLevel !=-1 && bNumberingIsNumber && sText.isEmpty() )
2708 sText = sFieldValue;
2710 if( sText.isEmpty())
2716 if( !xPropSet.is() || !( xPropSet->getPropertyValue(
"PlaceholderText" ) >>= sText ) )
2718 if( sText.isEmpty() )
2732 mpFS->startElementNS(XML_a, XML_br);
2733 mpFS->singleElementNS(XML_a, XML_rPr, XML_sz,
2734 OString::number(nFontSize * 100).getStr());
2735 mpFS->endElementNS(XML_a, XML_br);
2738 mpFS->singleElementNS(XML_a, XML_br);
2745 mpFS->startElementNS( XML_a, XML_fld,
2746 XML_id, sUUID.getStr(),
2751 mpFS->startElementNS(XML_a, XML_r);
2757 mpFS->startElementNS(XML_a, XML_t);
2758 mpFS->writeEscaped( sText );
2759 mpFS->endElementNS( XML_a, XML_t );
2762 mpFS->endElementNS( XML_a, XML_fld );
2764 mpFS->endElementNS( XML_a, XML_r );
2770 OUString sPrefixSuffix;
2773 sPrefixSuffix =
"ParenBoth";
2775 sPrefixSuffix =
"ParenR";
2777 sPrefixSuffix =
"Period";
2779 switch( nNumberingType )
2783 return "alphaUc" + sPrefixSuffix;
2787 return "alphaLc" + sPrefixSuffix;
2790 return "romanUc" + sPrefixSuffix;
2793 return "romanLc" + sPrefixSuffix;
2797 if (sPrefixSuffix.isEmpty())
2798 return "arabicPlain";
2800 return "arabic" + sPrefixSuffix;
2811 if (nLevel < 0 || !
GetProperty(rXPropSet,
"NumberingRules"))
2816 if (!(
mAny >>= rXIndexAccess) || nLevel >= rXIndexAccess->getCount())
2819 SAL_INFO(
"oox.shape",
"numbering rules");
2822 rXIndexAccess->getByIndex(nLevel) >>= aPropertySequence;
2824 if (!aPropertySequence.hasElements())
2829 bool bPBehind =
false;
2830 bool bPBoth =
false;
2832 awt::FontDescriptor aFontDesc;
2833 bool bHasFontDesc =
false;
2834 uno::Reference<graphic::XGraphic> xGraphic;
2835 sal_Int16 nBulletRelSize = 0;
2836 sal_Int16 nStartWith = 1;
2838 bool bHasBulletColor =
false;
2839 awt::Size aGraphicSize;
2841 for (
const PropertyValue& rPropValue : std::as_const(aPropertySequence) )
2847 nNumberingType =
static_cast<SvxNumType>(*o3tl::doAccess<sal_Int16>(rPropValue.Value));
2851 if( *o3tl::doAccess<OUString>(rPropValue.Value) ==
")")
2856 auto s = o3tl::doAccess<OUString>(rPropValue.Value);
2865 bHasBulletColor =
true;
2869 aBulletChar = (*o3tl::doAccess<OUString>(rPropValue.Value))[ 0 ];
2873 aFontDesc = *o3tl::doAccess<awt::FontDescriptor>(rPropValue.Value);
2874 bHasFontDesc =
true;
2880 if ( aFontDesc.Name.equalsIgnoreAsciiCase(
"StarSymbol") )
2881 aFontDesc.CharSet = RTL_TEXTENCODING_MS_1252;
2884 else if (
aPropName ==
"BulletRelSize" )
2886 nBulletRelSize = *o3tl::doAccess<sal_Int16>(rPropValue.Value);
2890 nStartWith = *o3tl::doAccess<sal_Int16>(rPropValue.Value);
2894 auto xBitmap = rPropValue.Value.get<uno::Reference<awt::XBitmap>>();
2895 xGraphic.set(xBitmap, uno::UNO_QUERY);
2899 aGraphicSize = *o3tl::doAccess<awt::Size>(rPropValue.Value);
2900 SAL_INFO(
"oox.shape",
"graphic size: " << aGraphicSize.Width <<
"x" << aGraphicSize.Height);
2908 if (xGraphic.is() && aGraphic.
GetType() != GraphicType::NONE)
2913 OUString sRelationId;
2915 if (fBulletSizeRel < 1.0f)
2918 Size aDestSize(64, 64);
2919 float fBulletSizeRelX = fBulletSizeRel / aGraphicSize.Height * aGraphicSize.Width;
2920 tools::Long nPaddingX = std::max<tools::Long>(0, std::lround((aDestSize.
Width() - fBulletSizeRelX * aDestSize.
Width()) / 2.f));
2930 aDestBitmap.
CopyPixel(aDestRect, aSourceRect, &aSourceBitmap);
2931 Graphic aDestGraphic(aDestBitmap);
2933 fBulletSizeRel = 1.0f;
2940 mpFS->singleElementNS( XML_a, XML_buSzPct,
2941 XML_val, OString::number(std::min<sal_Int32>(std::lround(100000.f * fBulletSizeRel), 400000)));
2942 mpFS->startElementNS(XML_a, XML_buBlip);
2943 mpFS->singleElementNS(XML_a, XML_blip,
FSNS(XML_r, XML_embed), sRelationId);
2944 mpFS->endElementNS( XML_a, XML_buBlip );
2954 mpFS->startElementNS(XML_a, XML_buClr);
2956 mpFS->endElementNS( XML_a, XML_buClr );
2959 if( nBulletRelSize && nBulletRelSize != 100 )
2960 mpFS->singleElementNS( XML_a, XML_buSzPct,
2961 XML_val, OString::number(std::clamp<sal_Int32>(1000*nBulletRelSize, 25000, 400000)));
2966 mpFS->singleElementNS( XML_a, XML_buFont,
2967 XML_typeface, aFontDesc.Name,
2971 OUString aAutoNumType =
GetAutoNumType( nNumberingType, bSDot, bPBehind, bPBoth );
2973 if (!aAutoNumType.isEmpty())
2975 mpFS->singleElementNS(XML_a, XML_buAutoNum,
2981 mpFS->singleElementNS(XML_a, XML_buChar, XML_char, OUString(aBulletChar));
2988 css::uno::Sequence<css::style::TabStop> aTabStops;
2990 aTabStops = *o3tl::doAccess<css::uno::Sequence<css::style::TabStop>>(
mAny);
2992 if (aTabStops.getLength() > 0)
2993 mpFS->startElementNS(XML_a, XML_tabLst);
2995 for (
const css::style::TabStop& rTabStop : std::as_const(aTabStops))
2999 switch (rTabStop.Alignment)
3001 case css::style::TabAlign_DECIMAL:
3004 case css::style::TabAlign_RIGHT:
3007 case css::style::TabAlign_CENTER:
3010 case css::style::TabAlign_LEFT:
3014 mpFS->singleElementNS(XML_a, XML_tab, XML_algn, sAlignment, XML_pos, sPosition);
3016 if (aTabStops.getLength() > 0)
3017 mpFS->endElementNS(XML_a, XML_tabLst);
3025 uno::Reference<lang::XServiceInfo> xServiceInfo(rXShape, uno::UNO_QUERY_THROW);
3026 bRet = xServiceInfo->supportsService(
"com.sun.star.drawing.GroupShape");
3033 if (nLevel < 0 || !
GetProperty(rXPropSet,
"NumberingRules"))
3038 if (!(
mAny >>= rXIndexAccess) || nLevel >= rXIndexAccess->getCount())
3041 SAL_INFO(
"oox.shape",
"numbering rules");
3044 rXIndexAccess->getByIndex(nLevel) >>= aPropertySequence;
3046 if (!aPropertySequence.hasElements())
3049 for (
const PropertyValue& rPropValue : std::as_const(aPropertySequence) )
3054 return *o3tl::doAccess<sal_Int32>(rPropValue.Value);
3062 const char* sAlignment =
nullptr;
3064 switch( nAlignment )
3066 case style::ParagraphAdjust_CENTER:
3069 case style::ParagraphAdjust_RIGHT:
3072 case style::ParagraphAdjust_BLOCK:
3073 sAlignment =
"just";
3084 if( rSpacing.Mode == LineSpacingMode::PROP )
3086 mpFS->singleElementNS( XML_a, XML_spcPct,
3087 XML_val, OString::number(
static_cast<sal_Int32
>(rSpacing.Height)*1000));
3089 else if (rSpacing.Mode == LineSpacingMode::MINIMUM
3090 && fFirstCharHeight >
static_cast<float>(rSpacing.Height) * 0.001 * 72.0 / 2.54)
3093 mpFS->singleElementNS(XML_a, XML_spcPct, XML_val,
3094 OString::number(
static_cast<sal_Int32
>(100000)));
3098 mpFS->singleElementNS( XML_a, XML_spcPts,
3099 XML_val, OString::number(std::lround(rSpacing.Height / 25.4 * 72)));
3107 PropertyState eState;
3109 if( !rXPropSet.is() || !rXPropState.is() )
3112 sal_Int16 nLevel = -1;
3116 bool bWriteNumbering =
true;
3117 bool bForceZeroIndent =
false;
3123 bool bNumberingOnThisLevel =
false;
3128 for (
const PropertyValue& rRule : rNumRuleOfLevel)
3129 if (rRule.Name ==
"NumberingType" && rRule.Value.hasValue())
3130 bNumberingOnThisLevel = rRule.Value.get<sal_uInt16>() != style::NumberingType::NUMBER_NONE;
3133 const bool bIsNumberingVisible = rXPropSet->getPropertyValue(
"NumberingIsNumber").get<
bool>();
3134 const bool bIsLineEmpty = !xParaText->getString().getLength();
3136 bWriteNumbering = !bIsLineEmpty && bIsNumberingVisible && (nLevel != -1);
3137 bForceZeroIndent = (!bIsNumberingVisible || bIsLineEmpty || !bNumberingOnThisLevel);
3142 sal_Int16 nTmp = sal_Int16(style::ParagraphAdjust_LEFT);
3145 style::ParagraphAdjust nAlignment =
static_cast<style::ParagraphAdjust
>(nTmp);
3147 bool bHasLinespacing =
false;
3148 LineSpacing aLineSpacing;
3150 && (
mAny >>= aLineSpacing)
3151 && (eState == beans::PropertyState_DIRECT_VALUE ||
3153 aLineSpacing.Mode != LineSpacingMode::PROP || aLineSpacing.Height != 100))
3154 bHasLinespacing =
true;
3159 sal_Int16 nWritingMode;
3160 if( (
mAny >>= nWritingMode ) && nWritingMode == text::WritingMode2::RL_TB )
3166 sal_Int32 nParaLeftMargin = 0;
3167 sal_Int32 nParaFirstLineIndent = 0;
3170 mAny >>= nParaLeftMargin;
3171 if (
GetProperty(rXPropSet,
"ParaFirstLineIndent"))
3172 mAny >>= nParaFirstLineIndent;
3174 sal_Int32 nParaTopMargin = 0;
3175 sal_Int32 nParaBottomMargin = 0;
3178 mAny >>= nParaTopMargin;
3180 mAny >>= nParaBottomMargin;
3185 if (bWriteNumbering && !bForceZeroIndent)
3188 || nAlignment != style::ParagraphAdjust_LEFT
3189 || bHasLinespacing))
3194 if (
GetProperty(rXShapePropSet,
"TextFitToSize") &&
mAny.get<TextFitToSizeType>() == TextFitToSizeType_AUTOFIT)
3204 nLineIndentation = nLineIndentation * nFontScaleY / 100;
3205 nParaLeftMargin = nParaLeftMargin * nFontScaleY / 100;
3206 nParaFirstLineIndent = nParaFirstLineIndent * nFontScaleY / 100;
3211 if (nParaLeftMargin)
3212 mpFS->startElementNS( XML_a, nElement,
3219 mpFS->startElementNS( XML_a, nElement,
3227 if( bHasLinespacing )
3229 mpFS->startElementNS(XML_a, XML_lnSpc);
3231 mpFS->endElementNS( XML_a, XML_lnSpc );
3234 if( nParaTopMargin != 0 )
3236 mpFS->startElementNS(XML_a, XML_spcBef);
3238 mpFS->singleElementNS( XML_a, XML_spcPts,
3239 XML_val, OString::number(std::lround(nParaTopMargin / 25.4 * 72)));
3241 mpFS->endElementNS( XML_a, XML_spcBef );
3244 if( nParaBottomMargin != 0 )
3246 mpFS->startElementNS(XML_a, XML_spcAft);
3248 mpFS->singleElementNS( XML_a, XML_spcPts,
3249 XML_val, OString::number(std::lround(nParaBottomMargin / 25.4 * 72)));
3251 mpFS->endElementNS( XML_a, XML_spcAft );
3254 if (!bWriteNumbering)
3255 mpFS->singleElementNS(XML_a, XML_buNone);
3262 if( nElement != XML_lvl1pPr )
3263 mpFS->endElementNS( XML_a, nElement );
3269 bool& rbOverridingCharHeight, sal_Int32& rnCharHeight,
3270 const css::uno::Reference<css::beans::XPropertySet>& rXShapePropSet)
3277 if (!xEnumeration.is())
3283 if (!xEnumeration->hasMoreElements())
3286 Any aAny(xEnumeration->nextElement());
3289 float fFirstCharHeight = rnCharHeight / 1000.;
3292 = xFirstRunPropSet->getPropertySetInfo();
3294 if (xFirstRunPropSetInfo->hasPropertyByName(
"CharHeight"))
3295 fFirstCharHeight = xFirstRunPropSet->getPropertyValue(
"CharHeight").get<
float>();
3297 mpFS->startElementNS(XML_a, XML_lstStyle);
3299 mpFS->startElementNS(XML_a, XML_lvl1pPr);
3300 WriteRunProperties(xFirstRunPropSet,
false, XML_defRPr,
true, rbOverridingCharHeight,
3301 rnCharHeight,
GetScriptType(rRun->getString()), rXShapePropSet);
3302 mpFS->endElementNS(XML_a, XML_lvl1pPr);
3303 mpFS->endElementNS(XML_a, XML_lstStyle);
3308 bool& rbOverridingCharHeight, sal_Int32& rnCharHeight,
3309 const css::uno::Reference< css::beans::XPropertySet >& rXShapePropSet)
3316 if( !enumeration.is() )
3319 mpFS->startElementNS(XML_a, XML_p);
3321 bool bPropertiesWritten =
false;
3322 while( enumeration->hasMoreElements() )
3325 Any any ( enumeration->nextElement() );
3329 if( !bPropertiesWritten )
3331 float fFirstCharHeight = rnCharHeight / 1000.;
3334 if( xFirstRunPropSetInfo->hasPropertyByName(
"CharHeight") )
3336 fFirstCharHeight = xFirstRunPropSet->getPropertyValue(
"CharHeight").get<
float>();
3337 rnCharHeight = 100 * fFirstCharHeight;
3338 rbOverridingCharHeight =
true;
3341 bPropertiesWritten =
true;
3343 WriteRun(
run, rbOverridingCharHeight, rnCharHeight, rXShapePropSet);
3347 sal_Int16 nDummy = -1;
3349 rnCharHeight, nDummy, rXShapePropSet);
3351 mpFS->endElementNS( XML_a, XML_p );
3356 bool bResult(
false);
3357 if (rXShapePropSet.is())
3360 if (
GetProperty(rXShapePropSet,
"CustomShapeGeometry"))
3362 mAny >>= aCustomShapeGeometryProps;
3363 uno::Sequence<beans::PropertyValue> aTextPathSeq;
3364 for (
const auto& rProp : std::as_const(aCustomShapeGeometryProps))
3366 if (rProp.Name ==
"TextPath")
3368 rProp.Value >>= aTextPathSeq;
3369 for (
const auto& rTextPathItem : std::as_const(aTextPathSeq))
3371 if (rTextPathItem.Name ==
"TextPath")
3373 rTextPathItem.Value >>= bResult;
3386 sal_Int32 nXmlNamespace,
bool bWritePropertiesAsLstStyles)
3389 uno::Reference<XText> xXText(rXIface, UNO_QUERY);
3393 uno::Reference<drawing::XShape> xShape(rXIface, UNO_QUERY);
3394 uno::Reference<XPropertySet> rXPropSet(rXIface, UNO_QUERY);
3396 constexpr const sal_Int32 constDefaultLeftRightInset = 254;
3397 constexpr const sal_Int32 constDefaultTopBottomInset = 127;
3398 sal_Int32 nLeft = constDefaultLeftRightInset;
3399 sal_Int32 nRight = constDefaultLeftRightInset;
3400 sal_Int32 nTop = constDefaultTopBottomInset;
3401 sal_Int32 nBottom = constDefaultTopBottomInset;
3417 sal_Int32 nTextHeight = xShape->getSize().Height;
3430 if (nTop + nBottom >= nTextHeight)
3435 std::swap(nTop, nBottom);
3436 nTop = nTextHeight - nTop;
3437 nBottom = nTextHeight - nBottom;
3441 std::optional<OString> sWritingMode;
3446 sWritingMode =
"eaVert";
3450 sal_Int16 nWritingMode;
3451 if (
mAny >>= nWritingMode)
3453 if (nWritingMode == text::WritingMode2::TB_RL)
3454 sWritingMode =
"eaVert";
3455 else if (nWritingMode == text::WritingMode2::BT_LR)
3456 sWritingMode =
"vert270";
3457 else if (nWritingMode == text::WritingMode2::TB_RL90)
3458 sWritingMode =
"vert";
3459 else if (nWritingMode == text::WritingMode2::TB_LR)
3460 sWritingMode =
"mongolianVert";
3466 uno::Sequence<beans::PropertyValue> aTextPathSeq;
3467 bool bScaleX(
false);
3468 OUString sShapeType(
"non-primitive");
3469 OUString sMSWordPresetTextWarp;
3470 sal_Int32 nTextPreRotateAngle = 0;
3471 std::optional<Degree100> nTextRotateAngleDeg100;
3473 if (
GetProperty(rXPropSet,
"CustomShapeGeometry"))
3476 if (
mAny >>= aProps )
3478 for (
const auto& rProp : std::as_const(aProps) )
3480 if (rProp.Name ==
"TextPreRotateAngle")
3481 rProp.Value >>= nTextPreRotateAngle;
3482 else if (rProp.Name ==
"AdjustmentValues")
3483 rProp.Value >>= aAdjustmentSeq;
3484 else if (rProp.Name ==
"TextRotateAngle")
3486 double fTextRotateAngle = 0;
3487 rProp.Value >>= fTextRotateAngle;
3488 nTextRotateAngleDeg100 =
Degree100(std::lround(fTextRotateAngle * 100.0));
3490 else if (rProp.Name ==
"Type")
3491 rProp.Value >>= sShapeType;
3492 else if (rProp.Name ==
"TextPath")
3494 rProp.Value >>= aTextPathSeq;
3495 for (
const auto& rTextPathItem : std::as_const(aTextPathSeq))
3497 if (rTextPathItem.Name ==
"ScaleX")
3498 rTextPathItem.Value >>= bScaleX;
3501 else if (rProp.Name ==
"PresetTextWarp")
3502 rProp.Value >>= sMSWordPresetTextWarp;
3515 uno::Reference<beans::XPropertySet> xPropSet(xTextFrame, uno::UNO_QUERY);
3516 auto aAny = xPropSet->getPropertyValue(
"WritingMode");
3517 sal_Int16 nWritingMode;
3518 if (aAny >>= nWritingMode)
3520 switch (nWritingMode)
3522 case WritingMode2::TB_RL:
3523 sWritingMode =
"eaVert";
3525 case WritingMode2::BT_LR:
3526 sWritingMode =
"vert270";
3528 case WritingMode2::TB_RL90:
3529 sWritingMode =
"vert";
3531 case WritingMode2::TB_LR:
3532 sWritingMode =
"mongolianVert";
3544 std::optional<OUString> sHorzOverflow;
3545 std::optional<OUString> sVertOverflow;
3546 bool bUpright =
false;
3547 std::optional<OString> isUpright;
3548 if (rXPropSet->getPropertySetInfo()->hasPropertyByName(
"InteropGrabBag"))
3550 uno::Sequence<beans::PropertyValue> aGrabBag;
3551 rXPropSet->getPropertyValue(
"InteropGrabBag") >>= aGrabBag;
3552 for (
const auto& aProp : std::as_const(aGrabBag))
3554 if (aProp.Name ==
"Upright")
3556 aProp.Value >>= bUpright;
3557 isUpright = OString(bUpright ?
"1" :
"0");
3559 else if (aProp.Name ==
"horzOverflow")
3562 aProp.Value >>= sValue;
3563 sHorzOverflow = sValue;
3565 else if (aProp.Name ==
"vertOverflow")
3568 aProp.Value >>= sValue;
3569 sVertOverflow = sValue;
3577 if (sPresetWarp.isEmpty())
3578 sPresetWarp = bIsFontworkShape ? std::u16string_view(
u"textPlain") : std::u16string_view(
u"textNoShape");
3580 bool bFromWordArt = !bScaleX
3581 && ( sPresetWarp ==
"textArchDown" || sPresetWarp ==
"textArchUp"
3582 || sPresetWarp ==
"textButton" || sPresetWarp ==
"textCircle");
3586 Degree100 nShapeRotateAngleDeg100(0_deg100);
3591 bool bWasAngleChanged
3592 = (nShapeRotateAngleDeg100 > 4500_deg100 && nShapeRotateAngleDeg100 <= 13500_deg100)
3593 || (nShapeRotateAngleDeg100 > 22500_deg100
3594 && nShapeRotateAngleDeg100 <= 31500_deg100);
3595 if (bWasAngleChanged)
3597 nTextRotateAngleDeg100 = nTextRotateAngleDeg100.value_or(0_deg100) + 9000_deg100;
3598 nTextPreRotateAngle -= 90;
3604 Degree100 nAngleSum = nShapeRotateAngleDeg100 + nTextRotateAngleDeg100.value_or(0_deg100);
3607 nTextRotateAngleDeg100.reset();
3613 if (bWasAngleChanged)
3615 nTextPreRotateAngle += 90;
3616 nTextRotateAngleDeg100 = nTextRotateAngleDeg100.value_or(0_deg100) - 9000_deg100;
3623 if (nTextPreRotateAngle != 0 && !sWritingMode)
3625 if (nTextPreRotateAngle == -90 || nTextPreRotateAngle == 270)
3626 sWritingMode =
"vert";
3627 else if (nTextPreRotateAngle == -270 || nTextPreRotateAngle == 90)
3628 sWritingMode =
"vert270";
3629 else if (nTextPreRotateAngle == -180 || nTextPreRotateAngle == 180)
3631#if defined __GNUC__ && !defined __clang__ && __GNUC__ == 12
3632#pragma GCC diagnostic push
3633#pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
3635 nTextRotateAngleDeg100
3636 =
NormAngle18000(nTextRotateAngleDeg100.value_or(0_deg100) + 18000_deg100);
3637#if defined __GNUC__ && !defined __clang__ && __GNUC__ == 12
3638#pragma GCC diagnostic pop
3643 SAL_WARN(
"oox",
"unsuitable value for TextPreRotateAngle:" << nTextPreRotateAngle);
3645 else if (nTextPreRotateAngle != 0 && sWritingMode && sWritingMode.value() ==
"eaVert")
3656 if (sWritingMode.value() ==
"vert" || sWritingMode.value() ==
"eaVert")
3658 sal_Int32 nHelp = nLeft;
3664 else if (sWritingMode.value() ==
"vert270")
3666 sal_Int32 nHelp = nLeft;
3672 else if (sWritingMode.value() ==
"mongolianVert")
3679 std::optional<OString> sTextRotateAngleMSUnit;
3680 if (nTextRotateAngleDeg100.has_value())
3681#if defined __GNUC__ && !defined __clang__ && __GNUC__ == 12
3682#pragma GCC diagnostic push
3683#pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
3685 sTextRotateAngleMSUnit
3687#if defined __GNUC__ && !defined __clang__ && __GNUC__ == 12
3688#pragma GCC diagnostic pop
3694 TextVerticalAdjust eVerticalAlignment(TextVerticalAdjust_TOP);
3696 mAny >>= eVerticalAlignment;
3697 TextHorizontalAdjust eHorizontalAlignment(TextHorizontalAdjust_CENTER);
3698 if (
GetProperty(rXPropSet,
"TextHorizontalAdjust"))
3699 mAny >>= eHorizontalAlignment;
3701 const char* sAnchor =
nullptr;
3702 bool bAnchorCtr =
false;
3703 if (sWritingMode.has_value()
3704 && (sWritingMode.value() ==
"eaVert" || sWritingMode.value() ==
"mongolianVert"))
3706 bAnchorCtr = eVerticalAlignment == TextVerticalAdjust_CENTER
3707 || eVerticalAlignment == TextVerticalAdjust_BOTTOM
3708 || eVerticalAlignment == TextVerticalAdjust_BLOCK;
3709 switch (eHorizontalAlignment)
3711 case TextHorizontalAdjust_CENTER:
3714 case TextHorizontalAdjust_LEFT:
3715 sAnchor = sWritingMode.value() ==
"eaVert" ?
"b" :
"t";
3717 case TextHorizontalAdjust_RIGHT:
3719 sAnchor = sWritingMode.value() ==
"eaVert" ?
"t" :
"b";
3725 bAnchorCtr = eHorizontalAlignment == TextHorizontalAdjust_CENTER
3726 || eHorizontalAlignment == TextHorizontalAdjust_RIGHT;
3730 bool bHasWrap =
false;
3741 const char* pWrap = (bHasWrap && !bWrap) || bIsFontworkShape ?
"none" :
nullptr;
3747 uno::Reference<lang::XServiceInfo> xServiceInfo(rXIface, uno::UNO_QUERY);
3748 if ((xServiceInfo.is() && xServiceInfo->supportsService(
"com.sun.star.drawing.TextShape"))
3749 || bIsFontworkShape)
3753 sal_Int16 nCols = 0;
3754 sal_Int32 nColSpacing = -1;
3757 if (css::uno::Reference<css::text::XTextColumns> xCols{
mAny, css::uno::UNO_QUERY })
3759 nCols = xCols->getColumnCount();
3760 if (css::uno::Reference<css::beans::XPropertySet> xProps{
mAny,
3761 css::uno::UNO_QUERY })
3764 mAny >>= nColSpacing;
3769 mpFS->startElementNS( (nXmlNamespace ? nXmlNamespace : XML_a), XML_bodyPr,
3773 XML_horzOverflow, sHorzOverflow,
3774 XML_vertOverflow, sVertOverflow,
3780 XML_anchor, sAnchor,
3782 XML_vert, sWritingMode,
3783 XML_upright, isUpright,
3784 XML_rot, sTextRotateAngleMSUnit);
3786 if (bIsFontworkShape)
3788 if (aAdjustmentSeq.hasElements())
3790 mpFS->startElementNS(XML_a, XML_prstTxWarp, XML_prst, sPresetWarp);
3791 mpFS->startElementNS(XML_a, XML_avLst);
3792 bool bHasTwoHandles(
3793 sPresetWarp ==
"textArchDownPour" || sPresetWarp ==
"textArchUpPour"
3794 || sPresetWarp ==
"textButtonPour" || sPresetWarp ==
"textCirclePour"
3795 || sPresetWarp ==
"textDoubleWave1" || sPresetWarp ==
"textWave1"
3796 || sPresetWarp ==
"textWave2" || sPresetWarp ==
"textWave4");
3797 for (sal_Int32
i = 0, nElems = aAdjustmentSeq.getLength();
i < nElems; ++
i )
3799 OString
sName =
"adj" + (bHasTwoHandles ? OString::number(
i + 1) : OString());
3801 if (aAdjustmentSeq[
i].
Value.getValueTypeClass() == TypeClass_DOUBLE)
3802 aAdjustmentSeq[
i].Value >>= fValue;
3805 sal_Int32 nNumber(0);
3806 aAdjustmentSeq[
i].Value >>= nNumber;
3807 fValue =
static_cast<double>(nNumber);
3812 if (sPresetWarp ==
"textArchDown" || sPresetWarp ==
"textArchUp"
3813 || sPresetWarp ==
"textButton" || sPresetWarp ==
"textCircle"
3815 && (sPresetWarp ==
"textArchDownPour" || sPresetWarp ==
"textArchUpPour"
3816 || sPresetWarp ==
"textButtonPour" || sPresetWarp ==
"textCirclePour")))
3823 && (sPresetWarp ==
"textDoubleWave1" || sPresetWarp ==
"textWave1"
3824 || sPresetWarp ==
"textWave2" || sPresetWarp ==
"textWave4"))
3826 fValue = fValue / 0.216 - 50000.0;
3829 && (sPresetWarp ==
"textArchDownPour"
3830 || sPresetWarp ==
"textArchUpPour"
3831 || sPresetWarp ==
"textButtonPour"
3832 || sPresetWarp ==
"textCirclePour"))
3840 OString sFmla =
"val " + OString::number(std::lround(fValue));
3841 mpFS->singleElementNS(XML_a, XML_gd, XML_name,
sName, XML_fmla, sFmla);
3843 if (!bHasTwoHandles)
3846 mpFS->endElementNS(XML_a, XML_avLst);
3847 mpFS->endElementNS(XML_a, XML_prstTxWarp);
3851 mpFS->singleElementNS(XML_a, XML_prstTxWarp, XML_prst, sPresetWarp);
3857 if (!sMSWordPresetTextWarp.isEmpty())
3858 mpFS->singleElementNS(XML_a, XML_prstTxWarp, XML_prst, sMSWordPresetTextWarp);
3864 bool bTextAutoGrowHeight =
false;
3866 if (pSdrObjCustomShape &&
GetProperty(rXPropSet,
"TextAutoGrowHeight"))
3868 mAny >>= bTextAutoGrowHeight;
3870 mpFS->singleElementNS(XML_a, (bTextAutoGrowHeight ? XML_spAutoFit : XML_noAutofit));
3874 TextFitToSizeType eFit = TextFitToSizeType_NONE;
3878 if (eFit == TextFitToSizeType_AUTOFIT)
3880 const sal_Int32 MAX_SCALE_VAL = 100000;
3881 sal_Int32 nFontScale = MAX_SCALE_VAL;
3890 mpFS->singleElementNS(XML_a, XML_normAutofit, XML_fontScale,
3896 bool bTextAutoGrowHeight =
false;
3898 mAny >>= bTextAutoGrowHeight;
3899 mpFS->singleElementNS(XML_a, (bTextAutoGrowHeight ? XML_spAutoFit : XML_noAutofit));
3905 mpFS->endElementNS((nXmlNamespace ? nXmlNamespace : XML_a), XML_bodyPr);
3909 if( !access.is() || !bText )
3913 if( !enumeration.is() )
3942 bool bOverridingCharHeight =
false;
3943 sal_Int32 nCharHeight = -1;
3944 bool bFirstParagraph =
true;
3948 if(xXText->getString().isEmpty() && enumeration->hasMoreElements())
3950 Any aAny (enumeration->nextElement());
3952 if( aAny >>= xParagraph )
3954 mpFS->startElementNS(XML_a, XML_p);
3956 sal_Int16 nDummy = -1;
3958 bOverridingCharHeight, nCharHeight, nDummy, rXPropSet);
3959 mpFS->endElementNS(XML_a, XML_p);
3964 while( enumeration->hasMoreElements() )
3967 Any any ( enumeration->nextElement() );
3971 if (bFirstParagraph && bWritePropertiesAsLstStyles)
3975 bFirstParagraph =
false;
3982 mpFS->startElementNS(XML_a, XML_prstGeom, XML_prst, pShape);
3983 if ( !rAvList.empty() )
3986 mpFS->startElementNS(XML_a, XML_avLst);
3987 for (
auto const& elem : rAvList)
3989 OString
sName =
"adj" + ( ( elem.first > 0 ) ? OString::number(elem.first) : OString() );
3990 OString sFmla =
"val " + OString::number( elem.second );
3992 mpFS->singleElementNS(XML_a, XML_gd, XML_name,
sName, XML_fmla, sFmla);
3994 mpFS->endElementNS( XML_a, XML_avLst );
3997 mpFS->singleElementNS(XML_a, XML_avLst);
3999 mpFS->endElementNS( XML_a, XML_prstGeom );
4004 mpFS->startElementNS(XML_a, XML_prstGeom, XML_prst, pShape);
4005 mpFS->singleElementNS(XML_a, XML_avLst);
4006 mpFS->endElementNS( XML_a, XML_prstGeom );
4011 std::map< OString, std::vector<OString> > aRet;
4013 OUString aPath(
"$BRAND_BASE_DIR/" LIBO_SHARE_FOLDER
"/filter/oox-drawingml-adj-names");
4014 rtl::Bootstrap::expandMacros(aPath);
4017 SAL_WARN(
"oox.shape",
"failed to open oox-drawingml-adj-names");
4018 OStringBuffer aLine;
4019 bool bNotDone = aStream.
ReadLine(aLine);
4025 OString aValue( std::string_view(aLine).substr(
nIndex) );
4026 aRet[aKey].push_back(aValue);
4027 bNotDone = aStream.
ReadLine(aLine);
4034 static std::map< OString, std::vector<OString> > aAdjMap =
lcl_getAdjNames();
4036 std::vector<OString> aAdjustments;
4037 if (aAdjMap.find(pShape) != aAdjMap.end())
4038 aAdjustments = aAdjMap[pShape];
4040 mpFS->startElementNS(XML_a, XML_prstGeom, XML_prst, pShape);
4041 mpFS->startElementNS(XML_a, XML_avLst);
4043 Sequence< drawing::EnhancedCustomShapeAdjustmentValue > aAdjustmentSeq;
4044 if ( ( rProp.Value >>= aAdjustmentSeq )
4045 && eShapeType != mso_sptActionButtonForwardNext
4046 && eShapeType != mso_sptActionButtonBackPrevious
4050 SAL_INFO(
"oox.shape",
"adj seq len: " << aAdjustmentSeq.getLength());
4051 sal_Int32 nAdjustmentsWhichNeedsToBeConverted = 0;
4052 if ( bPredefinedHandlesUsed )
4060 for (sal_Int32
i = 0; i < static_cast<sal_Int32>(aAdjustments.size());
i++)
4065 OString aAdjName = aAdjustmentSeq[
i].Name.isEmpty()
4067 : aAdjustmentSeq[
i].Name.toUtf8();
4069 mpFS->singleElementNS( XML_a, XML_gd,
4071 XML_fmla,
"val " + OString::number(nValue));
4077 mpFS->endElementNS( XML_a, XML_avLst );
4078 mpFS->endElementNS( XML_a, XML_prstGeom );
4084FindNextCommandEndSubpath(
const sal_Int32 nStart,
4085 const uno::Sequence<drawing::EnhancedCustomShapeSegment>& rSegments)
4087 sal_Int32
i = nStart < 0 ? 0 : nStart;
4088 while (
i < rSegments.getLength() && rSegments[
i].Command != ENDSUBPATH)
4093bool HasCommandInSubPath(
const sal_Int16 nCommand,
const sal_Int32 nFirst,
const sal_Int32 nLast,
4094 const uno::Sequence<drawing::EnhancedCustomShapeSegment>& rSegments)
4096 for (sal_Int32
i = nFirst < 0 ? 0 : nFirst;
i <= nLast &&
i < rSegments.getLength();
i++)
4098 if (rSegments[
i].Command == nCommand)
4106void getEllipsePointAndAngleFromRayPoint(
double& rfAngleDeg,
double& rfSx,
double& rfSy,
4107 const double fWR,
const double fHR,
const double fCx,
4108 const double fCy,
const double fRayPx,
const double fRayPy)
4119 double fCircleMathAngle = atan2(-fWR / fHR * (fRayPy - fCy), fRayPx - fCx);
4121 double fPointMathEllipse_x = fWR * cos(fCircleMathAngle);
4122 double fPointMathEllipse_y = fHR * sin(fCircleMathAngle);
4124 double fEllipseMathAngle = atan2(fPointMathEllipse_y, fPointMathEllipse_x);
4127 rfSx = fPointMathEllipse_x + fCx;
4128 rfSy = -fPointMathEllipse_y + fCy;
4132void getEllipsePointFromViewAngle(
double& rfSx,
double& rfSy,
const double fWR,
const double fHR,
4133 const double fCx,
const double fCy,
const double fViewAngleDeg)
4144 double fRadius = 1.0 / std::hypot(fX, fY);
4150sal_Int32 GetCustomGeometryPointValue(
const css::drawing::EnhancedCustomShapeParameter& rParam,
4152 const bool bReplaceGeoWidth,
const bool bReplaceGeoHeight)
4154 double fValue = 0.0;
4155 rCustomShape2d.
GetParameter(fValue, rParam, bReplaceGeoWidth, bReplaceGeoHeight);
4156 sal_Int32
nValue(std::lround(fValue));
4176 std::vector<Guide>& rGuideList, TextAreaRect& rTextAreaRect)
4180 if (aTextAreaLO == aLogicRectLO)
4182 rTextAreaRect.left =
"l";
4183 rTextAreaRect.top =
"t";
4184 rTextAreaRect.right =
"r";
4185 rTextAreaRect.bottom =
"b";
4190 aTextAreaLO.
Move((aLogicRectLO.
Center().X() - aTextAreaLO.
Center().X()) * 2, 0);
4192 aTextAreaLO.
Move(0, (aLogicRectLO.
Center().Y() - aTextAreaLO.
Center().Y()) * 2);
4196 const sal_Int32 nWidth = aLogicRectLO.
Right() - aLogicRectLO.
Left();
4200 aGuide.sName =
"textAreaLeft";
4201 sal_Int32 nHelp = aTextAreaLO.
Left() - aLogicRectLO.
Left();
4203 aGuide.sFormula =
"*/ " + sLeft +
" w " + sWidth;
4204 rTextAreaRect.left = aGuide.sName;
4205 rGuideList.push_back(aGuide);
4208 aGuide.sName =
"textAreaRight";
4209 nHelp = aTextAreaLO.
Right() - aLogicRectLO.
Left();
4211 aGuide.sFormula =
"*/ " + sRight +
" w " + sWidth;
4212 rTextAreaRect.right = aGuide.sName;
4213 rGuideList.push_back(aGuide);
4216 const sal_Int32 nHeight = aLogicRectLO.
Bottom() - aLogicRectLO.
Top();
4220 aGuide.sName =
"textAreaTop";
4221 nHelp = aTextAreaLO.
Top() - aLogicRectLO.
Top();
4223 aGuide.sFormula =
"*/ " + sTop +
" h " + sHeight;
4224 rTextAreaRect.top = aGuide.sName;
4225 rGuideList.push_back(aGuide);
4228 aGuide.sName =
"textAreaBottom";
4229 nHelp = aTextAreaLO.
Bottom() - aLogicRectLO.
Top();
4231 aGuide.sFormula =
"*/ " + sBottom +
" h " + sHeight;
4232 rTextAreaRect.bottom = aGuide.sName;
4233 rGuideList.push_back(aGuide);
4243 uno::Reference< beans::XPropertySet > aXPropSet;
4246 if ( ! (aAny >>= aXPropSet) )
4251 aAny = aXPropSet->getPropertyValue(
"CustomShapeGeometry" );
4255 catch( const ::uno::Exception& )
4260 auto pGeometrySeq = o3tl::tryAccess<uno::Sequence<beans::PropertyValue>>(aAny);
4264 auto pPathProp = std::find_if(std::cbegin(*pGeometrySeq), std::cend(*pGeometrySeq),
4265 [](
const PropertyValue& rProp) {
return rProp.Name ==
"Path"; });
4266 if (pPathProp == std::cend(*pGeometrySeq))
4269 uno::Sequence<beans::PropertyValue> aPathProp;
4270 pPathProp->
Value >>= aPathProp;
4272 uno::Sequence<drawing::EnhancedCustomShapeParameterPair> aPairs;
4273 uno::Sequence<drawing::EnhancedCustomShapeSegment>
aSegments;
4274 uno::Sequence<awt::Size> aPathSize;
4275 bool bReplaceGeoWidth =
false;
4276 bool bReplaceGeoHeight =
false;
4277 for (
const beans::PropertyValue& rPathProp : std::as_const(aPathProp))
4279 if (rPathProp.Name ==
"Coordinates")
4280 rPathProp.Value >>= aPairs;
4281 else if (rPathProp.Name ==
"Segments")
4283 else if (rPathProp.Name ==
"SubViewSize")
4284 rPathProp.Value >>= aPathSize;
4285 else if (rPathProp.Name ==
"StretchX")
4286 bReplaceGeoWidth =
true;
4287 else if (rPathProp.Name ==
"StretchY")
4288 bReplaceGeoHeight =
true;
4291 if ( !aPairs.hasElements() )
4296 aSegments = uno::Sequence<drawing::EnhancedCustomShapeSegment>
4300 static_cast<sal_Int16
>(std::min( aPairs.getLength() - 1, sal_Int32(32767) )) },
4301 { CLOSESUBPATH, 0 },
4306 int nExpectedPairCount = std::accumulate(std::cbegin(
aSegments), std::cend(
aSegments), 0,
4307 [](
const int nSum,
const drawing::EnhancedCustomShapeSegment& rSegment) {
return nSum + rSegment.Count; });
4309 if ( nExpectedPairCount > aPairs.getLength() )
4311 SAL_WARN(
"oox.shape",
"Segments need " << nExpectedPairCount <<
" coordinates, but Coordinates have only " << aPairs.getLength() <<
" pairs.");
4319 TextAreaRect aTextAreaRect;
4320 std::vector<Guide> aGuideList;
4321 prepareTextArea(aCustomShape2d, aGuideList, aTextAreaRect);
4322 mpFS->startElementNS(XML_a, XML_custGeom);
4323 mpFS->singleElementNS(XML_a, XML_avLst);
4324 if (aGuideList.empty())
4326 mpFS->singleElementNS(XML_a, XML_gdLst);
4330 mpFS->startElementNS(XML_a, XML_gdLst);
4331 for (
auto const& elem : aGuideList)
4333 mpFS->singleElementNS(XML_a, XML_gd, XML_name, elem.sName, XML_fmla, elem.sFormula);
4335 mpFS->endElementNS(XML_a, XML_gdLst);
4337 mpFS->singleElementNS(XML_a, XML_ahLst);
4338 mpFS->singleElementNS(XML_a, XML_rect, XML_l, aTextAreaRect.left, XML_t, aTextAreaRect.top,
4339 XML_r, aTextAreaRect.right, XML_b, aTextAreaRect.bottom);
4340 mpFS->startElementNS(XML_a, XML_pathLst);
4343 bool bUseGlobalViewBox(
false);
4347 sal_Int32 nViewBoxWidth(0);
4348 sal_Int32 nViewBoxHeight(0);
4349 if (!aPathSize.hasElements())
4351 bUseGlobalViewBox =
true;
4355 auto pProp = std::find_if(
4356 std::cbegin(*pGeometrySeq), std::cend(*pGeometrySeq),
4357 [](
const beans::PropertyValue& rGeomProp) {
return rGeomProp.Name ==
"ViewBox"; });
4358 if (pProp != std::cend(*pGeometrySeq))
4360 css::awt::Rectangle aViewBox;
4361 if (pProp->Value >>= aViewBox)
4363 nViewBoxWidth = aViewBox.Width;
4364 nViewBoxHeight = aViewBox.Height;
4365 css::drawing::EnhancedCustomShapeParameter aECSP;
4366 aECSP.Type = css::drawing::EnhancedCustomShapeParameterType::NORMAL;
4367 aECSP.Value <<= nViewBoxWidth;
4369 aCustomShape2d.
GetParameter(fRetValue, aECSP,
true,
false);
4371 aECSP.Value <<= nViewBoxHeight;
4372 aCustomShape2d.
GetParameter(fRetValue, aECSP,
false,
true);
4379 if ((nViewBoxWidth == 0 && nViewBoxHeight == 0) || pProp == std::cend(*pGeometrySeq))
4383 aPairs[0].First.Value >>= nXMin;
4384 sal_Int32 nXMax = nXMin;
4386 aPairs[0].Second.Value >>= nYMin;
4387 sal_Int32 nYMax = nYMin;
4389 for (
const auto& rPair : std::as_const(aPairs))
4391 sal_Int32 nX = GetCustomGeometryPointValue(rPair.First, aCustomShape2d,
4392 bReplaceGeoWidth,
false);
4393 sal_Int32 nY = GetCustomGeometryPointValue(rPair.Second, aCustomShape2d,
false,
4404 nViewBoxWidth = std::max(nXMax, nXMax - nXMin);
4405 nViewBoxHeight = std::max(nYMax, nYMax - nYMin);
4412 sal_Int32 nPairIndex = 0;
4413 sal_Int32 nPathSizeIndex = 0;
4414 sal_Int32 nSubpathStartIndex(0);
4415 sal_Int32 nSubPathIndex(0);
4420 sal_Int32 nNextNcommandIndex = FindNextCommandEndSubpath(nSubpathStartIndex,
aSegments);
4424 std::optional<OString> sFill;
4425 if (HasCommandInSubPath(NOFILL, nSubpathStartIndex, nNextNcommandIndex - 1,
aSegments))
4427 else if (HasCommandInSubPath(DARKEN, nSubpathStartIndex, nNextNcommandIndex - 1,
aSegments))
4429 else if (HasCommandInSubPath(DARKENLESS, nSubpathStartIndex, nNextNcommandIndex - 1,
4431 sFill =
"darkenLess";
4432 else if (HasCommandInSubPath(LIGHTEN, nSubpathStartIndex, nNextNcommandIndex - 1,
4435 else if (HasCommandInSubPath(LIGHTENLESS, nSubpathStartIndex, nNextNcommandIndex - 1,
4437 sFill =
"lightenLess";
4442 if (nLuminanceChange <= -40)
4444 else if (nLuminanceChange <= -10)
4445 sFill =
"darkenLess";
4446 else if (nLuminanceChange >= 40)
4448 else if (nLuminanceChange >= 10)
4449 sFill =
"lightenLess";
4452 std::optional<OString> sStroke;
4453 if (HasCommandInSubPath(NOSTROKE, nSubpathStartIndex, nNextNcommandIndex - 1,
aSegments))
4457 mpFS->startElementNS(
4458 XML_a, XML_path, XML_fill, sFill, XML_stroke, sStroke, XML_w,
4459 OString::number(bUseGlobalViewBox ? nViewBoxWidth : aPathSize[nPathSizeIndex].
Width),
4461 OString::number(bUseGlobalViewBox ? nViewBoxHeight : aPathSize[nPathSizeIndex].
Height));
4466 double fCurrentX(0.0);
4467 double fCurrentY(0.0);
4468 bool bCurrentValid(
false);
4470 for (sal_Int32 nSegmentIndex = nSubpathStartIndex; nSegmentIndex < nNextNcommandIndex;
4473 const auto& rSegment(
aSegments[nSegmentIndex]);
4474 if (rSegment.Command == CLOSESUBPATH)
4476 mpFS->singleElementNS(XML_a, XML_close);
4480 for (sal_Int32 k = 0; k < rSegment.Count && bOK; ++k)
4483 fCurrentY, bCurrentValid, aCustomShape2d,
4484 bReplaceGeoWidth, bReplaceGeoHeight);
4488 mpFS->endElementNS(XML_a, XML_path);
4494 nSubpathStartIndex = nNextNcommandIndex + 1;
4497 }
while (nSubpathStartIndex <
aSegments.getLength());
4499 mpFS->endElementNS(XML_a, XML_pathLst);
4500 mpFS->endElementNS(XML_a, XML_custGeom);
4505 const sal_Int16 eCommand,
const sal_Int32
nCount,
4506 const uno::Sequence<css::drawing::EnhancedCustomShapeParameterPair>& rPairs,
4507 sal_Int32& rnPairIndex,
double& rfCurrentX,
double& rfCurrentY,
bool& rbCurrentValid,
4509 const bool bReplaceGeoHeight)
4515 if (rnPairIndex >= rPairs.getLength())
4518 mpFS->startElementNS(XML_a, XML_moveTo);
4521 mpFS->endElementNS(XML_a, XML_moveTo);
4522 rCustomShape2d.
GetParameter(rfCurrentX, rPairs[rnPairIndex].
First, bReplaceGeoWidth,
4524 rCustomShape2d.
GetParameter(rfCurrentY, rPairs[rnPairIndex].Second,
false,
4526 rbCurrentValid =
true;
4532 if (rnPairIndex >= rPairs.getLength())
4539 mpFS->startElementNS(XML_a, XML_lnTo);
4542 mpFS->endElementNS(XML_a, XML_lnTo);
4546 mpFS->startElementNS(XML_a, XML_moveTo);
4549 mpFS->endElementNS(XML_a, XML_moveTo);
4551 rCustomShape2d.
GetParameter(rfCurrentX, rPairs[rnPairIndex].
First, bReplaceGeoWidth,
4553 rCustomShape2d.
GetParameter(rfCurrentY, rPairs[rnPairIndex].Second,
false,
4555 rbCurrentValid =
true;
4561 if (rnPairIndex + 2 >= rPairs.getLength())
4564 mpFS->startElementNS(XML_a, XML_cubicBezTo);
4570 mpFS->endElementNS(XML_a, XML_cubicBezTo);
4571 rCustomShape2d.
GetParameter(rfCurrentX, rPairs[rnPairIndex + 2].
First, bReplaceGeoWidth,
4573 rCustomShape2d.
GetParameter(rfCurrentY, rPairs[rnPairIndex + 2].Second,
false,
4575 rbCurrentValid =
true;
4579 case ANGLEELLIPSETO:
4582 if (rnPairIndex + 2 >= rPairs.getLength())
4587 rCustomShape2d.
GetParameter(fCx, rPairs[rnPairIndex].
First, bReplaceGeoWidth,
false);
4589 rCustomShape2d.
GetParameter(fCy, rPairs[rnPairIndex].Second,
false, bReplaceGeoHeight);
4593 rCustomShape2d.
GetParameter(fHR, rPairs[rnPairIndex + 1].Second,
false,
false);
4594 double fStartAngle = 0.0;
4595 rCustomShape2d.
GetParameter(fStartAngle, rPairs[rnPairIndex + 2].
First,
false,
false);
4596 double fEndAngle = 0.0;
4597 rCustomShape2d.
GetParameter(fEndAngle, rPairs[rnPairIndex + 2].Second,
false,
false);
4600 sal_Int32 nStartAng(std::lround(fStartAngle * 60000));
4601 sal_Int32 nSwingAng = 0;
4604 nSwingAng = 360 * 60000;
4607 nSwingAng = std::lround((fEndAngle - fStartAngle) * 60000);
4609 nSwingAng += 360 * 60000;
4615 getEllipsePointFromViewAngle(fSx, fSy, fWR, fHR, fCx, fCy, fStartAngle);
4619 if (eCommand == ANGLEELLIPSETO && rbCurrentValid)
4621 mpFS->startElementNS(XML_a, XML_lnTo);
4622 mpFS->singleElementNS(XML_a, XML_pt, XML_x, OString::number(std::lround(fSx)),
4623 XML_y, OString::number(std::lround(fSy)));
4624 mpFS->endElementNS(XML_a, XML_lnTo);
4628 mpFS->startElementNS(XML_a, XML_moveTo);
4629 mpFS->singleElementNS(XML_a, XML_pt, XML_x, OString::number(std::lround(fSx)),
4630 XML_y, OString::number(std::lround(fSy)));
4631 mpFS->endElementNS(XML_a, XML_moveTo);
4635 mpFS->singleElement(
4636 FSNS(XML_a, XML_arcTo), XML_wR, OString::number(std::lround(fWR)), XML_hR,
4637 OString::number(std::lround(fHR)), XML_stAng, OString::number(nStartAng),
4638 XML_swAng, OString::number(nSwingAng));
4640 getEllipsePointFromViewAngle(rfCurrentX, rfCurrentY, fWR, fHR, fCx, fCy, fEndAngle);
4641 rbCurrentValid =
true;
4647 case CLOCKWISEARCTO:
4650 if (rnPairIndex + 3 >= rPairs.getLength())
4655 rCustomShape2d.
GetParameter(fX1, rPairs[rnPairIndex].
First, bReplaceGeoWidth,
false);
4657 rCustomShape2d.
GetParameter(fY1, rPairs[rnPairIndex].Second,
false, bReplaceGeoHeight);
4659 rCustomShape2d.
GetParameter(fX2, rPairs[rnPairIndex + 1].
First, bReplaceGeoWidth,
4662 rCustomShape2d.
GetParameter(fY2, rPairs[rnPairIndex + 1].Second,
false,
4665 rCustomShape2d.
GetParameter(fX3, rPairs[rnPairIndex + 2].
First, bReplaceGeoWidth,
4668 rCustomShape2d.
GetParameter(fY3, rPairs[rnPairIndex + 2].Second,
false,
4671 rCustomShape2d.
GetParameter(fX4, rPairs[rnPairIndex + 3].
First, bReplaceGeoWidth,
4674 rCustomShape2d.
GetParameter(fY4, rPairs[rnPairIndex + 3].Second,
false,
4677 const double fWR = (fX2 - fX1) / 2.0;
4678 const double fHR = (fY2 - fY1) / 2.0;
4679 const double fCx = (fX1 + fX2) / 2.0;
4680 const double fCy = (fY1 + fY2) / 2.0;
4682 double fStartAngle = 0.0;
4685 getEllipsePointAndAngleFromRayPoint(fStartAngle, fPx, fPy, fWR, fHR, fCx, fCy, fX3,
4689 if ((eCommand == ARCTO || eCommand == CLOCKWISEARCTO) && rbCurrentValid)
4691 mpFS->startElementNS(XML_a, XML_lnTo);
4692 mpFS->singleElementNS(XML_a, XML_pt, XML_x, OString::number(std::lround(fPx)),
4693 XML_y, OString::number(std::lround(fPy)));
4694 mpFS->endElementNS(XML_a, XML_lnTo);
4698 mpFS->startElementNS(XML_a, XML_moveTo);
4699 mpFS->singleElementNS(XML_a, XML_pt, XML_x, OString::number(std::lround(fPx)),
4700 XML_y, OString::number(std::lround(fPy)));
4701 mpFS->endElementNS(XML_a, XML_moveTo);
4704 double fEndAngle = 0.0;
4705 getEllipsePointAndAngleFromRayPoint(fEndAngle, fPx, fPy, fWR, fHR, fCx, fCy, fX4, fY4);
4706 double fSwingAngle(fEndAngle - fStartAngle);
4707 const bool bIsClockwise(eCommand == CLOCKWISEARCTO || eCommand == CLOCKWISEARC);
4708 if (bIsClockwise && fSwingAngle < 0)
4709 fSwingAngle += 360.0;
4710 else if (!bIsClockwise && fSwingAngle > 0)
4711 fSwingAngle -= 360.0;
4714 const sal_Int32 nStartAng(std::lround(fStartAngle * 60000));
4715 const sal_Int32 nSwingAng(std::lround(fSwingAngle * 60000));
4716 mpFS->singleElement(
FSNS(XML_a, XML_arcTo), XML_wR, OString::number(std::lround(fWR)),
4717 XML_hR, OString::number(std::lround(fHR)), XML_stAng,
4718 OString::number(nStartAng), XML_swAng, OString::number(nSwingAng));
4721 rbCurrentValid =
true;
4725 case ELLIPTICALQUADRANTX:
4726 case ELLIPTICALQUADRANTY:
4728 if (rnPairIndex >= rPairs.getLength())
4733 rCustomShape2d.
GetParameter(fX, rPairs[rnPairIndex].
First, bReplaceGeoWidth,
false);
4735 rCustomShape2d.
GetParameter(fY, rPairs[rnPairIndex].Second,
false, bReplaceGeoHeight);
4740 double fWR = std::abs(rfCurrentX - fX);
4741 double fHR = std::abs(rfCurrentY - fY);
4742 double fStartAngle(0.0);
4743 double fSwingAngle(0.0);
4745 if ((eCommand == ELLIPTICALQUADRANTX && !(
nCount % 2))
4746 || (eCommand == ELLIPTICALQUADRANTY && (
nCount % 2)))
4749 fStartAngle = fY < rfCurrentY ? 90.0 : 270.0;
4750 const bool bClockwise = (fX < rfCurrentX && fY < rfCurrentY)
4751 || (fX > rfCurrentX && fY > rfCurrentY);
4752 fSwingAngle = bClockwise ? 90.0 : -90.0;
4757 fStartAngle = fX < rfCurrentX ? 0.0 : 180.0;
4758 const bool bClockwise = (fX < rfCurrentX && fY > rfCurrentY)
4759 || (fX > rfCurrentX && fY < rfCurrentY);
4760 fSwingAngle = bClockwise ? 90.0 : -90.0;
4762 sal_Int32 nStartAng(std::lround(fStartAngle * 60000));
4763 sal_Int32 nSwingAng(std::lround(fSwingAngle * 60000));
4764 mpFS->singleElement(
4765 FSNS(XML_a, XML_arcTo), XML_wR, OString::number(std::lround(fWR)), XML_hR,
4766 OString::number(std::lround(fHR)), XML_stAng, OString::number(nStartAng),
4767 XML_swAng, OString::number(nSwingAng));
4772 mpFS->startElementNS(XML_a, XML_moveTo);
4775 mpFS->endElementNS(XML_a, XML_moveTo);
4779 rbCurrentValid =
true;
4783 case QUADRATICCURVETO:
4785 if (rnPairIndex + 1 >= rPairs.getLength())
4788 mpFS->startElementNS(XML_a, XML_quadBezTo);
4794 mpFS->endElementNS(XML_a, XML_quadBezTo);
4795 rCustomShape2d.
GetParameter(rfCurrentX, rPairs[rnPairIndex + 1].
First, bReplaceGeoWidth,
4797 rCustomShape2d.
GetParameter(rfCurrentY, rPairs[rnPairIndex + 1].Second,
false,
4799 rbCurrentValid =
true;
4805 if (rnPairIndex + 1 >= rPairs.getLength())
4811 rCustomShape2d.
GetParameter(fHR, rPairs[rnPairIndex].Second,
false,
false);
4812 double fStartAngle = 0.0;
4813 rCustomShape2d.
GetParameter(fStartAngle, rPairs[rnPairIndex + 1].
First,
false,
false);
4814 sal_Int32 nStartAng(std::lround(fStartAngle * 60000));
4815 double fSwingAng = 0.0;
4816 rCustomShape2d.
GetParameter(fSwingAng, rPairs[rnPairIndex + 1].Second,
false,
false);
4817 sal_Int32 nSwingAng(std::lround(fSwingAng * 60000));
4818 mpFS->singleElement(
FSNS(XML_a, XML_arcTo), XML_wR, OString::number(fWR), XML_hR,
4819 OString::number(fHR), XML_stAng, OString::number(nStartAng),
4820 XML_swAng, OString::number(nSwingAng));
4823 getEllipsePointFromViewAngle(fPx, fPy, fWR, fHR, 0.0, 0.0, fStartAngle);
4824 double fCx = rfCurrentX - fPx;
4825 double fCy = rfCurrentY - fPy;
4826 getEllipsePointFromViewAngle(rfCurrentX, rfCurrentY, fWR, fHR, fCx, fCy,
4827 fStartAngle + fSwingAng);
4828 rbCurrentValid =
true;
4840 const drawing::EnhancedCustomShapeParameterPair& rParamPair,
4842 const bool bReplaceGeoHeight)
4845 = GetCustomGeometryPointValue(rParamPair.First, rCustomShape2d, bReplaceGeoWidth,
false);
4847 = GetCustomGeometryPointValue(rParamPair.Second, rCustomShape2d,
false, bReplaceGeoHeight);
4849 mpFS->singleElementNS(XML_a, XML_pt, XML_x, OString::number(nX), XML_y, OString::number(nY));
4855 mpFS->startElementNS(XML_a, XML_custGeom);
4856 mpFS->singleElementNS(XML_a, XML_avLst);
4857 mpFS->singleElementNS(XML_a, XML_gdLst);
4858 mpFS->singleElementNS(XML_a, XML_ahLst);
4859 mpFS->singleElementNS(XML_a, XML_rect, XML_l,
"0", XML_t,
"0", XML_r,
"r", XML_b,
"b");
4860 mpFS->singleElementNS(XML_a, XML_pathLst);
4861 mpFS->endElementNS(XML_a, XML_custGeom);
4874 mpFS->startElementNS(XML_a, XML_custGeom);
4875 mpFS->singleElementNS(XML_a, XML_avLst);
4876 mpFS->singleElementNS(XML_a, XML_gdLst);
4877 mpFS->singleElementNS(XML_a, XML_ahLst);
4878 mpFS->singleElementNS(XML_a, XML_rect, XML_l,
"0", XML_t,
"0", XML_r,
"r", XML_b,
"b");
4880 mpFS->startElementNS(XML_a, XML_pathLst);
4882 awt::Size aSize = rXShape->getSize();
4883 awt::Point aPos = rXShape->getPosition();
4885 uno::Reference<XPropertySetInfo> xPropertySetInfo = xPropertySet->getPropertySetInfo();
4886 if (xPropertySetInfo->hasPropertyByName(
"AnchorPosition"))
4888 awt::Point aAnchorPosition;
4889 xPropertySet->getPropertyValue(
"AnchorPosition") >>= aAnchorPosition;
4890 aPos.X += aAnchorPosition.X;
4891 aPos.Y += aAnchorPosition.Y;
4895 std::optional<OString> sFill;
4901 mpFS->startElementNS(XML_a, XML_path, XML_fill, sFill, XML_w, OString::number(aSize.Width),
4902 XML_h, OString::number(aSize.Height));
4904 for (sal_uInt16
i = 0;
i < aPolyPolygon.
Count();
i++)
4910 mpFS->startElementNS(XML_a, XML_moveTo);
4912 mpFS->singleElementNS(XML_a, XML_pt, XML_x, OString::number(aPoly[0].
X() - aPos.X),
4913 XML_y, OString::number(aPoly[0].Y() - aPos.Y));
4915 mpFS->endElementNS(XML_a, XML_moveTo);
4918 for (sal_uInt16 j = 1; j < aPoly.
GetSize(); j++)
4921 if (flags == PolyFlags::Control)
4924 if (j + 2 < aPoly.
GetSize() && aPoly.
GetFlags(j + 1) == PolyFlags::Control
4925 && aPoly.
GetFlags(j + 2) != PolyFlags::Control)
4927 mpFS->startElementNS(XML_a, XML_cubicBezTo);
4930 mpFS->singleElementNS(XML_a, XML_pt, XML_x,
4931 OString::number(aPoly[j + k].
X() - aPos.X), XML_y,
4932 OString::number(aPoly[j + k].Y() - aPos.Y));
4934 mpFS->endElementNS(XML_a, XML_cubicBezTo);
4938 else if (flags == PolyFlags::Normal)
4940 mpFS->startElementNS(XML_a, XML_lnTo);
4941 mpFS->singleElementNS(XML_a, XML_pt, XML_x, OString::number(aPoly[j].
X() - aPos.X),
4942 XML_y, OString::number(aPoly[j].Y() - aPos.Y));
4943 mpFS->endElementNS(XML_a, XML_lnTo);
4948 mpFS->singleElementNS(XML_a, XML_close);
4949 mpFS->endElementNS(XML_a, XML_path);
4951 mpFS->endElementNS(XML_a, XML_pathLst);
4953 mpFS->endElementNS(XML_a, XML_custGeom);
4958 if( nStartID != -1 )
4960 mpFS->singleElementNS( XML_a, XML_stCxn,
4961 XML_id, OString::number(nStartID),
4962 XML_idx, OString::number(nStartGlueId) );
4966 mpFS->singleElementNS( XML_a, XML_endCxn,
4967 XML_id, OString::number(nEndID),
4968 XML_idx, OString::number(nEndGlueId) );
4976 rtl_TextEncoding eCharSet = rFontDesc.CharSet;
4978 rFontDesc.CharSet = eCharSet;
4985 const OUString& sFullStream,
4986 std::u16string_view sRelativeStream,
4988 const char* sContentType,
4989 const char* sRelationshipType,
4990 OUString* pRelationshipId )
4992 OUString sRelationshipId;
4993 if (xParentRelation.is())
4994 sRelationshipId =
GetFB()->
addRelation( xParentRelation, OUString::createFromAscii( sRelationshipType), sRelativeStream );
4996 sRelationshipId =
GetFB()->
addRelation( OUString::createFromAscii( sRelationshipType ), sRelativeStream );
4998 if( pRelationshipId )
4999 *pRelationshipId = sRelationshipId;
5011 xPropSet->getPropertyValue(
"FillStyle" ) >>= aFillStyle;
5014 if ( aFillStyle == FillStyle_SOLID &&
GetProperty( xPropSet,
"FillTransparence" ) )
5017 xPropSet->getPropertyValue(
"FillTransparence" ) >>= nVal;
5019 aFillStyle = FillStyle_NONE;
5021 if (aFillStyle == FillStyle_SOLID &&
GetProperty( xPropSet,
"FillTransparenceGradient"))
5023 awt::Gradient aTransparenceGradient;
5024 mAny >>= aTransparenceGradient;
5025 if (aTransparenceGradient.StartColor == 0xffffff && aTransparenceGradient.EndColor == 0xffffff)
5026 aFillStyle = FillStyle_NONE;
5029 bool bUseBackground(
false);
5030 if (
GetProperty(xPropSet,
"FillUseSlideBackground"))
5031 xPropSet->getPropertyValue(
"FillUseSlideBackground") >>= bUseBackground;
5033 switch( aFillStyle )
5035 case FillStyle_SOLID :
5038 case FillStyle_GRADIENT :
5041 case FillStyle_BITMAP :
5044 case FillStyle_HATCH :
5047 case FillStyle_NONE:
5048 if (!bUseBackground)
5049 mpFS->singleElementNS(XML_a, XML_noFill);
5060 OUString sSchemeClr;
5061 sal_uInt32 nIdx = 0;
5065 if( rProp.Name ==
"SchemeClr" )
5066 rProp.Value >>= sSchemeClr;
5067 else if( rProp.Name ==
"Idx" )
5068 rProp.Value >>= nIdx;
5069 else if( rProp.Name ==
"Transformations" )
5070 rProp.Value >>= aTransformations;
5072 mpFS->startElementNS(XML_a, nTokenId, XML_idx, OString::number(nIdx));
5074 mpFS->endElementNS( XML_a, nTokenId );
5079 mpFS->singleElementNS(XML_a, nTokenId, XML_idx, OString::number(0));
5093 for(
const auto& rProp : std::as_const(aGrabBag))
5095 if( rProp.Name ==
"StyleFillRef" )
5096 rProp.Value >>= aFillRefProperties;
5097 else if( rProp.Name ==
"StyleLnRef" )
5098 rProp.Value >>= aLnRefProperties;
5099 else if( rProp.Name ==
"StyleEffectRef" )
5100 rProp.Value >>= aEffectRefProperties;
5108 mpFS->singleElementNS(XML_a, XML_fontRef, XML_idx,
"minor");
5113 if( !aEffectProps.hasElements() )
5117 sal_Int32 nEffectToken = 0;
5118 bool bContainsColor =
false;
5119 if(
sName ==
u"outerShdw" )
5121 nEffectToken =
FSNS( XML_a, XML_outerShdw );
5122 bContainsColor =
true;
5124 else if(
sName ==
u"innerShdw" )
5126 nEffectToken =
FSNS( XML_a, XML_innerShdw );
5127 bContainsColor =
true;
5129 else if(
sName ==
u"glow" )
5131 nEffectToken =
FSNS( XML_a, XML_glow );
5132 bContainsColor =
true;
5134 else if(
sName ==
u"softEdge" )
5135 nEffectToken =
FSNS( XML_a, XML_softEdge );
5136 else if(
sName ==
u"reflection" )
5137 nEffectToken =
FSNS( XML_a, XML_reflection );
5138 else if(
sName ==
u"blur" )
5139 nEffectToken =
FSNS( XML_a, XML_blur );
5141 OUString sSchemeClr;
5146 for(
const auto& rEffectProp : aEffectProps )
5148 if( rEffectProp.Name ==
"Attribs" )
5151 uno::Sequence< beans::PropertyValue > aOuterShdwProps;
5152 rEffectProp.Value >>= aOuterShdwProps;
5153 for(
const auto& rOuterShdwProp : std::as_const(aOuterShdwProps) )
5155 if( rOuterShdwProp.Name ==
"algn" )
5158 rOuterShdwProp.Value >>= sVal;
5159 aOuterShdwAttrList->add( XML_algn, sVal );
5161 else if( rOuterShdwProp.Name ==
"blurRad" )
5164 rOuterShdwProp.Value >>= nVal;
5165 aOuterShdwAttrList->add( XML_blurRad, OString::number( nVal ).getStr() );
5167 else if( rOuterShdwProp.Name ==
"dir" )
5170 rOuterShdwProp.Value >>= nVal;
5171 aOuterShdwAttrList->add( XML_dir, OString::number( nVal ).getStr() );
5173 else if( rOuterShdwProp.Name ==
"dist" )
5176 rOuterShdwProp.Value >>= nVal;
5177 aOuterShdwAttrList->add( XML_dist, OString::number( nVal ).getStr() );
5179 else if( rOuterShdwProp.Name ==
"kx" )
5182 rOuterShdwProp.Value >>= nVal;
5183 aOuterShdwAttrList->add( XML_kx, OString::number( nVal ).getStr() );
5185 else if( rOuterShdwProp.Name ==
"ky" )
5188 rOuterShdwProp.Value >>= nVal;
5189 aOuterShdwAttrList->add( XML_ky, OString::number( nVal ).getStr() );
5191 else if( rOuterShdwProp.Name ==
"rotWithShape" )
5194 rOuterShdwProp.Value >>= nVal;
5195 aOuterShdwAttrList->add( XML_rotWithShape, OString::number( nVal ).getStr() );
5197 else if( rOuterShdwProp.Name ==
"sx" )
5200 rOuterShdwProp.Value >>= nVal;
5201 aOuterShdwAttrList->add( XML_sx, OString::number( nVal ).getStr() );
5203 else if( rOuterShdwProp.Name ==
"sy" )
5206 rOuterShdwProp.Value >>= nVal;
5207 aOuterShdwAttrList->add( XML_sy, OString::number( nVal ).getStr() );
5209 else if( rOuterShdwProp.Name ==
"rad" )
5212 rOuterShdwProp.Value >>= nVal;
5213 aOuterShdwAttrList->add( XML_rad, OString::number( nVal ).getStr() );
5215 else if( rOuterShdwProp.Name ==
"endA" )
5218 rOuterShdwProp.Value >>= nVal;
5219 aOuterShdwAttrList->add( XML_endA, OString::number( nVal ).getStr() );
5221 else if( rOuterShdwProp.Name ==
"endPos" )
5224 rOuterShdwProp.Value >>= nVal;
5225 aOuterShdwAttrList->add( XML_endPos, OString::number( nVal ).getStr() );
5227 else if( rOuterShdwProp.Name ==
"fadeDir" )
5230 rOuterShdwProp.Value >>= nVal;
5231 aOuterShdwAttrList->add( XML_fadeDir, OString::number( nVal ).getStr() );
5233 else if( rOuterShdwProp.Name ==
"stA" )
5236 rOuterShdwProp.Value >>= nVal;
5237 aOuterShdwAttrList->add( XML_stA, OString::number( nVal ).getStr() );
5239 else if( rOuterShdwProp.Name ==
"stPos" )
5242 rOuterShdwProp.Value >>= nVal;
5243 aOuterShdwAttrList->add( XML_stPos, OString::number( nVal ).getStr() );
5245 else if( rOuterShdwProp.Name ==
"grow" )
5248 rOuterShdwProp.Value >>= nVal;
5249 aOuterShdwAttrList->add( XML_grow, OString::number( nVal ).getStr() );
5253 else if(rEffectProp.Name ==
"RgbClr")
5255 rEffectProp.Value >>= nRgbClr;
5257 else if(rEffectProp.Name ==
"RgbClrTransparency")
5259 sal_Int32 nTransparency;
5260 if (rEffectProp.Value >>= nTransparency)
5264 else if(rEffectProp.Name ==
"SchemeClr")
5266 rEffectProp.Value >>= sSchemeClr;
5268 else if(rEffectProp.Name ==
"SchemeClrTransformations")
5270 rEffectProp.Value >>= aTransformations;
5274 if( nEffectToken <= 0 )
5277 mpFS->startElement( nEffectToken, aOuterShdwAttrList );
5279 if( bContainsColor )
5281 if( sSchemeClr.isEmpty() )
5287 mpFS->endElement( nEffectToken );
5292 return static_cast< sal_Int32
>(std::hypot(dX, dY) * 360);
5297 return (
static_cast< sal_Int32
>(basegfx::rad2deg<60000>(atan2(dY,dX))) + 21600000) % 21600000;
5303 bool bHasInteropGrabBag = rXPropSet->getPropertySetInfo()->hasPropertyByName(
"InteropGrabBag");
5304 if (bHasInteropGrabBag &&
GetProperty(rXPropSet,
"InteropGrabBag"))
5307 auto pProp = std::find_if(std::cbegin(aGrabBag), std::cend(aGrabBag),
5308 [](
const PropertyValue& rProp) {
return rProp.Name ==
"EffectProperties"; });
5309 if (pProp != std::cend(aGrabBag))
5311 pProp->Value >>= aEffects;
5312 auto pEffect = std::find_if(std::cbegin(aEffects), std::cend(aEffects),
5313 [](
const PropertyValue& rEffect) {
return rEffect.Name ==
"outerShdw"; });
5314 if (pEffect != std::cend(aEffects))
5315 pEffect->Value >>= aOuterShdwProps;
5322 if( !aEffects.hasElements() )
5328 if (!bHasEffects &&
GetProperty(rXPropSet,
"GlowEffectRadius"))
5332 bHasEffects = rad > 0;
5334 if (!bHasEffects &&
GetProperty(rXPropSet,
"SoftEdgeRadius"))
5338 bHasEffects = rad > 0;
5343 mpFS->startElementNS(XML_a, XML_effectLst);
5347 double dX = +0.0, dY = +0.0;
5349 rXPropSet->getPropertyValue(
"ShadowXDistance" ) >>= dX;
5350 rXPropSet->getPropertyValue(
"ShadowYDistance" ) >>= dY;
5351 rXPropSet->getPropertyValue(
"ShadowBlur" ) >>= nBlur;
5369 mpFS->endElementNS(XML_a, XML_effectLst);
5374 for(
auto& rOuterShdwProp : asNonConstRange(aOuterShdwProps) )
5376 if( rOuterShdwProp.Name ==
"Attribs" )
5379 rOuterShdwProp.Value >>= aAttribsProps;
5381 double dX = +0.0, dY = +0.0;
5383 rXPropSet->getPropertyValue(
"ShadowXDistance" ) >>= dX;
5384 rXPropSet->getPropertyValue(
"ShadowYDistance" ) >>= dY;
5385 rXPropSet->getPropertyValue(
"ShadowBlur" ) >>= nBlur;
5388 for(
auto& rAttribsProp : asNonConstRange(aAttribsProps) )
5390 if( rAttribsProp.Name ==
"dist" )
5394 else if( rAttribsProp.Name ==
"dir" )
5398 else if( rAttribsProp.Name ==
"blurRad" )
5404 rOuterShdwProp.Value <<= aAttribsProps;
5406 else if( rOuterShdwProp.Name ==
"RgbClr" )
5408 rOuterShdwProp.Value = rXPropSet->getPropertyValue(
"ShadowColor" );
5410 else if( rOuterShdwProp.Name ==
"RgbClrTransparency" )
5412 rOuterShdwProp.Value = rXPropSet->getPropertyValue(
"ShadowTransparence" );
5416 mpFS->startElementNS(XML_a, XML_effectLst);
5417 bool bGlowWritten =
false;
5418 for(
const auto& rEffect : std::as_const(aEffects) )
5421 && (rEffect.Name ==
"innerShdw" || rEffect.Name ==
"outerShdw"
5422 || rEffect.Name ==
"prstShdw" || rEffect.Name ==
"reflection"
5423 || rEffect.Name ==
"softEdge"))
5426 bGlowWritten =
true;
5429 if( rEffect.Name ==
"outerShdw" )
5436 rEffect.Value >>= aEffectProps;
5444 mpFS->endElementNS(XML_a, XML_effectLst);
5450 if (!rXPropSet->getPropertySetInfo()->hasPropertyByName(
"GlowEffectRadius"))
5456 rXPropSet->getPropertyValue(
"GlowEffectRadius") >>= nRad;
5474 if (!rXPropSet->getPropertySetInfo()->hasPropertyByName(
"SoftEdgeRadius"))
5480 rXPropSet->getPropertyValue(
"SoftEdgeRadius") >>= nRad;
5502 auto pShapeProp = std::find_if( std::cbegin(aGrabBag), std::cend(aGrabBag),
5503 [bIsText](
const PropertyValue& rProp)
5504 {
return rProp.Name == (bIsText ?
u"Text3DEffectProperties" :
u"3DEffectProperties"); });
5505 if (pShapeProp != std::cend(aGrabBag))
5508 pShapeProp->Value >>= a3DEffectProps;