include/xmloff/txtprmap.hxx | 7 +- sw/qa/extras/globalfilter/globalfilter.cxx | 80 +++++++++++++++++++++++++++++ vcl/source/gdi/dibtools.cxx | 25 ++++++--- xmloff/source/text/txtexppr.cxx | 10 +++ xmloff/source/text/txtprmap.cxx | 4 - 5 files changed, 114 insertions(+), 12 deletions(-)
New commits: commit e2383402d4cab93f4003e03912700a00525b7d4c Author: Michael Stahl <[email protected]> Date: Tue Feb 2 14:10:02 2016 +0100 xmloff: tdf#96147: ODF export: fix duplicate fo:background-color ... attributes that happen if both CharHighlight and CharBackColor properties are used, because the CharBackTransparent property wasn't taken into account, and combining the CharBackColor and CharBackTransparent properties happens *after* XMLTextExportPropertySetMapper::ContextFilter() runs. Also, it looks like a transparent highlight wouldn't export properly but apparently DomainMapper::getColorFromId() won't create such. (regression from f880962f5bf26bfaef06bd3f9e67e2d901a2e74c) Change-Id: Ib628ef8bb377482f74fadb97c81afb95fbbf7184 (cherry picked from commit 8dadefc35f8b33648fb6adbdaca75ea52b2705db) Reviewed-on: https://gerrit.libreoffice.org/22042 Tested-by: Jenkins <[email protected]> Reviewed-by: Miklos Vajna <[email protected]> diff --git a/include/xmloff/txtprmap.hxx b/include/xmloff/txtprmap.hxx index 5fa8e3c..79baf8b 100644 --- a/include/xmloff/txtprmap.hxx +++ b/include/xmloff/txtprmap.hxx @@ -197,9 +197,10 @@ #define CTF_RELWIDTHREL (XML_TEXT_CTF_START + 168) #define CTF_RELHEIGHTREL (XML_TEXT_CTF_START + 169) #define CTF_CHAR_BACKGROUND (XML_TEXT_CTF_START + 170) -#define CTF_CHAR_HIGHLIGHT (XML_TEXT_CTF_START + 171) -#define CTF_FILLSTYLE (XML_TEXT_CTF_START + 172) -#define CTF_FILLCOLOR (XML_TEXT_CTF_START + 173) +#define CTF_CHAR_BACKGROUND_TRANSPARENCY (XML_TEXT_CTF_START + 171) +#define CTF_CHAR_HIGHLIGHT (XML_TEXT_CTF_START + 172) +#define CTF_FILLSTYLE (XML_TEXT_CTF_START + 173) +#define CTF_FILLCOLOR (XML_TEXT_CTF_START + 174) enum class TextPropMap { diff --git a/sw/qa/extras/globalfilter/globalfilter.cxx b/sw/qa/extras/globalfilter/globalfilter.cxx index 1871c61..751f2a5 100644 --- a/sw/qa/extras/globalfilter/globalfilter.cxx +++ b/sw/qa/extras/globalfilter/globalfilter.cxx @@ -30,6 +30,7 @@ public: void testImageWithSpecialID(); void testGraphicShape(); void testCharHighlight(); + void testCharHighlightODF(); void testCharHighlightBody(); void testMSCharBackgroundEditing(); void testCharBackgroundToHighlighting(); @@ -43,6 +44,7 @@ public: CPPUNIT_TEST(testImageWithSpecialID); CPPUNIT_TEST(testGraphicShape); CPPUNIT_TEST(testCharHighlight); + CPPUNIT_TEST(testCharHighlightODF); CPPUNIT_TEST(testMSCharBackgroundEditing); CPPUNIT_TEST(testCharBackgroundToHighlighting); #if !defined(WNT) @@ -473,6 +475,84 @@ void Test::testCharHighlight() testCharHighlightBody(); } +void Test::testCharHighlightODF() +{ + mxComponent = loadFromDesktop(getURLFromSrc("/sw/qa/extras/globalfilter/data/char_background_editing.docx"), + "com.sun.star.text.TextDocument"); + + // don't check import, testMSCharBackgroundEditing already does that + + uno::Reference<text::XTextRange> xPara = getParagraph(1); + for (int i = 1; i <= 4; ++i) + { + uno::Reference<beans::XPropertySet> xRun(getRun(xPara,i), uno::UNO_QUERY); + switch (i) + { + case 1: // non-transparent highlight + xRun->setPropertyValue("CharBackColor", uno::makeAny(static_cast<sal_Int32>(128))); + xRun->setPropertyValue("CharBackTransparent", uno::makeAny(true)); + xRun->setPropertyValue("CharHighlight", uno::makeAny(static_cast<sal_Int32>(64))); + break; + + case 2: // transparent backcolor + xRun->setPropertyValue("CharBackColor", uno::makeAny(static_cast<sal_Int32>(128))); + xRun->setPropertyValue("CharBackTransparent", uno::makeAny(true)); + xRun->setPropertyValue("CharHighlight", uno::makeAny(static_cast<sal_Int32>(COL_TRANSPARENT))); + break; + + case 3: // non-transparent backcolor + xRun->setPropertyValue("CharBackColor", uno::makeAny(static_cast<sal_Int32>(128))); + xRun->setPropertyValue("CharBackTransparent", uno::makeAny(false)); + xRun->setPropertyValue("CharHighlight", uno::makeAny(static_cast<sal_Int32>(COL_TRANSPARENT))); + break; + + case 4: // non-transparent highlight again + xRun->setPropertyValue("CharBackColor", uno::makeAny(static_cast<sal_Int32>(128))); + xRun->setPropertyValue("CharBackTransparent", uno::makeAny(false)); + xRun->setPropertyValue("CharHighlight", uno::makeAny(static_cast<sal_Int32>(64))); + break; + } + } + + uno::Reference<frame::XStorable> xStorable(mxComponent, uno::UNO_QUERY); + utl::MediaDescriptor aMediaDescriptor; + aMediaDescriptor["FilterName"] <<= OUString::createFromAscii("writer8"); + + utl::TempFile aTempFile; + aTempFile.EnableKillingFile(); + xStorable->storeToURL(aTempFile.GetURL(), aMediaDescriptor.getAsConstPropertyValueList()); + + uno::Reference< lang::XComponent > xComponent(xStorable, uno::UNO_QUERY); + xComponent->dispose(); + mxComponent = loadFromDesktop(aTempFile.GetURL(), "com.sun.star.text.TextDocument"); + + xPara.set(getParagraph(1)); + for (int i = 1; i <= 4; ++i) + { + uno::Reference<beans::XPropertySet> xRun(getRun(xPara,i), uno::UNO_QUERY); + CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(COL_TRANSPARENT), getProperty<sal_Int32>(xRun, "CharHighlight")); + switch (i) + { + case 1: // non-transparent highlight + CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(64), getProperty<sal_Int32>(xRun, "CharBackColor")); + CPPUNIT_ASSERT_EQUAL(sal_False, getProperty<sal_Bool>(xRun, "CharBackTransparent")); + break; + case 2: // transparent backcolor + CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(COL_TRANSPARENT), getProperty<sal_Int32>(xRun, "CharBackColor")); + CPPUNIT_ASSERT_EQUAL(sal_True, getProperty<sal_Bool>(xRun, "CharBackTransparent")); + break; + case 3: // non-transparent backcolor + CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(128), getProperty<sal_Int32>(xRun, "CharBackColor")); + CPPUNIT_ASSERT_EQUAL(sal_False, getProperty<sal_Bool>(xRun, "CharBackTransparent")); + break; + case 4: // non-transparent highlight again + CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(64), getProperty<sal_Int32>(xRun, "CharBackColor")); + CPPUNIT_ASSERT_EQUAL(sal_False, getProperty<sal_Bool>(xRun, "CharBackTransparent")); + break; + } + } +} + void Test::testMSCharBackgroundEditing() { // Simulate the editing process of imported MSO character background attributes diff --git a/xmloff/source/text/txtexppr.cxx b/xmloff/source/text/txtexppr.cxx index 35a6300..6192bcf 100644 --- a/xmloff/source/text/txtexppr.cxx +++ b/xmloff/source/text/txtexppr.cxx @@ -669,6 +669,7 @@ void XMLTextExportPropertySetMapper::ContextFilter( // character background and highlight XMLPropertyState* pCharBackground = nullptr; + XMLPropertyState* pCharBackgroundTransparency = nullptr; XMLPropertyState* pCharHighlight = nullptr; bool bNeedsAnchor = false; @@ -831,6 +832,7 @@ void XMLTextExportPropertySetMapper::ContextFilter( break; case CTF_CHAR_BACKGROUND: pCharBackground = propertyState; break; + case CTF_CHAR_BACKGROUND_TRANSPARENCY: pCharBackgroundTransparency = propertyState; break; case CTF_CHAR_HIGHLIGHT: pCharHighlight = propertyState; break; } } @@ -1137,12 +1139,20 @@ void XMLTextExportPropertySetMapper::ContextFilter( // When both background attributes are available export the visible one if( pCharHighlight && pCharBackground ) { + assert(pCharBackgroundTransparency); // always together sal_uInt32 nColor = COL_TRANSPARENT; pCharHighlight->maValue >>= nColor; if( nColor == COL_TRANSPARENT ) + { + // actually this would not be exported as transparent anyway + // and we'd need another property CharHighlightTransparent for that pCharHighlight->mnIndex = -1; + } else + { pCharBackground->mnIndex = -1; + pCharBackgroundTransparency->mnIndex = -1; + } } SvXMLExportPropertyMapper::ContextFilter(bEnableFoFontFamily, rProperties, rPropSet); diff --git a/xmloff/source/text/txtprmap.cxx b/xmloff/source/text/txtprmap.cxx index 2cc88b1..2d27282 100644 --- a/xmloff/source/text/txtprmap.cxx +++ b/xmloff/source/text/txtprmap.cxx @@ -192,7 +192,7 @@ XMLPropertyMapEntry aXMLParaPropMap[] = // TODO: not used? // RES_CHRATR_BACKGROUND MT_E( "CharBackColor", FO, BACKGROUND_COLOR, XML_TYPE_COLORTRANSPARENT|MID_FLAG_MULTI_PROPERTY, CTF_CHAR_BACKGROUND ), - MT_E( "CharBackTransparent", FO, BACKGROUND_COLOR, XML_TYPE_ISTRANSPARENT|MID_FLAG_MERGE_ATTRIBUTE, 0 ), + MT_E( "CharBackTransparent", FO, BACKGROUND_COLOR, XML_TYPE_ISTRANSPARENT|MID_FLAG_MERGE_ATTRIBUTE, CTF_CHAR_BACKGROUND_TRANSPARENCY), MT_E( "CharBackColor", FO, TEXT_BACKGROUND_COLOR, XML_TYPE_COLOR|MID_FLAG_SPECIAL_ITEM_EXPORT, CTF_OLDTEXTBACKGROUND ), // RES_CHRATR_CJK_FONT MT_ED( "CharFontNameAsian", STYLE, FONT_NAME_ASIAN, XML_TYPE_STRING|MID_FLAG_SPECIAL_ITEM_IMPORT, CTF_FONTNAME_CJK ), @@ -535,7 +535,7 @@ XMLPropertyMapEntry aXMLTextPropMap[] = // TODO: not used? // RES_CHRATR_BACKGROUND MT_E( "CharBackColor", FO, BACKGROUND_COLOR, XML_TYPE_COLORTRANSPARENT|MID_FLAG_MULTI_PROPERTY, CTF_CHAR_BACKGROUND ), - MT_E( "CharBackTransparent", FO, BACKGROUND_COLOR, XML_TYPE_ISTRANSPARENT|MID_FLAG_MERGE_ATTRIBUTE, 0 ), + MT_E( "CharBackTransparent", FO, BACKGROUND_COLOR, XML_TYPE_ISTRANSPARENT|MID_FLAG_MERGE_ATTRIBUTE, CTF_CHAR_BACKGROUND_TRANSPARENCY), { "CharShadingValue", sizeof("CharShadingValue")-1, XML_NAMESPACE_LO_EXT, XML_CHAR_SHADING_VALUE, XML_TYPE_NUMBER|XML_TYPE_PROP_TEXT, 0, SvtSaveOptions::ODFVER_012_EXT_COMPAT, false }, MT_E( "CharBackColor", FO, TEXT_BACKGROUND_COLOR, XML_TYPE_COLOR|MID_FLAG_SPECIAL_ITEM_EXPORT, CTF_OLDTEXTBACKGROUND ), // RES_CHRATR_CJK_FONT commit 9f9d679e72ca473c39ae31a284f85dd7a17e1ca3 Author: David Tardon <[email protected]> Date: Fri Jan 22 19:25:12 2016 +0100 iat least partially sanitize image dimensions ... to avoid enormous allocations later. (cherry picked from commit 93ca0057d6eca140764de446ba9b7d4128e88205) Change-Id: Id178a17d2b901b7f59eab43c7d0f0074518b6c32 Reviewed-on: https://gerrit.libreoffice.org/21790 Tested-by: Jenkins <[email protected]> Reviewed-by: Miklos Vajna <[email protected]> diff --git a/vcl/source/gdi/dibtools.cxx b/vcl/source/gdi/dibtools.cxx index 46305a5..96f5c32 100644 --- a/vcl/source/gdi/dibtools.cxx +++ b/vcl/source/gdi/dibtools.cxx @@ -469,13 +469,8 @@ bool ImplDecodeRLE( sal_uInt8* pBuffer, DIBV5Header& rHeader, BitmapWriteAccess& return true; } -bool ImplReadDIBBits(SvStream& rIStm, DIBV5Header& rHeader, BitmapWriteAccess& rAcc, BitmapWriteAccess* pAccAlpha, bool bTopDown, bool& rAlphaUsed) +bool ImplReadDIBBits(SvStream& rIStm, DIBV5Header& rHeader, BitmapWriteAccess& rAcc, BitmapWriteAccess* pAccAlpha, bool bTopDown, bool& rAlphaUsed, const sal_uInt64 nAlignedWidth) { - const sal_Int64 nBitsPerLine (static_cast<sal_Int64>(rHeader.nWidth) * static_cast<sal_Int64>(rHeader.nBitCount)); - if (nBitsPerLine > SAL_MAX_UINT32) - return false; - - const sal_uLong nAlignedWidth = AlignedWidth4Bytes(static_cast<sal_uLong>(nBitsPerLine)); sal_uInt32 nRMask(( rHeader.nBitCount == 16 ) ? 0x00007c00UL : 0x00ff0000UL); sal_uInt32 nGMask(( rHeader.nBitCount == 16 ) ? 0x000003e0UL : 0x0000ff00UL); sal_uInt32 nBMask(( rHeader.nBitCount == 16 ) ? 0x0000001fUL : 0x000000ffUL); @@ -849,6 +844,21 @@ bool ImplReadDIBBody( SvStream& rIStm, Bitmap& rBmp, AlphaMask* pBmpAlpha, sal_u pIStm = &rIStm; } + const sal_Int64 nBitsPerLine (static_cast<sal_Int64>(aHeader.nWidth) * static_cast<sal_Int64>(aHeader.nBitCount)); + if (nBitsPerLine > SAL_MAX_UINT32) + return false; + const sal_uInt64 nAlignedWidth(AlignedWidth4Bytes(static_cast<sal_uLong>(nBitsPerLine))); + + // (partially) check the image dimensions to avoid potential large bitmap allocation if the input is damaged + if (aHeader.nCompression == ZCOMPRESS || aHeader.nCompression == COMPRESS_NONE) + { + sal_uInt64 nMaxWidth = pIStm->remainingSize(); + if (aHeader.nHeight != 0) + nMaxWidth /= aHeader.nHeight; + if (nMaxWidth < nAlignedWidth) + return false; + } + const Size aSizePixel(aHeader.nWidth, aHeader.nHeight); BitmapPalette aDummyPal; Bitmap aNewBmp(aSizePixel, nBitCount, &aDummyPal); @@ -885,6 +895,7 @@ bool ImplReadDIBBody( SvStream& rIStm, Bitmap& rBmp, AlphaMask* pBmpAlpha, sal_u aNewBmpAlpha = AlphaMask(aSizePixel); pAccAlpha = aNewBmpAlpha.AcquireWriteAccess(); } + // read palette if(nColors) { @@ -902,7 +913,7 @@ bool ImplReadDIBBody( SvStream& rIStm, Bitmap& rBmp, AlphaMask* pBmpAlpha, sal_u pIStm->SeekRel(nOffset - (pIStm->Tell() - nStmPos)); } - bRet = ImplReadDIBBits(*pIStm, aHeader, *pAcc, pAccAlpha, bTopDown, bAlphaUsed); + bRet = ImplReadDIBBits(*pIStm, aHeader, *pAcc, pAccAlpha, bTopDown, bAlphaUsed, nAlignedWidth); if(bRet && aHeader.nXPelsPerMeter && aHeader.nYPelsPerMeter) { _______________________________________________ Libreoffice-commits mailing list [email protected] http://lists.freedesktop.org/mailman/listinfo/libreoffice-commits
