vcl/inc/impfont.hxx      |    4 -
 vcl/source/font/font.cxx |  115 ++++++++++++++++++++++++++++++++++++++++++++---
 2 files changed, 112 insertions(+), 7 deletions(-)

New commits:
commit a5cecd2ea50dc930cfc0d90be69c08ddd144d3db
Author:     Armin Le Grand (Allotropia) <armin.le.gr...@me.com>
AuthorDate: Tue Feb 2 17:57:12 2021 +0100
Commit:     Armin Le Grand <armin.le.gr...@me.com>
CommitDate: Tue Mar 9 10:20:22 2021 +0100

    tdf#127471 improve SVM FontScaling im/export
    
    Due to svg::Font Width and it's expression of
    FontScaling being system-dependent the FontScaling
    when exchanging beween win-based SVM creators and
    others was creating errors.
    Corrected this to work now with newly created SVM
    files in both directions. For more aspects see
    discussion in task.
    
    Change-Id: I326e4e7e895a9dfc3cdfc5323174ca81e22795e8
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/110330
    Tested-by: Jenkins
    Reviewed-by: Armin Le Grand <armin.le.gr...@me.com>
    (cherry picked from commit 40b56cd8da8c38582dc4660b486993d1b4711535)
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/112088

diff --git a/vcl/inc/impfont.hxx b/vcl/inc/impfont.hxx
index caa917a751f0..ba1ea3683926 100644
--- a/vcl/inc/impfont.hxx
+++ b/vcl/inc/impfont.hxx
@@ -84,8 +84,8 @@ public:
 
 private:
     friend class vcl::Font;
-    friend SvStream&    ReadImplFont( SvStream& rIStm, ImplFont& );
-    friend SvStream&    WriteImplFont( SvStream& rOStm, const ImplFont& );
+    friend SvStream&    ReadImplFont( SvStream& rIStm, ImplFont&, tools::Long& 
);
+    friend SvStream&    WriteImplFont( SvStream& rOStm, const ImplFont&, const 
tools::Long& );
 
     void                AskConfig();
 
diff --git a/vcl/source/font/font.cxx b/vcl/source/font/font.cxx
index 2818e71e00ea..180f5bbf122b 100644
--- a/vcl/source/font/font.cxx
+++ b/vcl/source/font/font.cxx
@@ -34,6 +34,10 @@
 #include <rtl/instance.hxx>
 #include <TypeSerializer.hxx>
 
+#ifdef _WIN32
+#include <vcl/metric.hxx>
+#endif
+
 using namespace vcl;
 
 namespace
@@ -357,7 +361,7 @@ void Font::GetFontAttributes( FontAttributes& rAttrs ) const
     rAttrs.SetSymbolFlag( mpImplFont->GetCharSet() == RTL_TEXTENCODING_SYMBOL 
);
 }
 
-SvStream& ReadImplFont( SvStream& rIStm, ImplFont& rImplFont )
+SvStream& ReadImplFont( SvStream& rIStm, ImplFont& rImplFont, tools::Long& 
rnNormedFontScaling )
 {
     VersionCompat   aCompat( rIStm, StreamMode::READ );
     sal_uInt16      nTmp16(0);
@@ -400,15 +404,25 @@ SvStream& ReadImplFont( SvStream& rIStm, ImplFont& 
rImplFont )
         rIStm.ReadUInt16( nTmp16 ); rImplFont.meOverline = 
static_cast<FontLineStyle>(nTmp16);
     }
 
+    // tdf#127471 read NormedFontScaling
+    if( aCompat.GetVersion() >= 4 )
+    {
+        sal_Int32 nNormedFontScaling(0);
+        rIStm.ReadInt32(nNormedFontScaling);
+        rnNormedFontScaling = nNormedFontScaling;
+    }
+
     // Relief
     // CJKContextLanguage
 
     return rIStm;
 }
 
-SvStream& WriteImplFont( SvStream& rOStm, const ImplFont& rImplFont )
+SvStream& WriteImplFont( SvStream& rOStm, const ImplFont& rImplFont, const 
tools::Long& rnNormedFontScaling )
 {
-    VersionCompat aCompat( rOStm, StreamMode::WRITE, 3 );
+    // tdf#127471 increase to version 4
+    VersionCompat aCompat( rOStm, StreamMode::WRITE, 4 );
+
     TypeSerializer aSerializer(rOStm);
     rOStm.WriteUniOrByteString( rImplFont.GetFamilyName(), 
rOStm.GetStreamCharSet() );
     rOStm.WriteUniOrByteString( rImplFont.GetStyleName(), 
rOStm.GetStreamCharSet() );
@@ -440,17 +454,108 @@ SvStream& WriteImplFont( SvStream& rOStm, const 
ImplFont& rImplFont )
     // new in version 3
     rOStm.WriteUInt16( rImplFont.meOverline );
 
+    // new in version 4, NormedFontScaling
+    rOStm.WriteInt32(rnNormedFontScaling);
+
     return rOStm;
 }
 
 SvStream& ReadFont( SvStream& rIStm, vcl::Font& rFont )
 {
-    return ReadImplFont( rIStm, *rFont.mpImplFont );
+    // tdf#127471 try to read NormedFontScaling
+    tools::Long nNormedFontScaling(0);
+    SvStream& rRetval(ReadImplFont( rIStm, *rFont.mpImplFont, 
nNormedFontScaling ));
+
+    if (nNormedFontScaling > 0)
+    {
+#ifdef _WIN32
+        // we run on windows and a NormedFontScaling was written
+        if(rFont.GetFontSize().getWidth() == nNormedFontScaling)
+        {
+            // the writing producer was running on a non-windows system, adapt 
to needed windows
+            // system-specific pre-multiply
+            const tools::Long 
nHeight(std::max<tools::Long>(rFont.GetFontSize().getHeight(), 0));
+            sal_uInt32 nScaledWidth(0);
+
+            if(nHeight > 0)
+            {
+                vcl::Font aUnscaledFont(rFont);
+                aUnscaledFont.SetAverageFontWidth(0);
+                const FontMetric 
aUnscaledFontMetric(Application::GetDefaultDevice()->GetFontMetric(aUnscaledFont));
+
+                if (aUnscaledFontMetric.GetAverageFontWidth() > 0)
+                {
+                    const double 
fScaleFactor(static_cast<double>(nNormedFontScaling) / 
static_cast<double>(nHeight));
+                    nScaledWidth = 
basegfx::fround(static_cast<double>(aUnscaledFontMetric.GetAverageFontWidth()) 
* fScaleFactor);
+                }
+            }
+
+            rFont.SetAverageFontWidth(nScaledWidth);
+        }
+        else
+        {
+            // the writing producer was on a windows system, correct 
pre-multiplied value
+            // is already set, nothing to do. Ignore 2nd value. Here a check
+            // could be done if adapting the 2nd, NormedFontScaling value 
would be similar to
+            // the set value for plausability reasons
+        }
+#else
+        // we do not run on windows and a NormedFontScaling was written
+        if(rFont.GetFontSize().getWidth() == nNormedFontScaling)
+        {
+            // the writing producer was not on a windows system, correct value
+            // already set, nothing to do
+        }
+        else
+        {
+            // the writing producer was on a windows system, correct 
FontScvaling.
+            // The correct non-pre-multiplied value is the 2nd one, use it
+            rFont.SetAverageFontWidth(nNormedFontScaling);
+        }
+#endif
+    }
+
+    return rRetval;
 }
 
 SvStream& WriteFont( SvStream& rOStm, const vcl::Font& rFont )
 {
-    return WriteImplFont( rOStm, *rFont.mpImplFont );
+    // tdf#127471 prepare NormedFontScaling for additional export
+    tools::Long nNormedFontScaling(rFont.GetFontSize().getWidth());
+
+    // FontScaling usage at vcl-Font is detected by checking that FontWidth != 0
+    if (nNormedFontScaling > 0)
+    {
+        const tools::Long 
nHeight(std::max<tools::Long>(rFont.GetFontSize().getHeight(), 0));
+
+        // check for negative height
+        if(0 == nHeight)
+        {
+            nNormedFontScaling = 0;
+        }
+        else
+        {
+#ifdef _WIN32
+            // for WIN32 the value is pre-multiplied with AverageFontWidth
+            // which makes it system-dependent. Turn that back to have the
+            // normed non-windows form of it for export as 2nd value
+            vcl::Font aUnscaledFont(rFont);
+            aUnscaledFont.SetAverageFontWidth(0);
+            const FontMetric aUnscaledFontMetric(
+                Application::GetDefaultDevice()->GetFontMetric(aUnscaledFont));
+
+            if (aUnscaledFontMetric.GetAverageFontWidth() > 0)
+            {
+                const double fScaleFactor(
+                    static_cast<double>(nNormedFontScaling)
+                    / 
static_cast<double>(aUnscaledFontMetric.GetAverageFontWidth()));
+                nNormedFontScaling = static_cast<tools::Long>(fScaleFactor * 
nHeight);
+            }
+#endif
+        }
+    }
+
+    return WriteImplFont( rOStm, *rFont.mpImplFont, nNormedFontScaling );
 }
 
 namespace
_______________________________________________
Libreoffice-commits mailing list
libreoffice-comm...@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits

Reply via email to