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/animation/CSSFontVariationSettingsInterpolationType.h" |
| 6 |
| 7 #include "core/css/CSSFontVariationValue.h" |
| 8 #include "core/css/CSSValueList.h" |
| 9 |
| 10 namespace blink { |
| 11 |
| 12 class CSSFontVariationSettingsNonInterpolableValue |
| 13 : public NonInterpolableValue { |
| 14 public: |
| 15 ~CSSFontVariationSettingsNonInterpolableValue() final {} |
| 16 |
| 17 static PassRefPtr<CSSFontVariationSettingsNonInterpolableValue> Create( |
| 18 Vector<AtomicString> tags) { |
| 19 return AdoptRef( |
| 20 new CSSFontVariationSettingsNonInterpolableValue(std::move(tags))); |
| 21 } |
| 22 |
| 23 const Vector<AtomicString> Tags() const { return tags_; } |
| 24 |
| 25 DECLARE_NON_INTERPOLABLE_VALUE_TYPE(); |
| 26 |
| 27 private: |
| 28 CSSFontVariationSettingsNonInterpolableValue(Vector<AtomicString> tags) |
| 29 : tags_(std::move(tags)) { |
| 30 DCHECK_GT(tags_.size(), 0u); |
| 31 } |
| 32 |
| 33 const Vector<AtomicString> tags_; |
| 34 }; |
| 35 |
| 36 DEFINE_NON_INTERPOLABLE_VALUE_TYPE( |
| 37 CSSFontVariationSettingsNonInterpolableValue); |
| 38 DEFINE_NON_INTERPOLABLE_VALUE_TYPE_CASTS( |
| 39 CSSFontVariationSettingsNonInterpolableValue); |
| 40 |
| 41 static const Vector<AtomicString> GetTags( |
| 42 const NonInterpolableValue& non_interpolable_value) { |
| 43 return ToCSSFontVariationSettingsNonInterpolableValue(non_interpolable_value) |
| 44 .Tags(); |
| 45 } |
| 46 |
| 47 static bool TagsMatch(const NonInterpolableValue& a, |
| 48 const NonInterpolableValue& b) { |
| 49 return GetTags(a) == GetTags(b); |
| 50 } |
| 51 |
| 52 class UnderlyingTagsChecker : public InterpolationType::ConversionChecker { |
| 53 public: |
| 54 ~UnderlyingTagsChecker() final {} |
| 55 |
| 56 static std::unique_ptr<UnderlyingTagsChecker> Create( |
| 57 const Vector<AtomicString>& tags) { |
| 58 return WTF::WrapUnique(new UnderlyingTagsChecker(tags)); |
| 59 } |
| 60 |
| 61 private: |
| 62 UnderlyingTagsChecker(const Vector<AtomicString>& tags) : tags_(tags) {} |
| 63 |
| 64 bool IsValid(const InterpolationEnvironment&, |
| 65 const InterpolationValue& underlying) const final { |
| 66 return tags_ == GetTags(*underlying.non_interpolable_value); |
| 67 } |
| 68 |
| 69 const Vector<AtomicString> tags_; |
| 70 }; |
| 71 |
| 72 class InheritedFontVariationSettingsChecker |
| 73 : public InterpolationType::ConversionChecker { |
| 74 public: |
| 75 ~InheritedFontVariationSettingsChecker() final {} |
| 76 |
| 77 static std::unique_ptr<InheritedFontVariationSettingsChecker> Create( |
| 78 const FontVariationSettings* settings) { |
| 79 return WTF::WrapUnique(new InheritedFontVariationSettingsChecker(settings)); |
| 80 } |
| 81 |
| 82 private: |
| 83 InheritedFontVariationSettingsChecker(const FontVariationSettings* settings) |
| 84 : settings_(settings) {} |
| 85 |
| 86 bool IsValid(const InterpolationEnvironment& environment, |
| 87 const InterpolationValue&) const final { |
| 88 return DataEquivalent(settings_.Get(), environment.GetState() |
| 89 .ParentStyle() |
| 90 ->GetFontDescription() |
| 91 .VariationSettings()); |
| 92 } |
| 93 |
| 94 RefPtr<const FontVariationSettings> settings_; |
| 95 }; |
| 96 |
| 97 static InterpolationValue ConvertFontVariationSettings( |
| 98 const FontVariationSettings* settings) { |
| 99 if (!settings || settings->size() == 0) { |
| 100 return nullptr; |
| 101 } |
| 102 size_t length = settings->size(); |
| 103 std::unique_ptr<InterpolableList> numbers = InterpolableList::Create(length); |
| 104 Vector<AtomicString> tags; |
| 105 for (size_t i = 0; i < length; ++i) { |
| 106 numbers->Set(i, InterpolableNumber::Create(settings->at(i).Value())); |
| 107 tags.push_back(settings->at(i).Tag()); |
| 108 } |
| 109 return InterpolationValue( |
| 110 std::move(numbers), |
| 111 CSSFontVariationSettingsNonInterpolableValue::Create(std::move(tags))); |
| 112 } |
| 113 |
| 114 InterpolationValue |
| 115 CSSFontVariationSettingsInterpolationType::MaybeConvertNeutral( |
| 116 const InterpolationValue& underlying, |
| 117 ConversionCheckers& conversion_checkers) const { |
| 118 conversion_checkers.push_back(UnderlyingTagsChecker::Create( |
| 119 GetTags(*underlying.non_interpolable_value))); |
| 120 return InterpolationValue(underlying.interpolable_value->CloneAndZero(), |
| 121 underlying.non_interpolable_value); |
| 122 } |
| 123 |
| 124 InterpolationValue |
| 125 CSSFontVariationSettingsInterpolationType::MaybeConvertInitial( |
| 126 const StyleResolverState&, |
| 127 ConversionCheckers&) const { |
| 128 return ConvertFontVariationSettings(FontBuilder::InitialVariationSettings()); |
| 129 } |
| 130 |
| 131 InterpolationValue |
| 132 CSSFontVariationSettingsInterpolationType::MaybeConvertInherit( |
| 133 const StyleResolverState& state, |
| 134 ConversionCheckers& conversion_checkers) const { |
| 135 const FontVariationSettings* inherited = |
| 136 state.ParentStyle()->GetFontDescription().VariationSettings(); |
| 137 conversion_checkers.push_back( |
| 138 InheritedFontVariationSettingsChecker::Create(inherited)); |
| 139 return ConvertFontVariationSettings(inherited); |
| 140 } |
| 141 |
| 142 InterpolationValue CSSFontVariationSettingsInterpolationType::MaybeConvertValue( |
| 143 const CSSValue& value, |
| 144 const StyleResolverState*, |
| 145 ConversionCheckers&) const { |
| 146 if (!value.IsValueList()) { |
| 147 return nullptr; |
| 148 } |
| 149 const CSSValueList& list = ToCSSValueList(value); |
| 150 size_t length = list.length(); |
| 151 std::unique_ptr<InterpolableList> numbers = InterpolableList::Create(length); |
| 152 Vector<AtomicString> tags; |
| 153 for (size_t i = 0; i < length; ++i) { |
| 154 const CSSFontVariationValue& item = ToCSSFontVariationValue(list.Item(i)); |
| 155 numbers->Set(i, InterpolableNumber::Create(item.Value())); |
| 156 tags.push_back(item.Tag()); |
| 157 } |
| 158 return InterpolationValue( |
| 159 std::move(numbers), |
| 160 CSSFontVariationSettingsNonInterpolableValue::Create(std::move(tags))); |
| 161 } |
| 162 |
| 163 InterpolationValue CSSFontVariationSettingsInterpolationType:: |
| 164 MaybeConvertStandardPropertyUnderlyingValue( |
| 165 const ComputedStyle& style) const { |
| 166 return ConvertFontVariationSettings( |
| 167 style.GetFontDescription().VariationSettings()); |
| 168 } |
| 169 |
| 170 PairwiseInterpolationValue |
| 171 CSSFontVariationSettingsInterpolationType::MaybeMergeSingles( |
| 172 InterpolationValue&& start, |
| 173 InterpolationValue&& end) const { |
| 174 if (TagsMatch(*start.non_interpolable_value, *end.non_interpolable_value)) { |
| 175 return PairwiseInterpolationValue(std::move(start.interpolable_value), |
| 176 std::move(end.interpolable_value), |
| 177 std::move(start.non_interpolable_value)); |
| 178 } |
| 179 return nullptr; |
| 180 } |
| 181 |
| 182 void CSSFontVariationSettingsInterpolationType::Composite( |
| 183 UnderlyingValueOwner& underlying_value_owner, |
| 184 double underlying_fraction, |
| 185 const InterpolationValue& value, |
| 186 double interpolation_fraction) const { |
| 187 if (TagsMatch(*underlying_value_owner.Value().non_interpolable_value, |
| 188 *value.non_interpolable_value)) { |
| 189 underlying_value_owner.MutableValue().interpolable_value->ScaleAndAdd( |
| 190 underlying_fraction, *value.interpolable_value); |
| 191 } else { |
| 192 underlying_value_owner.Set(*this, value); |
| 193 } |
| 194 } |
| 195 |
| 196 void CSSFontVariationSettingsInterpolationType::ApplyStandardPropertyValue( |
| 197 const InterpolableValue& interpolable_value, |
| 198 const NonInterpolableValue* non_interpolable_value, |
| 199 StyleResolverState& state) const { |
| 200 const InterpolableList& numbers = ToInterpolableList(interpolable_value); |
| 201 const Vector<AtomicString>& tags = GetTags(*non_interpolable_value); |
| 202 DCHECK_EQ(numbers.length(), tags.size()); |
| 203 |
| 204 RefPtr<FontVariationSettings> settings = FontVariationSettings::Create(); |
| 205 size_t length = numbers.length(); |
| 206 for (size_t i = 0; i < length; ++i) { |
| 207 settings->Append(FontVariationAxis( |
| 208 tags[i], ToInterpolableNumber(numbers.Get(i))->Value())); |
| 209 } |
| 210 state.GetFontBuilder().SetVariationSettings(settings); |
| 211 } |
| 212 |
| 213 } // namespace blink |
OLD | NEW |