tdf#55058 tdf#106084 tdf#114738 EMF+ Add rotation support for String drawing

Added rotation support for DrawString and DrawDriverString

The EmfPlusDrawString record specifies text output with string formatting.
The EmfPlusDrawDriverString record specifies text output
with character positions.

Now both EMF+ records properly support rotation.

Change-Id: I15a7a6dd2b8a209cf2aac2af75d7dd89cedd1aeb
Reviewed-on: https://gerrit.libreoffice.org/62783
Tested-by: Jenkins
Reviewed-by: Bartosz Kosiorek <gang65@poczta.onet.pl>
diff --git a/drawinglayer/source/tools/emfphelperdata.cxx b/drawinglayer/source/tools/emfphelperdata.cxx
index c7ccf3a..c900268 100644
--- a/drawinglayer/source/tools/emfphelperdata.cxx
+++ b/drawinglayer/source/tools/emfphelperdata.cxx
@@ -33,6 +33,7 @@
#include <drawinglayer/primitive2d/textprimitive2d.hxx>
#include <drawinglayer/primitive2d/bitmapprimitive2d.hxx>
#include <drawinglayer/primitive2d/metafileprimitive2d.hxx>
#include <drawinglayer/primitive2d/transformprimitive2d.hxx>
#include <drawinglayer/attribute/fontattribute.hxx>
#include <basegfx/matrix/b2dhommatrixtools.hxx>
#include <basegfx/polygon/b2dpolygonclipper.hxx>
@@ -1366,7 +1367,8 @@ namespace emfplushelper
                            }

                            const basegfx::B2DHomMatrix transformMatrix = basegfx::utils::createScaleTranslateB2DHomMatrix(
                                        MapSize(font->emSize, font->emSize), Map(lx + stringAlignmentHorizontalOffset, ly + font->emSize));
                                        ::basegfx::B2DSize(font->emSize, font->emSize),
                                        ::basegfx::B2DPoint(lx + stringAlignmentHorizontalOffset, ly + font->emSize));

                            const Color color = EMFPGetBrushColorOrARGBColor(flags, brushId);
                            mrPropertyHolders.Current().setTextColor(color.getBColor());
@@ -1375,38 +1377,28 @@ namespace emfplushelper
                            if (color.GetTransparency() < 255)
                            {
                                std::vector<double> emptyVector;
                                if (color.GetTransparency() == 0)
                                {
                                    // not transparent
                                    mrTargetHolders.Current().append(
                                                o3tl::make_unique<drawinglayer::primitive2d::TextSimplePortionPrimitive2D>(
                                                    transformMatrix,
                                                    text,
                                                    0,             // text always starts at 0
                                                    stringLength,
                                                    emptyVector,   // EMF-PLUS has no DX-array
                                                    fontAttribute,
                                                    locale,
                                                    color.getBColor()));
                                }
                                else
                                {
                                    const drawinglayer::primitive2d::Primitive2DReference aPrimitive(
                                                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(
                                            new drawinglayer::primitive2d::TextSimplePortionPrimitive2D(
                                                transformMatrix,
                                                text,
                                                0,             // text always starts at 0
                                                stringLength,
                                                emptyVector,   // EMF-PLUS has no DX-array
                                                fontAttribute,
                                                locale,
                                                color.getBColor()));

                                    mrTargetHolders.Current().append(
                                                o3tl::make_unique<drawinglayer::primitive2d::UnifiedTransparencePrimitive2D>(
                                                    drawinglayer::primitive2d::Primitive2DContainer { aPrimitive },
                                                    color.GetTransparency() / 255.0));
                                if (color.GetTransparency() != 0)
                                {
                                    aPrimitiveText = new drawinglayer::primitive2d::UnifiedTransparencePrimitive2D(
                                                drawinglayer::primitive2d::Primitive2DContainer { aPrimitiveText },
                                                color.GetTransparency() / 255.0);
                                }

                                mrTargetHolders.Current().append(
                                            o3tl::make_unique<drawinglayer::primitive2d::TransformPrimitive2D>(
                                                maMapTransform,
                                                drawinglayer::primitive2d::Primitive2DContainer { aPrimitiveText } ));
                            }
                        }
                        else
@@ -1794,45 +1786,33 @@ namespace emfplushelper
                                // last entry
                                aDXArray.push_back(0);

                                // prepare transform matrix
                                basegfx::B2DHomMatrix transformMatrix = basegfx::utils::createScaleTranslateB2DHomMatrix(
                                    MapSize(font->emSize,font->emSize),Map(charsPosX[pos],charsPosY[pos]));
                                            ::basegfx::B2DSize(font->emSize, font->emSize),
                                            ::basegfx::B2DPoint(charsPosX[pos], charsPosY[pos]));
                                if (hasMatrix)
                                    transformMatrix *= transform;
                                if (color.GetTransparency() < 255)
                                {
                                    if (color.GetTransparency() == 0)
                                    drawinglayer::primitive2d::Primitive2DReference aPrimitiveText(
                                                new drawinglayer::primitive2d::TextSimplePortionPrimitive2D(
                                                    transformMatrix,
                                                    text,
                                                    pos,            // take character at current pos
                                                    aLength,        // use determined length
                                                    aDXArray,       // generated DXArray
                                                    fontAttribute,
                                                    Application::GetSettings().GetLanguageTag().getLocale(),
                                                    color.getBColor()));
                                    if (color.GetTransparency() != 0)
                                    {
                                        // not transparent
                                        mrTargetHolders.Current().append(
                                                    o3tl::make_unique<drawinglayer::primitive2d::TextSimplePortionPrimitive2D>(
                                                        transformMatrix,
                                                        text,
                                                        pos,            // take character at current pos
                                                        aLength,        // use determined length
                                                        aDXArray,       // generated DXArray
                                                        fontAttribute,
                                                        Application::GetSettings().GetLanguageTag().getLocale(),
                                                        color.getBColor()));
                                        aPrimitiveText = new drawinglayer::primitive2d::UnifiedTransparencePrimitive2D(
                                                    drawinglayer::primitive2d::Primitive2DContainer { aPrimitiveText },
                                                    color.GetTransparency() / 255.0);
                                    }
                                    else
                                    {
                                        const drawinglayer::primitive2d::Primitive2DReference aPrimitive(
                                                    new drawinglayer::primitive2d::TextSimplePortionPrimitive2D(
                                                        transformMatrix,
                                                        text,
                                                        pos,            // take character at current pos
                                                        aLength,        // use determined length
                                                        aDXArray,       // generated DXArray
                                                        fontAttribute,
                                                        Application::GetSettings().GetLanguageTag().getLocale(),
                                                        color.getBColor()));

                                        mrTargetHolders.Current().append(
                                                    o3tl::make_unique<drawinglayer::primitive2d::UnifiedTransparencePrimitive2D>(
                                                        drawinglayer::primitive2d::Primitive2DContainer { aPrimitive },
                                                        color.GetTransparency() / 255.0));
                                    }
                                    mrTargetHolders.Current().append(
                                                o3tl::make_unique<drawinglayer::primitive2d::TransformPrimitive2D>(
                                                    maMapTransform,
                                                    drawinglayer::primitive2d::Primitive2DContainer { aPrimitiveText } ));
                                }

                                // update pos
diff --git a/emfio/qa/cppunit/emf/EmfImportTest.cxx b/emfio/qa/cppunit/emf/EmfImportTest.cxx
index 49c7abd..4eb34e3 100644
--- a/emfio/qa/cppunit/emf/EmfImportTest.cxx
+++ b/emfio/qa/cppunit/emf/EmfImportTest.cxx
@@ -106,12 +106,12 @@ void Test::TestDrawString()
    CPPUNIT_ASSERT (pDocument);

    // check correct import of the DrawString: height, position, text, color and font
    assertXPath(pDocument, "/primitive2D/metafile/transform/textsimpleportion", "height", "276");
    assertXPath(pDocument, "/primitive2D/metafile/transform/textsimpleportion", "x", "25");
    assertXPath(pDocument, "/primitive2D/metafile/transform/textsimpleportion", "y", "323");
    assertXPath(pDocument, "/primitive2D/metafile/transform/textsimpleportion", "text", "TEST");
    assertXPath(pDocument, "/primitive2D/metafile/transform/textsimpleportion", "fontcolor", "#000000");
    assertXPath(pDocument, "/primitive2D/metafile/transform/textsimpleportion", "familyname", "CALIBRI");
    assertXPath(pDocument, "/primitive2D/metafile/transform/transform/textsimpleportion", "height", "120");
    assertXPath(pDocument, "/primitive2D/metafile/transform/transform/textsimpleportion", "x", "817");
    assertXPath(pDocument, "/primitive2D/metafile/transform/transform/textsimpleportion", "y", "1137");
    assertXPath(pDocument, "/primitive2D/metafile/transform/transform/textsimpleportion", "text", "TEST");
    assertXPath(pDocument, "/primitive2D/metafile/transform/transform/textsimpleportion", "fontcolor", "#000000");
    assertXPath(pDocument, "/primitive2D/metafile/transform/transform/textsimpleportion", "familyname", "CALIBRI");
}

void Test::TestDrawStringTransparent()
@@ -127,15 +127,15 @@ void Test::TestDrawStringTransparent()

    //TODO Strange that transparency is set to 0 even if it is not fully transparent
    // check correct import of the DrawString: transparency, height, position, text, color and font
    assertXPath(pDocument, "/primitive2D/metafile/transform/unifiedtransparence", "transparence", "0");
    assertXPath(pDocument, "/primitive2D/metafile/transform/transform/unifiedtransparence", "transparence", "0");

    //TODO Where was textsimpleportion gone?
    //assertXPath(pDocument, "/primitive2D/metafile/transform/textsimpleportion", "height", "276");
    //assertXPath(pDocument, "/primitive2D/metafile/transform/textsimpleportion", "x", "25");
    //assertXPath(pDocument, "/primitive2D/metafile/transform/textsimpleportion", "y", "323");
    //assertXPath(pDocument, "/primitive2D/metafile/transform/textsimpleportion", "text", "Transparent Text");
    //assertXPath(pDocument, "/primitive2D/metafile/transform/textsimpleportion", "fontcolor", "#000000");
    //assertXPath(pDocument, "/primitive2D/metafile/transform/textsimpleportion", "familyname", "CALIBRI");
    //assertXPath(pDocument, "/primitive2D/metafile/transform/transform/textsimpleportion", "height", "276");
    //assertXPath(pDocument, "/primitive2D/metafile/transform/transform/textsimpleportion", "x", "25");
    //assertXPath(pDocument, "/primitive2D/metafile/transform/transform/textsimpleportion", "y", "323");
    //assertXPath(pDocument, "/primitive2D/metafile/transform/transform/textsimpleportion", "text", "Transparent Text");
    //assertXPath(pDocument, "/primitive2D/metafile/transform/transform/textsimpleportion", "fontcolor", "#000000");
    //assertXPath(pDocument, "/primitive2D/metafile/transform/transform/textsimpleportion", "familyname", "CALIBRI");
}

void Test::TestDrawLine()