diff --git a/include/docmodel/theme/FormatScheme.hxx b/include/docmodel/theme/FormatScheme.hxx index eb1eea3fbdca..4c72311de929 100644 --- a/include/docmodel/theme/FormatScheme.hxx +++ b/include/docmodel/theme/FormatScheme.hxx @@ -84,6 +84,8 @@ struct DOCMODEL_DLLPUBLIC RelativeRectangle sal_Int32 mnTop = 0; sal_Int32 mnRight = 0; sal_Int32 mnBottom = 0; + + bool isZero() const { return mnLeft == 0 && mnTop == 0 && mnRight == 0 && mnBottom == 0; } }; class DOCMODEL_DLLPUBLIC GradientFill : public Fill diff --git a/oox/source/export/ThemeExport.cxx b/oox/source/export/ThemeExport.cxx index e22d6c9f2caf..6a96eee51b24 100644 --- a/oox/source/export/ThemeExport.cxx +++ b/oox/source/export/ThemeExport.cxx @@ -13,6 +13,7 @@ #include #include #include +#include #include #include #include @@ -30,10 +31,19 @@ namespace void writeRelativeRectangle(sax_fastparser::FSHelperPtr pFS, sal_Int32 nToken, model::RelativeRectangle const& rRelativeRectangle) { - pFS->singleElementNS(XML_a, nToken, XML_l, OString::number(rRelativeRectangle.mnLeft), XML_t, - OString::number(rRelativeRectangle.mnTop), XML_r, - OString::number(rRelativeRectangle.mnRight), XML_b, - OString::number(rRelativeRectangle.mnBottom)); + // Only write non-0 offsets, 0 is the default in CT_RelativeRect + pFS->singleElementNS(XML_a, nToken, XML_l, + sax_fastparser::UseIf(OString::number(rRelativeRectangle.mnLeft), + rRelativeRectangle.mnLeft != 0), + XML_t, + sax_fastparser::UseIf(OString::number(rRelativeRectangle.mnTop), + rRelativeRectangle.mnTop != 0), + XML_r, + sax_fastparser::UseIf(OString::number(rRelativeRectangle.mnRight), + rRelativeRectangle.mnRight != 0), + XML_b, + sax_fastparser::UseIf(OString::number(rRelativeRectangle.mnBottom), + rRelativeRectangle.mnBottom != 0)); } } // end anonymous namespace @@ -98,8 +108,12 @@ void fillAttrList(rtl::Reference const& pAttr if (!rThemeFont.maPanose.isEmpty()) pAttrList->add(XML_panose, rThemeFont.maPanose); - pAttrList->add(XML_pitchFamily, OString::number(rThemeFont.getPitchFamily())); - pAttrList->add(XML_charset, OString::number(rThemeFont.maCharset)); + // CT_TextFont gives pitchFamily a default of 0 and + // charset a default of 1 (=WINDOWS_CHARSET_DEFAULT), skip writing the defaults + if (rThemeFont.getPitchFamily() != 0) + pAttrList->add(XML_pitchFamily, OString::number(rThemeFont.getPitchFamily())); + if (rThemeFont.maCharset != WINDOWS_CHARSET_DEFAULT) + pAttrList->add(XML_charset, OString::number(rThemeFont.maCharset)); } } // end anonymous ns @@ -387,11 +401,16 @@ void ThemeExport::writeGradientFill(model::GradientFill const& rGradientFill) if (!sPathType.isEmpty()) { mpFS->startElementNS(XML_a, XML_path, XML_path, sPathType); + // The fillToRect element is always written, because a missing one defaults to offsets + // of 50%, not 0 ([MS-OI29500] Part 1 Section 20.1.8) writeRelativeRectangle(mpFS, XML_fillToRect, rGradientFill.maFillToRectangle); mpFS->endElementNS(XML_a, XML_path); } } - writeRelativeRectangle(mpFS, XML_tileRect, rGradientFill.maTileRectangle); + // A missing tileRect means offsets of 0 ([MS-OI29500] Part 1 Section 20.1.8), + // so an all-zero one can be omitted + if (!rGradientFill.maTileRectangle.isZero()) + writeRelativeRectangle(mpFS, XML_tileRect, rGradientFill.maTileRectangle); mpFS->endElementNS(XML_a, XML_gradFill); } @@ -646,7 +665,9 @@ void ThemeExport::writeBlipFill(model::BlipFill const& rBlipFill) writeBlip(rBlipFill); - writeRelativeRectangle(mpFS, XML_srcRect, rBlipFill.maClipRectangle); + // A missing srcRect means no cropping, so an all-zero one can be omitted + if (!rBlipFill.maClipRectangle.isZero()) + writeRelativeRectangle(mpFS, XML_srcRect, rBlipFill.maClipRectangle); if (rBlipFill.meMode == model::BitmapMode::Tile) { @@ -662,9 +683,18 @@ void ThemeExport::writeBlipFill(model::BlipFill const& rBlipFill) } else if (rBlipFill.meMode == model::BitmapMode::Stretch) { - mpFS->startElementNS(XML_a, XML_stretch); - writeRelativeRectangle(mpFS, XML_fillRect, rBlipFill.maFillRectangle); - mpFS->endElementNS(XML_a, XML_stretch); + // A missing fillRect means offsets of 0 ([MS-OI29500] Part 1 Section 20.1.8), + // so an all-zero one can be omitted + if (rBlipFill.maFillRectangle.isZero()) + { + mpFS->singleElementNS(XML_a, XML_stretch); + } + else + { + mpFS->startElementNS(XML_a, XML_stretch); + writeRelativeRectangle(mpFS, XML_fillRect, rBlipFill.maFillRectangle); + mpFS->endElementNS(XML_a, XML_stretch); + } } mpFS->endElementNS(XML_a, XML_blipFill);