Kaydet (Commit) 1835074d authored tarafından Jacobo Aragunde Pérez's avatar Jacobo Aragunde Pérez

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
üst 0f5a7bc9
......@@ -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:
......
......@@ -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 );
......
......@@ -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:
......
......@@ -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
......
......@@ -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;
}}
......
......@@ -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>
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment