OLD | NEW |
(Empty) | |
| 1 // Copyright 2017 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 "core/css/properties/CSSShorthandPropertyAPIFont.h" |
| 6 |
| 7 #include "core/css/CSSFontFamilyValue.h" |
| 8 #include "core/css/CSSIdentifierValue.h" |
| 9 #include "core/css/CSSPrimitiveValueMappings.h" |
| 10 #include "core/css/parser/CSSParserContext.h" |
| 11 #include "core/css/parser/CSSParserFastPaths.h" |
| 12 #include "core/css/parser/CSSPropertyParserHelpers.h" |
| 13 #include "core/css/properties/CSSPropertyFontUtils.h" |
| 14 #include "platform/fonts/FontTraits.h" |
| 15 |
| 16 namespace blink { |
| 17 |
| 18 namespace { |
| 19 |
| 20 bool ConsumeSystemFont(bool important, |
| 21 CSSParserTokenRange& range, |
| 22 HeapVector<CSSProperty, 256>& properties) { |
| 23 CSSValueID system_font_id = range.ConsumeIncludingWhitespace().Id(); |
| 24 DCHECK_GE(system_font_id, CSSValueCaption); |
| 25 DCHECK_LE(system_font_id, CSSValueStatusBar); |
| 26 if (!range.AtEnd()) |
| 27 return false; |
| 28 |
| 29 FontStyle font_style = kFontStyleNormal; |
| 30 FontWeight font_weight = kFontWeightNormal; |
| 31 float font_size = 0; |
| 32 AtomicString font_family; |
| 33 LayoutTheme::GetTheme().SystemFont(system_font_id, font_style, font_weight, |
| 34 font_size, font_family); |
| 35 |
| 36 CSSPropertyParserHelpers::AddProperty( |
| 37 CSSPropertyFontStyle, CSSPropertyFont, |
| 38 *CSSIdentifierValue::Create( |
| 39 font_style == kFontStyleItalic ? CSSValueItalic : CSSValueNormal), |
| 40 important, CSSPropertyParserHelpers::IsImplicitProperty::kNotImplicit, |
| 41 properties); |
| 42 CSSPropertyParserHelpers::AddProperty( |
| 43 CSSPropertyFontWeight, CSSPropertyFont, |
| 44 *CSSIdentifierValue::Create(font_weight), important, |
| 45 CSSPropertyParserHelpers::IsImplicitProperty::kNotImplicit, properties); |
| 46 CSSPropertyParserHelpers::AddProperty( |
| 47 CSSPropertyFontSize, CSSPropertyFont, |
| 48 *CSSPrimitiveValue::Create(font_size, |
| 49 CSSPrimitiveValue::UnitType::kPixels), |
| 50 important, CSSPropertyParserHelpers::IsImplicitProperty::kNotImplicit, |
| 51 properties); |
| 52 |
| 53 CSSValueList* font_family_list = CSSValueList::CreateCommaSeparated(); |
| 54 font_family_list->Append(*CSSFontFamilyValue::Create(font_family)); |
| 55 CSSPropertyParserHelpers::AddProperty( |
| 56 CSSPropertyFontFamily, CSSPropertyFont, *font_family_list, important, |
| 57 CSSPropertyParserHelpers::IsImplicitProperty::kNotImplicit, properties); |
| 58 |
| 59 CSSPropertyParserHelpers::AddProperty( |
| 60 CSSPropertyFontStretch, CSSPropertyFont, |
| 61 *CSSIdentifierValue::Create(CSSValueNormal), important, |
| 62 CSSPropertyParserHelpers::IsImplicitProperty::kNotImplicit, properties); |
| 63 CSSPropertyParserHelpers::AddProperty( |
| 64 CSSPropertyFontVariantCaps, CSSPropertyFont, |
| 65 *CSSIdentifierValue::Create(CSSValueNormal), important, |
| 66 CSSPropertyParserHelpers::IsImplicitProperty::kNotImplicit, properties); |
| 67 CSSPropertyParserHelpers::AddProperty( |
| 68 CSSPropertyFontVariantLigatures, CSSPropertyFont, |
| 69 *CSSIdentifierValue::Create(CSSValueNormal), important, |
| 70 CSSPropertyParserHelpers::IsImplicitProperty::kNotImplicit, properties); |
| 71 CSSPropertyParserHelpers::AddProperty( |
| 72 CSSPropertyFontVariantNumeric, CSSPropertyFont, |
| 73 *CSSIdentifierValue::Create(CSSValueNormal), important, |
| 74 CSSPropertyParserHelpers::IsImplicitProperty::kNotImplicit, properties); |
| 75 CSSPropertyParserHelpers::AddProperty( |
| 76 CSSPropertyLineHeight, CSSPropertyFont, |
| 77 *CSSIdentifierValue::Create(CSSValueNormal), important, |
| 78 CSSPropertyParserHelpers::IsImplicitProperty::kNotImplicit, properties); |
| 79 return true; |
| 80 } |
| 81 |
| 82 bool ConsumeFont(bool important, |
| 83 CSSParserTokenRange& range, |
| 84 const CSSParserContext& context, |
| 85 HeapVector<CSSProperty, 256>& properties) { |
| 86 // Let's check if there is an inherit or initial somewhere in the shorthand. |
| 87 CSSParserTokenRange range_copy = range; |
| 88 while (!range_copy.AtEnd()) { |
| 89 CSSValueID id = range_copy.ConsumeIncludingWhitespace().Id(); |
| 90 if (id == CSSValueInherit || id == CSSValueInitial) |
| 91 return false; |
| 92 } |
| 93 // Optional font-style, font-variant, font-stretch and font-weight. |
| 94 CSSIdentifierValue* font_style = nullptr; |
| 95 CSSIdentifierValue* font_variant_caps = nullptr; |
| 96 CSSIdentifierValue* font_weight = nullptr; |
| 97 CSSIdentifierValue* font_stretch = nullptr; |
| 98 while (!range.AtEnd()) { |
| 99 CSSValueID id = range.Peek().Id(); |
| 100 if (!font_style && CSSParserFastPaths::IsValidKeywordPropertyAndValue( |
| 101 CSSPropertyFontStyle, id, context.Mode())) { |
| 102 font_style = CSSPropertyParserHelpers::ConsumeIdent(range); |
| 103 continue; |
| 104 } |
| 105 if (!font_variant_caps && |
| 106 (id == CSSValueNormal || id == CSSValueSmallCaps)) { |
| 107 // Font variant in the shorthand is particular, it only accepts normal or |
| 108 // small-caps. |
| 109 // See https://drafts.csswg.org/css-fonts/#propdef-font |
| 110 font_variant_caps = CSSPropertyFontUtils::ConsumeFontVariantCSS21(range); |
| 111 if (font_variant_caps) |
| 112 continue; |
| 113 } |
| 114 if (!font_weight) { |
| 115 font_weight = CSSPropertyFontUtils::ConsumeFontWeight(range); |
| 116 if (font_weight) |
| 117 continue; |
| 118 } |
| 119 if (!font_stretch && CSSParserFastPaths::IsValidKeywordPropertyAndValue( |
| 120 CSSPropertyFontStretch, id, context.Mode())) |
| 121 font_stretch = CSSPropertyParserHelpers::ConsumeIdent(range); |
| 122 else |
| 123 break; |
| 124 } |
| 125 |
| 126 if (range.AtEnd()) |
| 127 return false; |
| 128 |
| 129 CSSPropertyParserHelpers::AddProperty( |
| 130 CSSPropertyFontStyle, CSSPropertyFont, |
| 131 font_style ? *font_style : *CSSIdentifierValue::Create(CSSValueNormal), |
| 132 important, CSSPropertyParserHelpers::IsImplicitProperty::kNotImplicit, |
| 133 properties); |
| 134 CSSPropertyParserHelpers::AddProperty( |
| 135 CSSPropertyFontVariantCaps, CSSPropertyFont, |
| 136 font_variant_caps ? *font_variant_caps |
| 137 : *CSSIdentifierValue::Create(CSSValueNormal), |
| 138 important, CSSPropertyParserHelpers::IsImplicitProperty::kNotImplicit, |
| 139 properties); |
| 140 CSSPropertyParserHelpers::AddProperty( |
| 141 CSSPropertyFontVariantLigatures, CSSPropertyFont, |
| 142 *CSSIdentifierValue::Create(CSSValueNormal), important, |
| 143 CSSPropertyParserHelpers::IsImplicitProperty::kNotImplicit, properties); |
| 144 CSSPropertyParserHelpers::AddProperty( |
| 145 CSSPropertyFontVariantNumeric, CSSPropertyFont, |
| 146 *CSSIdentifierValue::Create(CSSValueNormal), important, |
| 147 CSSPropertyParserHelpers::IsImplicitProperty::kNotImplicit, properties); |
| 148 |
| 149 CSSPropertyParserHelpers::AddProperty( |
| 150 CSSPropertyFontWeight, CSSPropertyFont, |
| 151 font_weight ? *font_weight : *CSSIdentifierValue::Create(CSSValueNormal), |
| 152 important, CSSPropertyParserHelpers::IsImplicitProperty::kNotImplicit, |
| 153 properties); |
| 154 CSSPropertyParserHelpers::AddProperty( |
| 155 CSSPropertyFontStretch, CSSPropertyFont, |
| 156 font_stretch ? *font_stretch |
| 157 : *CSSIdentifierValue::Create(CSSValueNormal), |
| 158 important, CSSPropertyParserHelpers::IsImplicitProperty::kNotImplicit, |
| 159 properties); |
| 160 |
| 161 // Now a font size _must_ come. |
| 162 CSSValue* font_size = |
| 163 CSSPropertyFontUtils::ConsumeFontSize(range, context.Mode()); |
| 164 if (!font_size || range.AtEnd()) |
| 165 return false; |
| 166 |
| 167 CSSPropertyParserHelpers::AddProperty( |
| 168 CSSPropertyFontSize, CSSPropertyFont, *font_size, important, |
| 169 CSSPropertyParserHelpers::IsImplicitProperty::kNotImplicit, properties); |
| 170 |
| 171 if (CSSPropertyParserHelpers::ConsumeSlashIncludingWhitespace(range)) { |
| 172 CSSValue* line_height = |
| 173 CSSPropertyFontUtils::ConsumeLineHeight(range, context.Mode()); |
| 174 if (!line_height) |
| 175 return false; |
| 176 CSSPropertyParserHelpers::AddProperty( |
| 177 CSSPropertyLineHeight, CSSPropertyFont, *line_height, important, |
| 178 CSSPropertyParserHelpers::IsImplicitProperty::kNotImplicit, properties); |
| 179 } else { |
| 180 CSSPropertyParserHelpers::AddProperty( |
| 181 CSSPropertyLineHeight, CSSPropertyFont, |
| 182 *CSSIdentifierValue::Create(CSSValueNormal), important, |
| 183 CSSPropertyParserHelpers::IsImplicitProperty::kNotImplicit, properties); |
| 184 } |
| 185 |
| 186 // Font family must come now. |
| 187 CSSValue* parsed_family_value = |
| 188 CSSPropertyFontUtils::ConsumeFontFamily(range); |
| 189 if (!parsed_family_value) |
| 190 return false; |
| 191 |
| 192 CSSPropertyParserHelpers::AddProperty( |
| 193 CSSPropertyFontFamily, CSSPropertyFont, *parsed_family_value, important, |
| 194 CSSPropertyParserHelpers::IsImplicitProperty::kNotImplicit, properties); |
| 195 |
| 196 // FIXME: http://www.w3.org/TR/2011/WD-css3-fonts-20110324/#font-prop requires |
| 197 // that "font-stretch", "font-size-adjust", and "font-kerning" be reset to |
| 198 // their initial values but we don't seem to support them at the moment. They |
| 199 // should also be added here once implemented. |
| 200 return range.AtEnd(); |
| 201 } |
| 202 |
| 203 } // namespace |
| 204 |
| 205 bool CSSShorthandPropertyAPIFont::parseShorthand( |
| 206 bool important, |
| 207 CSSParserTokenRange& range, |
| 208 const CSSParserContext& context, |
| 209 const CSSParserLocalContext&, |
| 210 HeapVector<CSSProperty, 256>& properties) { |
| 211 const CSSParserToken& token = range.Peek(); |
| 212 if (token.Id() >= CSSValueCaption && token.Id() <= CSSValueStatusBar) |
| 213 return ConsumeSystemFont(important, range, properties); |
| 214 return ConsumeFont(important, range, context, properties); |
| 215 } |
| 216 } // namespace blink |
OLD | NEW |