diff options
author | Allan Sandfeld Jensen <allan.jensen@qt.io> | 2018-05-15 10:20:33 +0200 |
---|---|---|
committer | Allan Sandfeld Jensen <allan.jensen@qt.io> | 2018-05-15 10:28:57 +0000 |
commit | d17ea114e5ef69ad5d5d7413280a13e6428098aa (patch) | |
tree | 2c01a75df69f30d27b1432467cfe7c1467a498da /chromium/third_party/blink/renderer/core/css/resolver/font_builder.cc | |
parent | 8c5c43c7b138c9b4b0bf56d946e61d3bbc111bec (diff) | |
download | qtwebengine-chromium-d17ea114e5ef69ad5d5d7413280a13e6428098aa.tar.gz |
BASELINE: Update Chromium to 67.0.3396.47
Change-Id: Idcb1341782e417561a2473eeecc82642dafda5b7
Reviewed-by: Michal Klocek <michal.klocek@qt.io>
Diffstat (limited to 'chromium/third_party/blink/renderer/core/css/resolver/font_builder.cc')
-rw-r--r-- | chromium/third_party/blink/renderer/core/css/resolver/font_builder.cc | 456 |
1 files changed, 456 insertions, 0 deletions
diff --git a/chromium/third_party/blink/renderer/core/css/resolver/font_builder.cc b/chromium/third_party/blink/renderer/core/css/resolver/font_builder.cc new file mode 100644 index 00000000000..feb1b80c2d2 --- /dev/null +++ b/chromium/third_party/blink/renderer/core/css/resolver/font_builder.cc @@ -0,0 +1,456 @@ +/* + * Copyright (C) 1999 Lars Knoll (knoll@kde.org) + * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Apple Inc. + * All rights reserved. + * Copyright (C) 2013 Google Inc. All rights reserved. + * Copyright (C) 2015 Collabora Ltd. All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + * + */ + +#include "third_party/blink/renderer/core/css/resolver/font_builder.h" + +#include "third_party/blink/renderer/core/css_value_keywords.h" +#include "third_party/blink/renderer/core/dom/document.h" +#include "third_party/blink/renderer/core/frame/local_frame.h" +#include "third_party/blink/renderer/core/frame/settings.h" +#include "third_party/blink/renderer/core/layout/text_autosizer.h" +#include "third_party/blink/renderer/core/style/computed_style.h" +#include "third_party/blink/renderer/platform/font_family_names.h" +#include "third_party/blink/renderer/platform/fonts/font_description.h" + +namespace blink { + +FontBuilder::FontBuilder(const Document* document) + : document_(document), flags_(0) { + DCHECK(!document || document->GetFrame()); +} + +void FontBuilder::SetInitial(float effective_zoom) { + DCHECK(document_->GetSettings()); + if (!document_->GetSettings()) + return; + + SetFamilyDescription(font_description_, + FontBuilder::InitialFamilyDescription()); + SetSize(font_description_, FontBuilder::InitialSize()); +} + +void FontBuilder::DidChangeEffectiveZoom() { + Set(PropertySetFlag::kEffectiveZoom); +} + +void FontBuilder::DidChangeTextOrientation() { + Set(PropertySetFlag::kTextOrientation); +} + +void FontBuilder::DidChangeWritingMode() { + Set(PropertySetFlag::kWritingMode); +} + +FontFamily FontBuilder::StandardFontFamily() const { + FontFamily family; + family.SetFamily(StandardFontFamilyName()); + return family; +} + +AtomicString FontBuilder::StandardFontFamilyName() const { + Settings* settings = document_->GetSettings(); + if (settings) + return settings->GetGenericFontFamilySettings().Standard(); + return AtomicString(); +} + +AtomicString FontBuilder::GenericFontFamilyName( + FontDescription::GenericFamilyType generic_family) const { + switch (generic_family) { + default: + NOTREACHED(); + FALLTHROUGH; + case FontDescription::kNoFamily: + return AtomicString(); + case FontDescription::kStandardFamily: + return StandardFontFamilyName(); + case FontDescription::kSerifFamily: + return FontFamilyNames::webkit_serif; + case FontDescription::kSansSerifFamily: + return FontFamilyNames::webkit_sans_serif; + case FontDescription::kMonospaceFamily: + return FontFamilyNames::webkit_monospace; + case FontDescription::kCursiveFamily: + return FontFamilyNames::webkit_cursive; + case FontDescription::kFantasyFamily: + return FontFamilyNames::webkit_fantasy; + case FontDescription::kPictographFamily: + return FontFamilyNames::webkit_pictograph; + } +} + +float FontBuilder::FontSizeForKeyword(unsigned keyword, + bool is_monospace) const { + return FontSizeFunctions::FontSizeForKeyword(document_, keyword, + is_monospace); +} + +void FontBuilder::SetFamilyDescription( + const FontDescription::FamilyDescription& family_description) { + SetFamilyDescription(font_description_, family_description); +} + +void FontBuilder::SetWeight(FontSelectionValue weight) { + Set(PropertySetFlag::kWeight); + + font_description_.SetWeight(weight); +} + +void FontBuilder::SetStyle(FontSelectionValue slope) { + Set(PropertySetFlag::kStyle); + + font_description_.SetStyle(slope); +} + +void FontBuilder::SetStretch(FontSelectionValue stretch) { + Set(PropertySetFlag::kStretch); + + font_description_.SetStretch(stretch); +} + +void FontBuilder::SetSize(const FontDescription::Size& size) { + SetSize(font_description_, size); +} + +void FontBuilder::SetSizeAdjust(float aspect_value) { + Set(PropertySetFlag::kSizeAdjust); + + font_description_.SetSizeAdjust(aspect_value); +} + +void FontBuilder::SetLocale(scoped_refptr<const LayoutLocale> locale) { + Set(PropertySetFlag::kLocale); + + font_description_.SetLocale(std::move(locale)); +} + +void FontBuilder::SetVariantCaps(FontDescription::FontVariantCaps caps) { + Set(PropertySetFlag::kVariantCaps); + + font_description_.SetVariantCaps(caps); +} + +void FontBuilder::SetVariantEastAsian(const FontVariantEastAsian east_asian) { + Set(PropertySetFlag::kVariantEastAsian); + + font_description_.SetVariantEastAsian(east_asian); +} + +void FontBuilder::SetVariantLigatures( + const FontDescription::VariantLigatures& ligatures) { + Set(PropertySetFlag::kVariantLigatures); + + font_description_.SetVariantLigatures(ligatures); +} + +void FontBuilder::SetVariantNumeric(const FontVariantNumeric& variant_numeric) { + Set(PropertySetFlag::kVariantNumeric); + + font_description_.SetVariantNumeric(variant_numeric); +} + +void FontBuilder::SetTextRendering(TextRenderingMode text_rendering_mode) { + Set(PropertySetFlag::kTextRendering); + + font_description_.SetTextRendering(text_rendering_mode); +} + +void FontBuilder::SetKerning(FontDescription::Kerning kerning) { + Set(PropertySetFlag::kKerning); + + font_description_.SetKerning(kerning); +} + +void FontBuilder::SetFontSmoothing(FontSmoothingMode foont_smoothing_mode) { + Set(PropertySetFlag::kFontSmoothing); + + font_description_.SetFontSmoothing(foont_smoothing_mode); +} + +void FontBuilder::SetFeatureSettings( + scoped_refptr<FontFeatureSettings> settings) { + Set(PropertySetFlag::kFeatureSettings); + font_description_.SetFeatureSettings(std::move(settings)); +} + +void FontBuilder::SetVariationSettings( + scoped_refptr<FontVariationSettings> settings) { + Set(PropertySetFlag::kVariationSettings); + font_description_.SetVariationSettings(std::move(settings)); +} + +void FontBuilder::SetFamilyDescription( + FontDescription& font_description, + const FontDescription::FamilyDescription& family_description) { + Set(PropertySetFlag::kFamily); + + bool is_initial = + family_description.generic_family == FontDescription::kStandardFamily && + family_description.family.FamilyIsEmpty(); + + font_description.SetGenericFamily(family_description.generic_family); + font_description.SetFamily(is_initial ? StandardFontFamily() + : family_description.family); +} + +void FontBuilder::SetSize(FontDescription& font_description, + const FontDescription::Size& size) { + float specified_size = size.value; + + if (specified_size < 0) + return; + + Set(PropertySetFlag::kSize); + + // Overly large font sizes will cause crashes on some platforms (such as + // Windows). Cap font size here to make sure that doesn't happen. + specified_size = std::min(kMaximumAllowedFontSize, specified_size); + + font_description.SetKeywordSize(size.keyword); + font_description.SetSpecifiedSize(specified_size); + font_description.SetIsAbsoluteSize(size.is_absolute); +} + +float FontBuilder::GetComputedSizeFromSpecifiedSize( + FontDescription& font_description, + float effective_zoom, + float specified_size) { + DCHECK(document_); + float zoom_factor = effective_zoom; + // FIXME: Why is this here!!!!?! + if (LocalFrame* frame = document_->GetFrame()) + zoom_factor *= frame->TextZoomFactor(); + + return FontSizeFunctions::GetComputedSizeFromSpecifiedSize( + document_, zoom_factor, font_description.IsAbsoluteSize(), + specified_size); +} + +static FontOrientation ComputeFontOrientation(const ComputedStyle& style) { + if (style.IsHorizontalWritingMode()) + return FontOrientation::kHorizontal; + + switch (style.GetTextOrientation()) { + case ETextOrientation::kMixed: + return FontOrientation::kVerticalMixed; + case ETextOrientation::kUpright: + return FontOrientation::kVerticalUpright; + case ETextOrientation::kSideways: + return FontOrientation::kVerticalRotated; + default: + NOTREACHED(); + return FontOrientation::kVerticalMixed; + } +} + +void FontBuilder::CheckForGenericFamilyChange( + const FontDescription& old_description, + FontDescription& new_description) { + DCHECK(document_); + if (new_description.IsAbsoluteSize()) + return; + + if (new_description.IsMonospace() == old_description.IsMonospace()) + return; + + // For now, lump all families but monospace together. + if (new_description.GenericFamily() != FontDescription::kMonospaceFamily && + old_description.GenericFamily() != FontDescription::kMonospaceFamily) + return; + + // We know the parent is monospace or the child is monospace, and that font + // size was unspecified. We want to scale our font size as appropriate. + // If the font uses a keyword size, then we refetch from the table rather than + // multiplying by our scale factor. + float size; + if (new_description.KeywordSize()) { + size = FontSizeForKeyword(new_description.KeywordSize(), + new_description.IsMonospace()); + } else { + Settings* settings = document_->GetSettings(); + float fixed_scale_factor = + (settings && settings->GetDefaultFixedFontSize() && + settings->GetDefaultFontSize()) + ? static_cast<float>(settings->GetDefaultFixedFontSize()) / + settings->GetDefaultFontSize() + : 1; + size = old_description.IsMonospace() + ? new_description.SpecifiedSize() / fixed_scale_factor + : new_description.SpecifiedSize() * fixed_scale_factor; + } + + new_description.SetSpecifiedSize(size); +} + +void FontBuilder::UpdateSpecifiedSize(FontDescription& font_description, + const ComputedStyle& style) { + float specified_size = font_description.SpecifiedSize(); + + if (!specified_size && font_description.KeywordSize()) + specified_size = FontSizeForKeyword(font_description.KeywordSize(), + font_description.IsMonospace()); + + font_description.SetSpecifiedSize(specified_size); + + CheckForGenericFamilyChange(style.GetFontDescription(), font_description); +} + +void FontBuilder::UpdateAdjustedSize(FontDescription& font_description, + const ComputedStyle& style, + FontSelector* font_selector) { + const float specified_size = font_description.SpecifiedSize(); + if (!font_description.HasSizeAdjust() || !specified_size) + return; + + // We need to create a temporal Font to get xHeight of a primary font. + // The aspect value is based on the xHeight of the font for the computed font + // size, so we need to reset the adjustedSize to computedSize. See + // FontDescription::EffectiveFontSize. + font_description.SetAdjustedSize(font_description.ComputedSize()); + + Font font(font_description); + font.Update(font_selector); + + const SimpleFontData* font_data = font.PrimaryFont(); + + if (!font_data || !font_data->GetFontMetrics().HasXHeight()) + return; + + const float size_adjust = font_description.SizeAdjust(); + float aspect_value = font_data->GetFontMetrics().XHeight() / specified_size; + float adjusted_size = (size_adjust / aspect_value) * specified_size; + adjusted_size = GetComputedSizeFromSpecifiedSize( + font_description, style.EffectiveZoom(), adjusted_size); + + adjusted_size = TextAutosizer::ComputeAutosizedFontSize( + adjusted_size, style.TextAutosizingMultiplier()); + font_description.SetAdjustedSize(adjusted_size); +} + +void FontBuilder::UpdateComputedSize(FontDescription& font_description, + const ComputedStyle& style) { + float computed_size = + GetComputedSizeFromSpecifiedSize(font_description, style.EffectiveZoom(), + font_description.SpecifiedSize()); + computed_size = TextAutosizer::ComputeAutosizedFontSize( + computed_size, style.TextAutosizingMultiplier()); + font_description.SetComputedSize(computed_size); +} + +void FontBuilder::UpdateFontDescription(FontDescription& description, + FontOrientation font_orientation) { + if (IsSet(PropertySetFlag::kFamily)) { + description.SetGenericFamily(font_description_.GenericFamily()); + description.SetFamily(font_description_.Family()); + } + if (IsSet(PropertySetFlag::kSize)) { + description.SetKeywordSize(font_description_.KeywordSize()); + description.SetSpecifiedSize(font_description_.SpecifiedSize()); + description.SetIsAbsoluteSize(font_description_.IsAbsoluteSize()); + } + + if (IsSet(PropertySetFlag::kSizeAdjust)) + description.SetSizeAdjust(font_description_.SizeAdjust()); + if (IsSet(PropertySetFlag::kWeight)) + description.SetWeight(font_description_.Weight()); + if (IsSet(PropertySetFlag::kStretch)) + description.SetStretch(font_description_.Stretch()); + if (IsSet(PropertySetFlag::kFeatureSettings)) + description.SetFeatureSettings(font_description_.FeatureSettings()); + if (IsSet(PropertySetFlag::kLocale)) + description.SetLocale(font_description_.Locale()); + if (IsSet(PropertySetFlag::kStyle)) + description.SetStyle(font_description_.Style()); + if (IsSet(PropertySetFlag::kVariantCaps)) + description.SetVariantCaps(font_description_.VariantCaps()); + if (IsSet(PropertySetFlag::kVariantEastAsian)) + description.SetVariantEastAsian(font_description_.VariantEastAsian()); + if (IsSet(PropertySetFlag::kVariantLigatures)) + description.SetVariantLigatures(font_description_.GetVariantLigatures()); + if (IsSet(PropertySetFlag::kVariantNumeric)) + description.SetVariantNumeric(font_description_.VariantNumeric()); + if (IsSet(PropertySetFlag::kVariationSettings)) + description.SetVariationSettings(font_description_.VariationSettings()); + if (IsSet(PropertySetFlag::kTextRendering)) + description.SetTextRendering(font_description_.TextRendering()); + if (IsSet(PropertySetFlag::kKerning)) + description.SetKerning(font_description_.GetKerning()); + if (IsSet(PropertySetFlag::kFontSmoothing)) + description.SetFontSmoothing(font_description_.FontSmoothing()); + if (IsSet(PropertySetFlag::kTextOrientation) || + IsSet(PropertySetFlag::kWritingMode)) + description.SetOrientation(font_orientation); + + float size = description.SpecifiedSize(); + if (!size && description.KeywordSize()) { + size = FontSizeForKeyword(description.KeywordSize(), + description.IsMonospace()); + } + + description.SetSpecifiedSize(size); + description.SetComputedSize(size); + if (size && description.HasSizeAdjust()) + description.SetAdjustedSize(size); +} + +void FontBuilder::CreateFont(FontSelector* font_selector, + ComputedStyle& style) { + DCHECK(document_); + + if (!flags_) + return; + + FontDescription description = style.GetFontDescription(); + + UpdateFontDescription(description, ComputeFontOrientation(style)); + + UpdateSpecifiedSize(description, style); + UpdateComputedSize(description, style); + UpdateAdjustedSize(description, style, font_selector); + + style.SetFontDescription(description); + style.GetFont().Update(font_selector); + flags_ = 0; +} + +void FontBuilder::CreateFontForDocument(FontSelector* font_selector, + ComputedStyle& document_style) { + DCHECK(document_); + FontDescription font_description = FontDescription(); + font_description.SetLocale(document_style.GetFontDescription().Locale()); + + SetFamilyDescription(font_description, + FontBuilder::InitialFamilyDescription()); + SetSize(font_description, + FontDescription::Size(FontSizeFunctions::InitialKeywordSize(), 0.0f, + false)); + UpdateSpecifiedSize(font_description, document_style); + UpdateComputedSize(font_description, document_style); + + font_description.SetOrientation(ComputeFontOrientation(document_style)); + document_style.SetFontDescription(font_description); + document_style.GetFont().Update(font_selector); +} + +} // namespace blink |