diff options
author | Armin Le Grand (Allotropia) <armin.le.grand@me.com> | 2021-02-02 17:57:12 +0100 |
---|---|---|
committer | Armin Le Grand <Armin.Le.Grand@me.com> | 2021-02-03 17:06:13 +0100 |
commit | 40b56cd8da8c38582dc4660b486993d1b4711535 (patch) | |
tree | 83a528bd0e45b4fdc5bc3207a64f3dddf7c9c180 /vcl | |
parent | 11e91719ef362e38b3b92e525763a5a89f4eeecb (diff) |
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.Grand@me.com>
Diffstat (limited to 'vcl')
-rw-r--r-- | vcl/inc/impfont.hxx | 4 | ||||
-rw-r--r-- | vcl/source/font/font.cxx | 115 |
2 files changed, 112 insertions, 7 deletions
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 2c64a4a14d0f..891f1be5f8d7 100644 --- a/vcl/source/font/font.cxx +++ b/vcl/source/font/font.cxx @@ -35,6 +35,10 @@ #include <rtl/instance.hxx> #include <vcl/TypeSerializer.hxx> +#ifdef _WIN32 +#include <vcl/metric.hxx> +#endif + using namespace vcl; namespace @@ -358,7 +362,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 ) { VersionCompatRead aCompat( rIStm ); sal_uInt16 nTmp16(0); @@ -401,15 +405,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 ) { - VersionCompatWrite aCompat( rOStm, 3 ); + // tdf#127471 increase to version 4 + VersionCompatWrite aCompat( rOStm, 4 ); + TypeSerializer aSerializer(rOStm); rOStm.WriteUniOrByteString( rImplFont.GetFamilyName(), rOStm.GetStreamCharSet() ); rOStm.WriteUniOrByteString( rImplFont.GetStyleName(), rOStm.GetStreamCharSet() ); @@ -441,17 +455,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 |