tdf#130857 qt weld: Support mail merge "Server Auth" dialog
[LibreOffice.git] / oox / source / drawingml / misccontexts.cxx
blobccbff30df1a3ccfb791312a8c22aceafbf9bbe31
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
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 )
66 switch( nElement )
68 case A_TOKEN( gsLst ):
69 return this; // for gs elements
71 case A_TOKEN( gs ):
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;
78 if (mpGradientFill)
80 model::GradientStop& rStop = mpGradientFill->maGradientStops.emplace_back();
81 rStop.mfPosition = fPosition;
82 pComplexColor = &rStop.maColor;
85 return new ColorContext(*this, aElement->second, pComplexColor);
87 break;
89 case A_TOKEN( lin ):
91 mrGradientProps.moShadeAngle = rAttribs.getInteger(XML_ang);
92 mrGradientProps.moShadeScaled = rAttribs.getBool(XML_scaled);
94 if (mpGradientFill)
96 mpGradientFill->meGradientType = model::GradientType::Linear;
97 mpGradientFill->maLinearGradient.mnAngle = rAttribs.getInteger(XML_ang, 0);
98 mpGradientFill->maLinearGradient.mbScaled = rAttribs.getBool(XML_scaled, false);
101 break;
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;
108 if (mpGradientFill)
110 switch (nToken)
112 case XML_rect:
113 mpGradientFill->meGradientType = model::GradientType::Rectangle;
114 break;
115 case XML_circle:
116 mpGradientFill->meGradientType = model::GradientType::Circle;
117 break;
118 case XML_shape:
119 mpGradientFill->meGradientType = model::GradientType::Shape;
120 break;
121 default:
122 break;
125 return this; // for fillToRect element
127 case A_TOKEN( fillToRect ):
129 mrGradientProps.moFillToRect = GetRelativeRect( rAttribs.getFastAttributeList() );
130 if (mpGradientFill)
131 fillRelativeRectangle(mpGradientFill->maFillToRectangle, rAttribs.getFastAttributeList());
133 break;
135 case A_TOKEN( tileRect ):
136 mrGradientProps.moTileRect = GetRelativeRect(rAttribs.getFastAttributeList());
137 if (mpGradientFill)
138 fillRelativeRectangle(mpGradientFill->maTileRectangle, rAttribs.getFastAttributeList());
139 break;
141 return nullptr;
145 namespace
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);
215 if (mpPatternFill)
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;
233 switch( nElement )
235 case A_TOKEN( bgClr ):
236 if (mpPatternFill)
237 pComplexColor = &mpPatternFill->maBackgroundColor;
238 return new ColorContext(*this, mrPatternProps.maPattBgColor, pComplexColor);
239 case A_TOKEN( fgClr ):
240 if (mpPatternFill)
241 pComplexColor = &mpPatternFill->maForegroundColor;
242 return new ColorContext(*this, mrPatternProps.maPattFgColor, pComplexColor);
244 return nullptr;
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 );
256 if (mpBlipFill)
258 auto& rEffect = mpBlipFill->maBlipEffects.emplace_back();
259 rEffect.meType = model::BlipEffectType::ColorChange;
260 rEffect.mbUseAlpha = mbUseAlpha;
264 ColorChangeContext::~ColorChangeContext()
266 if( !mbUseAlpha )
267 mrBlipProps.maColorChangeTo.clearTransparence();
270 ContextHandlerRef ColorChangeContext::onCreateContext(
271 sal_Int32 nElement, const AttributeList& )
273 model::ComplexColor* pComplexColor = nullptr;
274 switch (nElement)
276 case A_TOKEN(clrFrom):
277 if (mpBlipFill)
279 auto& rEffect = mpBlipFill->maBlipEffects.back();
280 pComplexColor = &rEffect.getColorFrom();
282 return new ColorContext(*this, mrBlipProps.maColorChangeFrom, pComplexColor);
283 case A_TOKEN(clrTo):
284 if (mpBlipFill)
286 auto& rEffect = mpBlipFill->maBlipEffects.back();
287 pComplexColor = &rEffect.getColorTo();
289 return new ColorContext(*this, mrBlipProps.maColorChangeTo, pComplexColor);
291 return nullptr;
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;
308 if (mpBlipFill)
309 mpBlipFill->mxGraphic = std::move(xGraphic);
312 else if( rAttribs.hasAttribute( R_TOKEN( link ) ) )
314 // external URL
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
318 // code rework.
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;
325 if (mpBlipFill)
326 mpBlipFill->mxGraphic = std::move(xGraphic);
330 ContextHandlerRef BlipContext::onCreateContext(
331 sal_Int32 nElement, const AttributeList& rAttribs )
333 switch( nElement )
335 case A_TOKEN( biLevel ):
337 sal_Int32 nTreshold = rAttribs.getInteger(XML_thresh, 0);
339 mrBlipProps.moBiLevelThreshold = nTreshold;
340 mrBlipProps.moColorEffect = getBaseToken(nElement);
342 if (mpBlipFill)
344 auto& rEffect = mpBlipFill->maBlipEffects.emplace_back();
345 rEffect.meType = model::BlipEffectType::BiLevel;
346 rEffect.mnThreshold = nTreshold;
349 break;
351 case A_TOKEN( grayscl ):
353 mrBlipProps.moColorEffect = getBaseToken( nElement );
354 if (mpBlipFill)
356 auto& rEffect = mpBlipFill->maBlipEffects.emplace_back();
357 rEffect.meType = model::BlipEffectType::Grayscale;
360 break;
362 case A_TOKEN( clrChange ):
364 return new ColorChangeContext(*this, rAttribs, mrBlipProps, mpBlipFill);
366 break;
367 case A_TOKEN( duotone ):
368 return new DuotoneContext( *this, mrBlipProps );
370 case A_TOKEN( extLst ):
371 return new BlipExtensionContext(*this, mrBlipProps, mpBlipFill);
373 case A_TOKEN( lum ):
375 mrBlipProps.moBrightness = rAttribs.getInteger( XML_bright );
376 mrBlipProps.moContrast = rAttribs.getInteger( XML_contrast );
378 if (mpBlipFill)
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);
386 break;
387 case A_TOKEN( alphaModFix ):
389 mrBlipProps.moAlphaModFix = rAttribs.getInteger(XML_amt);
390 if (mpBlipFill)
392 auto& rEffect = mpBlipFill->maBlipEffects.emplace_back();
393 rEffect.meType = model::BlipEffectType::AlphaModulateFixed;
394 rEffect.mnAmount = rAttribs.getInteger(XML_amt, 100 * 1000);
397 break;
399 return nullptr;
402 DuotoneContext::DuotoneContext( ContextHandler2Helper const & rParent,
403 BlipFillProperties& rBlipProps ) :
404 ContextHandler2( rParent ),
405 mrBlipProps( rBlipProps ),
406 mnColorIndex( 0 )
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);
421 return 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 );
431 if (mpBlipFill)
432 mpBlipFill->mbRotateWithShape = rAttribs.getBool(XML_rotWithShape, false);
435 ContextHandlerRef BlipFillContext::onCreateContext(
436 sal_Int32 nElement, const AttributeList& rAttribs )
438 switch( nElement )
440 case A_TOKEN( blip ):
441 return new BlipContext(*this, rAttribs, mrBlipProps, mpBlipFill);
443 case A_TOKEN( srcRect ):
445 mrBlipProps.moClipRect = GetRelativeRect( rAttribs.getFastAttributeList() );
447 if (mpBlipFill)
448 fillRelativeRectangle(mpBlipFill->maClipRectangle, rAttribs.getFastAttributeList());
450 break;
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 );
462 if (mpBlipFill)
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;
475 default:
476 case XML_none: mpBlipFill->meTileFlipMode = model::FlipMode::None; break;
478 mpBlipFill->meTileAlignment = convertToRectangleAlignment(rAttribs.getToken(XML_algn, XML_TOKEN_INVALID));
481 break;
483 case A_TOKEN( stretch ):
485 mrBlipProps.moBitmapMode = getBaseToken( nElement );
486 if (mpBlipFill)
488 mpBlipFill->meMode = model::BitmapMode::Stretch;
490 return this; // for fillRect element
492 break;
494 case A_TOKEN( fillRect ):
496 mrBlipProps.moFillRect = GetRelativeRect( rAttribs.getFastAttributeList() );
498 if (mpBlipFill)
499 fillRelativeRectangle(mpBlipFill->maFillRectangle, rAttribs.getFastAttributeList());
501 break;
503 return nullptr;
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)
523 switch( nElement )
525 case A_TOKEN( noFill ):
527 rFillProps.moFillType = getBaseToken(nElement);
528 if (pFillStyle)
530 pFillStyle->mpFill = std::make_shared<model::NoFill>();
532 return nullptr;
534 case A_TOKEN( solidFill ):
536 rFillProps.moFillType = getBaseToken(nElement);
537 model::SolidFill* pSolidFill = nullptr;
538 if (pFillStyle)
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;
549 if (pFillStyle)
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;
560 if (pFillStyle)
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;
572 if (pFillStyle)
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 ):
581 // TODO
582 rFillProps.moFillType = getBaseToken( nElement );
583 return nullptr;
586 return nullptr;
589 SimpleFillPropertiesContext::SimpleFillPropertiesContext( ContextHandler2Helper const & rParent, Color& rColor ) :
590 FillPropertiesContext( rParent, *this ),
591 mrColor( rColor )
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)
613 switch( nElement )
615 case A_TOKEN(ext):
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;
634 if (mpBlipFill)
635 mpBlipFill->mxGraphic = std::move(xGraphic);
638 // TODO - link
640 break;
642 return nullptr;
645 ArtisticEffectContext::ArtisticEffectContext( ContextHandler2Helper const & rParent, ArtisticEffectProperties& rEffect ) :
646 ContextHandler2( rParent ),
647 maEffect( rEffect )
651 ArtisticEffectContext::~ArtisticEffectContext()
655 ContextHandlerRef ArtisticEffectContext::onCreateContext(
656 sal_Int32 nElement, const AttributeList& rAttribs )
658 // containers
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 );
675 // effects
676 maEffect.msName = ArtisticEffectProperties::getEffectString( nElement );
677 if( maEffect.isEmpty() )
678 return nullptr;
680 // effect attributes
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 );
697 return nullptr;
700 } // namespace oox::drawingml
702 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */