drawinglayer/source/tools/emfphelperdata.cxx | 267 ++++++++---------- drawinglayer/source/tools/primitive2dxmldump.cxx | 82 +++-- emfio/qa/cppunit/emf/EmfImportTest.cxx | 46 ++- emfio/qa/cppunit/emf/data/TestDrawStringWithBrush.emf |binary svgio/qa/cppunit/SvgImportTest.cxx | 4 svx/qa/unit/sdr.cxx | 8 svx/qa/unit/svdraw.cxx | 6 7 files changed, 216 insertions(+), 197 deletions(-)
New commits: commit 1eb828add814108d63ea61e38d948a0337fc4ee6 Author: Bartosz Kosiorek <gan...@poczta.onet.pl> AuthorDate: Wed Jun 23 16:55:21 2021 +0200 Commit: Xisco Fauli <xiscofa...@libreoffice.org> CommitDate: Thu Jun 24 10:30:30 2021 +0200 EMF+ tdf#142975 Add brush support to DrawString record Change-Id: Icfcb4199dcd755fb20e14a8166571b6d6e763f2e Reviewed-on: https://gerrit.libreoffice.org/c/core/+/117671 Tested-by: Jenkins Reviewed-by: Bartosz Kosiorek <gan...@poczta.onet.pl> (cherry picked from commit 9e8c35cc3f1f5e1c08afd46e0d0fbc07f1ff21f9) Reviewed-on: https://gerrit.libreoffice.org/c/core/+/117721 Reviewed-by: Xisco Fauli <xiscofa...@libreoffice.org> diff --git a/drawinglayer/source/tools/emfphelperdata.cxx b/drawinglayer/source/tools/emfphelperdata.cxx index 1f3143112320..e756b16ff70f 100644 --- a/drawinglayer/source/tools/emfphelperdata.cxx +++ b/drawinglayer/source/tools/emfphelperdata.cxx @@ -457,12 +457,14 @@ namespace emfplushelper color = Color(ColorAlpha, (brushIndexOrColor >> 24), (brushIndexOrColor >> 16) & 0xff, (brushIndexOrColor >> 8) & 0xff, brushIndexOrColor & 0xff); } - else // we use a pen + else // we use a brush { - const EMFPPen* pen = static_cast<EMFPPen*>(maEMFPObjects[brushIndexOrColor & 0xff].get()); - if (pen) + const EMFPBrush* brush = static_cast<EMFPBrush*>(maEMFPObjects[brushIndexOrColor & 0xff].get()); + if (brush) { - color = pen->GetColor(); + color = brush->GetColor(); + if (brush->type != BrushTypeSolidColor) + SAL_WARN("drawinglayer.emf", "EMF+\t\t TODO Brush other than solid color is not supported"); } } return color; @@ -1527,161 +1529,152 @@ namespace emfplushelper } case EmfPlusRecordTypeDrawString: { - sal_uInt32 brushId; - sal_uInt32 formatId; - sal_uInt32 stringLength; + sal_uInt32 brushId, formatId, stringLength; rMS.ReadUInt32(brushId).ReadUInt32(formatId).ReadUInt32(stringLength); SAL_INFO("drawinglayer.emf", "EMF+\t FontId: " << OUString::number(flags & 0xFF)); SAL_INFO("drawinglayer.emf", "EMF+\t BrushId: " << BrushIDToString(flags, brushId)); SAL_INFO("drawinglayer.emf", "EMF+\t FormatId: " << formatId); SAL_INFO("drawinglayer.emf", "EMF+\t Length: " << stringLength); - if (flags & 0x8000) + // read the layout rectangle + float lx, ly, lw, lh; + rMS.ReadFloat(lx).ReadFloat(ly).ReadFloat(lw).ReadFloat(lh); + + SAL_INFO("drawinglayer.emf", "EMF+\t DrawString layoutRect: " << lx << "," << ly << " - " << lw << "x" << lh); + // parse the string + const OUString text = read_uInt16s_ToOUString(rMS, stringLength); + SAL_INFO("drawinglayer.emf", "EMF+\t DrawString string: " << text); + // get the stringFormat from the Object table ( this is OPTIONAL and may be nullptr ) + const EMFPStringFormat *stringFormat = dynamic_cast<EMFPStringFormat*>(maEMFPObjects[formatId & 0xff].get()); + // get the font from the flags + const EMFPFont *font = static_cast< EMFPFont* >( maEMFPObjects[flags & 0xff].get() ); + if (!font) { - // read the layout rectangle - float lx, ly, lw, lh; - rMS.ReadFloat(lx).ReadFloat(ly).ReadFloat(lw).ReadFloat(lh); - - SAL_INFO("drawinglayer.emf", "EMF+\t DrawString layoutRect: " << lx << "," << ly << " - " << lw << "x" << lh); - // parse the string - const OUString text = read_uInt16s_ToOUString(rMS, stringLength); - SAL_INFO("drawinglayer.emf", "EMF+\t DrawString string: " << text); - // get the stringFormat from the Object table ( this is OPTIONAL and may be nullptr ) - const EMFPStringFormat *stringFormat = dynamic_cast<EMFPStringFormat*>(maEMFPObjects[formatId & 0xff].get()); - // get the font from the flags - const EMFPFont *font = static_cast< EMFPFont* >( maEMFPObjects[flags & 0xff].get() ); - if (!font) + break; + } + mrPropertyHolders.Current().setFont(vcl::Font(font->family, Size(font->emSize, font->emSize))); + + drawinglayer::attribute::FontAttribute fontAttribute( + font->family, // font family + "", // (no) font style + font->Bold() ? 8u : 1u, // weight: 8 = bold + font->family == "SYMBOL", // symbol + stringFormat && stringFormat->DirectionVertical(), // vertical + font->Italic(), // italic + false, // monospaced + false, // outline = false, no such thing in MS-EMFPLUS + stringFormat && stringFormat->DirectionRightToLeft(), // right-to-left + false); // BiDiStrong + + css::lang::Locale locale; + double stringAlignmentHorizontalOffset = 0.0; + if (stringFormat) + { + SAL_WARN_IF(stringFormat->DirectionRightToLeft(), "drawinglayer.emf", "EMF+\t DrawString Alignment TODO For a right-to-left layout rectangle, the origin should be at the upper right."); + if (stringFormat->stringAlignment == StringAlignmentNear) + // Alignment is to the left side of the layout rectangle (lx, ly, lw, lh) { - break; + stringAlignmentHorizontalOffset = stringFormat->leadingMargin * font->emSize; + } else if (stringFormat->stringAlignment == StringAlignmentCenter) + // Alignment is centered between the origin and extent of the layout rectangle + { + stringAlignmentHorizontalOffset = 0.5 * lw + stringFormat->leadingMargin * font->emSize - 0.3 * font->emSize * stringLength; + } else if (stringFormat->stringAlignment == StringAlignmentFar) + // Alignment is to the right side of the layout rectangle + { + stringAlignmentHorizontalOffset = lw - stringFormat->trailingMargin * font->emSize - 0.6 * font->emSize * stringLength; } - mrPropertyHolders.Current().setFont(vcl::Font(font->family, Size(font->emSize, font->emSize))); - drawinglayer::attribute::FontAttribute fontAttribute( - font->family, // font family - "", // (no) font style - font->Bold() ? 8u : 1u, // weight: 8 = bold - font->family == "SYMBOL", // symbol - stringFormat && stringFormat->DirectionVertical(), // vertical - font->Italic(), // italic - false, // monospaced - false, // outline = false, no such thing in MS-EMFPLUS - stringFormat && stringFormat->DirectionRightToLeft(), // right-to-left - false); // BiDiStrong - - css::lang::Locale locale; - double stringAlignmentHorizontalOffset = 0.0; - if (stringFormat) - { - SAL_WARN_IF(stringFormat->DirectionRightToLeft(), "drawinglayer.emf", "EMF+\t DrawString Alignment TODO For a right-to-left layout rectangle, the origin should be at the upper right."); - if (stringFormat->stringAlignment == StringAlignmentNear) - // Alignment is to the left side of the layout rectangle (lx, ly, lw, lh) - { - stringAlignmentHorizontalOffset = stringFormat->leadingMargin * font->emSize; - } else if (stringFormat->stringAlignment == StringAlignmentCenter) - // Alignment is centered between the origin and extent of the layout rectangle - { - stringAlignmentHorizontalOffset = 0.5 * lw + stringFormat->leadingMargin * font->emSize - 0.3 * font->emSize * stringLength; - } else if (stringFormat->stringAlignment == StringAlignmentFar) - // Alignment is to the right side of the layout rectangle - { - stringAlignmentHorizontalOffset = lw - stringFormat->trailingMargin * font->emSize - 0.6 * font->emSize * stringLength; - } + LanguageTag aLanguageTag(static_cast< LanguageType >(stringFormat->language)); + locale = aLanguageTag.getLocale(); + } + else + { + // By default LeadingMargin is 1/6 inch + // TODO for typographic fonts set value to 0. + stringAlignmentHorizontalOffset = 16.0; - LanguageTag aLanguageTag(static_cast< LanguageType >(stringFormat->language)); - locale = aLanguageTag.getLocale(); - } - else - { - // By default LeadingMargin is 1/6 inch - // TODO for typographic fonts set value to 0. - stringAlignmentHorizontalOffset = 16.0; + // use system default + locale = Application::GetSettings().GetLanguageTag().getLocale(); + } - // use system default - locale = Application::GetSettings().GetLanguageTag().getLocale(); - } + const basegfx::B2DHomMatrix transformMatrix = basegfx::utils::createScaleTranslateB2DHomMatrix( + ::basegfx::B2DSize(font->emSize, font->emSize), + ::basegfx::B2DPoint(lx + stringAlignmentHorizontalOffset, ly + font->emSize)); - const basegfx::B2DHomMatrix transformMatrix = basegfx::utils::createScaleTranslateB2DHomMatrix( - ::basegfx::B2DSize(font->emSize, font->emSize), - ::basegfx::B2DPoint(lx + stringAlignmentHorizontalOffset, ly + font->emSize)); + Color uncorrectedColor = EMFPGetBrushColorOrARGBColor(flags, brushId); + Color color; - Color uncorrectedColor = EMFPGetBrushColorOrARGBColor(flags, brushId); - Color color; + if (mbSetTextContrast) + { + const auto gammaVal = mnTextContrast / 1000; + const basegfx::BColorModifier_gamma gamma(gammaVal); + + // gamma correct transparency color + sal_uInt16 alpha = uncorrectedColor.GetAlpha(); + alpha = std::clamp(std::pow(alpha, 1.0 / gammaVal), 0.0, 1.0) * 255; + + basegfx::BColor modifiedColor(gamma.getModifiedColor(uncorrectedColor.getBColor())); + color.SetRed(modifiedColor.getRed() * 255); + color.SetGreen(modifiedColor.getGreen() * 255); + color.SetBlue(modifiedColor.getBlue() * 255); + color.SetAlpha(alpha); + } + else + { + color = uncorrectedColor; + } + + mrPropertyHolders.Current().setTextColor(color.getBColor()); + mrPropertyHolders.Current().setTextColorActive(true); - if (mbSetTextContrast) + if (color.GetAlpha() > 0) + { + std::vector<double> emptyVector; + rtl::Reference<drawinglayer::primitive2d::BasePrimitive2D> pBaseText; + if (font->Underline() || font->Strikeout()) { - const auto gammaVal = mnTextContrast / 1000; - const basegfx::BColorModifier_gamma gamma(gammaVal); - - // gamma correct transparency color - sal_uInt16 alpha = uncorrectedColor.GetAlpha(); - alpha = std::clamp(std::pow(alpha, 1.0 / gammaVal), 0.0, 1.0) * 255; - - basegfx::BColor modifiedColor(gamma.getModifiedColor(uncorrectedColor.getBColor())); - color.SetRed(modifiedColor.getRed() * 255); - color.SetGreen(modifiedColor.getGreen() * 255); - color.SetBlue(modifiedColor.getBlue() * 255); - color.SetAlpha(alpha); + pBaseText = new drawinglayer::primitive2d::TextDecoratedPortionPrimitive2D( + transformMatrix, + text, + 0, // text always starts at 0 + stringLength, + emptyVector, // EMF-PLUS has no DX-array + fontAttribute, + locale, + color.getBColor(), // Font Color + COL_TRANSPARENT, // Fill Color + color.getBColor(), // OverlineColor + color.getBColor(), // TextlineColor + drawinglayer::primitive2d::TEXT_LINE_NONE, + font->Underline() ? drawinglayer::primitive2d::TEXT_LINE_SINGLE : drawinglayer::primitive2d::TEXT_LINE_NONE, + false, + font->Strikeout() ? drawinglayer::primitive2d::TEXT_STRIKEOUT_SINGLE : drawinglayer::primitive2d::TEXT_STRIKEOUT_NONE); } else { - color = uncorrectedColor; + pBaseText = new drawinglayer::primitive2d::TextSimplePortionPrimitive2D( + transformMatrix, + text, + 0, // text always starts at 0 + stringLength, + emptyVector, // EMF-PLUS has no DX-array + fontAttribute, + locale, + color.getBColor()); } - - mrPropertyHolders.Current().setTextColor(color.getBColor()); - mrPropertyHolders.Current().setTextColorActive(true); - - if (color.GetAlpha() > 0) + drawinglayer::primitive2d::Primitive2DReference aPrimitiveText(pBaseText); + if (color.IsTransparent()) { - std::vector<double> emptyVector; - rtl::Reference<drawinglayer::primitive2d::BasePrimitive2D> pBaseText; - if (font->Underline() || font->Strikeout()) - { - pBaseText = new drawinglayer::primitive2d::TextDecoratedPortionPrimitive2D( - transformMatrix, - text, - 0, // text always starts at 0 - stringLength, - emptyVector, // EMF-PLUS has no DX-array - fontAttribute, - locale, - color.getBColor(), - COL_TRANSPARENT, - color.getBColor(), - color.getBColor(), - drawinglayer::primitive2d::TEXT_LINE_NONE, - font->Underline() ? drawinglayer::primitive2d::TEXT_LINE_SINGLE : drawinglayer::primitive2d::TEXT_LINE_NONE, - false, - font->Strikeout() ? drawinglayer::primitive2d::TEXT_STRIKEOUT_SINGLE : drawinglayer::primitive2d::TEXT_STRIKEOUT_NONE); - } - else - { - pBaseText = new drawinglayer::primitive2d::TextSimplePortionPrimitive2D( - transformMatrix, - text, - 0, // text always starts at 0 - stringLength, - emptyVector, // EMF-PLUS has no DX-array - fontAttribute, - locale, - color.getBColor()); - } - drawinglayer::primitive2d::Primitive2DReference aPrimitiveText(pBaseText); - if (color.IsTransparent()) - { - aPrimitiveText = new drawinglayer::primitive2d::UnifiedTransparencePrimitive2D( - drawinglayer::primitive2d::Primitive2DContainer { aPrimitiveText }, - (255 - color.GetAlpha()) / 255.0); - } - - mrTargetHolders.Current().append( - new drawinglayer::primitive2d::TransformPrimitive2D( - maMapTransform, - drawinglayer::primitive2d::Primitive2DContainer { aPrimitiveText } )); + aPrimitiveText = new drawinglayer::primitive2d::UnifiedTransparencePrimitive2D( + drawinglayer::primitive2d::Primitive2DContainer { aPrimitiveText }, + (255 - color.GetAlpha()) / 255.0); } - } - else - { - SAL_WARN("drawinglayer.emf", "EMF+\t DrawString TODO - drawing with brush not yet supported"); + + mrTargetHolders.Current().append( + new drawinglayer::primitive2d::TransformPrimitive2D( + maMapTransform, + drawinglayer::primitive2d::Primitive2DContainer { aPrimitiveText } )); } break; } diff --git a/drawinglayer/source/tools/primitive2dxmldump.cxx b/drawinglayer/source/tools/primitive2dxmldump.cxx index 9ed0e796fb01..4b0c47f41da0 100644 --- a/drawinglayer/source/tools/primitive2dxmldump.cxx +++ b/drawinglayer/source/tools/primitive2dxmldump.cxx @@ -25,6 +25,8 @@ #include <drawinglayer/primitive2d/PolyPolygonColorPrimitive2D.hxx> #include <drawinglayer/primitive2d/hiddengeometryprimitive2d.hxx> #include <drawinglayer/primitive2d/polygonprimitive2d.hxx> +#include <drawinglayer/primitive2d/textdecoratedprimitive2d.hxx> +#include <primitive2d/textlineprimitive2d.hxx> #include <drawinglayer/primitive2d/textprimitive2d.hxx> #include <drawinglayer/primitive2d/maskprimitive2d.hxx> #include <drawinglayer/primitive2d/unifiedtransparenceprimitive2d.hxx> @@ -56,6 +58,19 @@ OUString convertColorToString(const basegfx::BColor& rColor) return "#" + aRGBString; } +void writeMatrix(::tools::XmlWriter& rWriter, const basegfx::B2DHomMatrix& rMatrix) +{ + rWriter.attribute("xy11", rMatrix.get(0,0)); + rWriter.attribute("xy12", rMatrix.get(0,1)); + rWriter.attribute("xy13", rMatrix.get(0,2)); + rWriter.attribute("xy21", rMatrix.get(1,0)); + rWriter.attribute("xy22", rMatrix.get(1,1)); + rWriter.attribute("xy23", rMatrix.get(1,2)); + rWriter.attribute("xy31", rMatrix.get(2,0)); + rWriter.attribute("xy32", rMatrix.get(2,1)); + rWriter.attribute("xy33", rMatrix.get(2,2)); +} + void writePolyPolygon(::tools::XmlWriter& rWriter, const basegfx::B2DPolyPolygon& rB2DPolyPolygon) { rWriter.startElement("polypolygon"); @@ -211,17 +226,7 @@ void Primitive2dXmlDump::decomposeAndWrite( { const BitmapPrimitive2D& rBitmapPrimitive2D = dynamic_cast<const BitmapPrimitive2D&>(*pBasePrimitive); rWriter.startElement("bitmap"); - - basegfx::B2DHomMatrix const & rMatrix = rBitmapPrimitive2D.getTransform(); - rWriter.attribute("xy11", rMatrix.get(0,0)); - rWriter.attribute("xy12", rMatrix.get(0,1)); - rWriter.attribute("xy13", rMatrix.get(0,2)); - rWriter.attribute("xy21", rMatrix.get(1,0)); - rWriter.attribute("xy22", rMatrix.get(1,1)); - rWriter.attribute("xy23", rMatrix.get(1,2)); - rWriter.attribute("xy31", rMatrix.get(2,0)); - rWriter.attribute("xy32", rMatrix.get(2,1)); - rWriter.attribute("xy33", rMatrix.get(2,2)); + writeMatrix(rWriter, rBitmapPrimitive2D.getTransform()); const BitmapEx aBitmapEx(VCLUnoHelper::GetBitmap(rBitmapPrimitive2D.getXBitmap())); const Size& rSizePixel(aBitmapEx.GetSizePixel()); @@ -260,18 +265,7 @@ void Primitive2dXmlDump::decomposeAndWrite( { const TransformPrimitive2D& rTransformPrimitive2D = dynamic_cast<const TransformPrimitive2D&>(*pBasePrimitive); rWriter.startElement("transform"); - - basegfx::B2DHomMatrix const & rMatrix = rTransformPrimitive2D.getTransformation(); - rWriter.attributeDouble("xy11", rMatrix.get(0,0)); - rWriter.attributeDouble("xy12", rMatrix.get(0,1)); - rWriter.attributeDouble("xy13", rMatrix.get(0,2)); - rWriter.attributeDouble("xy21", rMatrix.get(1,0)); - rWriter.attributeDouble("xy22", rMatrix.get(1,1)); - rWriter.attributeDouble("xy23", rMatrix.get(1,2)); - rWriter.attributeDouble("xy31", rMatrix.get(2,0)); - rWriter.attributeDouble("xy32", rMatrix.get(2,1)); - rWriter.attributeDouble("xy33", rMatrix.get(2,2)); - + writeMatrix(rWriter, rTransformPrimitive2D.getTransformation()); decomposeAndWrite(rTransformPrimitive2D.getChildren(), rWriter); rWriter.endElement(); } @@ -355,7 +349,35 @@ void Primitive2dXmlDump::decomposeAndWrite( rWriter.content(basegfx::utils::exportToSvgPoints(rPolygonHairlinePrimitive2D.getB2DPolygon())); rWriter.endElement(); + rWriter.endElement(); + } + break; + case PRIMITIVE2D_ID_TEXTDECORATEDPORTIONPRIMITIVE2D: + { + const TextDecoratedPortionPrimitive2D& rTextDecoratedPortionPrimitive2D = dynamic_cast<const TextDecoratedPortionPrimitive2D&>(*pBasePrimitive); + rWriter.startElement("textdecoratedportion"); + writeMatrix(rWriter, rTextDecoratedPortionPrimitive2D.getTextTransform()); + + rWriter.attribute("text", rTextDecoratedPortionPrimitive2D.getText()); + rWriter.attribute("fontcolor", convertColorToString(rTextDecoratedPortionPrimitive2D.getFontColor())); + + const drawinglayer::attribute::FontAttribute& aFontAttribute = rTextDecoratedPortionPrimitive2D.getFontAttribute(); + rWriter.attribute("familyname", aFontAttribute.getFamilyName()); + rWriter.endElement(); + } + break; + + case PRIMITIVE2D_ID_TEXTLINEPRIMITIVE2D: + { + const TextLinePrimitive2D& rTextLinePrimitive2D = dynamic_cast<const TextLinePrimitive2D&>(*pBasePrimitive); + rWriter.startElement("textline"); + writeMatrix(rWriter, rTextLinePrimitive2D.getObjectTransformation()); + + rWriter.attribute("width", rTextLinePrimitive2D.getWidth()); + rWriter.attribute("offset", rTextLinePrimitive2D.getOffset()); + rWriter.attribute("height", rTextLinePrimitive2D.getHeight()); + rWriter.attribute("color", convertColorToString(rTextLinePrimitive2D.getLineColor())); rWriter.endElement(); } break; @@ -406,9 +428,8 @@ void Primitive2dXmlDump::decomposeAndWrite( { const UnifiedTransparencePrimitive2D& rUnifiedTransparencePrimitive2D = dynamic_cast<const UnifiedTransparencePrimitive2D&>(*pBasePrimitive); rWriter.startElement("unifiedtransparence"); - rWriter.attribute("transparence", OString::number(rUnifiedTransparencePrimitive2D.getTransparence())); + rWriter.attribute("transparence", std::lround(100 * rUnifiedTransparencePrimitive2D.getTransparence())); decomposeAndWrite(rUnifiedTransparencePrimitive2D.getChildren(), rWriter); - rWriter.endElement(); } break; @@ -452,16 +473,7 @@ void Primitive2dXmlDump::decomposeAndWrite( rWriter.attributeDouble("opacity", rSvgLinearGradientPrimitive2D.getGradientEntries().front().getOpacity()); rWriter.startElement("transform"); - basegfx::B2DHomMatrix const & rMatrix = rSvgLinearGradientPrimitive2D.getGradientTransform(); - rWriter.attributeDouble("xy11", rMatrix.get(0,0)); - rWriter.attributeDouble("xy12", rMatrix.get(0,1)); - rWriter.attributeDouble("xy13", rMatrix.get(0,2)); - rWriter.attributeDouble("xy21", rMatrix.get(1,0)); - rWriter.attributeDouble("xy22", rMatrix.get(1,1)); - rWriter.attributeDouble("xy23", rMatrix.get(1,2)); - rWriter.attributeDouble("xy31", rMatrix.get(2,0)); - rWriter.attributeDouble("xy32", rMatrix.get(2,1)); - rWriter.attributeDouble("xy33", rMatrix.get(2,2)); + writeMatrix(rWriter, rSvgLinearGradientPrimitive2D.getGradientTransform()); rWriter.endElement(); writePolyPolygon(rWriter, rSvgLinearGradientPrimitive2D.getPolyPolygon()); diff --git a/emfio/qa/cppunit/emf/EmfImportTest.cxx b/emfio/qa/cppunit/emf/EmfImportTest.cxx index 1383b5fdfc03..34288bcf61eb 100644 --- a/emfio/qa/cppunit/emf/EmfImportTest.cxx +++ b/emfio/qa/cppunit/emf/EmfImportTest.cxx @@ -48,6 +48,7 @@ class Test : public test::BootstrapFixture, public XmlTestTools, public unotest: void testPolyPolygon(); void TestDrawString(); void TestDrawStringTransparent(); + void TestDrawStringWithBrush(); void TestDrawLine(); void TestLinearGradient(); void TestTextMapMode(); @@ -87,6 +88,7 @@ public: CPPUNIT_TEST(testPolyPolygon); CPPUNIT_TEST(TestDrawString); CPPUNIT_TEST(TestDrawStringTransparent); + CPPUNIT_TEST(TestDrawStringWithBrush); CPPUNIT_TEST(TestDrawLine); CPPUNIT_TEST(TestLinearGradient); CPPUNIT_TEST(TestTextMapMode); @@ -189,10 +191,9 @@ void Test::testPolyPolygon() void Test::TestDrawString() { #if HAVE_MORE_FONTS - // This unit checks for a correct import of an EMF+ file with only one DrawString Record + // EMF+ file with only one DrawString Record // Since the text is undecorated the optimal choice is a simpletextportion primitive - // first, get the sequence of primitives and dump it Primitive2DSequence aSequence = parseEmf(u"/emfio/qa/cppunit/emf/data/TestDrawString.emf"); CPPUNIT_ASSERT_EQUAL(1, static_cast<int>(aSequence.getLength())); drawinglayer::Primitive2dXmlDump dumper; @@ -212,17 +213,15 @@ void Test::TestDrawString() void Test::TestDrawStringTransparent() { #if HAVE_MORE_FONTS - // This unit checks for a correct import of an EMF+ file with one DrawString Record with transparency + // EMF+ file with one DrawString Record with transparency - // first, get the sequence of primitives and dump it Primitive2DSequence aSequence = parseEmf(u"/emfio/qa/cppunit/emf/data/TestDrawStringTransparent.emf"); CPPUNIT_ASSERT_EQUAL(1, static_cast<int>(aSequence.getLength())); drawinglayer::Primitive2dXmlDump dumper; xmlDocUniquePtr pDocument = dumper.dumpAndParse(comphelper::sequenceToContainer<Primitive2DContainer>(aSequence)); CPPUNIT_ASSERT (pDocument); - assertXPath(pDocument, "/primitive2D/metafile/transform/mask/transform/unifiedtransparence", "transparence", "0.498039215686275"); - + assertXPath(pDocument, "/primitive2D/metafile/transform/mask/transform/unifiedtransparence", "transparence", "50"); assertXPath(pDocument, "/primitive2D/metafile/transform/mask/transform/unifiedtransparence/textsimpleportion", "height", "24"); assertXPath(pDocument, "/primitive2D/metafile/transform/mask/transform/unifiedtransparence/textsimpleportion", "x", "66"); assertXPath(pDocument, "/primitive2D/metafile/transform/mask/transform/unifiedtransparence/textsimpleportion", "y", "74"); @@ -232,12 +231,27 @@ void Test::TestDrawStringTransparent() #endif } +void Test::TestDrawStringWithBrush() +{ + // tdf#142975 EMF+ with records: DrawString, Brush and Font + Primitive2DSequence aSequence = parseEmf(u"/emfio/qa/cppunit/emf/data/TestDrawStringWithBrush.emf"); + CPPUNIT_ASSERT_EQUAL(1, static_cast<int>(aSequence.getLength())); + drawinglayer::Primitive2dXmlDump dumper; + xmlDocUniquePtr pDocument = dumper.dumpAndParse(comphelper::sequenceToContainer<Primitive2DContainer>(aSequence)); + CPPUNIT_ASSERT (pDocument); + assertXPath(pDocument, "/primitive2D/metafile/transform/transform/textdecoratedportion", "xy11", "20"); + assertXPath(pDocument, "/primitive2D/metafile/transform/transform/textdecoratedportion", "xy13", "16"); + assertXPath(pDocument, "/primitive2D/metafile/transform/transform/textdecoratedportion", "xy22", "20"); + assertXPath(pDocument, "/primitive2D/metafile/transform/transform/textdecoratedportion", "xy33", "1"); + assertXPath(pDocument, "/primitive2D/metafile/transform/transform/textdecoratedportion", "text", "0123456789ABCDEF"); + assertXPath(pDocument, "/primitive2D/metafile/transform/transform/textdecoratedportion", "fontcolor", "#a50021"); + assertXPath(pDocument, "/primitive2D/metafile/transform/transform/textdecoratedportion", "familyname", "TIMES NEW ROMAN"); +} + void Test::TestDrawLine() { - // This unit checks for a correct import of an EMF+ file with only one DrawLine Record + // EMF+ with records: DrawLine // The line is colored and has a specified width, therefore a polypolygonstroke primitive is the optimal choice - - // first, get the sequence of primitives and dump it Primitive2DSequence aSequence = parseEmf(u"/emfio/qa/cppunit/emf/data/TestDrawLine.emf"); CPPUNIT_ASSERT_EQUAL(1, static_cast<int>(aSequence.getLength())); drawinglayer::Primitive2dXmlDump dumper; @@ -251,18 +265,18 @@ void Test::TestDrawLine() void Test::TestLinearGradient() { - // This unit checks for a correct import of an EMF+ file with LinearGradient brush + // EMF+ file with LinearGradient brush Primitive2DSequence aSequence = parseEmf(u"/emfio/qa/cppunit/emf/data/TestLinearGradient.emf"); CPPUNIT_ASSERT_EQUAL(1, static_cast<int>(aSequence.getLength())); drawinglayer::Primitive2dXmlDump dumper; xmlDocUniquePtr pDocument = dumper.dumpAndParse(comphelper::sequenceToContainer<Primitive2DContainer>(aSequence)); CPPUNIT_ASSERT (pDocument); - assertXPath(pDocument, "/primitive2D/metafile/transform", "xy11", "1.0000656512605"); + assertXPath(pDocument, "/primitive2D/metafile/transform", "xy11", "1"); assertXPath(pDocument, "/primitive2D/metafile/transform", "xy12", "0"); assertXPath(pDocument, "/primitive2D/metafile/transform", "xy13", "0"); assertXPath(pDocument, "/primitive2D/metafile/transform", "xy21", "0"); - assertXPath(pDocument, "/primitive2D/metafile/transform", "xy22", "1.00013140604468"); + assertXPath(pDocument, "/primitive2D/metafile/transform", "xy22", "1"); assertXPath(pDocument, "/primitive2D/metafile/transform", "xy23", "0"); assertXPath(pDocument, "/primitive2D/metafile/transform/mask/polypolygon", "height", "7610"); assertXPath(pDocument, "/primitive2D/metafile/transform/mask/polypolygon", "width", "15232"); @@ -284,7 +298,7 @@ void Test::TestLinearGradient() void Test::TestTextMapMode() { - // Check import of EMF image with records: SETMAPMODE with MM_TEXT MapMode, POLYLINE16, EXTCREATEPEN, EXTTEXTOUTW + // EMF with records: SETMAPMODE with MM_TEXT MapMode, POLYLINE16, EXTCREATEPEN, EXTTEXTOUTW // MM_TEXT is mapped to one device pixel. Positive x is to the right; positive y is down. Primitive2DSequence aSequence = parseEmf(u"/emfio/qa/cppunit/emf/data/TextMapMode.emf"); CPPUNIT_ASSERT_EQUAL(1, static_cast<int>(aSequence.getLength())); @@ -318,7 +332,7 @@ void Test::TestTextMapMode() void Test::TestEnglishMapMode() { - // Check import of EMF image with records: SETMAPMODE with MM_ENGLISH MapMode, STROKEANDFILLPATH, EXTTEXTOUTW, SETTEXTALIGN, STRETCHDIBITS + // EMF image with records: SETMAPMODE with MM_ENGLISH MapMode, STROKEANDFILLPATH, EXTTEXTOUTW, SETTEXTALIGN, STRETCHDIBITS // MM_LOENGLISH is mapped to 0.01 inch. Positive x is to the right; positive y is up.M Primitive2DSequence aSequence = parseEmf(u"/emfio/qa/cppunit/emf/data/test_mm_hienglish_ref.emf"); CPPUNIT_ASSERT_EQUAL(1, static_cast<int>(aSequence.getLength())); @@ -351,7 +365,7 @@ void Test::TestEnglishMapMode() void Test::TestRectangleWithModifyWorldTransform() { - // Check import of EMF image with records: EXTCREATEPEN, SELECTOBJECT, MODIFYWORLDTRANSFORM, RECTANGLE + // EMF image with records: EXTCREATEPEN, SELECTOBJECT, MODIFYWORLDTRANSFORM, RECTANGLE Primitive2DSequence aSequence = parseEmf(u"/emfio/qa/cppunit/emf/data/TestRectangleWithModifyWorldTransform.emf"); CPPUNIT_ASSERT_EQUAL(1, static_cast<int>(aSequence.getLength())); @@ -452,7 +466,7 @@ void Test::TestEllipseXformIntersectClipRect() void Test::TestDrawPolyLine16WithClip() { - // Check import of EMF image with records: + // EMF image with records: // CREATEBRUSHINDIRECT, FILLRGN, BEGINPATH, POLYGON16, SELECTCLIPPATH, MODIFYWORLDTRANSFORM, SELECTOBJECT Primitive2DSequence aSequence = parseEmf(u"/emfio/qa/cppunit/emf/data/TestDrawPolyLine16WithClip.emf"); CPPUNIT_ASSERT_EQUAL(1, static_cast<int>(aSequence.getLength())); diff --git a/emfio/qa/cppunit/emf/data/TestDrawStringWithBrush.emf b/emfio/qa/cppunit/emf/data/TestDrawStringWithBrush.emf new file mode 100644 index 000000000000..3afb53ed5ed2 Binary files /dev/null and b/emfio/qa/cppunit/emf/data/TestDrawStringWithBrush.emf differ diff --git a/svgio/qa/cppunit/SvgImportTest.cxx b/svgio/qa/cppunit/SvgImportTest.cxx index e0895588a17f..25baf76fdad8 100644 --- a/svgio/qa/cppunit/SvgImportTest.cxx +++ b/svgio/qa/cppunit/SvgImportTest.cxx @@ -381,7 +381,7 @@ void Test::testTdf79163() CPPUNIT_ASSERT (pDocument); - assertXPath(pDocument, "/primitive2D/transform/unifiedtransparence", "transparence", "0.5"); + assertXPath(pDocument, "/primitive2D/transform/unifiedtransparence", "transparence", "50"); } void Test::testTdf97542_1() @@ -464,7 +464,7 @@ void Test::testRGBAColor() CPPUNIT_ASSERT (pDocument); - assertXPath(pDocument, "/primitive2D/transform/unifiedtransparence", "transparence", "0.5"); + assertXPath(pDocument, "/primitive2D/transform/unifiedtransparence", "transparence", "50"); } void Test::testNoneColor() diff --git a/svx/qa/unit/sdr.cxx b/svx/qa/unit/sdr.cxx index f6eb74488797..10f9901a0d60 100644 --- a/svx/qa/unit/sdr.cxx +++ b/svx/qa/unit/sdr.cxx @@ -86,15 +86,15 @@ CPPUNIT_TEST_FIXTURE(SdrTest, testShadowScaleOrigin) // Examine the created primitives. drawinglayer::Primitive2dXmlDump aDumper; xmlDocUniquePtr pDocument = aDumper.dumpAndParse(xPrimitiveSequence); - double fShadowX = getXPath(pDocument, "//shadow/transform", "xy13").toDouble(); - double fShadowY = getXPath(pDocument, "//shadow/transform", "xy23").toDouble(); + sal_Int32 fShadowX = getXPath(pDocument, "//shadow/transform", "xy13").toInt32(); + sal_Int32 fShadowY = getXPath(pDocument, "//shadow/transform", "xy23").toInt32(); // Without the accompanying fix in place, this test would have failed with: // - Expected: -705 // - Actual : -158 // i.e. the shadow origin was not the top right corner for scaling (larger x position, so it was // visible on the right of the shape as well). - CPPUNIT_ASSERT_EQUAL(-705., std::round(fShadowX)); - CPPUNIT_ASSERT_EQUAL(-685., std::round(fShadowY)); + CPPUNIT_ASSERT_EQUAL(sal_Int32(-705), fShadowX); + CPPUNIT_ASSERT_EQUAL(sal_Int32(-684), fShadowY); } CPPUNIT_TEST_FIXTURE(SdrTest, testZeroWidthTextWrap) diff --git a/svx/qa/unit/svdraw.cxx b/svx/qa/unit/svdraw.cxx index d6e43d6f9887..fa344d80acb4 100644 --- a/svx/qa/unit/svdraw.cxx +++ b/svx/qa/unit/svdraw.cxx @@ -110,9 +110,9 @@ CPPUNIT_TEST_FIXTURE(SvdrawTest, testSemiTransparentText) // - Actual : 0 // - XPath '//unifiedtransparence' number of nodes is incorrect // i.e. the text was just plain red, not semi-transparent. - double fTransparence = getXPath(pDocument, "//unifiedtransparence", "transparence").toDouble(); - CPPUNIT_ASSERT_EQUAL(nTransparence, - static_cast<sal_Int16>(basegfx::fround(fTransparence * 100))); + sal_Int16 fTransparence + = getXPath(pDocument, "//unifiedtransparence", "transparence").toInt32(); + CPPUNIT_ASSERT_EQUAL(nTransparence, fTransparence); } CPPUNIT_TEST_FIXTURE(SvdrawTest, testHandlePathObjScale) _______________________________________________ Libreoffice-commits mailing list libreoffice-comm...@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits