tdf#113624 EMF+ Add support for different units conversion

With previous implementation only Pixel unit was supported.
Other units (eg. inch, milimeters, points, world) was treated
as Pixel.
With this patch the correct unit conversion was implemented to following records:
 - FontObject
 - PenObject
 - SetWorldTransform

As a result records are properly scaled.
Tested with DrawString record from:
https://bugs.documentfoundation.org/attachment.cgi?id=140287

Change-Id: I77435ad8f1bbac08f298a03d91d0c7f1f1734e5c
Reviewed-on: https://gerrit.libreoffice.org/52825
Tested-by: Jenkins <ci@libreoffice.org>
Reviewed-by: Bartosz Kosiorek <gang65@poczta.onet.pl>
diff --git a/drawinglayer/source/tools/emfpfont.cxx b/drawinglayer/source/tools/emfpfont.cxx
index 6c1b1a8..4c6d162 100644
--- a/drawinglayer/source/tools/emfpfont.cxx
+++ b/drawinglayer/source/tools/emfpfont.cxx
@@ -49,6 +49,9 @@ namespace emfplushelper
        SAL_INFO("drawinglayer", "EMF+\tfont\nEMF+\theader: 0x" << std::hex << (header >> 12) << " version: 0x" << (header & 0x1fff) << " size: " << std::dec << emSize << " unit: 0x" << std::hex << sizeUnit << std::dec);
        SAL_INFO("drawinglayer", "EMF+\tflags: 0x" << std::hex << fontFlags << " reserved: 0x" << reserved << " length: 0x" << std::hex << length << std::dec);

        //tdf#113624 Convert unit to Pixels
        emSize = emSize * EmfPlusHelperData::getUnitToPixelMultiplier(static_cast<UnitType>(sizeUnit));

        if (length > 0 && length < 0x4000)
        {
            rtl_uString *pStr = rtl_uString_alloc(length);
diff --git a/drawinglayer/source/tools/emfphelperdata.cxx b/drawinglayer/source/tools/emfphelperdata.cxx
index bd7b4d9..ee0bf69 100644
--- a/drawinglayer/source/tools/emfphelperdata.cxx
+++ b/drawinglayer/source/tools/emfphelperdata.cxx
@@ -114,6 +114,44 @@ namespace emfplushelper
        StringAlignmentFar = 0x00000002
    } StringAlignment;

    float EmfPlusHelperData::getUnitToPixelMultiplier(const UnitType aUnitType)
    {
        switch (aUnitType)
        {
            case UnitTypePixel:
            {
                return 1.0f;
            }
            case UnitTypePoint:
            {
                SAL_INFO("drawinglayer", "EMF+\t Converting Points to Pixels.");
                return 1.333333f;
            }
            case UnitTypeInch:
            {
                SAL_INFO("drawinglayer", "EMF+\t TODO Test Converting Inches to Pixels, if it is working correctly.");
                return 96.0f;
            }
            case UnitTypeMillimeter:
            {
                SAL_INFO("drawinglayer", "EMF+\t TODO Test Converting Milimeters to Pixels, if it is working correctly.");
                return 3.779528f;
            }
            case UnitTypeDocument:
            {
                SAL_INFO("drawinglayer", "EMF+\t TODO Test Converting Documents to Pixels, if it is working correctly.");
                return 0.32f;
            }
            case UnitTypeWorld:
            case UnitTypeDisplay:
            default:
            {
                SAL_WARN("drawinglayer", "EMF+\tTODO Unimplemented support of Unit Type: 0x" << std::hex << aUnitType);
            }
        }
        return 1.0f;
    }

    void EmfPlusHelperData::processObjectRecord(SvMemoryStream& rObjectStream, sal_uInt16 flags, sal_uInt32 dataSize, bool bUseWholeStream)
    {
        sal_uInt32 index;
@@ -1245,7 +1283,7 @@ namespace emfplushelper
                        }
                        else
                        {
                            SAL_WARN("drawinglayer", "EMF+ DrawImage(Points) Wrong EMF+ file. Only Unit Type Pixel is support by EMF+ standard in DrawImage(Points)");
                            SAL_WARN("drawinglayer", "EMF+ DrawImage(Points) Wrong EMF+ file. Only Unit Type Pixel is support by EMF+ specification for DrawImage(Points)");
                        }
                        break;
                    }
@@ -1380,14 +1418,15 @@ namespace emfplushelper
                        SAL_INFO("drawinglayer", "EMF+ SetPageTransform");
                        SAL_INFO("drawinglayer", "EMF+\tscale: " << mfPageScale << " unit: " << flags);

                        if (flags != UnitTypePixel)
                        if ((flags == UnitTypeDisplay) || (flags == UnitTypeWorld))
                        {
                            SAL_WARN("drawinglayer", "EMF+\t TODO Only UnitTypePixel is supported. ");
                            SAL_WARN("drawinglayer", "EMF+ file error. UnitTypeDisplay and UnitTypeWorld are not supported by SetPageTransform in EMF+ specification.");
                        }
                        else
                        {
                            mnMmX *= mfPageScale;
                            mnMmY *= mfPageScale;
                            const float aPageScaleMul = mfPageScale * getUnitToPixelMultiplier(static_cast<UnitType>(flags));
                            mnMmX *= aPageScaleMul;
                            mnMmY *= aPageScaleMul;
                            mappingChanged();
                        }
                        break;
diff --git a/drawinglayer/source/tools/emfphelperdata.hxx b/drawinglayer/source/tools/emfphelperdata.hxx
index 3c03af6..b70730d 100644
--- a/drawinglayer/source/tools/emfphelperdata.hxx
+++ b/drawinglayer/source/tools/emfphelperdata.hxx
@@ -262,6 +262,8 @@ namespace emfplushelper
        static void ReadRectangle(SvStream& s, float& x, float& y, float &width, float& height, bool bCompressed = false);
        static bool readXForm(SvStream& rIn, basegfx::B2DHomMatrix& rTarget);
        ::basegfx::B2DPolyPolygon const combineClip(::basegfx::B2DPolyPolygon const & leftPolygon, int combineMode, ::basegfx::B2DPolyPolygon const & rightPolygon);

        static float getUnitToPixelMultiplier(const UnitType aUnitType);
    };
}

diff --git a/drawinglayer/source/tools/emfppen.cxx b/drawinglayer/source/tools/emfppen.cxx
index ac9d63a..eb655d6 100644
--- a/drawinglayer/source/tools/emfppen.cxx
+++ b/drawinglayer/source/tools/emfppen.cxx
@@ -171,6 +171,8 @@ namespace emfplushelper
        SAL_INFO("drawinglayer", "EMF+\t graphics version: 0x" << std::hex << graphicsVersion << " type (must be set to zero): " << penType <<
            " pen data flags: 0x" << penDataFlags << " unit: " << penUnit << " width: " << std::dec << penWidth);

        penWidth = penWidth * EmfPlusHelperData::getUnitToPixelMultiplier(static_cast<UnitType>(penUnit));

        if (penDataFlags & PenDataTransform)
        {
            EmfPlusHelperData::readXForm(s, pen_transformation);