[Libreoffice-commits] core.git: Branch 'libreoffice-7-2' - drawinglayer/source emfio/qa

Bartosz Kosiorek (via logerrit) logerrit at kemper.freedesktop.org
Fri Jul 2 10:51:05 UTC 2021


 drawinglayer/source/tools/emfphelperdata.cxx      |   44 ++++++----
 drawinglayer/source/tools/emfpstringformat.cxx    |    8 -
 emfio/qa/cppunit/emf/EmfImportTest.cxx            |   92 ++++++++++++++++++++++
 emfio/qa/cppunit/emf/data/TestDrawStringAlign.emf |binary
 4 files changed, 122 insertions(+), 22 deletions(-)

New commits:
commit b19b08e51163e949ba4aa656196ebb554ca879a2
Author:     Bartosz Kosiorek <gang65 at poczta.onet.pl>
AuthorDate: Thu Jun 24 18:58:39 2021 +0200
Commit:     Xisco Fauli <xiscofauli at libreoffice.org>
CommitDate: Fri Jul 2 12:50:29 2021 +0200

    EMF+ tdf#142995 tdf#142997 tdf#143076 Add alignment support for DrawString
    
    With this commit, real size of the text is used to make
    proper horizontal alignment. Additionally vertical alignment
    is added and fix for Center alignment was applied
    
    Change-Id: I17d9fd7de7f00f5e69f99c5b09061eb6059be67e
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/117794
    Tested-by: Jenkins
    Reviewed-by: Bartosz Kosiorek <gang65 at poczta.onet.pl>
    (cherry picked from commit 574dc1e8ff6ea4214fefd91216fca5146a4ff13e)
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/118257
    Reviewed-by: Xisco Fauli <xiscofauli at libreoffice.org>

diff --git a/drawinglayer/source/tools/emfphelperdata.cxx b/drawinglayer/source/tools/emfphelperdata.cxx
index e756b16ff70f..23ceb6487d66 100644
--- a/drawinglayer/source/tools/emfphelperdata.cxx
+++ b/drawinglayer/source/tools/emfphelperdata.cxx
@@ -34,6 +34,7 @@
 #include <drawinglayer/primitive2d/PolyPolygonColorPrimitive2D.hxx>
 #include <drawinglayer/primitive2d/svggradientprimitive2d.hxx>
 #include <drawinglayer/primitive2d/textdecoratedprimitive2d.hxx>
+#include <drawinglayer/primitive2d/textlayoutdevice.hxx>
 #include <drawinglayer/primitive2d/textprimitive2d.hxx>
 #include <drawinglayer/primitive2d/bitmapprimitive2d.hxx>
 #include <drawinglayer/primitive2d/metafileprimitive2d.hxx>
@@ -1568,25 +1569,35 @@ namespace emfplushelper
 
                         css::lang::Locale locale;
                         double stringAlignmentHorizontalOffset = 0.0;
+                        double stringAlignmentVerticalOffset = font->emSize;
                         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.");
+                            LanguageTag aLanguageTag(static_cast<LanguageType>(stringFormat->language));
+                            locale = aLanguageTag.getLocale();
+                            drawinglayer::primitive2d::TextLayouterDevice aTextLayouter;
+
+                            aTextLayouter.setFontAttribute(fontAttribute, font->emSize,
+                                font->emSize, locale);
+
+                            double fTextWidth = aTextLayouter.getTextWidth(text, 0, stringLength);
+                            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)
-                            {
+                                // 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 if (stringFormat->stringAlignment == StringAlignmentCenter)
+                                // Alignment is centered between the origin and extent of the layout rectangle
+                                stringAlignmentHorizontalOffset = 0.5 * lw + (stringFormat->leadingMargin - stringFormat->trailingMargin) * font->emSize - 0.5 * fTextWidth;
+                            else if (stringFormat->stringAlignment == StringAlignmentFar)
+                                // Alignment is to the right side of the layout rectangle
+                                stringAlignmentHorizontalOffset = lw - stringFormat->trailingMargin * font->emSize - fTextWidth;
+
+                            if (stringFormat->lineAlign == StringAlignmentNear)
+                                stringAlignmentVerticalOffset = font->emSize;
+                            else if (stringFormat->lineAlign == StringAlignmentCenter)
+                                stringAlignmentVerticalOffset = 0.5 * lh + 0.5 * font->emSize;
+                            else if (stringFormat->lineAlign == StringAlignmentFar)
+                                stringAlignmentVerticalOffset = lh;
                         }
                         else
                         {
@@ -1600,7 +1611,8 @@ namespace emfplushelper
 
                         const basegfx::B2DHomMatrix transformMatrix = basegfx::utils::createScaleTranslateB2DHomMatrix(
                                     ::basegfx::B2DSize(font->emSize, font->emSize),
-                                    ::basegfx::B2DPoint(lx + stringAlignmentHorizontalOffset, ly + font->emSize));
+                                    ::basegfx::B2DPoint(lx + stringAlignmentHorizontalOffset,
+                                                        ly + stringAlignmentVerticalOffset));
 
                         Color uncorrectedColor = EMFPGetBrushColorOrARGBColor(flags, brushId);
                         Color color;
diff --git a/drawinglayer/source/tools/emfpstringformat.cxx b/drawinglayer/source/tools/emfpstringformat.cxx
index 63cc42471b3b..071493c13062 100644
--- a/drawinglayer/source/tools/emfpstringformat.cxx
+++ b/drawinglayer/source/tools/emfpstringformat.cxx
@@ -217,18 +217,14 @@ namespace emfplushelper
         SAL_INFO("drawinglayer.emf", "EMF+\t\tTabStopCount: " << tabStopCount);
         SAL_INFO("drawinglayer.emf", "EMF+\t\tRangeCount: " << rangeCount);
 
-        SAL_WARN_IF(stringAlignment != StringAlignment::StringAlignmentNear, "drawinglayer.emf", "EMF+\t TODO EMFPStringFormat:StringAlignment");
-        SAL_WARN_IF(lineAlign != StringAlignment::StringAlignmentNear, "drawinglayer.emf", "EMF+\t TODO EMFPStringFormat:lineAlign");
         SAL_WARN_IF(digitSubstitution != StringDigitSubstitution::StringDigitSubstitutionNone,
-                        "drawinglayer.emf", "EMF+\t TODO EMFPStringFormat:digitSubstitution");
+                    "drawinglayer.emf", "EMF+\t TODO EMFPStringFormat:digitSubstitution");
         SAL_WARN_IF(firstTabOffset != 0.0, "drawinglayer.emf", "EMF+\t TODO EMFPStringFormat:firstTabOffset");
         SAL_WARN_IF(hotkeyPrefix != HotkeyPrefix::HotkeyPrefixNone, "drawinglayer.emf", "EMF+\t TODO EMFPStringFormat:hotkeyPrefix");
-        SAL_WARN_IF(leadingMargin != 0.0, "drawinglayer.emf", "EMF+\t TODO EMFPStringFormat:leadingMargin");
-        SAL_WARN_IF(trailingMargin != 0.0, "drawinglayer.emf", "EMF+\t TODO EMFPStringFormat:trailingMargin");
         SAL_WARN_IF(tracking != 1.0, "drawinglayer.emf", "EMF+\t TODO EMFPStringFormat:tracking");
         SAL_WARN_IF(trimming != StringTrimming::StringTrimmingNone, "drawinglayer.emf", "EMF+\t TODO EMFPStringFormat:trimming");
         SAL_WARN_IF(tabStopCount, "drawinglayer.emf", "EMF+\t TODO EMFPStringFormat:tabStopCount");
-        SAL_WARN_IF(rangeCount, "drawinglayer.emf", "EMF+\t TODO EMFPStringFormat:StringFormatData");
+        SAL_WARN_IF(rangeCount != 0, "drawinglayer.emf", "EMF+\t TODO EMFPStringFormat:StringFormatData");
     }
 }
 
diff --git a/emfio/qa/cppunit/emf/EmfImportTest.cxx b/emfio/qa/cppunit/emf/EmfImportTest.cxx
index 34288bcf61eb..63e1d575803b 100644
--- a/emfio/qa/cppunit/emf/EmfImportTest.cxx
+++ b/emfio/qa/cppunit/emf/EmfImportTest.cxx
@@ -47,6 +47,7 @@ class Test : public test::BootstrapFixture, public XmlTestTools, public unotest:
 
     void testPolyPolygon();
     void TestDrawString();
+    void TestDrawStringAlign();
     void TestDrawStringTransparent();
     void TestDrawStringWithBrush();
     void TestDrawLine();
@@ -87,6 +88,7 @@ public:
     CPPUNIT_TEST_SUITE(Test);
     CPPUNIT_TEST(testPolyPolygon);
     CPPUNIT_TEST(TestDrawString);
+    CPPUNIT_TEST(TestDrawStringAlign);
     CPPUNIT_TEST(TestDrawStringTransparent);
     CPPUNIT_TEST(TestDrawStringWithBrush);
     CPPUNIT_TEST(TestDrawLine);
@@ -210,6 +212,96 @@ void Test::TestDrawString()
 #endif
 }
 
+void Test::TestDrawStringAlign()
+{
+#if HAVE_MORE_FONTS
+    // EMF+ DrawString with alignment (StringAlignmentNear, StringAlignmentFar, StringAlignmentCenter)
+    // It seems Arial font is replaced with Liberation Sans. These numbers are valid for Liberation Sans.
+    Primitive2DSequence aSequence = parseEmf(u"/emfio/qa/cppunit/emf/data/TestDrawStringAlign.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", 9);
+    assertXPath(pDocument, "/primitive2D/metafile/transform/mask/transform[1]/textsimpleportion",
+                "width", "12");
+    assertXPath(pDocument, "/primitive2D/metafile/transform/mask/transform[1]/textsimpleportion",
+                "height", "12");
+    assertXPath(pDocument, "/primitive2D/metafile/transform/mask/transform[1]/textsimpleportion",
+                "x", "12");
+    assertXPath(pDocument, "/primitive2D/metafile/transform/mask/transform[1]/textsimpleportion",
+                "y", "22");
+    assertXPath(pDocument, "/primitive2D/metafile/transform/mask/transform[1]/textsimpleportion",
+                "text", "HLVT");
+    assertXPath(pDocument, "/primitive2D/metafile/transform/mask/transform[1]/textsimpleportion",
+                "fontcolor", "#000000");
+    assertXPath(pDocument, "/primitive2D/metafile/transform/mask/transform[1]/textsimpleportion",
+                "familyname", "ARIAL");
+
+    assertXPath(pDocument, "/primitive2D/metafile/transform/mask/transform[2]/textsimpleportion",
+                "width", "12");
+    assertXPath(pDocument, "/primitive2D/metafile/transform/mask/transform[2]/textsimpleportion",
+                "height", "12");
+    assertXPath(pDocument, "/primitive2D/metafile/transform/mask/transform[2]/textsimpleportion",
+                "x", "143");
+    assertXPath(pDocument, "/primitive2D/metafile/transform/mask/transform[2]/textsimpleportion",
+                "y", "22");
+    assertXPath(pDocument, "/primitive2D/metafile/transform/mask/transform[2]/textsimpleportion",
+                "text", "HCVT");
+
+    // TODO Make the position of the text the same across the platforms (Arial vs Liberation Sans).
+    assertXPath(pDocument, "/primitive2D/metafile/transform/mask/transform[3]/textsimpleportion",
+                "x", "276");
+    assertXPath(pDocument, "/primitive2D/metafile/transform/mask/transform[3]/textsimpleportion",
+                "y", "22");
+    assertXPath(pDocument, "/primitive2D/metafile/transform/mask/transform[3]/textsimpleportion",
+                "text", "HRVT");
+
+    assertXPath(pDocument, "/primitive2D/metafile/transform/mask/transform[4]/textsimpleportion",
+                "x", "12");
+    assertXPath(pDocument, "/primitive2D/metafile/transform/mask/transform[4]/textsimpleportion",
+                "y", "66");
+    assertXPath(pDocument, "/primitive2D/metafile/transform/mask/transform[4]/textsimpleportion",
+                "text", "HLVC");
+
+    assertXPath(pDocument, "/primitive2D/metafile/transform/mask/transform[5]/textsimpleportion",
+                "x", "142");
+    assertXPath(pDocument, "/primitive2D/metafile/transform/mask/transform[5]/textsimpleportion",
+                "y", "66");
+    assertXPath(pDocument, "/primitive2D/metafile/transform/mask/transform[5]/textsimpleportion",
+                "text", "HCVC");
+
+    assertXPath(pDocument, "/primitive2D/metafile/transform/mask/transform[6]/textsimpleportion",
+                "x", "274");
+    assertXPath(pDocument, "/primitive2D/metafile/transform/mask/transform[6]/textsimpleportion",
+                "y", "66");
+    assertXPath(pDocument, "/primitive2D/metafile/transform/mask/transform[6]/textsimpleportion",
+                "text", "HRVC");
+
+    assertXPath(pDocument, "/primitive2D/metafile/transform/mask/transform[7]/textsimpleportion",
+                "x", "12");
+    assertXPath(pDocument, "/primitive2D/metafile/transform/mask/transform[7]/textsimpleportion",
+                "y", "110");
+    assertXPath(pDocument, "/primitive2D/metafile/transform/mask/transform[7]/textsimpleportion",
+                "text", "HLVB");
+
+    assertXPath(pDocument, "/primitive2D/metafile/transform/mask/transform[8]/textsimpleportion",
+                "x", "143");
+    assertXPath(pDocument, "/primitive2D/metafile/transform/mask/transform[8]/textsimpleportion",
+                "y", "110");
+    assertXPath(pDocument, "/primitive2D/metafile/transform/mask/transform[8]/textsimpleportion",
+                "text", "HCVB");
+
+    assertXPath(pDocument, "/primitive2D/metafile/transform/mask/transform[9]/textsimpleportion",
+                "x", "275");
+    assertXPath(pDocument, "/primitive2D/metafile/transform/mask/transform[9]/textsimpleportion",
+                "y", "110");
+    assertXPath(pDocument, "/primitive2D/metafile/transform/mask/transform[9]/textsimpleportion",
+                "text", "HRVB");
+#endif
+}
+
 void Test::TestDrawStringTransparent()
 {
 #if HAVE_MORE_FONTS
diff --git a/emfio/qa/cppunit/emf/data/TestDrawStringAlign.emf b/emfio/qa/cppunit/emf/data/TestDrawStringAlign.emf
new file mode 100644
index 000000000000..bc3a33c61fc2
Binary files /dev/null and b/emfio/qa/cppunit/emf/data/TestDrawStringAlign.emf differ


More information about the Libreoffice-commits mailing list