diff options
author | Mike Kaganski <mike.kaganski@collabora.com> | 2016-08-23 00:33:26 +1000 |
---|---|---|
committer | Stephan Bergmann <sbergman@redhat.com> | 2016-08-30 05:40:43 +0000 |
commit | 20f6a6b159c69771dc0e087f63b6c701908e32e2 (patch) | |
tree | 455b03cfe737f212d31810994fba2e91ff54ce56 | |
parent | 965f379b6ed2884f60b7fd6c0aae107fa5fceea7 (diff) |
tdf#99402: fix Metafile Font handling
1. For DEFAULT_CHARSET/OEM_CHARSET, use correct encoding
based on LibreOffice Default Language for Documents setting
(Tools->Options...->Language Settings->Languages).
For that, two functions added to tencinfo.h, that map language
names to corresponding Windows ANSI/OEM encodings.
2. If charset is DEFAULT_CHARSET/OEM_CHARSET for Symbol font,
then always use RTL_TEXTENCODING_SYMBOL.
Unit test is included.
Change-Id: Ibff63e7a03dec42a9d2a74399936d6bc04f2ff1a
Reviewed-on: https://gerrit.libreoffice.org/28322
Tested-by: Jenkins <ci@libreoffice.org>
Reviewed-by: Stephan Bergmann <sbergman@redhat.com>
-rw-r--r-- | include/rtl/tencinfo.h | 2 | ||||
-rw-r--r-- | include/unotools/wincodepage.hxx | 35 | ||||
-rw-r--r-- | unotools/Library_utl.mk | 1 | ||||
-rw-r--r-- | unotools/source/misc/wincodepage.cxx | 156 | ||||
-rw-r--r-- | vcl/CppunitTest_vcl_wmf_test.mk | 200 | ||||
-rw-r--r-- | vcl/qa/cppunit/wmf/wmfimporttest.cxx | 48 | ||||
-rw-r--r-- | vcl/source/filter/wmf/winmtf.cxx | 28 |
7 files changed, 449 insertions, 21 deletions
diff --git a/include/rtl/tencinfo.h b/include/rtl/tencinfo.h index 48f2ff0fdcf8..c6980112410c 100644 --- a/include/rtl/tencinfo.h +++ b/include/rtl/tencinfo.h @@ -170,6 +170,8 @@ SAL_DLLPUBLIC sal_Bool SAL_CALL rtl_getTextEncodingInfo( @return The corresponding rtl_TextEncoding value, or RTL_TEXTENCODING_DONTKNOW if no mapping is applicable. + If nWinCharset is 255 (OEM_CHARSET), then return value is RTL_TEXTENCODING_IBM_850, + regardless of current locale. */ SAL_DLLPUBLIC rtl_TextEncoding SAL_CALL rtl_getTextEncodingFromWindowsCharset( sal_uInt8 nWinCharset ); diff --git a/include/unotools/wincodepage.hxx b/include/unotools/wincodepage.hxx new file mode 100644 index 000000000000..f106a0f1760f --- /dev/null +++ b/include/unotools/wincodepage.hxx @@ -0,0 +1,35 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#ifndef INCLUDED_UNOTOOLS_WINCODEPAGE_HXX +#define INCLUDED_UNOTOOLS_WINCODEPAGE_HXX + +#include <unotools/unotoolsdllapi.h> +#include <rtl/textenc.h> + +/** Map from a ISO-639 language code (and optionally ISO-3166 country/region code) +to a text encoding of corresponding Windows ANSI or OEM codepage. + +@param pLanguage +Any language-country string. Must not be null. + +@param bOEM +If true, OEM codepage is returned, otherwise ANSI. + +@return +The corresponding rtl_TextEncoding value. +If no mapping is found, RTL_TEXTENCODING_IBM_850 is returned when bOEM is true, +RTL_TEXTENCODING_MS_1252 otherwise. +*/ +UNOTOOLS_DLLPUBLIC rtl_TextEncoding utl_getWinTextEncodingFromLangStr( + const char* pLanguage, bool bOEM = false); + +#endif // INCLUDED_UNOTOOLS_WINCODEPAGE_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/unotools/Library_utl.mk b/unotools/Library_utl.mk index fb0f19f93be7..0d4ea9f2e692 100644 --- a/unotools/Library_utl.mk +++ b/unotools/Library_utl.mk @@ -103,6 +103,7 @@ $(eval $(call gb_Library_add_exception_objects,utl,\ unotools/source/misc/sharedunocomponent \ unotools/source/misc/syslocale \ unotools/source/misc/unotoolsservices \ + unotools/source/misc/wincodepage \ unotools/source/misc/ServiceDocumenter \ unotools/source/streaming/streamhelper \ unotools/source/streaming/streamwrap \ diff --git a/unotools/source/misc/wincodepage.cxx b/unotools/source/misc/wincodepage.cxx new file mode 100644 index 000000000000..5a8c44c9a923 --- /dev/null +++ b/unotools/source/misc/wincodepage.cxx @@ -0,0 +1,156 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#include <unotools/wincodepage.hxx> +#include "rtl/string.h" +#include "rtl/textenc.h" + +namespace{ + +// See https://msdn.microsoft.com/en-us/library/windows/desktop/dd317756 +rtl_TextEncoding impl_getWinTextEncodingFromLangStrANSI(const char* pLanguage) +{ + auto nLangLen = rtl_str_getLength(pLanguage); + + struct LangEncodingDef + { + const char* mpLangStr; + decltype(nLangLen) mnLangStrLen; + rtl_TextEncoding meTextEncoding; + }; + static LangEncodingDef const aLanguageTab[] = + { + { "en", 2, RTL_TEXTENCODING_MS_1252 }, // Most used -> first in list + { "th", 2, RTL_TEXTENCODING_MS_874 }, + { "ja", 2, RTL_TEXTENCODING_MS_932 }, + { "zh-cn", 5, RTL_TEXTENCODING_MS_936 }, // Chinese (simplified) - must go before "zh" + { "ko", 2, RTL_TEXTENCODING_MS_949 }, + { "zh", 2, RTL_TEXTENCODING_MS_950 }, // Chinese (traditional) + { "bs", 2, RTL_TEXTENCODING_MS_1250 }, + { "cs", 2, RTL_TEXTENCODING_MS_1250 }, + { "hr", 2, RTL_TEXTENCODING_MS_1250 }, + { "hu", 2, RTL_TEXTENCODING_MS_1250 }, + { "pl", 2, RTL_TEXTENCODING_MS_1250 }, + { "ro", 2, RTL_TEXTENCODING_MS_1250 }, + { "sk", 2, RTL_TEXTENCODING_MS_1250 }, + { "sl", 2, RTL_TEXTENCODING_MS_1250 }, +// { "sr", 2, RTL_TEXTENCODING_MS_1250 }, + { "sq", 2, RTL_TEXTENCODING_MS_1250 }, + { "be", 2, RTL_TEXTENCODING_MS_1251 }, + { "bg", 2, RTL_TEXTENCODING_MS_1251 }, + { "mk", 2, RTL_TEXTENCODING_MS_1251 }, + { "ru", 2, RTL_TEXTENCODING_MS_1251 }, + { "sr", 2, RTL_TEXTENCODING_MS_1251 }, + { "uk", 2, RTL_TEXTENCODING_MS_1251 }, + { "es", 2, RTL_TEXTENCODING_MS_1252 }, + { "el", 2, RTL_TEXTENCODING_MS_1253 }, + { "tr", 2, RTL_TEXTENCODING_MS_1254 }, + { "he", 2, RTL_TEXTENCODING_MS_1255 }, + { "ar", 2, RTL_TEXTENCODING_MS_1256 }, + { "et", 2, RTL_TEXTENCODING_MS_1257 }, + { "lt", 2, RTL_TEXTENCODING_MS_1257 }, + { "lv", 2, RTL_TEXTENCODING_MS_1257 }, + { "vi", 2, RTL_TEXTENCODING_MS_1258 }, + }; + + for (auto& def : aLanguageTab) + { + if (rtl_str_shortenedCompareIgnoreAsciiCase_WithLength(pLanguage, nLangLen, + def.mpLangStr, def.mnLangStrLen, + def.mnLangStrLen) == 0) + { + return def.meTextEncoding; + } + } + + return RTL_TEXTENCODING_MS_1252; +} + +/* ----------------------------------------------------------------------- */ + +// See https://msdn.microsoft.com/en-us/library/windows/desktop/dd317756 +// See http://shapelib.maptools.org/codepage.html +rtl_TextEncoding impl_getWinTextEncodingFromLangStrOEM(const char* pLanguage) +{ + auto nLangLen = rtl_str_getLength(pLanguage); + + struct LangEncodingDef + { + const char* mpLangStr; + decltype(nLangLen) mnLangStrLen; + rtl_TextEncoding meTextEncoding; + }; + static LangEncodingDef const aLanguageTab[] = + { + { "de", 2, RTL_TEXTENCODING_IBM_437 }, // OEM United States + { "en-us", 5, RTL_TEXTENCODING_IBM_437 }, // OEM United States + { "fi", 2, RTL_TEXTENCODING_IBM_437 }, // OEM United States + { "fr-ca", 5, RTL_TEXTENCODING_IBM_863 }, // OEM French Canadian; French Canadian (DOS) + { "fr", 2, RTL_TEXTENCODING_IBM_437 }, // OEM United States + { "it", 2, RTL_TEXTENCODING_IBM_437 }, // OEM United States + { "nl", 2, RTL_TEXTENCODING_IBM_437 }, // OEM United States + { "sv", 2, RTL_TEXTENCODING_IBM_437 }, // OEM United States + { "el", 2, RTL_TEXTENCODING_IBM_737 }, // OEM Greek (formerly 437G); Greek (DOS) + { "et", 2, RTL_TEXTENCODING_IBM_775 }, // OEM Baltic; Baltic (DOS) + { "lt", 2, RTL_TEXTENCODING_IBM_775 }, // OEM Baltic; Baltic (DOS) + { "lv", 2, RTL_TEXTENCODING_IBM_775 }, // OEM Baltic; Baltic (DOS) + { "en", 2, RTL_TEXTENCODING_IBM_850 }, // OEM Multilingual Latin 1; Western European (DOS) + { "bs", 2, RTL_TEXTENCODING_IBM_852 }, // OEM Latin 2; Central European (DOS) + { "cs", 2, RTL_TEXTENCODING_IBM_852 }, // OEM Latin 2; Central European (DOS) + { "hr", 2, RTL_TEXTENCODING_IBM_852 }, // OEM Latin 2; Central European (DOS) + { "hu", 2, RTL_TEXTENCODING_IBM_852 }, // OEM Latin 2; Central European (DOS) + { "pl", 2, RTL_TEXTENCODING_IBM_852 }, // OEM Latin 2; Central European (DOS) + { "ro", 2, RTL_TEXTENCODING_IBM_852 }, // OEM Latin 2; Central European (DOS) + { "sk", 2, RTL_TEXTENCODING_IBM_852 }, // OEM Latin 2; Central European (DOS) + { "sl", 2, RTL_TEXTENCODING_IBM_852 }, // OEM Latin 2; Central European (DOS) +// { "sr", 2, RTL_TEXTENCODING_IBM_852 }, // OEM Latin 2; Central European (DOS) + { "bg", 2, RTL_TEXTENCODING_IBM_855 }, // OEM Cyrillic (primarily Russian) + { "mk", 2, RTL_TEXTENCODING_IBM_855 }, // OEM Cyrillic (primarily Russian) + { "sr", 2, RTL_TEXTENCODING_IBM_855 }, // OEM Cyrillic (primarily Russian) + { "tr", 2, RTL_TEXTENCODING_IBM_857 }, // OEM Turkish; Turkish (DOS) + { "pt", 2, RTL_TEXTENCODING_IBM_860 }, // OEM Portuguese; Portuguese (DOS) + { "is", 2, RTL_TEXTENCODING_IBM_861 }, // OEM Icelandic; Icelandic (DOS) + { "he", 2, RTL_TEXTENCODING_IBM_862 }, // OEM Hebrew; Hebrew (DOS) + { "ar", 2, RTL_TEXTENCODING_IBM_864 }, // OEM Arabic; Arabic (864) + { "da", 2, RTL_TEXTENCODING_IBM_865 }, // OEM Nordic; Nordic (DOS) + { "nn", 2, RTL_TEXTENCODING_IBM_865 }, // OEM Nordic; Nordic (DOS) + { "be", 2, RTL_TEXTENCODING_IBM_866 }, // OEM Russian; Cyrillic (DOS) + { "ru", 2, RTL_TEXTENCODING_IBM_866 }, // OEM Russian; Cyrillic (DOS) + { "uk", 2, RTL_TEXTENCODING_IBM_866 }, // OEM Russian; Cyrillic (DOS) + { "th", 2, RTL_TEXTENCODING_MS_874 }, // ANSI/OEM Thai (ISO 8859-11); Thai (Windows) + { "ja", 2, RTL_TEXTENCODING_MS_932 }, // ANSI/OEM Japanese; Japanese (Shift-JIS) + { "zh-cn", 5, RTL_TEXTENCODING_MS_936 }, // ANSI/OEM Simplified Chinese (PRC, Singapore); Chinese Simplified (GB2312) + { "ko", 2, RTL_TEXTENCODING_MS_949 }, // ANSI/OEM Korean (Unified Hangul Code) + { "zh", 2, RTL_TEXTENCODING_MS_950 }, // ANSI/OEM Traditional Chinese (Taiwan; Hong Kong SAR, PRC); Chinese Traditional (Big5) + { "vi", 2, RTL_TEXTENCODING_MS_1258 }, // ANSI/OEM Vietnamese; Vietnamese (Windows) + }; + + for (auto& def : aLanguageTab) + { + if (rtl_str_shortenedCompareIgnoreAsciiCase_WithLength(pLanguage, nLangLen, + def.mpLangStr, def.mnLangStrLen, + def.mnLangStrLen) == 0) + { + return def.meTextEncoding; + } + } + + return RTL_TEXTENCODING_IBM_850; +} + +} // namespace + +rtl_TextEncoding utl_getWinTextEncodingFromLangStr(const char* pLanguage, bool bOEM) +{ + return bOEM ? + impl_getWinTextEncodingFromLangStrOEM(pLanguage) : + impl_getWinTextEncodingFromLangStrANSI(pLanguage); +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/vcl/CppunitTest_vcl_wmf_test.mk b/vcl/CppunitTest_vcl_wmf_test.mk index 56136c83f3ec..d63d0b9b31a7 100644 --- a/vcl/CppunitTest_vcl_wmf_test.mk +++ b/vcl/CppunitTest_vcl_wmf_test.mk @@ -14,34 +14,200 @@ $(eval $(call gb_CppunitTest_add_exception_objects,vcl_wmf_test, \ )) $(eval $(call gb_CppunitTest_use_externals,vcl_wmf_test,\ - boost_headers \ + boost_headers \ libxml2 \ )) - $(eval $(call gb_CppunitTest_set_include,vcl_wmf_test,\ $$(INCLUDE) \ -I$(SRCDIR)/vcl/inc \ + -I$(SRCDIR)/vcl/source/filter/wmf \ +)) + +$(eval $(call gb_CppunitTest_use_library_objects,vcl_wmf_test, \ + test-setupvcl \ + vcl \ +)) + +$(eval $(call gb_CppunitTest_use_externals,vcl_wmf_test,\ + $(if $(filter LINUX MACOSX %BSD SOLARIS,$(OS)), \ + curl) \ + jpeg \ + $(if $(filter-out IOS WNT,$(OS)), \ + nss3 \ + plc4) \ + libeot \ )) -$(eval $(call gb_CppunitTest_use_libraries,vcl_wmf_test, \ - comphelper \ - cppu \ - cppuhelper \ - sal \ +$(eval $(call gb_CppunitTest_use_libraries,vcl_wmf_test,\ + $(call gb_Helper_optional,BREAKPAD, \ + crashreport) \ + basegfx \ + comphelper \ + cppu \ + cppuhelper \ + i18nlangtag \ + i18nutil \ + $(if $(filter OPENCL,$(BUILD_TYPE)),opencl) \ + sal \ + salhelper \ + sot \ + svl \ svt \ - test \ - tl \ - unotest \ - vcl \ - utl \ - $(gb_UWINAPI) \ + test \ + tl \ + ucbhelper \ + unotest \ + utl \ + xmlreader \ + $(gb_UWINAPI) \ +)) + +ifeq ($(OS),MACOSX) +$(eval $(call gb_CppunitTest_add_libs,vcl_wmf_test,\ + -framework IOKit \ + -F/System/Library/PrivateFrameworks \ + -framework CoreUI \ + -lobjc \ +)) +endif + +ifeq ($(ENABLE_JAVA),TRUE) +$(eval $(call gb_CppunitTest_use_libraries,vcl_wmf_test,\ + jvmaccess \ +)) +endif + +$(eval $(call gb_CppunitTest_use_externals,vcl_wmf_test,\ + gio \ + harfbuzz \ + icuuc \ + lcms2 \ +)) +ifeq ($(ENABLE_HEADLESS),) +$(eval $(call gb_CppunitTest_use_externals,vcl_wmf_test,\ + glew \ + )) +endif + +ifeq ($(ENABLE_GRAPHITE),TRUE) +$(eval $(call gb_CppunitTest_use_external,vcl_wmf_test,graphite)) +endif + +ifeq ($(OS),MACOSX) +$(eval $(call gb_CppunitTest_use_system_darwin_frameworks,vcl_wmf_test,\ + ApplicationServices \ +)) +$(eval $(call gb_CppunitTest_use_system_darwin_frameworks,vcl_wmf_test,\ + $(if $(filter X86_64,$(CPUNAME)),,QuickTime) \ + Cocoa \ + Carbon \ + CoreFoundation \ + OpenGL \ +)) +ifneq ($(ENABLE_MACOSX_SANDBOX),TRUE) +$(eval $(call gb_CppunitTest_use_libraries,vcl_wmf_test,\ + AppleRemote \ +)) +endif +endif + +ifeq ($(USING_X11),TRUE) +$(eval $(call gb_CppunitTest_use_externals,vcl_wmf_test,\ + cairo \ + cups \ + dbus \ + fontconfig \ + freetype \ + valgrind \ +)) +endif + +ifeq ($(ENABLE_HEADLESS),TRUE) +$(eval $(call gb_CppunitTest_use_externals,vcl_wmf_test,\ + cairo \ + freetype \ +)) +ifneq ($(OS),EMSCRIPTEN) +$(eval $(call gb_CppunitTest_use_externals,vcl_wmf_test,\ + fontconfig \ +)) +endif +else +ifeq ($(OS),LINUX) +$(eval $(call gb_CppunitTest_add_libs,vcl_wmf_test,\ + -lm \ + -ldl \ + -lpthread \ + -lGL \ + -lX11 \ +)) +endif +endif + +ifeq ($(OS),ANDROID) +$(eval $(call gb_CppunitTest_add_libs,vcl_wmf_test,\ + -llog \ + -landroid \ + -llo-bootstrap \ +)) +$(eval $(call gb_CppunitTest_use_externals,vcl_wmf_test,\ + cairo \ + fontconfig \ + freetype \ + expat \ )) +endif + +ifeq ($(OS),IOS) +$(eval $(call gb_CppunitTest_use_system_darwin_frameworks,vcl_wmf_test,\ + UIKit \ + CoreFoundation \ +)) +endif + +ifeq ($(OS),WNT) +$(eval $(call gb_CppunitTest_use_system_win32_libs,vcl_wmf_test,\ + advapi32 \ + crypt32 \ + gdi32 \ + gdiplus \ + glu32 \ + imm32 \ + mpr \ + msimg32 \ + opengl32 \ + ole32 \ + shell32 \ + usp10 \ + uuid \ + version \ + winspool \ + setupapi \ + shlwapi \ +)) +#$(eval $(call gb_CppunitTest_add_nativeres,vcl_wmf_test,vcl/salsrc)) +endif + +ifeq ($(OS), WNT) +$(eval $(call gb_CppunitTest_use_externals,vcl_wmf_test,\ + glyphy \ +)) +endif + +ifeq ($(OS), $(filter LINUX %BSD SOLARIS, $(OS))) +$(eval $(call gb_CppunitTest_add_libs,vcl_wmf_test,\ + -lm $(DLOPEN_LIBS) \ + -lpthread \ + -lGL \ + -lX11 \ + -lXext \ +)) +endif $(eval $(call gb_CppunitTest_use_sdk_api,vcl_wmf_test)) $(eval $(call gb_CppunitTest_use_ure,vcl_wmf_test)) -$(eval $(call gb_CppunitTest_use_vcl,vcl_wmf_test)) $(eval $(call gb_CppunitTest_use_components,vcl_wmf_test,\ configmgr/source/configmgr \ @@ -52,4 +218,10 @@ $(eval $(call gb_CppunitTest_use_components,vcl_wmf_test,\ $(eval $(call gb_CppunitTest_use_configuration,vcl_wmf_test)) +# See gb_CppunitTest__use_vcl (solenv/gbuild/CppunitTest.mk; headless): +ifeq ($(USING_X11),TRUE) +$(call gb_CppunitTest_get_target,vcl_wmf_test): \ + $(call gb_Library_get_target,desktop_detector) +endif + # vim: set noet sw=4 ts=4: diff --git a/vcl/qa/cppunit/wmf/wmfimporttest.cxx b/vcl/qa/cppunit/wmf/wmfimporttest.cxx index 1d333f39ceec..67b8329f6c8a 100644 --- a/vcl/qa/cppunit/wmf/wmfimporttest.cxx +++ b/vcl/qa/cppunit/wmf/wmfimporttest.cxx @@ -17,15 +17,17 @@ * the License at http://www.apache.org/licenses/LICENSE-2.0 . */ -#include <test/bootstrapfixture.hxx> #include <test/xmltesttools.hxx> #include <test/mtfxmldump.hxx> +#include <test/setupvcl.hxx> +#include <unotest/bootstrapfixturebase.hxx> #include <vcl/wmf.hxx> #include <vcl/metaact.hxx> +#include <winmtf.hxx> using namespace css; -class WmfTest : public test::BootstrapFixture, public XmlTestTools +class WmfTest : public test::BootstrapFixtureBase, public XmlTestTools { OUString maDataUrl; @@ -36,25 +38,38 @@ class WmfTest : public test::BootstrapFixture, public XmlTestTools public: WmfTest() : - BootstrapFixture(true, false), maDataUrl("/vcl/qa/cppunit/wmf/data/") {} + // Hack around missing "once per class" setUp/tearDown in CppUnit; must be + // called before/after all other tests: + void globalSetUp() { test::setUpVcl(); } + void globalTearDown() { /* DeInitVCL(); */ } + // on e.g. Mac OS X, DeInitVCL() causes more trouble than it's worth, + // calling VclPtr<WorkWindow>::disposeAndClear -> ... -> + // vcl::Window::dispose -> UnoWrapper::WindowDestroy (tk) -> ... -> + // Application::GetSolarMutex in the vcl library (linked from tk) + // instead of the vcl objects linked into the unit test library, which + // isn't initialized + void testNonPlaceableWmf(); void testSine(); void testEmfProblem(); void testEmfLineStyles(); void testWorldTransformFontSize(); void testTdf93750(); + void testTdf99402(); CPPUNIT_TEST_SUITE(WmfTest); + CPPUNIT_TEST(globalSetUp); CPPUNIT_TEST(testNonPlaceableWmf); CPPUNIT_TEST(testSine); CPPUNIT_TEST(testEmfProblem); CPPUNIT_TEST(testEmfLineStyles); CPPUNIT_TEST(testWorldTransformFontSize); CPPUNIT_TEST(testTdf93750); - + CPPUNIT_TEST(testTdf99402); + CPPUNIT_TEST(globalTearDown); CPPUNIT_TEST_SUITE_END(); }; @@ -227,6 +242,31 @@ void WmfTest::testTdf93750() assertXPath(pDoc, "/metafile/push[1]/comment[3]", "datasize", "72"); } +void WmfTest::testTdf99402() +{ + // Symbol font should arrive with RTL_TEXTENCODING_SYMBOL encoding, + // even if charset is OEM_CHARSET/DEFAULT_CHARSET in WMF + LOGFONTW logfontw; + logfontw.lfHeight = 0; + logfontw.lfWidth = 0; + logfontw.lfEscapement = 0; + logfontw.lfOrientation = 0; + logfontw.lfWeight = 0; + logfontw.lfItalic = 0; + logfontw.lfUnderline = 0; + logfontw.lfStrikeOut = 0; + logfontw.lfCharSet = OEM_CHARSET; + logfontw.lfOutPrecision = 0; // OUT_DEFAULT_PRECIS + logfontw.lfClipPrecision = 0; // CLIP_DEFAULT_PRECIS + logfontw.lfQuality = 0; // DEFAULT_QUALITY + logfontw.lfPitchAndFamily = FF_ROMAN | DEFAULT_PITCH; + logfontw.alfFaceName = "Symbol"; + + WinMtfFontStyle fontStyle(logfontw); + + CPPUNIT_ASSERT_EQUAL(RTL_TEXTENCODING_SYMBOL, fontStyle.aFont.GetCharSet()); +} + CPPUNIT_TEST_SUITE_REGISTRATION(WmfTest); CPPUNIT_PLUGIN_IMPLEMENT(); diff --git a/vcl/source/filter/wmf/winmtf.cxx b/vcl/source/filter/wmf/winmtf.cxx index 804b7040f648..58a2d6c9d3b6 100644 --- a/vcl/source/filter/wmf/winmtf.cxx +++ b/vcl/source/filter/wmf/winmtf.cxx @@ -30,6 +30,9 @@ #include <rtl/tencinfo.h> #include <vcl/virdev.hxx> #include <o3tl/make_unique.hxx> +#include "officecfg/Setup.hxx" +#include "officecfg/Office/Linguistic.hxx" +#include "unotools/wincodepage.hxx" #if OSL_DEBUG_LEVEL > 1 #define EMFP_DEBUG(x) x @@ -142,11 +145,28 @@ void WinMtfPathObj::ClosePath() bClosed = true; } +namespace { + +OUString getLODefaultLanguage() +{ + OUString result(officecfg::Office::Linguistic::General::DefaultLocale::get()); + if (result.isEmpty()) + result = officecfg::Setup::L10N::ooSetupSystemLocale::get(); + return result; +} + +} + WinMtfFontStyle::WinMtfFontStyle( LOGFONTW& rFont ) { rtl_TextEncoding eCharSet; - if ( ( rFont.lfCharSet == OEM_CHARSET ) || ( rFont.lfCharSet == DEFAULT_CHARSET ) ) - eCharSet = osl_getThreadTextEncoding(); + if ((rFont.lfCharSet == DEFAULT_CHARSET) || (rFont.lfCharSet == OEM_CHARSET)) + if (rFont.alfFaceName == "Symbol") + // Workaround for incorrect charset for the Symbol nonstandard font + eCharSet = RTL_TEXTENCODING_SYMBOL; + else + eCharSet = utl_getWinTextEncodingFromLangStr(getLODefaultLanguage().toUtf8().getStr(), + rFont.lfCharSet == OEM_CHARSET); else eCharSet = rtl_getTextEncodingFromWindowsCharset( rFont.lfCharSet ); if ( eCharSet == RTL_TEXTENCODING_DONTKNOW ) @@ -198,7 +218,9 @@ WinMtfFontStyle::WinMtfFontStyle( LOGFONTW& rFont ) aFont.SetPitch( ePitch ); FontWeight eWeight; - if( rFont.lfWeight <= FW_THIN ) + if (rFont.lfWeight == 0) // default weight SHOULD be used + eWeight = WEIGHT_DONTKNOW; + else if (rFont.lfWeight <= FW_THIN) eWeight = WEIGHT_THIN; else if( rFont.lfWeight <= FW_ULTRALIGHT ) eWeight = WEIGHT_ULTRALIGHT; |