OLD | NEW |
(Empty) | |
| 1 // Copyright 2015 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. |
| 4 |
| 5 #include "platform/fonts/opentype/OpenTypeCapsSupport.h" |
| 6 |
| 7 namespace blink { |
| 8 |
| 9 OpenTypeCapsSupport::OpenTypeCapsSupport() |
| 10 : m_harfBuzzFace(nullptr) |
| 11 , m_requestedCaps(FontDescription::CapsNormal) |
| 12 , m_fontSupport(FontSupport::Full) |
| 13 , m_capsSynthesis(CapsSynthesis::None) |
| 14 { |
| 15 } |
| 16 |
| 17 OpenTypeCapsSupport::OpenTypeCapsSupport(const HarfBuzzFace* harfBuzzFace, |
| 18 FontDescription::FontVariantCaps requestedCaps, |
| 19 hb_script_t script) |
| 20 : m_harfBuzzFace(harfBuzzFace) |
| 21 , m_requestedCaps(requestedCaps) |
| 22 , m_fontSupport(FontSupport::Full) |
| 23 , m_capsSynthesis(CapsSynthesis::None) |
| 24 { |
| 25 if (requestedCaps != FontDescription::CapsNormal) |
| 26 determineFontSupport(script); |
| 27 } |
| 28 |
| 29 FontDescription::FontVariantCaps OpenTypeCapsSupport::fontFeatureToUse( |
| 30 SmallCapsIterator::SmallCapsBehavior sourceTextCase) |
| 31 { |
| 32 if (m_fontSupport == FontSupport::Full) |
| 33 return m_requestedCaps; |
| 34 |
| 35 if (m_fontSupport == FontSupport::Fallback) { |
| 36 if (m_requestedCaps == FontDescription::FontVariantCaps::AllPetiteCaps) |
| 37 return FontDescription::FontVariantCaps::AllSmallCaps; |
| 38 |
| 39 if (m_requestedCaps == FontDescription::FontVariantCaps::PetiteCaps |
| 40 || (m_requestedCaps == FontDescription::FontVariantCaps::Unicase |
| 41 && sourceTextCase == SmallCapsIterator::SmallCapsSameCase)) |
| 42 return FontDescription::FontVariantCaps::SmallCaps; |
| 43 } |
| 44 |
| 45 return FontDescription::FontVariantCaps::CapsNormal; |
| 46 } |
| 47 |
| 48 bool OpenTypeCapsSupport::needsRunCaseSplitting() |
| 49 { |
| 50 // Lack of titling case support is ignored, titling case is not synthesized. |
| 51 return m_fontSupport != FontSupport::Full |
| 52 && m_requestedCaps != FontDescription::TitlingCaps; |
| 53 } |
| 54 |
| 55 bool OpenTypeCapsSupport::needsSyntheticFont( |
| 56 SmallCapsIterator::SmallCapsBehavior runCase) |
| 57 { |
| 58 if (m_fontSupport == FontSupport::Full) |
| 59 return false; |
| 60 |
| 61 if (m_requestedCaps == FontDescription::TitlingCaps) |
| 62 return false; |
| 63 |
| 64 if (m_fontSupport == FontSupport::None) { |
| 65 if (runCase == SmallCapsIterator::SmallCapsUppercaseNeeded |
| 66 && (m_capsSynthesis == CapsSynthesis::LowerToSmallCaps |
| 67 || m_capsSynthesis == CapsSynthesis::BothToSmallCaps)) |
| 68 return true; |
| 69 |
| 70 if (runCase == SmallCapsIterator::SmallCapsSameCase |
| 71 && (m_capsSynthesis == CapsSynthesis::UpperToSmallCaps |
| 72 || m_capsSynthesis == CapsSynthesis::BothToSmallCaps)) { |
| 73 return true; |
| 74 } |
| 75 } |
| 76 |
| 77 return false; |
| 78 } |
| 79 |
| 80 CaseMapIntend OpenTypeCapsSupport::needsCaseChange( |
| 81 SmallCapsIterator::SmallCapsBehavior runCase) |
| 82 { |
| 83 CaseMapIntend caseMapIntend = CaseMapIntend::KeepSameCase; |
| 84 |
| 85 if (m_fontSupport == FontSupport::Full) |
| 86 return caseMapIntend; |
| 87 |
| 88 switch (runCase) { |
| 89 case SmallCapsIterator::SmallCapsSameCase: |
| 90 caseMapIntend = m_fontSupport == FontSupport::Fallback |
| 91 && (m_capsSynthesis == CapsSynthesis::BothToSmallCaps |
| 92 || m_capsSynthesis == CapsSynthesis::UpperToSmallCaps) |
| 93 ? CaseMapIntend::LowerCase |
| 94 : CaseMapIntend::KeepSameCase; |
| 95 break; |
| 96 case SmallCapsIterator::SmallCapsUppercaseNeeded: |
| 97 caseMapIntend = m_fontSupport != FontSupport::Fallback |
| 98 && (m_capsSynthesis == CapsSynthesis::LowerToSmallCaps |
| 99 || m_capsSynthesis == CapsSynthesis::BothToSmallCaps) |
| 100 ? CaseMapIntend::UpperCase |
| 101 : CaseMapIntend::KeepSameCase; |
| 102 break; |
| 103 default: |
| 104 break; |
| 105 } |
| 106 return caseMapIntend; |
| 107 } |
| 108 |
| 109 void OpenTypeCapsSupport::determineFontSupport(hb_script_t script) |
| 110 { |
| 111 switch (m_requestedCaps) { |
| 112 case FontDescription::SmallCaps: |
| 113 if (!supportsOpenTypeFeature(script, HB_TAG('s', 'm', 'c', 'p'))) { |
| 114 m_fontSupport = FontSupport::None; |
| 115 m_capsSynthesis = CapsSynthesis::LowerToSmallCaps; |
| 116 } |
| 117 break; |
| 118 case FontDescription::AllSmallCaps: |
| 119 if (!(supportsOpenTypeFeature(script, HB_TAG('s', 'm', 'c', 'p')) |
| 120 && supportsOpenTypeFeature( |
| 121 script, |
| 122 HB_TAG('c', '2', 's', 'c')))) { |
| 123 m_fontSupport = FontSupport::None; |
| 124 m_capsSynthesis = CapsSynthesis::BothToSmallCaps; |
| 125 } |
| 126 break; |
| 127 case FontDescription::PetiteCaps: |
| 128 if (!supportsOpenTypeFeature(script, HB_TAG('p', 'c', 'a', 'p'))) { |
| 129 if (supportsOpenTypeFeature(script, HB_TAG('s', 'm', 'c', 'p'))) { |
| 130 m_fontSupport = FontSupport::Fallback; |
| 131 } else { |
| 132 m_fontSupport = FontSupport::None; |
| 133 m_capsSynthesis = CapsSynthesis::LowerToSmallCaps; |
| 134 } |
| 135 } |
| 136 break; |
| 137 case FontDescription::AllPetiteCaps: |
| 138 if (!(supportsOpenTypeFeature(script, HB_TAG('p', 'c', 'a', 'p')) |
| 139 && supportsOpenTypeFeature( |
| 140 script, |
| 141 HB_TAG('c', '2', 'p', 'c')))) { |
| 142 if (supportsOpenTypeFeature(script, HB_TAG('s', 'm', 'c', 'p')) |
| 143 && supportsOpenTypeFeature( |
| 144 script, |
| 145 HB_TAG('c', '2', 's', 'c'))) { |
| 146 m_fontSupport = FontSupport::Fallback; |
| 147 } else { |
| 148 m_fontSupport = FontSupport::None; |
| 149 m_capsSynthesis = CapsSynthesis::BothToSmallCaps; |
| 150 } |
| 151 } |
| 152 break; |
| 153 case FontDescription::Unicase: |
| 154 if (!supportsOpenTypeFeature(script, HB_TAG('u', 'n', 'i', 'c'))) { |
| 155 m_capsSynthesis = CapsSynthesis::UpperToSmallCaps; |
| 156 if (supportsOpenTypeFeature(script, HB_TAG('s', 'm', 'c', 'p'))) { |
| 157 m_fontSupport = FontSupport::Fallback; |
| 158 } else { |
| 159 m_fontSupport = FontSupport::None; |
| 160 } |
| 161 } |
| 162 break; |
| 163 case FontDescription::TitlingCaps: |
| 164 if (!supportsOpenTypeFeature(script, HB_TAG('t', 'i', 't', 'l'))) { |
| 165 m_fontSupport = FontSupport::None; |
| 166 } |
| 167 break; |
| 168 default: |
| 169 ASSERT_NOT_REACHED(); |
| 170 } |
| 171 } |
| 172 |
| 173 } // namespace blink |
OLD | NEW |