diff options
Diffstat (limited to 'oox/source/drawingml/misccontexts.cxx')
-rw-r--r-- | oox/source/drawingml/misccontexts.cxx | 703 |
1 files changed, 703 insertions, 0 deletions
diff --git a/oox/source/drawingml/misccontexts.cxx b/oox/source/drawingml/misccontexts.cxx new file mode 100644 index 0000000000..93d2c8ee41 --- /dev/null +++ b/oox/source/drawingml/misccontexts.cxx @@ -0,0 +1,703 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#include <drawingml/misccontexts.hxx> +#include <oox/helper/attributelist.hxx> +#include <oox/helper/graphichelper.hxx> +#include <oox/core/xmlfilterbase.hxx> +#include <oox/drawingml/drawingmltypes.hxx> +#include <drawingml/fillproperties.hxx> +#include <oox/token/namespaces.hxx> +#include <oox/token/tokens.hxx> +#include <vcl/GraphicExternalLink.hxx> +#include <vcl/graph.hxx> +#include <unordered_map> +#include <frozen/bits/defines.h> +#include <frozen/bits/elsa_std.h> +#include <frozen/unordered_map.h> + +using namespace ::com::sun::star; +using namespace ::com::sun::star::uno; +using namespace ::com::sun::star::xml::sax; +using ::oox::core::ContextHandler2; +using ::oox::core::ContextHandlerRef; + +namespace oox::drawingml { + +SolidFillContext::SolidFillContext(ContextHandler2Helper const & rParent, FillProperties& rFillProps, model::SolidFill* pSolidFill) + : ColorContext(rParent, rFillProps.maFillColor, pSolidFill ? &pSolidFill->maColor : nullptr) +{ +} + +SolidFillContext::~SolidFillContext() +{} + +GradientFillContext::GradientFillContext(ContextHandler2Helper const & rParent, + const AttributeList& rAttribs, GradientFillProperties& rGradientProps, model::GradientFill* pGradientFill) + : ContextHandler2(rParent) + , mpGradientFill(pGradientFill) + , mrGradientProps(rGradientProps) +{ + auto oRotateWithShape = rAttribs.getBool(XML_rotWithShape); + mrGradientProps.moShadeFlip = rAttribs.getToken( XML_flip ); + mrGradientProps.moRotateWithShape = oRotateWithShape; + if (mpGradientFill && oRotateWithShape.has_value()) + mpGradientFill->mbRotateWithShape = *oRotateWithShape; +} + +ContextHandlerRef GradientFillContext::onCreateContext( + sal_Int32 nElement, const AttributeList& rAttribs ) +{ + switch( nElement ) + { + case A_TOKEN( gsLst ): + return this; // for gs elements + + case A_TOKEN( gs ): + if (rAttribs.hasAttribute(XML_pos)) + { + double fPosition = getLimitedValue<double>(rAttribs.getDouble(XML_pos, 0.0) / 100000.0, 0.0, 1.0); + auto aElement = mrGradientProps.maGradientStops.emplace(fPosition, Color()); + + model::ComplexColor* pComplexColor = nullptr; + if (mpGradientFill) + { + model::GradientStop& rStop = mpGradientFill->maGradientStops.emplace_back(); + rStop.mfPosition = fPosition; + pComplexColor = &rStop.maColor; + } + + return new ColorContext(*this, aElement->second, pComplexColor); + } + break; + + case A_TOKEN( lin ): + { + mrGradientProps.moShadeAngle = rAttribs.getInteger(XML_ang); + mrGradientProps.moShadeScaled = rAttribs.getBool(XML_scaled); + + if (mpGradientFill) + { + mpGradientFill->meGradientType = model::GradientType::Linear; + mpGradientFill->maLinearGradient.mnAngle = rAttribs.getInteger(XML_ang, 0); + mpGradientFill->maLinearGradient.mbScaled = rAttribs.getBool(XML_scaled, false); + } + } + break; + + case A_TOKEN( path ): + { + // always set a path type, this disables linear gradient in conversion + sal_Int32 nToken = rAttribs.getToken(XML_path, XML_rect); + mrGradientProps.moGradientPath = nToken; + if (mpGradientFill) + { + switch (nToken) + { + case XML_rect: + mpGradientFill->meGradientType = model::GradientType::Rectangle; + break; + case XML_circle: + mpGradientFill->meGradientType = model::GradientType::Circle; + break; + case XML_shape: + mpGradientFill->meGradientType = model::GradientType::Shape; + break; + default: + break; + } + } + return this; // for fillToRect element + } + case A_TOKEN( fillToRect ): + { + mrGradientProps.moFillToRect = GetRelativeRect( rAttribs.getFastAttributeList() ); + if (mpGradientFill) + fillRelativeRectangle(mpGradientFill->maFillToRectangle, rAttribs.getFastAttributeList()); + } + break; + + case A_TOKEN( tileRect ): + mrGradientProps.moTileRect = GetRelativeRect(rAttribs.getFastAttributeList()); + if (mpGradientFill) + fillRelativeRectangle(mpGradientFill->maTileRectangle, rAttribs.getFastAttributeList()); + break; + } + return nullptr; +} + + +namespace +{ + +constexpr frozen::unordered_map<sal_Int32, model::PatternPreset, 54> constPatternPresetMap +{ + { XML_pct5, model::PatternPreset::Percent_5 }, + { XML_pct10, model::PatternPreset::Percent_10 }, + { XML_pct20, model::PatternPreset::Percent_20 }, + { XML_pct25, model::PatternPreset::Percent_25 }, + { XML_pct30, model::PatternPreset::Percent_30 }, + { XML_pct40, model::PatternPreset::Percent_40 }, + { XML_pct50, model::PatternPreset::Percent_50 }, + { XML_pct60, model::PatternPreset::Percent_60 }, + { XML_pct70, model::PatternPreset::Percent_70 }, + { XML_pct75, model::PatternPreset::Percent_75 }, + { XML_pct80, model::PatternPreset::Percent_80 }, + { XML_pct90, model::PatternPreset::Percent_90 }, + { XML_horz, model::PatternPreset::Horizontal }, + { XML_vert, model::PatternPreset::Vertical }, + { XML_ltHorz, model::PatternPreset::LightHorizontal }, + { XML_ltVert, model::PatternPreset::LightVertical }, + { XML_dkHorz, model::PatternPreset::DarkHorizontal }, + { XML_dkVert, model::PatternPreset::DarkVertical }, + { XML_narHorz, model::PatternPreset::NarrowHorizontal }, + { XML_narVert, model::PatternPreset::NarrowVertical }, + { XML_dashHorz, model::PatternPreset::DashedHorizontal }, + { XML_dashVert, model::PatternPreset::DashedVertical }, + { XML_cross, model::PatternPreset::Cross }, + { XML_dnDiag, model::PatternPreset::DownwardDiagonal }, + { XML_upDiag, model::PatternPreset::UpwardDiagonal }, + { XML_ltDnDiag, model::PatternPreset::LightDownwardDiagonal }, + { XML_ltUpDiag, model::PatternPreset::LightUpwardDiagonal }, + { XML_dkDnDiag, model::PatternPreset::DarkDownwardDiagonal }, + { XML_dkUpDiag, model::PatternPreset::DarkUpwardDiagonal }, + { XML_wdDnDiag, model::PatternPreset::WideDownwardDiagonal }, + { XML_wdUpDiag, model::PatternPreset::WideUpwardDiagonal }, + { XML_dashDnDiag, model::PatternPreset::DashedDownwardDiagonal }, + { XML_dashUpDiag, model::PatternPreset::DashedUpwardDiagonal }, + { XML_diagCross, model::PatternPreset::DiagonalCross }, + { XML_smCheck, model::PatternPreset::SmallCheckerBoard }, + { XML_lgCheck, model::PatternPreset::LargeCheckerBoard }, + { XML_smGrid, model::PatternPreset::SmallGrid }, + { XML_lgGrid, model::PatternPreset::LargeGrid }, + { XML_dotGrid, model::PatternPreset::DottedGrid }, + { XML_smConfetti, model::PatternPreset::SmallConfetti }, + { XML_lgConfetti, model::PatternPreset::LargeConfetti }, + { XML_horzBrick, model::PatternPreset::HorizontalBrick }, + { XML_diagBrick, model::PatternPreset::DiagonalBrick }, + { XML_solidDmnd, model::PatternPreset::SolidDiamond }, + { XML_openDmnd, model::PatternPreset::OpenDiamond }, + { XML_dotDmnd, model::PatternPreset::DottedDiamond }, + { XML_plaid, model::PatternPreset::Plaid }, + { XML_sphere, model::PatternPreset::Sphere }, + { XML_weave, model::PatternPreset::Weave }, + { XML_divot, model::PatternPreset::Divot }, + { XML_shingle, model::PatternPreset::Shingle }, + { XML_wave, model::PatternPreset::Wave }, + { XML_trellis, model::PatternPreset::Trellis }, + { XML_zigZag, model::PatternPreset::ZigZag } +}; + +} // end anonymous namespace +PatternFillContext::PatternFillContext(ContextHandler2Helper const & rParent, + const AttributeList& rAttribs, PatternFillProperties& rPatternProps, model::PatternFill* pPatternFill) + : ContextHandler2(rParent) + , mpPatternFill(pPatternFill) + , mrPatternProps(rPatternProps) +{ + mrPatternProps.moPattPreset = rAttribs.getToken(XML_prst); + + if (mpPatternFill) + { + sal_Int32 nToken = rAttribs.getToken(XML_prst, XML_TOKEN_INVALID); + + auto aIterator = constPatternPresetMap.find(nToken); + if (aIterator != constPatternPresetMap.end()) + { + auto const& aPair = *aIterator; + model::PatternPreset ePatternPreset = aPair.second; + mpPatternFill->mePatternPreset = ePatternPreset; + } + } +} + +ContextHandlerRef PatternFillContext::onCreateContext( + sal_Int32 nElement, const AttributeList& ) +{ + model::ComplexColor* pComplexColor = nullptr; + switch( nElement ) + { + case A_TOKEN( bgClr ): + if (mpPatternFill) + pComplexColor = &mpPatternFill->maBackgroundColor; + return new ColorContext(*this, mrPatternProps.maPattBgColor, pComplexColor); + case A_TOKEN( fgClr ): + if (mpPatternFill) + pComplexColor = &mpPatternFill->maForegroundColor; + return new ColorContext(*this, mrPatternProps.maPattFgColor, pComplexColor); + } + return nullptr; +} + +ColorChangeContext::ColorChangeContext( ContextHandler2Helper const & rParent, + const AttributeList& rAttribs, BlipFillProperties& rBlipProps, model::BlipFill* pBlipFill) + : ContextHandler2(rParent) + , mpBlipFill(pBlipFill) + , mrBlipProps(rBlipProps) +{ + mrBlipProps.maColorChangeFrom.setUnused(); + mrBlipProps.maColorChangeTo.setUnused(); + mbUseAlpha = rAttribs.getBool( XML_useA, true ); + if (mpBlipFill) + { + auto& rEffect = mpBlipFill->maBlipEffects.emplace_back(); + rEffect.meType = model::BlipEffectType::ColorChange; + rEffect.mbUseAlpha = mbUseAlpha; + } +} + +ColorChangeContext::~ColorChangeContext() +{ + if( !mbUseAlpha ) + mrBlipProps.maColorChangeTo.clearTransparence(); +} + +ContextHandlerRef ColorChangeContext::onCreateContext( + sal_Int32 nElement, const AttributeList& ) +{ + model::ComplexColor* pComplexColor = nullptr; + switch (nElement) + { + case A_TOKEN(clrFrom): + if (mpBlipFill) + { + auto& rEffect = mpBlipFill->maBlipEffects.back(); + pComplexColor = &rEffect.getColorFrom(); + } + return new ColorContext(*this, mrBlipProps.maColorChangeFrom, pComplexColor); + case A_TOKEN(clrTo): + if (mpBlipFill) + { + auto& rEffect = mpBlipFill->maBlipEffects.back(); + pComplexColor = &rEffect.getColorTo(); + } + return new ColorContext(*this, mrBlipProps.maColorChangeTo, pComplexColor); + } + return nullptr; +} + +BlipContext::BlipContext(ContextHandler2Helper const & rParent, const AttributeList& rAttribs, + BlipFillProperties& rBlipProps, model::BlipFill* pBlipFill) + : ContextHandler2(rParent) + , mpBlipFill(pBlipFill) + , mrBlipProps(rBlipProps) +{ + if( rAttribs.hasAttribute( R_TOKEN( embed ) ) ) + { + // internal picture URL + OUString aFragmentPath = getFragmentPathFromRelId( rAttribs.getStringDefaulted( R_TOKEN( embed )) ); + if (!aFragmentPath.isEmpty()) + { + auto xGraphic = getFilter().getGraphicHelper().importEmbeddedGraphic(aFragmentPath); + mrBlipProps.mxFillGraphic = xGraphic; + if (mpBlipFill) + mpBlipFill->mxGraphic = xGraphic; + } + } + else if( rAttribs.hasAttribute( R_TOKEN( link ) ) ) + { + // external URL + + // we will embed this link, this is better than just doing nothing... + // TODO: import this graphic as real link, but this requires some + // code rework. + OUString aRelId = rAttribs.getStringDefaulted( R_TOKEN( link )); + OUString aTargetLink = getFilter().getAbsoluteUrl( getRelations().getExternalTargetFromRelId( aRelId ) ); + GraphicExternalLink aLink(aTargetLink); + Graphic aGraphic(aLink); + auto xGraphic = aGraphic.GetXGraphic(); + mrBlipProps.mxFillGraphic = xGraphic; + if (mpBlipFill) + mpBlipFill->mxGraphic = xGraphic; + } +} + +ContextHandlerRef BlipContext::onCreateContext( + sal_Int32 nElement, const AttributeList& rAttribs ) +{ + switch( nElement ) + { + case A_TOKEN( biLevel ): + { + sal_Int32 nTreshold = rAttribs.getInteger(XML_thresh, 0); + + mrBlipProps.moBiLevelThreshold = nTreshold; + mrBlipProps.moColorEffect = getBaseToken(nElement); + + if (mpBlipFill) + { + auto& rEffect = mpBlipFill->maBlipEffects.emplace_back(); + rEffect.meType = model::BlipEffectType::BiLevel; + rEffect.mnThreshold = nTreshold; + } + } + break; + + case A_TOKEN( grayscl ): + { + mrBlipProps.moColorEffect = getBaseToken( nElement ); + if (mpBlipFill) + { + auto& rEffect = mpBlipFill->maBlipEffects.emplace_back(); + rEffect.meType = model::BlipEffectType::Grayscale; + } + } + break; + + case A_TOKEN( clrChange ): + { + return new ColorChangeContext(*this, rAttribs, mrBlipProps, mpBlipFill); + } + break; + case A_TOKEN( duotone ): + return new DuotoneContext( *this, mrBlipProps ); + + case A_TOKEN( extLst ): + return new BlipExtensionContext(*this, mrBlipProps, mpBlipFill); + + case A_TOKEN( lum ): + { + mrBlipProps.moBrightness = rAttribs.getInteger( XML_bright ); + mrBlipProps.moContrast = rAttribs.getInteger( XML_contrast ); + + if (mpBlipFill) + { + auto& rEffect = mpBlipFill->maBlipEffects.emplace_back(); + rEffect.meType = model::BlipEffectType::Luminance; + rEffect.mnBrightness = rAttribs.getInteger(XML_bright, 0); + rEffect.mnContrast = rAttribs.getInteger(XML_contrast, 0); + } + } + break; + case A_TOKEN( alphaModFix ): + { + mrBlipProps.moAlphaModFix = rAttribs.getInteger(XML_amt); + if (mpBlipFill) + { + auto& rEffect = mpBlipFill->maBlipEffects.emplace_back(); + rEffect.meType = model::BlipEffectType::AlphaModulateFixed; + rEffect.mnAmount = rAttribs.getInteger(XML_amt, 100 * 1000); + } + } + break; + } + return nullptr; +} + +DuotoneContext::DuotoneContext( ContextHandler2Helper const & rParent, + BlipFillProperties& rBlipProps ) : + ContextHandler2( rParent ), + mrBlipProps( rBlipProps ), + mnColorIndex( 0 ) +{ + mrBlipProps.maDuotoneColors[0].setUnused(); + mrBlipProps.maDuotoneColors[1].setUnused(); +} + +DuotoneContext::~DuotoneContext() +{ +} + +::oox::core::ContextHandlerRef DuotoneContext::onCreateContext( + sal_Int32 /*nElement*/, const AttributeList& /*rAttribs*/ ) +{ + if( mnColorIndex < 2 ) + return new ColorValueContext(*this, mrBlipProps.maDuotoneColors[mnColorIndex++], nullptr); + return nullptr; +} + +BlipFillContext::BlipFillContext(ContextHandler2Helper const & rParent, const AttributeList& rAttribs, + BlipFillProperties& rBlipProps, model::BlipFill* pBlipFill) + : ContextHandler2( rParent ) + , mpBlipFill(pBlipFill) + , mrBlipProps(rBlipProps) +{ + mrBlipProps.moRotateWithShape = rAttribs.getBool( XML_rotWithShape ); + if (mpBlipFill) + mpBlipFill->mbRotateWithShape = rAttribs.getBool(XML_rotWithShape, false); +} + +ContextHandlerRef BlipFillContext::onCreateContext( + sal_Int32 nElement, const AttributeList& rAttribs ) +{ + switch( nElement ) + { + case A_TOKEN( blip ): + return new BlipContext(*this, rAttribs, mrBlipProps, mpBlipFill); + + case A_TOKEN( srcRect ): + { + mrBlipProps.moClipRect = GetRelativeRect( rAttribs.getFastAttributeList() ); + + if (mpBlipFill) + fillRelativeRectangle(mpBlipFill->maClipRectangle, rAttribs.getFastAttributeList()); + } + break; + + case A_TOKEN( tile ): + { + mrBlipProps.moBitmapMode = getBaseToken( nElement ); + mrBlipProps.moTileOffsetX = rAttribs.getInteger( XML_tx ); + mrBlipProps.moTileOffsetY = rAttribs.getInteger( XML_ty ); + mrBlipProps.moTileScaleX = rAttribs.getInteger( XML_sx ); + mrBlipProps.moTileScaleY = rAttribs.getInteger( XML_sy ); + mrBlipProps.moTileAlign = rAttribs.getToken( XML_algn ); + mrBlipProps.moTileFlip = rAttribs.getToken( XML_flip ); + + if (mpBlipFill) + { + mpBlipFill->meMode = model::BitmapMode::Tile; + mpBlipFill->mnTileOffsetX = rAttribs.getInteger(XML_tx, 0); + mpBlipFill->mnTileOffsetY = rAttribs.getInteger(XML_ty, 0); + mpBlipFill->mnTileScaleX = rAttribs.getInteger(XML_sx, 0); + mpBlipFill->mnTileScaleY = rAttribs.getInteger(XML_sy, 0); + + switch (rAttribs.getToken(XML_flip, XML_none)) + { + case XML_x: mpBlipFill->meTileFlipMode = model::FlipMode::X; break; + case XML_y: mpBlipFill->meTileFlipMode = model::FlipMode::Y; break; + case XML_xy: mpBlipFill->meTileFlipMode = model::FlipMode::XY; break; + default: + case XML_none: mpBlipFill->meTileFlipMode = model::FlipMode::None; break; + } + mpBlipFill->meTileAlignment = convertToRectangleAlignment(rAttribs.getToken(XML_algn, XML_TOKEN_INVALID)); + } + } + break; + + case A_TOKEN( stretch ): + { + mrBlipProps.moBitmapMode = getBaseToken( nElement ); + if (mpBlipFill) + { + mpBlipFill->meMode = model::BitmapMode::Stretch; + } + return this; // for fillRect element + } + break; + + case A_TOKEN( fillRect ): + { + mrBlipProps.moFillRect = GetRelativeRect( rAttribs.getFastAttributeList() ); + + if (mpBlipFill) + fillRelativeRectangle(mpBlipFill->maFillRectangle, rAttribs.getFastAttributeList()); + } + break; + } + return nullptr; +} + +FillPropertiesContext::FillPropertiesContext( ContextHandler2Helper const & rParent, FillProperties& rFillProps ) : + ContextHandler2( rParent ), + mrFillProps( rFillProps ) +{ +} + +ContextHandlerRef FillPropertiesContext::onCreateContext( + sal_Int32 nElement, const AttributeList& rAttribs ) +{ + return createFillContext(*this, nElement, rAttribs, mrFillProps, &maFillStyle); +} + +ContextHandlerRef FillPropertiesContext::createFillContext( + ContextHandler2Helper const & rParent, sal_Int32 nElement, + const AttributeList& rAttribs, FillProperties& rFillProps, + model::FillStyle* pFillStyle) +{ + switch( nElement ) + { + case A_TOKEN( noFill ): + { + rFillProps.moFillType = getBaseToken(nElement); + if (pFillStyle) + { + pFillStyle->mpFill = std::make_shared<model::NoFill>(); + } + return nullptr; + } + case A_TOKEN( solidFill ): + { + rFillProps.moFillType = getBaseToken(nElement); + model::SolidFill* pSolidFill = nullptr; + if (pFillStyle) + { + pFillStyle->mpFill = std::make_shared<model::SolidFill>(); + pSolidFill = static_cast<model::SolidFill*>(pFillStyle->mpFill.get()); + } + return new SolidFillContext(rParent, rFillProps, pSolidFill); + } + case A_TOKEN( gradFill ): + { + rFillProps.moFillType = getBaseToken(nElement); + model::GradientFill* pGradientFill = nullptr; + if (pFillStyle) + { + pFillStyle->mpFill = std::make_shared<model::GradientFill>(); + pGradientFill = static_cast<model::GradientFill*>(pFillStyle->mpFill.get()); + } + return new GradientFillContext(rParent, rAttribs, rFillProps.maGradientProps, pGradientFill); + } + case A_TOKEN( pattFill ): + { + rFillProps.moFillType = getBaseToken( nElement ); + model::PatternFill* pPatternFill = nullptr; + if (pFillStyle) + { + auto pFill = std::make_shared<model::PatternFill>(); + pPatternFill = pFill.get(); + pFillStyle->mpFill = pFill; + } + return new PatternFillContext(rParent, rAttribs, rFillProps.maPatternProps, pPatternFill); + } + case A_TOKEN( blipFill ): + { + rFillProps.moFillType = getBaseToken( nElement ); + model::BlipFill* pBlipFill = nullptr; + if (pFillStyle) + { + pFillStyle->mpFill = std::make_unique<model::BlipFill>(); + pBlipFill = static_cast<model::BlipFill*>(pFillStyle->mpFill.get()); + } + return new BlipFillContext( rParent, rAttribs, rFillProps.maBlipProps, pBlipFill); + } + case A_TOKEN( grpFill ): + { + // TODO + rFillProps.moFillType = getBaseToken( nElement ); + return nullptr; + }; + } + return nullptr; +} + +SimpleFillPropertiesContext::SimpleFillPropertiesContext( ContextHandler2Helper const & rParent, Color& rColor ) : + FillPropertiesContext( rParent, *this ), + mrColor( rColor ) +{ +} + +SimpleFillPropertiesContext::~SimpleFillPropertiesContext() +{ + mrColor = getBestSolidColor(); +} + +BlipExtensionContext::BlipExtensionContext(ContextHandler2Helper const & rParent, BlipFillProperties& rBlipProps, model::BlipFill* pBlipFill) + : ContextHandler2(rParent) + , mrBlipProps(rBlipProps) + , mpBlipFill(pBlipFill) +{ +} + +BlipExtensionContext::~BlipExtensionContext() +{ +} + +ContextHandlerRef BlipExtensionContext::onCreateContext(sal_Int32 nElement, const AttributeList& rAttribs) +{ + switch( nElement ) + { + case A_TOKEN(ext): + return new BlipExtensionContext(*this, mrBlipProps, mpBlipFill); + + case OOX_TOKEN(a14, imgProps): + return new ArtisticEffectContext(*this, mrBlipProps.maEffect); + + // Import the SVG Blip + case OOX_TOKEN(asvg, svgBlip): + { + if (rAttribs.hasAttribute(R_TOKEN(embed))) + { + OUString aFragmentPath = getFragmentPathFromRelId(rAttribs.getStringDefaulted(R_TOKEN(embed))); + if (!aFragmentPath.isEmpty()) + { + // Read the graphic from the fragment path + auto xGraphic = getFilter().getGraphicHelper().importEmbeddedGraphic(aFragmentPath); + + // Overwrite the fill graphic with the one contining SVG + mrBlipProps.mxFillGraphic = xGraphic; + if (mpBlipFill) + mpBlipFill->mxGraphic = xGraphic; + } + } + // TODO - link + } + break; + } + return nullptr; +} + +ArtisticEffectContext::ArtisticEffectContext( ContextHandler2Helper const & rParent, ArtisticEffectProperties& rEffect ) : + ContextHandler2( rParent ), + maEffect( rEffect ) +{ +} + +ArtisticEffectContext::~ArtisticEffectContext() +{ +} + +ContextHandlerRef ArtisticEffectContext::onCreateContext( + sal_Int32 nElement, const AttributeList& rAttribs ) +{ + // containers + if( nElement == OOX_TOKEN( a14, imgLayer ) ) + { + if( rAttribs.hasAttribute( R_TOKEN( embed ) ) ) + { + OUString aFragmentPath = getFragmentPathFromRelId( rAttribs.getStringDefaulted( R_TOKEN( embed )) ); + if( !aFragmentPath.isEmpty() ) + { + getFilter().importBinaryData( maEffect.mrOleObjectInfo.maEmbeddedData, aFragmentPath ); + maEffect.mrOleObjectInfo.maProgId = aFragmentPath; + } + } + return new ArtisticEffectContext( *this, maEffect ); + } + if( nElement == OOX_TOKEN( a14, imgEffect ) ) + return new ArtisticEffectContext( *this, maEffect ); + + // effects + maEffect.msName = ArtisticEffectProperties::getEffectString( nElement ); + if( maEffect.isEmpty() ) + return nullptr; + + // effect attributes + sal_Int32 const aAttribs[19] = { + XML_visible, XML_trans, XML_crackSpacing, XML_pressure, XML_numberOfShades, + XML_grainSize, XML_intensity, XML_smoothness, XML_gridSize, XML_pencilSize, + XML_size, XML_brushSize, XML_scaling, XML_detail, XML_bright, XML_contrast, + XML_colorTemp, XML_sat, XML_amount + }; + for(sal_Int32 nAttrib : aAttribs) + { + if( rAttribs.hasAttribute( nAttrib ) ) + { + OUString sName = ArtisticEffectProperties::getEffectString( nAttrib ); + if( !sName.isEmpty() ) + maEffect.maAttribs[sName] <<= rAttribs.getInteger( nAttrib, 0 ); + } + } + + return nullptr; +} + +} // namespace oox::drawingml + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |