oox: add support for theme import and export of blip effects
This adds support for (most) blip effects import, export and the document model. Change-Id: Iec15f4de22c31268019fa1a60432e40ae8f03635 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/150262 Tested-by: Jenkins Reviewed-by: Tomaž Vajngerl <quikee@gmail.com>
This commit is contained in:
committed by
Tomaž Vajngerl
parent
b09c377888
commit
6252959192
@@ -311,12 +311,49 @@ enum class RectangleAlignment
|
||||
constexpr sal_uInt16 RECTANGLE_ALIGNMENT_COUNT
|
||||
= static_cast<sal_uInt16>(RectangleAlignment::BottomRight) + 1;
|
||||
|
||||
enum class ColorEffectType
|
||||
enum class BlipEffectType
|
||||
{
|
||||
None,
|
||||
AlphaBiLevel,
|
||||
AlphaCeiling,
|
||||
AlphaFloor,
|
||||
AlphaInverse,
|
||||
AlphaModulate,
|
||||
AlphaModulateFixed,
|
||||
AlphaReplace,
|
||||
BiLevel,
|
||||
Blur,
|
||||
ColorChange,
|
||||
ColorReplace,
|
||||
DuoTone,
|
||||
FillOverlay,
|
||||
Grayscale,
|
||||
ColorChange
|
||||
HSL,
|
||||
Luminance,
|
||||
Tint,
|
||||
};
|
||||
|
||||
class BlipEffect
|
||||
{
|
||||
public:
|
||||
BlipEffectType meType = BlipEffectType::None;
|
||||
|
||||
sal_Int32 mnThreshold = 0; // AlphaBiLevel, BiLevel
|
||||
ColorDefinition maColor1; // AlphaInverse, ColorReplace, DuoTone, ColorChange (from)
|
||||
ColorDefinition maColor2; // DuoTone, ColorChange (to)
|
||||
sal_Int32 mnAmount = 0; // AlphaModulateFixed, Tint
|
||||
sal_Int32 mnRadius = 0; // Blur
|
||||
bool mbGrow = false; // Blur
|
||||
sal_Int32 mnAlpha = 0; // AlphaReplace
|
||||
bool mbUseAlpha = false; // ColorChange
|
||||
sal_Int32 mnHue = 0; // HSL, Tint
|
||||
sal_Int32 mnSaturation = 0; // HSL
|
||||
sal_Int32 mnLuminance = 0; // HSL
|
||||
sal_Int32 mnBrightness = 0; // Luminance
|
||||
sal_Int32 mnContrast = 0; // Luminance
|
||||
|
||||
ColorDefinition& getColorFrom() { return maColor1; }
|
||||
ColorDefinition& getColorTo() { return maColor2; }
|
||||
};
|
||||
|
||||
class DOCMODEL_DLLPUBLIC BlipFill : public Fill
|
||||
@@ -335,13 +372,7 @@ public:
|
||||
RectangleAlignment meTileAlignment = RectangleAlignment::TopLeft;
|
||||
|
||||
css::uno::Reference<css::graphic::XGraphic> mxGraphic;
|
||||
|
||||
ColorEffectType meColorEffectType = ColorEffectType::None;
|
||||
|
||||
sal_Int32 mnBiLevelThreshold = 0;
|
||||
ColorDefinition maColorFrom;
|
||||
ColorDefinition maColorTo;
|
||||
bool mbUseAlpha = false;
|
||||
std::vector<BlipEffect> maBlipEffects;
|
||||
|
||||
BlipFill()
|
||||
: Fill(FillType::Blip)
|
||||
|
||||
@@ -264,7 +264,7 @@ public:
|
||||
{}
|
||||
|
||||
OUString writeToStorage(Graphic const& rGraphic, bool bRelPathToMedia = false);
|
||||
OUString writeBlip(Graphic const& rGraphic , bool bRelPathToMedia = false);
|
||||
OUString writeBlip(Graphic const& rGraphic, std::vector<model::BlipEffect> const& rEffects, bool bRelPathToMedia = false);
|
||||
};
|
||||
|
||||
class OOX_DLLPUBLIC DrawingML
|
||||
|
||||
@@ -253,8 +253,9 @@ ColorChangeContext::ColorChangeContext( ContextHandler2Helper const & rParent,
|
||||
mbUseAlpha = rAttribs.getBool( XML_useA, true );
|
||||
if (mpBlipFill)
|
||||
{
|
||||
mpBlipFill->meColorEffectType = model::ColorEffectType::ColorChange;
|
||||
mpBlipFill->mbUseAlpha = mbUseAlpha;
|
||||
auto& rEffect = mpBlipFill->maBlipEffects.emplace_back();
|
||||
rEffect.meType = model::BlipEffectType::ColorChange;
|
||||
rEffect.mbUseAlpha = mbUseAlpha;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -272,11 +273,17 @@ ContextHandlerRef ColorChangeContext::onCreateContext(
|
||||
{
|
||||
case A_TOKEN(clrFrom):
|
||||
if (mpBlipFill)
|
||||
pColorDefinition = &mpBlipFill->maColorFrom;
|
||||
{
|
||||
auto& rEffect = mpBlipFill->maBlipEffects.back();
|
||||
pColorDefinition = &rEffect.getColorFrom();
|
||||
}
|
||||
return new ColorContext(*this, mrBlipProps.maColorChangeFrom, pColorDefinition);
|
||||
case A_TOKEN(clrTo):
|
||||
if (mpBlipFill)
|
||||
pColorDefinition = &mpBlipFill->maColorTo;
|
||||
{
|
||||
auto& rEffect = mpBlipFill->maBlipEffects.back();
|
||||
pColorDefinition = &rEffect.getColorTo();
|
||||
}
|
||||
return new ColorContext(*this, mrBlipProps.maColorChangeTo, pColorDefinition);
|
||||
}
|
||||
return nullptr;
|
||||
@@ -325,12 +332,16 @@ ContextHandlerRef BlipContext::onCreateContext(
|
||||
{
|
||||
case A_TOKEN( biLevel ):
|
||||
{
|
||||
mrBlipProps.moBiLevelThreshold = rAttribs.getInteger( XML_thresh );
|
||||
sal_Int32 nTreshold = rAttribs.getInteger(XML_thresh, 0);
|
||||
|
||||
mrBlipProps.moBiLevelThreshold = nTreshold;
|
||||
mrBlipProps.moColorEffect = getBaseToken(nElement);
|
||||
|
||||
if (mpBlipFill)
|
||||
{
|
||||
mpBlipFill->meColorEffectType = model::ColorEffectType::BiLevel;
|
||||
mpBlipFill->mnBiLevelThreshold = rAttribs.getInteger(XML_thresh, 0);
|
||||
auto& rEffect = mpBlipFill->maBlipEffects.emplace_back();
|
||||
rEffect.meType = model::BlipEffectType::BiLevel;
|
||||
rEffect.mnThreshold = nTreshold;
|
||||
}
|
||||
}
|
||||
break;
|
||||
@@ -340,7 +351,8 @@ ContextHandlerRef BlipContext::onCreateContext(
|
||||
mrBlipProps.moColorEffect = getBaseToken( nElement );
|
||||
if (mpBlipFill)
|
||||
{
|
||||
mpBlipFill->meColorEffectType = model::ColorEffectType::Grayscale;
|
||||
auto& rEffect = mpBlipFill->maBlipEffects.emplace_back();
|
||||
rEffect.meType = model::BlipEffectType::Grayscale;
|
||||
}
|
||||
}
|
||||
break;
|
||||
@@ -360,11 +372,25 @@ ContextHandlerRef BlipContext::onCreateContext(
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -581,13 +581,13 @@ OString convertRectangleAlignment(model::RectangleAlignment eFlipMode)
|
||||
}
|
||||
} // end anonymous ns
|
||||
|
||||
void ThemeExport::writeBlip(model::BlipFill const& rBlipFil)
|
||||
void ThemeExport::writeBlip(model::BlipFill const& rBlipFill)
|
||||
{
|
||||
if (!rBlipFil.mxGraphic.is())
|
||||
if (!rBlipFill.mxGraphic.is())
|
||||
return;
|
||||
oox::drawingml::GraphicExport aExporter(mpFS, mpFilterBase, meDocumentType);
|
||||
Graphic aGraphic(rBlipFil.mxGraphic);
|
||||
aExporter.writeBlip(aGraphic, false);
|
||||
Graphic aGraphic(rBlipFill.mxGraphic);
|
||||
aExporter.writeBlip(aGraphic, rBlipFill.maBlipEffects, false);
|
||||
}
|
||||
|
||||
void ThemeExport::writeBlipFill(model::BlipFill const& rBlipFill)
|
||||
|
||||
@@ -1475,7 +1475,7 @@ const char* DrawingML::GetRelationCompPrefix() const
|
||||
return getRelationCompPrefix(meDocumentType);
|
||||
}
|
||||
|
||||
OUString GraphicExport::writeBlip(Graphic const& rGraphic , bool bRelPathToMedia)
|
||||
OUString GraphicExport::writeBlip(Graphic const& rGraphic, std::vector<model::BlipEffect> const& rEffects, bool bRelPathToMedia)
|
||||
{
|
||||
OUString sRelId;
|
||||
|
||||
@@ -1483,8 +1483,114 @@ OUString GraphicExport::writeBlip(Graphic const& rGraphic , bool bRelPathToMedia
|
||||
|
||||
mpFS->startElementNS(XML_a, XML_blip, FSNS(XML_r, XML_embed), sRelId);
|
||||
|
||||
//WriteImageBrightnessContrastTransparence(rXPropSet);
|
||||
//WriteArtisticEffect(rXPropSet);
|
||||
for (auto const& rEffect : rEffects)
|
||||
{
|
||||
switch (rEffect.meType)
|
||||
{
|
||||
case model::BlipEffectType::AlphaBiLevel:
|
||||
{
|
||||
mpFS->singleElementNS(XML_a, XML_alphaBiLevel, XML_thresh, OString::number(rEffect.mnThreshold));
|
||||
}
|
||||
break;
|
||||
case model::BlipEffectType::AlphaCeiling:
|
||||
{
|
||||
mpFS->singleElementNS(XML_a, XML_alphaCeiling);
|
||||
}
|
||||
break;
|
||||
case model::BlipEffectType::AlphaFloor:
|
||||
{
|
||||
mpFS->singleElementNS(XML_a, XML_alphaFloor);
|
||||
}
|
||||
break;
|
||||
case model::BlipEffectType::AlphaInverse:
|
||||
{
|
||||
mpFS->singleElementNS(XML_a, XML_alphaInv);
|
||||
// TODO: export rEffect.maColor1
|
||||
}
|
||||
break;
|
||||
case model::BlipEffectType::AlphaModulate:
|
||||
{
|
||||
mpFS->singleElementNS(XML_a, XML_alphaMod);
|
||||
// TODO
|
||||
}
|
||||
break;
|
||||
case model::BlipEffectType::AlphaModulateFixed:
|
||||
{
|
||||
mpFS->singleElementNS(XML_a, XML_alphaModFix, XML_amt, OString::number(rEffect.mnAmount));
|
||||
}
|
||||
break;
|
||||
case model::BlipEffectType::AlphaReplace:
|
||||
{
|
||||
mpFS->singleElementNS(XML_a, XML_alphaRepl, XML_a, OString::number(rEffect.mnAlpha));
|
||||
}
|
||||
break;
|
||||
case model::BlipEffectType::BiLevel:
|
||||
{
|
||||
mpFS->singleElementNS(XML_a, XML_biLevel, XML_thresh, OString::number(rEffect.mnThreshold));
|
||||
}
|
||||
break;
|
||||
case model::BlipEffectType::Blur:
|
||||
{
|
||||
mpFS->singleElementNS(XML_a, XML_blur,
|
||||
XML_rad, OString::number(rEffect.mnRadius),
|
||||
XML_grow, rEffect.mbGrow ? "1" : "0");
|
||||
}
|
||||
break;
|
||||
case model::BlipEffectType::ColorChange:
|
||||
{
|
||||
mpFS->startElementNS(XML_a, XML_clrChange, XML_useA, rEffect.mbUseAlpha ? "1" : "0");
|
||||
mpFS->endElementNS(XML_a, XML_clrChange);
|
||||
}
|
||||
break;
|
||||
case model::BlipEffectType::ColorReplace:
|
||||
{
|
||||
mpFS->startElementNS(XML_a, XML_clrRepl);
|
||||
mpFS->endElementNS(XML_a, XML_clrRepl);
|
||||
}
|
||||
break;
|
||||
case model::BlipEffectType::DuoTone:
|
||||
{
|
||||
mpFS->startElementNS(XML_a, XML_duotone);
|
||||
mpFS->endElementNS(XML_a, XML_duotone);
|
||||
}
|
||||
break;
|
||||
case model::BlipEffectType::FillOverlay:
|
||||
{
|
||||
mpFS->singleElementNS(XML_a, XML_fillOverlay);
|
||||
}
|
||||
break;
|
||||
case model::BlipEffectType::Grayscale:
|
||||
{
|
||||
mpFS->singleElementNS(XML_a, XML_grayscl);
|
||||
}
|
||||
break;
|
||||
case model::BlipEffectType::HSL:
|
||||
{
|
||||
mpFS->singleElementNS(XML_a, XML_hsl,
|
||||
XML_hue, OString::number(rEffect.mnHue),
|
||||
XML_sat, OString::number(rEffect.mnSaturation),
|
||||
XML_lum, OString::number(rEffect.mnLuminance));
|
||||
}
|
||||
break;
|
||||
case model::BlipEffectType::Luminance:
|
||||
{
|
||||
mpFS->singleElementNS(XML_a, XML_lum,
|
||||
XML_bright, OString::number(rEffect.mnBrightness),
|
||||
XML_contrast, OString::number(rEffect.mnContrast));
|
||||
}
|
||||
break;
|
||||
case model::BlipEffectType::Tint:
|
||||
{
|
||||
mpFS->singleElementNS(XML_a, XML_tint,
|
||||
XML_hue, OString::number(rEffect.mnHue),
|
||||
XML_amt, OString::number(rEffect.mnAmount));
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
mpFS->endElementNS(XML_a, XML_blip);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user