diff options
author | Jacobo Aragunde Pérez <jaragunde@igalia.com> | 2013-12-10 10:53:29 +0100 |
---|---|---|
committer | Jacobo Aragunde Pérez <jaragunde@igalia.com> | 2013-12-11 17:38:56 +0100 |
commit | 1835074d525d12629008f8a6d5ed27402d18f4b3 (patch) | |
tree | b2a5fe34f61da528fa1f269815430b0abb3988ca | |
parent | 0f5a7bc99fff074336b8d122a0bcc8f3c8e79a7f (diff) |
fdo#64232: fix theme fonts application
We were applying the theme fonts taking only into account the
<a:latin>, <a:ea> and <a:cs> tags to set latin, eastAsia and cs fonts
respectively. Word uses in addition the <a:font> tags to define a
font name per language, in combination with <w:themeFontLang> tag in
settings.xml file which indicates the default language for latin, cs
and eastAsia. For example, with <w:themeFontLang w:bidi="he-IL" />
the default language for cs text is Hebrew, if the theme says
<a:font script="Hebr" typeface="Arial"/> then the selected font for
those sections of text should be Arial.
In theory, Word would also be able to define the language for a
specific section of text and that should receive the proper font from
the theme definition, but we are currently not supporting it. More
info: http://blogs.msdn.com/b/officeinteroperability/archive/2013/04/
22/office-open-xml-themes-schemes-and-fonts.aspx
Main changes in this patch:
* Added setter and getter values to ThemeTable and SettingsTable to
be able to pass the values read in <w:themeFontLang> tag.
* Added support to manage the values in <w:themeFontLang> and
<a:font> tags, which used to be discarded.
* Added methods to translate locale definitions to the language codes
used in the <a:font>, using a table defined in the link above.
Change-Id: I78e6da5feab34cb9ff770a2c60e2f7229e7fb140
-rw-r--r-- | writerfilter/source/dmapper/DomainMapper.cxx | 2 | ||||
-rw-r--r-- | writerfilter/source/dmapper/SettingsTable.cxx | 20 | ||||
-rw-r--r-- | writerfilter/source/dmapper/SettingsTable.hxx | 2 | ||||
-rw-r--r-- | writerfilter/source/dmapper/ThemeTable.cxx | 346 | ||||
-rw-r--r-- | writerfilter/source/dmapper/ThemeTable.hxx | 7 | ||||
-rw-r--r-- | writerfilter/source/ooxml/model.xml | 3 |
6 files changed, 380 insertions, 0 deletions
diff --git a/writerfilter/source/dmapper/DomainMapper.cxx b/writerfilter/source/dmapper/DomainMapper.cxx index 190e4b015bc7..360ac57f201b 100644 --- a/writerfilter/source/dmapper/DomainMapper.cxx +++ b/writerfilter/source/dmapper/DomainMapper.cxx @@ -4035,6 +4035,8 @@ void DomainMapper::lcl_table(Id name, writerfilter::Reference<Table>::Pointer_t } break; case NS_ooxml::LN_THEMETABLE: + m_pImpl->GetThemeTable()->setThemeFontLangProperties( + m_pImpl->GetSettingsTable()->GetThemeFontLangProperties() ); ref->resolve ( *m_pImpl->GetThemeTable() ); break; case NS_ooxml::LN_settings_settings: diff --git a/writerfilter/source/dmapper/SettingsTable.cxx b/writerfilter/source/dmapper/SettingsTable.cxx index b01047ac0a9a..3bbe5efb1ad1 100644 --- a/writerfilter/source/dmapper/SettingsTable.cxx +++ b/writerfilter/source/dmapper/SettingsTable.cxx @@ -73,6 +73,7 @@ struct SettingsTable_Impl bool embedSystemFonts; bool m_bDoNotUseHTMLParagraphAutoSpacing; bool m_bSplitPgBreakAndParaMark; + uno::Sequence<beans::PropertyValue> m_pThemeFontLangProps; SettingsTable_Impl( DomainMapper& rDMapper, const uno::Reference< lang::XMultiServiceFactory > xTextFactory ) : m_rDMapper( rDMapper ) @@ -97,6 +98,7 @@ struct SettingsTable_Impl , embedSystemFonts(false) , m_bDoNotUseHTMLParagraphAutoSpacing(false) , m_bSplitPgBreakAndParaMark(false) + , m_pThemeFontLangProps(3) {} }; @@ -117,12 +119,25 @@ SettingsTable::~SettingsTable() void SettingsTable::lcl_attribute(Id nName, Value & val) { int nIntValue = val.getInt(); + OUString sStringValue = val.getString(); switch(nName) { case NS_ooxml::LN_CT_Zoom_percent: m_pImpl->m_nZoomFactor = nIntValue; break; + case NS_ooxml::LN_CT_Language_val: + m_pImpl->m_pThemeFontLangProps[0].Name = "val"; + m_pImpl->m_pThemeFontLangProps[0].Value <<= sStringValue; + break; + case NS_ooxml::LN_CT_Language_eastAsia: + m_pImpl->m_pThemeFontLangProps[1].Name = "eastAsia"; + m_pImpl->m_pThemeFontLangProps[1].Value <<= sStringValue; + break; + case NS_ooxml::LN_CT_Language_bidi: + m_pImpl->m_pThemeFontLangProps[2].Name = "bidi"; + m_pImpl->m_pThemeFontLangProps[2].Value <<= sStringValue; + break; default: { #ifdef DEBUG_DMAPPER_SETTINGS_TABLE @@ -281,6 +296,11 @@ bool SettingsTable::GetSplitPgBreakAndParaMark() const return m_pImpl->m_bSplitPgBreakAndParaMark; } +uno::Sequence<beans::PropertyValue> SettingsTable::GetThemeFontLangProperties() const +{ + return m_pImpl->m_pThemeFontLangProps; +} + void SettingsTable::ApplyProperties( uno::Reference< text::XTextDocument > xDoc ) { uno::Reference< beans::XPropertySet> xDocProps( xDoc, uno::UNO_QUERY ); diff --git a/writerfilter/source/dmapper/SettingsTable.hxx b/writerfilter/source/dmapper/SettingsTable.hxx index 14b7552135f3..16799447a56e 100644 --- a/writerfilter/source/dmapper/SettingsTable.hxx +++ b/writerfilter/source/dmapper/SettingsTable.hxx @@ -71,6 +71,8 @@ class WRITERFILTER_DLLPRIVATE SettingsTable : public LoggedProperties, public Lo bool GetDoNotUseHTMLParagraphAutoSpacing() const; bool GetSplitPgBreakAndParaMark() const; + uno::Sequence<beans::PropertyValue> GetThemeFontLangProperties() const; + void ApplyProperties( uno::Reference< text::XTextDocument > xDoc ); private: diff --git a/writerfilter/source/dmapper/ThemeTable.cxx b/writerfilter/source/dmapper/ThemeTable.cxx index 06a492337b37..6d623e024b03 100644 --- a/writerfilter/source/dmapper/ThemeTable.cxx +++ b/writerfilter/source/dmapper/ThemeTable.cxx @@ -38,6 +38,10 @@ struct ThemeTable_Impl std::map<sal_uInt32, std::map<sal_uInt32, OUString> > m_themeFontMap; sal_uInt32 m_currentThemeFontId; std::map<sal_uInt32, OUString> m_currentFontThemeEntry; + OUString m_supplementalFontName; + sal_uInt32 m_supplementalFontId = 0; + OUString m_themeFontLangEastAsia; + OUString m_themeFontLangBidi; }; ThemeTable::ThemeTable() @@ -67,6 +71,19 @@ void ThemeTable::lcl_attribute(Id Name, Value & val) if (!sValue.isEmpty()) m_pImpl->m_currentFontThemeEntry[m_pImpl->m_currentThemeFontId] = sValue; break; + case NS_ooxml::LN_CT_SupplementalFont_script: + if (!sValue.isEmpty()) + { + if (sValue == m_pImpl->m_themeFontLangBidi) + m_pImpl->m_supplementalFontId = NS_ooxml::LN_CT_FontCollection_cs; + else if (sValue == m_pImpl->m_themeFontLangEastAsia) + m_pImpl->m_supplementalFontId = NS_ooxml::LN_CT_FontCollection_ea; + } + break; + case NS_ooxml::LN_CT_SupplementalFont_typeface: + if (!sValue.isEmpty()) + m_pImpl->m_supplementalFontName = sValue; + break; default: { #ifdef DEBUG_DOMAINMAPPER @@ -74,6 +91,12 @@ void ThemeTable::lcl_attribute(Id Name, Value & val) #endif } } + if(m_pImpl->m_supplementalFontId && m_pImpl->m_supplementalFontName.getLength() > 0) + { + m_pImpl->m_currentFontThemeEntry[m_pImpl->m_supplementalFontId] = m_pImpl->m_supplementalFontName; + m_pImpl->m_supplementalFontName = ""; + m_pImpl->m_supplementalFontId = 0; + } #ifdef DEBUG_DOMAINMAPPER dmapper_logger->endElement(); #endif @@ -117,6 +140,13 @@ void ThemeTable::lcl_sprm(Sprm& rSprm) pProperties->resolve(*this); } break; + case NS_ooxml::LN_CT_FontCollection_font: + { + writerfilter::Reference<Properties>::Pointer_t pProperties = rSprm.getProps(); + if (pProperties.get()) + pProperties->resolve(*this); + } + break; default: { #ifdef DEBUG_DOMAINMAPPER @@ -220,6 +250,322 @@ const OUString ThemeTable::getFontNameForTheme(const Id id) const } } +void ThemeTable::setThemeFontLangProperties(uno::Sequence<beans::PropertyValue> aPropSeq) +{ + for (sal_Int32 i = 0 ; i < aPropSeq.getLength() ; i ++) + { + OUString sLocaleName; + aPropSeq.getConstArray()[i].Value >>= sLocaleName; + if (aPropSeq.getConstArray()[i].Name == "eastAsia") + m_pImpl->m_themeFontLangEastAsia = fromLocaleToScriptTag(sLocaleName); + if (aPropSeq.getConstArray()[i].Name == "bidi") + m_pImpl->m_themeFontLangBidi = fromLocaleToScriptTag(sLocaleName); + + } +} + +OUString ThemeTable::fromLocaleToScriptTag(OUString sLocale) +{ + return fromLCIDToScriptTag(LanguageTag::convertToLanguageType(sLocale)); +} + +OUString ThemeTable::fromLCIDToScriptTag(LanguageType lang) +{ + // conversion list from: + // http://blogs.msdn.com/b/officeinteroperability/archive/2013/04/22/office-open-xml-themes-schemes-and-fonts.aspx + switch (lang) + { + case 0x429 : // lidFarsi + case 0x401 : // lidArabic + case 0x801 : // lidIraq + case 0xc01 : // lidEgyptian + case 0x1001 : // lidLibya + case 0x1401 : // lidAlgerian + case 0x1801 : // lidMorocco + case 0x1c01 : // lidTunisia + case 0x2001 : // lidOman + case 0x2401 : // lidYemen + case 0x2801 : // lidSyria + case 0x2c01 : // lidJordan + case 0x3001 : // lidLebanon + case 0x3401 : // lidKuwait + case 0x3801 : // lidUAE + case 0x3c01 : // lidBahrain + case 0x4001 : // lidQatar + case 0x420 : // lidUrdu + case 0x846 : // lidPunjabiPakistan + case 0x859 : // lidSindhiPakistan + case 0x45f : // lidTamazight + case 0x460 : // lidKashmiri + case 0x463 : // lidPashto + case 0x48c : // lidDari + return OUString("Arab"); + case 0x42b : // lidArmenian + return OUString("Armn"); + case 0x445 : // lidBengali + case 0x845 : // lidBengaliBangladesh + case 0x44d : // lidAssamese + case 0x458 : // lidManipuri + return OUString("Beng"); + case 0x45d : // lidInuktitut + return OUString("Cans"); + case 0x45c : // lidCherokee + return OUString("Cher"); + case 0x419 : // lidRussian + case 0x402 : // lidBulgarian + case 0x281a : // lidSerbianCyrillic + case 0x422 : // lidUkranian + case 0x819 : // lidRussianMoldavia + case 0xc1a : // lidSerbianCyrillicSerbMont + case 0x1c1a : // lidSerbianBosniaHerzegovinaCyrillic + case 0x201a : // lidBosnianBosniaHerzegovinaCyrillic + case 0x301a : // lidSerbianMontenegroCyrillic + case 0x423 : // lidByelorussian + case 0x428 : // lidTajik + case 0x82c : // lidAzeriCyrillic + case 0x42f : // lidMacedonian + case 0x43f : // lidKazakh + case 0x440 : // lidKyrgyz + case 0x843 : // lidUzbekCyrillic + case 0x444 : // lidTatar + case 0x450 : // lidMongolian + case 0x46d : // lidBashkir + case 0x485 : // lidSakha + return OUString("Cyrl"); + case 0x439 : // lidHindi + case 0x44e : // lidMarathi + case 0x44f : // lidSanskrit + case 0x457 : // lidKonkani + case 0x459 : // lidSindhi + case 0x860 : // lidKashmiriIndia + case 0x461 : // lidNepali + case 0x861 : // lidNepaliIndia + return OUString("Deva"); + case 0x45e : // lidAmharic + case 0x473 : // lidTigrignaEthiopic + case 0x873 : // lidTigrignaEritrea + return OUString("Ethi"); + case 0x437 : // lidGeorgian + return OUString("Geor"); + case 0x408 : // lidGreek + return OUString("Grek"); + case 0x447 : // lidGujarati + return OUString("Gujr"); + case 0x446 : // lidPunjabi + return OUString("Guru"); + case 0x412 : // lidKoreanExtWansung + return OUString("Hang"); + case 0x804 : // lidChineseSimp + case 0x1004 : // lidSingapore + return OUString("Hans"); + case 0x404 : // lidChineseTrad + case 0xc04 : // lidHongkong + case 0x1404 : // lidMacau + return OUString("Hant"); + case 0x40d : // lidHebrew + case 0x43d : // lidYiddish + return OUString("Hebr"); + case 0x411 : // lidJapanese + return OUString("Jpan"); + case 0x453 : // lidKhmer + return OUString("Khmr"); + case 0x44b : // lidKannada + return OUString("Knda"); + case 0x454 : // lidLao + return OUString("Laoo"); + case 0x409 : // lidAmerican + case 0xc09 : // lidAustralian + case 0x809 : // lidBritish + case 0x1009 : // lidEnglishCanadian + case 0x403 : // lidCatalan + case 0x406 : // lidDanish + case 0x413 : // lidDutch + case 0x813 : // lidDutchBelgian + case 0x479 : // lidPapiamentu + case 0x40b : // lidFinnish + case 0x40c : // lidFrench + case 0xc0c : // lidFrenchCanadian + case 0x407 : // lidGerman + case 0x807 : // lidSwissGerman + case 0xc07 : // lidAustrianGerman + case 0x1007 : // lidGermanLuxembourg + case 0x1407 : // lidGermanLiechtenstein + case 0x410 : // lidItalian + case 0x414 : // lidNorskBokmal + case 0x814 : // lidNorskNynorsk + case 0x416 : // lidPortBrazil + case 0x816 : // lidPortIberian + case 0x40a : // lidSpanish + case 0x41d : // lidSwedish + case 0x405 : // lidCzech + case 0x40e : // lidHungarian + case 0x415 : // lidPolish + case 0x41f : // lidTurkish + case 0x42d : // lidBasque + case 0x424 : // lidSlovenian + case 0x426 : // lidLatvian + case 0x427 : // lidLithuanian + case 0x418 : // lidRomanian + case 0x818 : // lidRomanianMoldavia + case 0x241a : // lidSerbianLatin + case 0x41a : // lidCroatian, lidCroat + case 0x491 : // lidGaelicScots + case 0x83c : // lidGaelicIrish + case 0x430 : // lidSutu + case 0x431 : // lidTsonga + case 0x432 : // lidTswana + case 0x433 : // lidVenda + case 0x434 : // lidXhosa + case 0x435 : // lidZulu + case 0x436 : // lidAfrikaans + case 0x425 : // lidEstonian + case 0x456 : // lidGalician + case 0x41b : // lidSlovak + case 0x1409 : // lidEnglishNewZealand + case 0x1809 : // lidEnglishIreland + case 0x1c09 : // lidEnglishSouthAfrica + case 0x2009 : // lidEnglishJamaica + case 0x2409 : // lidEnglishCaribbean + case 0x2809 : // lidEnglishBelize + case 0x2c09 : // lidEnglishTrinidad + case 0x3009 : // lidEnglishZimbabwe + case 0x3409 : // lidEnglishPhilippines + case 0x3809 : // lidEnglishIndonesia + case 0x3c09 : // lidEnglishHongKong + case 0x4009 : // lidEnglishIndia + case 0x4409 : // lidEnglishMalaysia + case 0x4809 : // lidEnglishSingapore + case 0x80a : // lidSpanishMexican, lidMexican + case 0xc0a : // lidSpanishModern + case 0x100a : // lidGuatemala + case 0x140a : // lidCostaRica + case 0x180a : // lidPanama + case 0x1c0a : // lidDominicanRepublic + case 0x200a : // lidSpanishSA, lidVenezuela + case 0x240a : // lidColombia + case 0x280a : // lidPeru + case 0x2c0a : // lidArgentina + case 0x300a : // lidEcuador + case 0x340a : // lidChile + case 0x380a : // lidUruguay + case 0x3c0a : // lidParguay + case 0x400a : // lidBolivia + case 0x440a : // lidElSalvador + case 0x480a : // lidHonduras + case 0x4c0a : // lidNicaragua + case 0x500a : // lidPuertoRico + case 0x540a : // lidSpanishUS + case 0x80c : // lidFrenchBelgian + case 0x100c : // lidFrenchSwiss + case 0x140c : // lidFrenchLuxembourg + case 0x180c : // lidFrenchMonaco + case 0x1c0c : // lidFrenchWestIndies + case 0x200c : // lidFrenchReunion + case 0x240c : // lidFrenchCongoDRC, lidFrenchZaire + case 0x280c : // lidFrenchSenegal + case 0x2c0c : // lidFrenchCameroon + case 0x300c : // lidFrenchCotedIvoire + case 0x340c : // lidFrenchMali + case 0x3c0c : // lidFrenchHaiti + case 0x380c : // lidFrenchMorocco + case 0x40f : // lidIcelandic + case 0x810 : // lidItalianSwiss + case 0x417 : // lidRhaetoRomanic, lidRomanic + case 0x81a : // lidSerbianLatinSerbMont, lidCroatSerbo + case 0x101a : // lidBosniaHerzegovina + case 0x141a : // lidBosnianBosniaHerzegovinaLatin + case 0x181a : // lidSerbianBosniaHerzegovinaLatin + case 0x2c1a : // lidSerbianMontenegroLatin + case 0x41c : // lidAlbanian + case 0x81d : // lidSwedishFinland + case 0x421 : // lidBahasa, lidIndonesian + case 0x42c : // lidAzeriLatin + case 0x42e : // lidSorbian + case 0x82e : // lidLowerSorbian + case 0x438 : // lidFaeroese + case 0x43a : // lidMaltese + case 0x43b : // lidSamiLappish + case 0x83b : // lidNorthSamiSwe + case 0xc3b : // lidNorthernSamiFi + case 0x103b : // lidLuleSamiNor + case 0x143b : // lidLuleSamiSwe + case 0x183b : // lidSouthSamiNor + case 0x1c3b : // lidSouthSamiSwe + case 0x203b : // lidSkoltSami + case 0x243b : // lidInariSami + case 0x43e : // lidMalaysian + case 0x83e : // lidMalayBrunei + case 0x441 : // lidSwahili + case 0x442 : // lidTurkmen + case 0x443 : // lidUzbekLatin + case 0x452 : // lidWelsh + case 0x85d : // lidInuktitutLatin + case 0x85f : // lidTamazightLatin + case 0x462 : // lidFrisian + case 0x464 : // lidFilipino + case 0x466 : // lidEdo + case 0x467 : // lidFulfulde + case 0x468 : // lidHausa + case 0x469 : // lidIbibio + case 0x46a : // lidYoruba + case 0x46b : // lidQuechuaBol + case 0x86b : // lidQuechuaEcu + case 0xc6b : // lidQuechuaPe + case 0x46c : // lidSesothoSaLeboa + case 0x46e : // lidLuxembourgish + case 0x46f : // lidGreenlandic + case 0x470 : // lidIgbo + case 0x471 : // lidKanuri + case 0x472 : // lidOromo + case 0x474 : // lidGuarani + case 0x475 : // lidHawaiian + case 0x476 : // lidLatin + case 0x477 : // lidSomali + case 0x47a : // lidMapudungun + case 0x47c : // lidMohawk + case 0x47e : // lidBreton + case 0x481 : // lidMaori + case 0x482 : // lidOccitan + case 0x483 : // lidCorsican + case 0x484 : // lidAlsatian + case 0x486 : // lidKiche + case 0x487 : // lidKinyarwanda + case 0x488 : // lidWolof + return OUString("Latn"); + case 0x44c : // lidMalayalam + return OUString("Mlym"); + case 0x850 : // lidMongolianMongo + return OUString("Mong"); + case 0x455 : // lidBurmese + return OUString("Mymr"); + case 0x448 : // lidOriya + return OUString("Orya"); + case 0x45b : // lidSinhalese + return OUString("Sinh"); + case 0x45a : // lidSyriac + return OUString("Syrc"); + case 0x449 : // lidTamil + return OUString("Taml"); + case 0x44a : // lidTelugu + return OUString("Telu"); + case 0x465 : // lidMaldivian + return OUString("Thaa"); + case 0x41e : // lidThai + return OUString("Thai"); + case 0x451 : // lidTibetan + case 0x851 : // lidBhutanese + return OUString("Tibt"); + case 0x480 : // lidUighur + return OUString("Uigh"); + case 0x42a : // lidVietnamese + return OUString("Viet"); + case 0x478 : // lidYi + return OUString("Yiii"); + default: + return OUString(""); + } +} + }//namespace dmapper } //namespace writerfilter diff --git a/writerfilter/source/dmapper/ThemeTable.hxx b/writerfilter/source/dmapper/ThemeTable.hxx index 75145555f576..190da8504e21 100644 --- a/writerfilter/source/dmapper/ThemeTable.hxx +++ b/writerfilter/source/dmapper/ThemeTable.hxx @@ -22,7 +22,9 @@ #include <WriterFilterDllApi.hxx> #include <resourcemodel/LoggedResources.hxx> +#include <com/sun/star/beans/PropertyValue.hpp> #include <com/sun/star/lang/XComponent.hpp> +#include <i18nlangtag/languagetag.hxx> #include <map> namespace writerfilter { @@ -41,6 +43,7 @@ public: const OUString getFontNameForTheme(const Id id) const; static OUString getStringForTheme(const Id id); + void setThemeFontLangProperties(uno::Sequence<beans::PropertyValue> aPropSeq); private: // Properties @@ -49,6 +52,10 @@ public: // Table virtual void lcl_entry(int pos, writerfilter::Reference<Properties>::Pointer_t ref); + + // Helper methods + OUString fromLocaleToScriptTag(OUString sLocale); + OUString fromLCIDToScriptTag(LanguageType lang); }; typedef boost::shared_ptr< ThemeTable > ThemeTablePtr; }} diff --git a/writerfilter/source/ooxml/model.xml b/writerfilter/source/ooxml/model.xml index 86c9138f7a6d..804a9ad251e2 100644 --- a/writerfilter/source/ooxml/model.xml +++ b/writerfilter/source/ooxml/model.xml @@ -989,6 +989,9 @@ </attribute> <attribute name="typeface"> <ref name="ST_TextTypeface"/> + <data type="string"> + <xs:documentation>Typeface</xs:documentation> + </data> <xs:documentation>Typeface</xs:documentation> </attribute> </define> |