1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include <drawingml/misccontexts.hxx>
21 #include <oox/helper/attributelist.hxx>
22 #include <oox/helper/graphichelper.hxx>
23 #include <oox/core/xmlfilterbase.hxx>
24 #include <oox/drawingml/drawingmltypes.hxx>
25 #include <drawingml/fillproperties.hxx>
26 #include <oox/token/namespaces.hxx>
27 #include <oox/token/tokens.hxx>
28 #include <vcl/GraphicExternalLink.hxx>
29 #include <vcl/graph.hxx>
30 #include <unordered_map>
31 #include <frozen/bits/defines.h>
32 #include <frozen/bits/elsa_std.h>
33 #include <frozen/unordered_map.h>
35 using namespace ::com::sun::star
;
36 using namespace ::com::sun::star::uno
;
37 using ::oox::core::ContextHandler2
;
38 using ::oox::core::ContextHandlerRef
;
40 namespace oox::drawingml
{
42 SolidFillContext::SolidFillContext(ContextHandler2Helper
const & rParent
, FillProperties
& rFillProps
, model::SolidFill
* pSolidFill
)
43 : ColorContext(rParent
, rFillProps
.maFillColor
, pSolidFill
? &pSolidFill
->maColor
: nullptr)
47 SolidFillContext::~SolidFillContext()
50 GradientFillContext::GradientFillContext(ContextHandler2Helper
const & rParent
,
51 const AttributeList
& rAttribs
, GradientFillProperties
& rGradientProps
, model::GradientFill
* pGradientFill
)
52 : ContextHandler2(rParent
)
53 , mpGradientFill(pGradientFill
)
54 , mrGradientProps(rGradientProps
)
56 auto oRotateWithShape
= rAttribs
.getBool(XML_rotWithShape
);
57 mrGradientProps
.moShadeFlip
= rAttribs
.getToken( XML_flip
);
58 mrGradientProps
.moRotateWithShape
= oRotateWithShape
;
59 if (mpGradientFill
&& oRotateWithShape
.has_value())
60 mpGradientFill
->mbRotateWithShape
= *oRotateWithShape
;
63 ContextHandlerRef
GradientFillContext::onCreateContext(
64 sal_Int32 nElement
, const AttributeList
& rAttribs
)
68 case A_TOKEN( gsLst
):
69 return this; // for gs elements
72 if (rAttribs
.hasAttribute(XML_pos
))
74 double fPosition
= getLimitedValue
<double>(rAttribs
.getDouble(XML_pos
, 0.0) / 100000.0, 0.0, 1.0);
75 auto aElement
= mrGradientProps
.maGradientStops
.emplace(fPosition
, Color());
77 model::ComplexColor
* pComplexColor
= nullptr;
80 model::GradientStop
& rStop
= mpGradientFill
->maGradientStops
.emplace_back();
81 rStop
.mfPosition
= fPosition
;
82 pComplexColor
= &rStop
.maColor
;
85 return new ColorContext(*this, aElement
->second
, pComplexColor
);
91 mrGradientProps
.moShadeAngle
= rAttribs
.getInteger(XML_ang
);
92 mrGradientProps
.moShadeScaled
= rAttribs
.getBool(XML_scaled
);
96 mpGradientFill
->meGradientType
= model::GradientType::Linear
;
97 mpGradientFill
->maLinearGradient
.mnAngle
= rAttribs
.getInteger(XML_ang
, 0);
98 mpGradientFill
->maLinearGradient
.mbScaled
= rAttribs
.getBool(XML_scaled
, false);
103 case A_TOKEN( path
):
105 // always set a path type, this disables linear gradient in conversion
106 sal_Int32 nToken
= rAttribs
.getToken(XML_path
, XML_rect
);
107 mrGradientProps
.moGradientPath
= nToken
;
113 mpGradientFill
->meGradientType
= model::GradientType::Rectangle
;
116 mpGradientFill
->meGradientType
= model::GradientType::Circle
;
119 mpGradientFill
->meGradientType
= model::GradientType::Shape
;
125 return this; // for fillToRect element
127 case A_TOKEN( fillToRect
):
129 mrGradientProps
.moFillToRect
= GetRelativeRect( rAttribs
.getFastAttributeList() );
131 fillRelativeRectangle(mpGradientFill
->maFillToRectangle
, rAttribs
.getFastAttributeList());
135 case A_TOKEN( tileRect
):
136 mrGradientProps
.moTileRect
= GetRelativeRect(rAttribs
.getFastAttributeList());
138 fillRelativeRectangle(mpGradientFill
->maTileRectangle
, rAttribs
.getFastAttributeList());
148 constexpr frozen::unordered_map
<sal_Int32
, model::PatternPreset
, 54> constPatternPresetMap
150 { XML_pct5
, model::PatternPreset::Percent_5
},
151 { XML_pct10
, model::PatternPreset::Percent_10
},
152 { XML_pct20
, model::PatternPreset::Percent_20
},
153 { XML_pct25
, model::PatternPreset::Percent_25
},
154 { XML_pct30
, model::PatternPreset::Percent_30
},
155 { XML_pct40
, model::PatternPreset::Percent_40
},
156 { XML_pct50
, model::PatternPreset::Percent_50
},
157 { XML_pct60
, model::PatternPreset::Percent_60
},
158 { XML_pct70
, model::PatternPreset::Percent_70
},
159 { XML_pct75
, model::PatternPreset::Percent_75
},
160 { XML_pct80
, model::PatternPreset::Percent_80
},
161 { XML_pct90
, model::PatternPreset::Percent_90
},
162 { XML_horz
, model::PatternPreset::Horizontal
},
163 { XML_vert
, model::PatternPreset::Vertical
},
164 { XML_ltHorz
, model::PatternPreset::LightHorizontal
},
165 { XML_ltVert
, model::PatternPreset::LightVertical
},
166 { XML_dkHorz
, model::PatternPreset::DarkHorizontal
},
167 { XML_dkVert
, model::PatternPreset::DarkVertical
},
168 { XML_narHorz
, model::PatternPreset::NarrowHorizontal
},
169 { XML_narVert
, model::PatternPreset::NarrowVertical
},
170 { XML_dashHorz
, model::PatternPreset::DashedHorizontal
},
171 { XML_dashVert
, model::PatternPreset::DashedVertical
},
172 { XML_cross
, model::PatternPreset::Cross
},
173 { XML_dnDiag
, model::PatternPreset::DownwardDiagonal
},
174 { XML_upDiag
, model::PatternPreset::UpwardDiagonal
},
175 { XML_ltDnDiag
, model::PatternPreset::LightDownwardDiagonal
},
176 { XML_ltUpDiag
, model::PatternPreset::LightUpwardDiagonal
},
177 { XML_dkDnDiag
, model::PatternPreset::DarkDownwardDiagonal
},
178 { XML_dkUpDiag
, model::PatternPreset::DarkUpwardDiagonal
},
179 { XML_wdDnDiag
, model::PatternPreset::WideDownwardDiagonal
},
180 { XML_wdUpDiag
, model::PatternPreset::WideUpwardDiagonal
},
181 { XML_dashDnDiag
, model::PatternPreset::DashedDownwardDiagonal
},
182 { XML_dashUpDiag
, model::PatternPreset::DashedUpwardDiagonal
},
183 { XML_diagCross
, model::PatternPreset::DiagonalCross
},
184 { XML_smCheck
, model::PatternPreset::SmallCheckerBoard
},
185 { XML_lgCheck
, model::PatternPreset::LargeCheckerBoard
},
186 { XML_smGrid
, model::PatternPreset::SmallGrid
},
187 { XML_lgGrid
, model::PatternPreset::LargeGrid
},
188 { XML_dotGrid
, model::PatternPreset::DottedGrid
},
189 { XML_smConfetti
, model::PatternPreset::SmallConfetti
},
190 { XML_lgConfetti
, model::PatternPreset::LargeConfetti
},
191 { XML_horzBrick
, model::PatternPreset::HorizontalBrick
},
192 { XML_diagBrick
, model::PatternPreset::DiagonalBrick
},
193 { XML_solidDmnd
, model::PatternPreset::SolidDiamond
},
194 { XML_openDmnd
, model::PatternPreset::OpenDiamond
},
195 { XML_dotDmnd
, model::PatternPreset::DottedDiamond
},
196 { XML_plaid
, model::PatternPreset::Plaid
},
197 { XML_sphere
, model::PatternPreset::Sphere
},
198 { XML_weave
, model::PatternPreset::Weave
},
199 { XML_divot
, model::PatternPreset::Divot
},
200 { XML_shingle
, model::PatternPreset::Shingle
},
201 { XML_wave
, model::PatternPreset::Wave
},
202 { XML_trellis
, model::PatternPreset::Trellis
},
203 { XML_zigZag
, model::PatternPreset::ZigZag
}
206 } // end anonymous namespace
207 PatternFillContext::PatternFillContext(ContextHandler2Helper
const & rParent
,
208 const AttributeList
& rAttribs
, PatternFillProperties
& rPatternProps
, model::PatternFill
* pPatternFill
)
209 : ContextHandler2(rParent
)
210 , mpPatternFill(pPatternFill
)
211 , mrPatternProps(rPatternProps
)
213 mrPatternProps
.moPattPreset
= rAttribs
.getToken(XML_prst
);
217 sal_Int32 nToken
= rAttribs
.getToken(XML_prst
, XML_TOKEN_INVALID
);
219 auto aIterator
= constPatternPresetMap
.find(nToken
);
220 if (aIterator
!= constPatternPresetMap
.end())
222 auto const& aPair
= *aIterator
;
223 model::PatternPreset ePatternPreset
= aPair
.second
;
224 mpPatternFill
->mePatternPreset
= ePatternPreset
;
229 ContextHandlerRef
PatternFillContext::onCreateContext(
230 sal_Int32 nElement
, const AttributeList
& )
232 model::ComplexColor
* pComplexColor
= nullptr;
235 case A_TOKEN( bgClr
):
237 pComplexColor
= &mpPatternFill
->maBackgroundColor
;
238 return new ColorContext(*this, mrPatternProps
.maPattBgColor
, pComplexColor
);
239 case A_TOKEN( fgClr
):
241 pComplexColor
= &mpPatternFill
->maForegroundColor
;
242 return new ColorContext(*this, mrPatternProps
.maPattFgColor
, pComplexColor
);
247 ColorChangeContext::ColorChangeContext( ContextHandler2Helper
const & rParent
,
248 const AttributeList
& rAttribs
, BlipFillProperties
& rBlipProps
, model::BlipFill
* pBlipFill
)
249 : ContextHandler2(rParent
)
250 , mpBlipFill(pBlipFill
)
251 , mrBlipProps(rBlipProps
)
253 mrBlipProps
.maColorChangeFrom
.setUnused();
254 mrBlipProps
.maColorChangeTo
.setUnused();
255 mbUseAlpha
= rAttribs
.getBool( XML_useA
, true );
258 auto& rEffect
= mpBlipFill
->maBlipEffects
.emplace_back();
259 rEffect
.meType
= model::BlipEffectType::ColorChange
;
260 rEffect
.mbUseAlpha
= mbUseAlpha
;
264 ColorChangeContext::~ColorChangeContext()
267 mrBlipProps
.maColorChangeTo
.clearTransparence();
270 ContextHandlerRef
ColorChangeContext::onCreateContext(
271 sal_Int32 nElement
, const AttributeList
& )
273 model::ComplexColor
* pComplexColor
= nullptr;
276 case A_TOKEN(clrFrom
):
279 auto& rEffect
= mpBlipFill
->maBlipEffects
.back();
280 pComplexColor
= &rEffect
.getColorFrom();
282 return new ColorContext(*this, mrBlipProps
.maColorChangeFrom
, pComplexColor
);
286 auto& rEffect
= mpBlipFill
->maBlipEffects
.back();
287 pComplexColor
= &rEffect
.getColorTo();
289 return new ColorContext(*this, mrBlipProps
.maColorChangeTo
, pComplexColor
);
294 BlipContext::BlipContext(ContextHandler2Helper
const & rParent
, const AttributeList
& rAttribs
,
295 BlipFillProperties
& rBlipProps
, model::BlipFill
* pBlipFill
)
296 : ContextHandler2(rParent
)
297 , mpBlipFill(pBlipFill
)
298 , mrBlipProps(rBlipProps
)
300 if( rAttribs
.hasAttribute( R_TOKEN( embed
) ) )
302 // internal picture URL
303 OUString aFragmentPath
= getFragmentPathFromRelId( rAttribs
.getStringDefaulted( R_TOKEN( embed
)) );
304 if (!aFragmentPath
.isEmpty())
306 auto xGraphic
= getFilter().getGraphicHelper().importEmbeddedGraphic(aFragmentPath
);
307 mrBlipProps
.mxFillGraphic
= xGraphic
;
309 mpBlipFill
->mxGraphic
= std::move(xGraphic
);
312 else if( rAttribs
.hasAttribute( R_TOKEN( link
) ) )
316 // we will embed this link, this is better than just doing nothing...
317 // TODO: import this graphic as real link, but this requires some
319 OUString aRelId
= rAttribs
.getStringDefaulted( R_TOKEN( link
));
320 OUString aTargetLink
= getFilter().getAbsoluteUrl( getRelations().getExternalTargetFromRelId( aRelId
) );
321 GraphicExternalLink
aLink(aTargetLink
);
322 Graphic
aGraphic(aLink
);
323 auto xGraphic
= aGraphic
.GetXGraphic();
324 mrBlipProps
.mxFillGraphic
= xGraphic
;
326 mpBlipFill
->mxGraphic
= std::move(xGraphic
);
330 ContextHandlerRef
BlipContext::onCreateContext(
331 sal_Int32 nElement
, const AttributeList
& rAttribs
)
335 case A_TOKEN( biLevel
):
337 sal_Int32 nTreshold
= rAttribs
.getInteger(XML_thresh
, 0);
339 mrBlipProps
.moBiLevelThreshold
= nTreshold
;
340 mrBlipProps
.moColorEffect
= getBaseToken(nElement
);
344 auto& rEffect
= mpBlipFill
->maBlipEffects
.emplace_back();
345 rEffect
.meType
= model::BlipEffectType::BiLevel
;
346 rEffect
.mnThreshold
= nTreshold
;
351 case A_TOKEN( grayscl
):
353 mrBlipProps
.moColorEffect
= getBaseToken( nElement
);
356 auto& rEffect
= mpBlipFill
->maBlipEffects
.emplace_back();
357 rEffect
.meType
= model::BlipEffectType::Grayscale
;
362 case A_TOKEN( clrChange
):
364 return new ColorChangeContext(*this, rAttribs
, mrBlipProps
, mpBlipFill
);
367 case A_TOKEN( duotone
):
368 return new DuotoneContext( *this, mrBlipProps
);
370 case A_TOKEN( extLst
):
371 return new BlipExtensionContext(*this, mrBlipProps
, mpBlipFill
);
375 mrBlipProps
.moBrightness
= rAttribs
.getInteger( XML_bright
);
376 mrBlipProps
.moContrast
= rAttribs
.getInteger( XML_contrast
);
380 auto& rEffect
= mpBlipFill
->maBlipEffects
.emplace_back();
381 rEffect
.meType
= model::BlipEffectType::Luminance
;
382 rEffect
.mnBrightness
= rAttribs
.getInteger(XML_bright
, 0);
383 rEffect
.mnContrast
= rAttribs
.getInteger(XML_contrast
, 0);
387 case A_TOKEN( alphaModFix
):
389 mrBlipProps
.moAlphaModFix
= rAttribs
.getInteger(XML_amt
);
392 auto& rEffect
= mpBlipFill
->maBlipEffects
.emplace_back();
393 rEffect
.meType
= model::BlipEffectType::AlphaModulateFixed
;
394 rEffect
.mnAmount
= rAttribs
.getInteger(XML_amt
, 100 * 1000);
402 DuotoneContext::DuotoneContext( ContextHandler2Helper
const & rParent
,
403 BlipFillProperties
& rBlipProps
) :
404 ContextHandler2( rParent
),
405 mrBlipProps( rBlipProps
),
408 mrBlipProps
.maDuotoneColors
[0].setUnused();
409 mrBlipProps
.maDuotoneColors
[1].setUnused();
412 DuotoneContext::~DuotoneContext()
416 ::oox::core::ContextHandlerRef
DuotoneContext::onCreateContext(
417 sal_Int32
/*nElement*/, const AttributeList
& /*rAttribs*/ )
419 if( mnColorIndex
< 2 )
420 return new ColorValueContext(*this, mrBlipProps
.maDuotoneColors
[mnColorIndex
++], nullptr);
424 BlipFillContext::BlipFillContext(ContextHandler2Helper
const & rParent
, const AttributeList
& rAttribs
,
425 BlipFillProperties
& rBlipProps
, model::BlipFill
* pBlipFill
)
426 : ContextHandler2( rParent
)
427 , mpBlipFill(pBlipFill
)
428 , mrBlipProps(rBlipProps
)
430 mrBlipProps
.moRotateWithShape
= rAttribs
.getBool( XML_rotWithShape
);
432 mpBlipFill
->mbRotateWithShape
= rAttribs
.getBool(XML_rotWithShape
, false);
435 ContextHandlerRef
BlipFillContext::onCreateContext(
436 sal_Int32 nElement
, const AttributeList
& rAttribs
)
440 case A_TOKEN( blip
):
441 return new BlipContext(*this, rAttribs
, mrBlipProps
, mpBlipFill
);
443 case A_TOKEN( srcRect
):
445 mrBlipProps
.moClipRect
= GetRelativeRect( rAttribs
.getFastAttributeList() );
448 fillRelativeRectangle(mpBlipFill
->maClipRectangle
, rAttribs
.getFastAttributeList());
452 case A_TOKEN( tile
):
454 mrBlipProps
.moBitmapMode
= getBaseToken( nElement
);
455 mrBlipProps
.moTileOffsetX
= rAttribs
.getInteger( XML_tx
);
456 mrBlipProps
.moTileOffsetY
= rAttribs
.getInteger( XML_ty
);
457 mrBlipProps
.moTileScaleX
= rAttribs
.getInteger( XML_sx
);
458 mrBlipProps
.moTileScaleY
= rAttribs
.getInteger( XML_sy
);
459 mrBlipProps
.moTileAlign
= rAttribs
.getToken( XML_algn
);
460 mrBlipProps
.moTileFlip
= rAttribs
.getToken( XML_flip
);
464 mpBlipFill
->meMode
= model::BitmapMode::Tile
;
465 mpBlipFill
->mnTileOffsetX
= rAttribs
.getInteger(XML_tx
, 0);
466 mpBlipFill
->mnTileOffsetY
= rAttribs
.getInteger(XML_ty
, 0);
467 mpBlipFill
->mnTileScaleX
= rAttribs
.getInteger(XML_sx
, 0);
468 mpBlipFill
->mnTileScaleY
= rAttribs
.getInteger(XML_sy
, 0);
470 switch (rAttribs
.getToken(XML_flip
, XML_none
))
472 case XML_x
: mpBlipFill
->meTileFlipMode
= model::FlipMode::X
; break;
473 case XML_y
: mpBlipFill
->meTileFlipMode
= model::FlipMode::Y
; break;
474 case XML_xy
: mpBlipFill
->meTileFlipMode
= model::FlipMode::XY
; break;
476 case XML_none
: mpBlipFill
->meTileFlipMode
= model::FlipMode::None
; break;
478 mpBlipFill
->meTileAlignment
= convertToRectangleAlignment(rAttribs
.getToken(XML_algn
, XML_TOKEN_INVALID
));
483 case A_TOKEN( stretch
):
485 mrBlipProps
.moBitmapMode
= getBaseToken( nElement
);
488 mpBlipFill
->meMode
= model::BitmapMode::Stretch
;
490 return this; // for fillRect element
494 case A_TOKEN( fillRect
):
496 mrBlipProps
.moFillRect
= GetRelativeRect( rAttribs
.getFastAttributeList() );
499 fillRelativeRectangle(mpBlipFill
->maFillRectangle
, rAttribs
.getFastAttributeList());
506 FillPropertiesContext::FillPropertiesContext( ContextHandler2Helper
const & rParent
, FillProperties
& rFillProps
) :
507 ContextHandler2( rParent
),
508 mrFillProps( rFillProps
)
512 ContextHandlerRef
FillPropertiesContext::onCreateContext(
513 sal_Int32 nElement
, const AttributeList
& rAttribs
)
515 return createFillContext(*this, nElement
, rAttribs
, mrFillProps
, &maFillStyle
);
518 ContextHandlerRef
FillPropertiesContext::createFillContext(
519 ContextHandler2Helper
const & rParent
, sal_Int32 nElement
,
520 const AttributeList
& rAttribs
, FillProperties
& rFillProps
,
521 model::FillStyle
* pFillStyle
)
525 case A_TOKEN( noFill
):
527 rFillProps
.moFillType
= getBaseToken(nElement
);
530 pFillStyle
->mpFill
= std::make_shared
<model::NoFill
>();
534 case A_TOKEN( solidFill
):
536 rFillProps
.moFillType
= getBaseToken(nElement
);
537 model::SolidFill
* pSolidFill
= nullptr;
540 pFillStyle
->mpFill
= std::make_shared
<model::SolidFill
>();
541 pSolidFill
= static_cast<model::SolidFill
*>(pFillStyle
->mpFill
.get());
543 return new SolidFillContext(rParent
, rFillProps
, pSolidFill
);
545 case A_TOKEN( gradFill
):
547 rFillProps
.moFillType
= getBaseToken(nElement
);
548 model::GradientFill
* pGradientFill
= nullptr;
551 pFillStyle
->mpFill
= std::make_shared
<model::GradientFill
>();
552 pGradientFill
= static_cast<model::GradientFill
*>(pFillStyle
->mpFill
.get());
554 return new GradientFillContext(rParent
, rAttribs
, rFillProps
.maGradientProps
, pGradientFill
);
556 case A_TOKEN( pattFill
):
558 rFillProps
.moFillType
= getBaseToken( nElement
);
559 model::PatternFill
* pPatternFill
= nullptr;
562 auto pFill
= std::make_shared
<model::PatternFill
>();
563 pPatternFill
= pFill
.get();
564 pFillStyle
->mpFill
= pFill
;
566 return new PatternFillContext(rParent
, rAttribs
, rFillProps
.maPatternProps
, pPatternFill
);
568 case A_TOKEN( blipFill
):
570 rFillProps
.moFillType
= getBaseToken( nElement
);
571 model::BlipFill
* pBlipFill
= nullptr;
574 pFillStyle
->mpFill
= std::make_unique
<model::BlipFill
>();
575 pBlipFill
= static_cast<model::BlipFill
*>(pFillStyle
->mpFill
.get());
577 return new BlipFillContext( rParent
, rAttribs
, rFillProps
.maBlipProps
, pBlipFill
);
579 case A_TOKEN( grpFill
):
582 rFillProps
.moFillType
= getBaseToken( nElement
);
589 SimpleFillPropertiesContext::SimpleFillPropertiesContext( ContextHandler2Helper
const & rParent
, Color
& rColor
) :
590 FillPropertiesContext( rParent
, *this ),
595 SimpleFillPropertiesContext::~SimpleFillPropertiesContext()
597 mrColor
= getBestSolidColor();
600 BlipExtensionContext::BlipExtensionContext(ContextHandler2Helper
const & rParent
, BlipFillProperties
& rBlipProps
, model::BlipFill
* pBlipFill
)
601 : ContextHandler2(rParent
)
602 , mrBlipProps(rBlipProps
)
603 , mpBlipFill(pBlipFill
)
607 BlipExtensionContext::~BlipExtensionContext()
611 ContextHandlerRef
BlipExtensionContext::onCreateContext(sal_Int32 nElement
, const AttributeList
& rAttribs
)
616 return new BlipExtensionContext(*this, mrBlipProps
, mpBlipFill
);
618 case OOX_TOKEN(a14
, imgProps
):
619 return new ArtisticEffectContext(*this, mrBlipProps
.maEffect
);
621 // Import the SVG Blip
622 case OOX_TOKEN(asvg
, svgBlip
):
624 if (rAttribs
.hasAttribute(R_TOKEN(embed
)))
626 OUString aFragmentPath
= getFragmentPathFromRelId(rAttribs
.getStringDefaulted(R_TOKEN(embed
)));
627 if (!aFragmentPath
.isEmpty())
629 // Read the graphic from the fragment path
630 auto xGraphic
= getFilter().getGraphicHelper().importEmbeddedGraphic(aFragmentPath
);
632 // Overwrite the fill graphic with the one containing SVG
633 mrBlipProps
.mxFillGraphic
= xGraphic
;
635 mpBlipFill
->mxGraphic
= std::move(xGraphic
);
645 ArtisticEffectContext::ArtisticEffectContext( ContextHandler2Helper
const & rParent
, ArtisticEffectProperties
& rEffect
) :
646 ContextHandler2( rParent
),
651 ArtisticEffectContext::~ArtisticEffectContext()
655 ContextHandlerRef
ArtisticEffectContext::onCreateContext(
656 sal_Int32 nElement
, const AttributeList
& rAttribs
)
659 if( nElement
== OOX_TOKEN( a14
, imgLayer
) )
661 if( rAttribs
.hasAttribute( R_TOKEN( embed
) ) )
663 OUString aFragmentPath
= getFragmentPathFromRelId( rAttribs
.getStringDefaulted( R_TOKEN( embed
)) );
664 if( !aFragmentPath
.isEmpty() )
666 getFilter().importBinaryData( maEffect
.mrOleObjectInfo
.maEmbeddedData
, aFragmentPath
);
667 maEffect
.mrOleObjectInfo
.maProgId
= aFragmentPath
;
670 return new ArtisticEffectContext( *this, maEffect
);
672 if( nElement
== OOX_TOKEN( a14
, imgEffect
) )
673 return new ArtisticEffectContext( *this, maEffect
);
676 maEffect
.msName
= ArtisticEffectProperties::getEffectString( nElement
);
677 if( maEffect
.isEmpty() )
681 sal_Int32
const aAttribs
[19] = {
682 XML_visible
, XML_trans
, XML_crackSpacing
, XML_pressure
, XML_numberOfShades
,
683 XML_grainSize
, XML_intensity
, XML_smoothness
, XML_gridSize
, XML_pencilSize
,
684 XML_size
, XML_brushSize
, XML_scaling
, XML_detail
, XML_bright
, XML_contrast
,
685 XML_colorTemp
, XML_sat
, XML_amount
687 for(sal_Int32 nAttrib
: aAttribs
)
689 if( rAttribs
.hasAttribute( nAttrib
) )
691 OUString sName
= ArtisticEffectProperties::getEffectString( nAttrib
);
692 if( !sName
.isEmpty() )
693 maEffect
.maAttribs
[sName
] <<= rAttribs
.getInteger( nAttrib
, 0 );
700 } // namespace oox::drawingml
702 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */