From 4ad38d3771ff5dbcbeaad1b4dce914481397ccda Mon Sep 17 00:00:00 2001 From: andycall Date: Mon, 7 Oct 2024 16:37:33 +0800 Subject: [PATCH] feat: add font and font_description. --- bridge/CMakeLists.txt | 2 + .../core/css/css_to_length_conversion_data.h | 2 + bridge/core/platform/fonts/font.cc | 37 ++ bridge/core/platform/fonts/font.h | 60 ++ .../core/platform/fonts/font_description.cc | 26 + bridge/core/platform/fonts/font_description.h | 560 ++++++++++++++++++ .../platform/fonts/font_selection_types.cc | 30 + .../platform/fonts/font_selection_types.h | 322 ++++++++++ bridge/core/style/font_size_style.h | 50 ++ bridge/test/test.cmake | 2 +- 10 files changed, 1090 insertions(+), 1 deletion(-) create mode 100644 bridge/core/platform/fonts/font.cc create mode 100644 bridge/core/platform/fonts/font.h create mode 100644 bridge/core/platform/fonts/font_description.cc create mode 100644 bridge/core/platform/fonts/font_description.h create mode 100644 bridge/core/platform/fonts/font_selection_types.cc create mode 100644 bridge/core/platform/fonts/font_selection_types.h create mode 100644 bridge/core/style/font_size_style.h diff --git a/bridge/CMakeLists.txt b/bridge/CMakeLists.txt index 5d715757b..0080fa9f5 100644 --- a/bridge/CMakeLists.txt +++ b/bridge/CMakeLists.txt @@ -604,6 +604,8 @@ if ($ENV{WEBF_JS_ENGINE} MATCHES "quickjs") core/platform/gfx/geometry/rect_conversions.cc core/platform/gfx/geometry/size_conversions.cc core/platform/fonts/font_family.cc + core/platform/fonts/font_selection_types.cc + core/platform/fonts/font.cc ) diff --git a/bridge/core/css/css_to_length_conversion_data.h b/bridge/core/css/css_to_length_conversion_data.h index 7440c938d..72b30a689 100644 --- a/bridge/core/css/css_to_length_conversion_data.h +++ b/bridge/core/css/css_to_length_conversion_data.h @@ -32,6 +32,8 @@ #define WEBF_CORE_CSS_CSS_TO_LENGTH_CONVERSION_DATA_H_ #include "core/css/css_length_resolver.h" +#include "core/platform/fonts/font.h" +#include "core/style/font_size_style.h" #include diff --git a/bridge/core/platform/fonts/font.cc b/bridge/core/platform/fonts/font.cc new file mode 100644 index 000000000..bcf8656e8 --- /dev/null +++ b/bridge/core/platform/fonts/font.cc @@ -0,0 +1,37 @@ +/* +* Copyright (C) 1999 Lars Knoll (knoll@kde.org) +* (C) 1999 Antti Koivisto (koivisto@kde.org) +* (C) 2000 Dirk Mueller (mueller@kde.org) +* Copyright (C) 2003, 2006, 2010, 2011 Apple Inc. All rights reserved. +* Copyright (c) 2007, 2008, 2010 Google Inc. 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 "font.h" + +namespace webf { + +Font::Font() = default; + +bool Font::operator==(const Font& other) const { + return font_description_ == other.font_description_; +} + +Font::Font(const FontDescription& fd) : font_description_(fd) {} + +} diff --git a/bridge/core/platform/fonts/font.h b/bridge/core/platform/fonts/font.h new file mode 100644 index 000000000..e2c73ead3 --- /dev/null +++ b/bridge/core/platform/fonts/font.h @@ -0,0 +1,60 @@ +/* +* Copyright (C) 2000 Lars Knoll (knoll@kde.org) +* (C) 2000 Antti Koivisto (koivisto@kde.org) +* (C) 2000 Dirk Mueller (mueller@kde.org) +* Copyright (C) 2003, 2006, 2007, 2010, 2011 Apple Inc. All rights reserved. +* Copyright (C) 2008 Holger Hans Peter Freyther +* +* 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. +* +*/ + +#ifndef WEBF_CORE_PLATFORM_FONTS_FONT_H_ +#define WEBF_CORE_PLATFORM_FONTS_FONT_H_ + +#include "foundation/macros.h" +#include "core/platform/fonts/font_description.h" + +namespace webf { + +class GCVisitor; + +class Font { + WEBF_DISALLOW_NEW(); + + public: + Font(); + explicit Font(const FontDescription&); + + Font(const Font&) = default; + Font(Font&&) = default; + Font& operator=(const Font&) = default; + Font& operator=(Font&&) = default; + + bool operator==(const Font& other) const; + bool operator!=(const Font& other) const { return !(*this == other); } + + const FontDescription& GetFontDescription() const { + return font_description_; + } + + public: + FontDescription font_description_; +}; + +} + +#endif // WEBF_CORE_PLATFORM_FONTS_FONT_H_ diff --git a/bridge/core/platform/fonts/font_description.cc b/bridge/core/platform/fonts/font_description.cc new file mode 100644 index 000000000..162a02b20 --- /dev/null +++ b/bridge/core/platform/fonts/font_description.cc @@ -0,0 +1,26 @@ +/* +* Copyright (C) 2000 Lars Knoll (knoll@kde.org) +* (C) 2000 Antti Koivisto (koivisto@kde.org) +* (C) 2000 Dirk Mueller (mueller@kde.org) +* Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008 Apple Inc. All rights +* reserved. +* Copyright (C) 2007 Nicholas Shanks +* +* 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 "font_description.h" diff --git a/bridge/core/platform/fonts/font_description.h b/bridge/core/platform/fonts/font_description.h new file mode 100644 index 000000000..07610ffe2 --- /dev/null +++ b/bridge/core/platform/fonts/font_description.h @@ -0,0 +1,560 @@ +/* +* Copyright (C) 2000 Lars Knoll (knoll@kde.org) +* (C) 2000 Antti Koivisto (koivisto@kde.org) +* (C) 2000 Dirk Mueller (mueller@kde.org) +* Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008 Apple Inc. All rights +* reserved. +* Copyright (C) 2007 Nicholas Shanks +* +* 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. +* +*/ + +#ifndef WEBF_CORE_PLATFORM_FONTS_FONT_DESCRIPTION_H_ +#define WEBF_CORE_PLATFORM_FONTS_FONT_DESCRIPTION_H_ + +#include +#include "foundation/macros.h" + +namespace webf { + +typedef struct { uint32_t parts[2]; } FieldsAsUnsignedType; + +class FontDescription { + USING_FAST_MALLOC(FontDescription); + + public: + enum HashCategory { + kHashEmptyValue = 0, + kHashDeletedValue, + kHashRegularValue + }; + + enum GenericFamilyType : uint8_t { + kNoFamily, + kStandardFamily, + kWebkitBodyFamily, + kSerifFamily, + kSansSerifFamily, + kMonospaceFamily, + kCursiveFamily, + kFantasyFamily + }; + static std::string ToString(GenericFamilyType); + + enum LigaturesState { + kNormalLigaturesState, + kDisabledLigaturesState, + kEnabledLigaturesState + }; + static std::string ToString(LigaturesState); + + enum Kerning { kAutoKerning, kNormalKerning, kNoneKerning }; + static std::string ToString(Kerning); + + static std::string ToString(FontSelectionValue); + + enum FontVariantCaps { + kCapsNormal, + kSmallCaps, + kAllSmallCaps, + kPetiteCaps, + kAllPetiteCaps, + kUnicase, + kTitlingCaps + }; + static String ToString(FontVariantCaps); + static String ToStringForIdl(FontVariantCaps); + + enum FontSynthesisWeight { + kAutoFontSynthesisWeight, + kNoneFontSynthesisWeight + }; + static String ToString(FontSynthesisWeight); + + enum FontSynthesisStyle { kAutoFontSynthesisStyle, kNoneFontSynthesisStyle }; + static String ToString(FontSynthesisStyle); + + enum FontSynthesisSmallCaps { + kAutoFontSynthesisSmallCaps, + kNoneFontSynthesisSmallCaps + }; + static String ToString(FontSynthesisSmallCaps); + + enum FontVariantPosition { + kNormalVariantPosition, + kSubVariantPosition, + kSuperVariantPosition + }; + static String ToString(FontVariantPosition); + + FontDescription(); + FontDescription(const FontDescription&); + + static FontDescription CreateHashTableEmptyValue(); + explicit FontDescription(WTF::HashTableDeletedValueType); + + FontDescription& operator=(const FontDescription&); + + bool operator==(const FontDescription&) const; + bool operator!=(const FontDescription& other) const { + return !(*this == other); + } + + struct VariantLigatures { + STACK_ALLOCATED(); + + public: + VariantLigatures(LigaturesState state = kNormalLigaturesState) + : common(state), + discretionary(state), + historical(state), + contextual(state) {} + + String ToString() const; + + unsigned common : 2; + unsigned discretionary : 2; + unsigned historical : 2; + unsigned contextual : 2; + + bool operator==(const VariantLigatures& other) const { + return common == other.common && discretionary == other.discretionary + && historical == other.historical && contextual == other.contextual; + } + }; + + struct Size { + STACK_ALLOCATED(); + + public: + Size(unsigned keyword, float value, bool is_absolute) + : keyword(keyword), is_absolute(is_absolute), value(value) {} + + String ToString() const; + + unsigned keyword : 4; // FontDescription::KeywordSize + unsigned is_absolute : 1; // FontDescription::IsAbsoluteSize + float value; // FontDescription::SpecifiedSize + }; + + struct FamilyDescription { + STACK_ALLOCATED(); + + public: + FamilyDescription(GenericFamilyType generic_family) + : generic_family(generic_family) {} + FamilyDescription(GenericFamilyType generic_family, + const FontFamily& family) + : generic_family(generic_family), family(family) {} + + String ToString() const; + + GenericFamilyType generic_family; + FontFamily family; + }; + + const FontFamily& Family() const { return family_list_; } + FamilyDescription GetFamilyDescription() const { + return FamilyDescription(GenericFamily(), Family()); + } + const FontFamily& FirstFamily() const { return family_list_; } + Size GetSize() const { + return Size(KeywordSize(), SpecifiedSize(), IsAbsoluteSize()); + } + float SpecifiedSize() const { return specified_size_; } + // Returns the result of applying font-size-adjust to the specified size. This + // is useful as an input to optical sizing and takes zooming out of the + // equation for determining the font size to be used for font-optical-sizing: + // auto;. + float AdjustedSpecifiedSize() const; + float ComputedSize() const { return computed_size_; } + + // TODO(xiaochengh): The functions and members for size-adjust descriptor and + // font-size-adjust property have similar names and are very confusing. Rename + // them for better clarity. + + // For CSS font-size-adjust property + FontSizeAdjust SizeAdjust() const { return size_adjust_; } + bool HasSizeAdjust() const { return !!size_adjust_; } + + // Return a copy with the size-adjust descriptor applied. + // https://drafts.csswg.org/css-fonts-5/#descdef-font-face-size-adjust + FontDescription SizeAdjustedFontDescription(float size_adjust) const; + + // The used value of font-size applying font-size-adjust or size-adjust. + // TODO(crbug.com/451346): Make font-size-adjust and size-adjust work + // together. + float AdjustedSize() const { return adjusted_size_; } + + int ComputedPixelSize() const { return int(computed_size_ + 0.5f); } + FontVariantCaps VariantCaps() const { + return static_cast(fields_.variant_caps_); + } + bool IsAbsoluteSize() const { return fields_.is_absolute_size_; } + FontSelectionValue Weight() const { return font_selection_request_.weight; } + FontSelectionValue Style() const { return font_selection_request_.slope; } + FontSelectionValue Stretch() const { return font_selection_request_.width; } + static FontSelectionValue LighterWeight(FontSelectionValue); + static FontSelectionValue BolderWeight(FontSelectionValue); + static Size LargerSize(const Size&); + static Size SmallerSize(const Size&); + GenericFamilyType GenericFamily() const { + return static_cast(fields_.generic_family_); + } + + // only use fixed default size when there is only one font family, and that + // family is "monospace" + bool IsMonospace() const { + return Family().FamilyName() == font_family_names::kMonospace && + Family().FamilyIsGeneric() && !Family().Next(); + } + Kerning GetKerning() const { return static_cast(fields_.kerning_); } + TextSpacingTrim GetTextSpacingTrim() const { + return static_cast(fields_.text_spacing_trim_); + } + FontVariantEastAsian VariantEastAsian() const { + return FontVariantEastAsian::InitializeFromUnsigned( + fields_.variant_east_asian_); + } + VariantLigatures GetVariantLigatures() const; + FontVariantNumeric VariantNumeric() const { + return FontVariantNumeric::InitializeFromUnsigned(fields_.variant_numeric_); + } + LigaturesState CommonLigaturesState() const { + return static_cast(fields_.common_ligatures_state_); + } + LigaturesState DiscretionaryLigaturesState() const { + return static_cast(fields_.discretionary_ligatures_state_); + } + LigaturesState HistoricalLigaturesState() const { + return static_cast(fields_.historical_ligatures_state_); + } + LigaturesState ContextualLigaturesState() const { + return static_cast(fields_.contextual_ligatures_state_); + } + unsigned KeywordSize() const { return fields_.keyword_size_; } + FontSmoothingMode FontSmoothing() const { + return static_cast(fields_.font_smoothing_); + } + OpticalSizing FontOpticalSizing() const { + return static_cast(fields_.font_optical_sizing_); + } + const FontPalette* GetFontPalette() const { return font_palette_.get(); } + const FontVariantAlternates* GetFontVariantAlternates() const { + return font_variant_alternates_.get(); + } + TextRenderingMode TextRendering() const { + return static_cast(fields_.text_rendering_); + } + const LayoutLocale* Locale() const { return locale_.get(); } + const LayoutLocale& LocaleOrDefault() const { + return LayoutLocale::ValueOrDefault(locale_.get()); + } + UScriptCode GetScript() const { return LocaleOrDefault().GetScript(); } + bool IsSyntheticBold() const { return fields_.synthetic_bold_; } + bool IsSyntheticItalic() const { return fields_.synthetic_italic_; } + bool IsSyntheticOblique() const { return fields_.synthetic_oblique_; } + bool UseSubpixelPositioning() const { + return fields_.subpixel_text_position_; + } + FontSynthesisWeight GetFontSynthesisWeight() const { + return static_cast(fields_.font_synthesis_weight_); + } + bool SyntheticBoldAllowed() const { + return fields_.font_synthesis_weight_ == kAutoFontSynthesisWeight; + } + FontSynthesisStyle GetFontSynthesisStyle() const { + return static_cast(fields_.font_synthesis_style_); + } + bool SyntheticItalicAllowed() const { + return fields_.font_synthesis_style_ == kAutoFontSynthesisStyle; + } + FontSynthesisSmallCaps GetFontSynthesisSmallCaps() const { + return static_cast( + fields_.font_synthesis_small_caps_); + } + + FontSelectionRequest GetFontSelectionRequest() const; + float WordSpacing() const { return word_spacing_; } + float LetterSpacing() const { return letter_spacing_; } + FontOrientation Orientation() const { + return static_cast(fields_.orientation_); + } + bool IsVerticalAnyUpright() const { + return blink::IsVerticalAnyUpright(Orientation()); + } + bool IsVerticalNonCJKUpright() const { + return blink::IsVerticalNonCJKUpright(Orientation()); + } + bool IsVerticalUpright(UChar32 character) const { + return blink::IsVerticalUpright(Orientation(), character); + } + bool IsVerticalBaseline() const { + return blink::IsVerticalBaseline(Orientation()); + } + FontWidthVariant WidthVariant() const { + return static_cast(fields_.width_variant_); + } + const FontFeatureSettings* FeatureSettings() const { + return feature_settings_.get(); + } + const FontVariationSettings* VariationSettings() const { + return variation_settings_.get(); + } + FontVariantPosition VariantPosition() const { + return static_cast(fields_.variant_position_); + } + FontVariantEmoji VariantEmoji() const { + return static_cast(fields_.variant_emoji_); + } + + float EffectiveFontSize() + const; // Returns either the computedSize or the computedPixelSize + FontCacheKey CacheKey(const FontFaceCreationParams&, + bool is_unique_match) const; + + void SetFamily(const FontFamily& family) { family_list_ = family; } + void SetComputedSize(float s) { computed_size_ = ClampTo(s); } + void SetSpecifiedSize(float s) { specified_size_ = ClampTo(s); } + void SetAdjustedSize(float s) { adjusted_size_ = ClampTo(s); } + void SetSizeAdjust(const FontSizeAdjust& size_adjust) { + size_adjust_ = size_adjust; + } + + void SetStyle(FontSelectionValue i); + void SetWeight(FontSelectionValue w) { font_selection_request_.weight = w; } + void SetStretch(FontSelectionValue s) { font_selection_request_.width = s; } + + void SetVariantCaps(FontVariantCaps); + void SetVariantEastAsian(const FontVariantEastAsian); + void SetVariantLigatures(const VariantLigatures&); + void SetVariantNumeric(const FontVariantNumeric&); + void SetIsAbsoluteSize(bool s) { fields_.is_absolute_size_ = s; } + + void SetGenericFamily(GenericFamilyType generic_family) { + fields_.generic_family_ = generic_family; + } + void SetKerning(Kerning kerning) { + fields_.kerning_ = kerning; + UpdateTypesettingFeatures(); + } + void SetTextSpacingTrim(TextSpacingTrim text_spacing_trim) { + fields_.text_spacing_trim_ = static_cast(text_spacing_trim); + } + void SetKeywordSize(unsigned s) { fields_.keyword_size_ = s; } + void SetFontSmoothing(FontSmoothingMode smoothing) { + fields_.font_smoothing_ = smoothing; + } + void SetFontOpticalSizing(OpticalSizing font_optical_sizing) { + fields_.font_optical_sizing_ = font_optical_sizing; + } + void SetFontPalette(scoped_refptr palette) { + font_palette_ = std::move(palette); + } + void SetFontVariantAlternates( + scoped_refptr alternates) { + font_variant_alternates_ = std::move(alternates); + } + void SetTextRendering(TextRenderingMode rendering) { + fields_.text_rendering_ = rendering; + UpdateTypesettingFeatures(); + } + void SetOrientation(FontOrientation orientation); + void SetWidthVariant(FontWidthVariant width_variant) { + fields_.width_variant_ = width_variant; + } + void SetLocale(scoped_refptr locale) { + locale_ = std::move(locale); + } + void SetSyntheticBold(bool synthetic_bold) { + fields_.synthetic_bold_ = synthetic_bold; + } + void SetSyntheticItalic(bool synthetic_italic) { + fields_.synthetic_italic_ = synthetic_italic; + } + void SetFontSynthesisWeight(FontSynthesisWeight font_synthesis_weight) { + fields_.font_synthesis_weight_ = font_synthesis_weight; + } + void SetFontSynthesisStyle(FontSynthesisStyle font_synthesis_style) { + fields_.font_synthesis_style_ = font_synthesis_style; + } + void SetFontSynthesisSmallCaps( + FontSynthesisSmallCaps font_synthesis_small_caps) { + fields_.font_synthesis_small_caps_ = font_synthesis_small_caps; + } + void SetFeatureSettings(scoped_refptr settings) { + feature_settings_ = std::move(settings); + } + void SetVariationSettings( + scoped_refptr settings) { + variation_settings_ = std::move(settings); + } + void SetVariantPosition(FontVariantPosition variant_position) { + fields_.variant_position_ = variant_position; + } + void SetVariantEmoji(FontVariantEmoji variant_emoji) { + fields_.variant_emoji_ = variant_emoji; + } + void SetWordSpacing(float s) { word_spacing_ = s; } + void SetLetterSpacing(float s) { + letter_spacing_ = s; + UpdateTypesettingFeatures(); + } + + TypesettingFeatures GetTypesettingFeatures() const { + return static_cast(fields_.typesetting_features_); + } + + static void SetSubpixelPositioning(bool b) { + use_subpixel_text_positioning_ = b; + } + static bool SubpixelPositioning() { return use_subpixel_text_positioning_; } + + void SetSubpixelAscentDescent(bool sp) { + fields_.subpixel_ascent_descent_ = sp; + } + + bool SubpixelAscentDescent() const { + return fields_.subpixel_ascent_descent_; + } + + HashCategory GetHashCategory() const { + return static_cast(fields_.hash_category_); + } + + bool IsHashTableEmptyValue() const { + return GetHashCategory() == kHashEmptyValue; + } + + bool IsHashTableDeletedValue() const { + return GetHashCategory() == kHashDeletedValue; + } + + unsigned StyleHashWithoutFamilyList() const; + unsigned GetHash() const; + + // TODO(drott): We should not expose internal structure here, but rather + // introduce a hash function here. + unsigned BitmapFields() const { return fields_as_unsigned_.parts[0]; } + unsigned AuxiliaryBitmapFields() const { + return fields_as_unsigned_.parts[1]; + } + + SkFontStyle SkiaFontStyle() const; + + void UpdateFromSkiaFontStyle(const SkFontStyle& font_style); + + int MinimumPrefixWidthToHyphenate() const; + + String ToString() const; + + private: + void UpdateSyntheticOblique(); + + FontFamily family_list_; // The list of font families to be used. + scoped_refptr feature_settings_; + scoped_refptr variation_settings_; + scoped_refptr locale_; + scoped_refptr font_palette_; + scoped_refptr font_variant_alternates_; + + void UpdateTypesettingFeatures(); + + // Specified CSS value. Independent of rendering issues such as integer + // rounding, minimum font sizes, and zooming. + float specified_size_; + // Computed size adjusted for the minimum font size and the zoom factor. + float computed_size_; + + // (Given aspect value / aspect value of a font family) * specifiedSize. + // This value is adjusted for the minimum font size and the zoom factor + // as well as a computed size is. + float adjusted_size_; + + float letter_spacing_; + float word_spacing_; + + FontSizeAdjust size_adjust_; + + // Covers stretch, style, weight. + FontSelectionRequest font_selection_request_; + FontSelectionValue original_slope; + + struct BitFields { + DISALLOW_NEW(); + + String ToString() const; + + unsigned orientation_ : kFontOrientationBitCount; + + unsigned width_variant_ : 2; // FontWidthVariant + + unsigned variant_caps_ : 3; // FontVariantCaps + unsigned + is_absolute_size_ : 1; // Whether or not CSS specified an explicit size + // (logical sizes like "medium" don't count). + unsigned generic_family_ : 3; // GenericFamilyType + + unsigned kerning_ : 2; // Kerning + + unsigned common_ligatures_state_ : 2; + unsigned discretionary_ligatures_state_ : 2; + unsigned historical_ligatures_state_ : 2; + unsigned contextual_ligatures_state_ : 2; + + // We cache whether or not a font is currently represented by a CSS keyword + // (e.g., medium). If so, then we can accurately translate across different + // generic families to adjust for different preference settings (e.g., 13px + // monospace vs. 16px everything else). Sizes are 1-8 (like the HTML size + // values for ). + unsigned keyword_size_ : 4; + + unsigned font_smoothing_ : 2; // FontSmoothingMode + unsigned text_rendering_ : 2; // TextRenderingMode + unsigned synthetic_bold_ : 1; + unsigned synthetic_italic_ : 1; + unsigned synthetic_oblique_ : 1; + unsigned font_synthesis_weight_ : 1; + unsigned font_synthesis_style_ : 1; + unsigned font_synthesis_small_caps_ : 1; + unsigned subpixel_text_position_ : 1; + unsigned typesetting_features_ : 3; + unsigned variant_numeric_ : 8; + unsigned variant_east_asian_ : 6; + unsigned subpixel_ascent_descent_ : 1; + unsigned font_optical_sizing_ : 1; + unsigned has_size_adjust_descriptor_ : 1; + unsigned variant_position_ : 2; + unsigned variant_emoji_ : 2; + unsigned text_spacing_trim_ : kTextSpacingTrimBitCount; + + unsigned hash_category_ : 2; // HashCategory + }; + + static_assert(sizeof(BitFields) == sizeof(FieldsAsUnsignedType), + "Mapped bitfield datatypes must have identical size."); + union { + BitFields fields_; + FieldsAsUnsignedType fields_as_unsigned_; + }; + + static bool use_subpixel_text_positioning_; +}; + +} + +#endif // WEBF_CORE_PLATFORM_FONTS_FONT_DESCRIPTION_H_ diff --git a/bridge/core/platform/fonts/font_selection_types.cc b/bridge/core/platform/fonts/font_selection_types.cc new file mode 100644 index 000000000..a07fb44a3 --- /dev/null +++ b/bridge/core/platform/fonts/font_selection_types.cc @@ -0,0 +1,30 @@ +/* +* Copyright (C) 2017 Apple Inc. All rights reserved. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions +* are met: +* 1. Redistributions of source code must retain the above copyright +* notice, this list of conditions and the following disclaimer. +* 2. Redistributions in binary form must reproduce the above copyright +* notice, this list of conditions and the following disclaimer in the +* documentation and/or other materials provided with the distribution. +* +* THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' +* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS +* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF +* THE POSSIBILITY OF SUCH DAMAGE. +*/ + +#include "font_selection_types.h" + +namespace webf { + +} diff --git a/bridge/core/platform/fonts/font_selection_types.h b/bridge/core/platform/fonts/font_selection_types.h new file mode 100644 index 000000000..df1f2fbaa --- /dev/null +++ b/bridge/core/platform/fonts/font_selection_types.h @@ -0,0 +1,322 @@ +/* +* Copyright (C) 2017 Apple Inc. All rights reserved. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions +* are met: +* 1. Redistributions of source code must retain the above copyright +* notice, this list of conditions and the following disclaimer. +* 2. Redistributions in binary form must reproduce the above copyright +* notice, this list of conditions and the following disclaimer in the +* documentation and/or other materials provided with the distribution. +* +* THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' +* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS +* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF +* THE POSSIBILITY OF SUCH DAMAGE. +*/ + +#ifndef WEBF_CORE_PLATFORM_FONTS_FONT_SELECTION_TYPES_H_ +#define WEBF_CORE_PLATFORM_FONTS_FONT_SELECTION_TYPES_H_ + +#include "foundation/macros.h" +#include "core/platform/math_extras.h" + +namespace webf { + +// Unclamped, unchecked, signed fixed-point number representing a value used for +// font variations. Sixteen bits in total, one sign bit, two fractional bits, +// means the smallest positive representable value is 0.25, the maximum +// representable value is 8191.75, and the minimum representable value is -8192. +class FontSelectionValue { + USING_FAST_MALLOC(FontSelectionValue); + + public: + FontSelectionValue() = default; + + // Explicit because it is lossy. + explicit constexpr FontSelectionValue(int x) + : backing_(ClampTo(x * fractionalEntropy)) {} + + // Explicit because it is lossy. + explicit constexpr FontSelectionValue(float x) + : backing_(ClampTo(x * fractionalEntropy)) {} + + // Explicit because it is lossy. + explicit constexpr FontSelectionValue(double x) + : backing_(ClampTo(x * fractionalEntropy)) {} + + constexpr operator float() const { + // floats have 23 fractional bits, but only 14 fractional bits are + // necessary, so every value can be represented losslessly. + return backing_ / static_cast(fractionalEntropy); + } + + constexpr FontSelectionValue operator+(const FontSelectionValue& other) const; + constexpr FontSelectionValue operator-(const FontSelectionValue& other) const; + constexpr FontSelectionValue operator*(const FontSelectionValue& other) const; + constexpr FontSelectionValue operator/(const FontSelectionValue& other) const; + constexpr FontSelectionValue operator-() const; + constexpr bool operator==(const FontSelectionValue& other) const; + constexpr bool operator!=(const FontSelectionValue& other) const; + constexpr bool operator<(const FontSelectionValue& other) const; + constexpr bool operator<=(const FontSelectionValue& other) const; + constexpr bool operator>(const FontSelectionValue& other) const; + constexpr bool operator>=(const FontSelectionValue& other) const; + + int16_t RawValue() const { return backing_; } + + std::string ToString() const; + + static constexpr FontSelectionValue MaximumValue() { + return FontSelectionValue(std::numeric_limits::max(), + RawTag::RawTag); + } + + static constexpr FontSelectionValue MinimumValue() { + return FontSelectionValue(std::numeric_limits::min(), + RawTag::RawTag); + } + + protected: + enum class RawTag { RawTag }; + + constexpr FontSelectionValue(int16_t rawValue, RawTag) : backing_(rawValue) {} + + private: + static constexpr int fractionalEntropy = 4; + // TODO(drott) crbug.com/745910 - Consider making this backed by a checked + // arithmetic type. + int16_t backing_{0}; +}; + +inline constexpr FontSelectionValue FontSelectionValue::operator+( + const FontSelectionValue& other) const { + return FontSelectionValue(backing_ + other.backing_, RawTag::RawTag); +} + +inline constexpr FontSelectionValue FontSelectionValue::operator-( + const FontSelectionValue& other) const { + return FontSelectionValue(backing_ - other.backing_, RawTag::RawTag); +} + +inline constexpr FontSelectionValue FontSelectionValue::operator*( + const FontSelectionValue& other) const { + return FontSelectionValue( + static_cast(backing_) * other.backing_ / fractionalEntropy, + RawTag::RawTag); +} + +inline constexpr FontSelectionValue FontSelectionValue::operator/( + const FontSelectionValue& other) const { + return FontSelectionValue( + static_cast(backing_) / other.backing_ * fractionalEntropy, + RawTag::RawTag); +} + +inline constexpr FontSelectionValue FontSelectionValue::operator-() const { + return FontSelectionValue(-backing_, RawTag::RawTag); +} + +inline constexpr bool FontSelectionValue::operator==( + const FontSelectionValue& other) const { + return backing_ == other.backing_; +} + +inline constexpr bool FontSelectionValue::operator!=( + const FontSelectionValue& other) const { + return !operator==(other); +} + +inline constexpr bool FontSelectionValue::operator<( + const FontSelectionValue& other) const { + return backing_ < other.backing_; +} + +inline constexpr bool FontSelectionValue::operator<=( + const FontSelectionValue& other) const { + return backing_ <= other.backing_; +} + +inline constexpr bool FontSelectionValue::operator>( + const FontSelectionValue& other) const { + return backing_ > other.backing_; +} + +inline constexpr bool FontSelectionValue::operator>=( + const FontSelectionValue& other) const { + return backing_ >= other.backing_; +} + +inline constexpr FontSelectionValue kItalicThreshold = FontSelectionValue(14); + +static constexpr inline bool isItalic(FontSelectionValue fontStyle) { + return fontStyle >= kItalicThreshold; +} + +inline constexpr FontSelectionValue kFontSelectionZeroValue = + FontSelectionValue(0); + +inline constexpr FontSelectionValue kNormalSlopeValue = FontSelectionValue(); + +inline constexpr FontSelectionValue kItalicSlopeValue = FontSelectionValue(14); + +inline constexpr FontSelectionValue kMaxObliqueValue = FontSelectionValue(90); + +inline constexpr FontSelectionValue kMinObliqueValue = FontSelectionValue(-90); + +inline constexpr FontSelectionValue kBoldThreshold = FontSelectionValue(600); + +inline constexpr FontSelectionValue kMinWeightValue = FontSelectionValue(1); + +inline constexpr FontSelectionValue kMaxWeightValue = FontSelectionValue(1000); + +inline constexpr FontSelectionValue kBlackWeightValue = FontSelectionValue(900); + +inline constexpr FontSelectionValue kExtraBoldWeightValue = + FontSelectionValue(800); + +inline constexpr FontSelectionValue kBoldWeightValue = FontSelectionValue(700); + +inline constexpr FontSelectionValue kSemiBoldWeightValue = + FontSelectionValue(600); + +inline constexpr FontSelectionValue kMediumWeightValue = + FontSelectionValue(500); + +inline constexpr FontSelectionValue kNormalWeightValue = + FontSelectionValue(400); + +inline constexpr FontSelectionValue kLightWeightValue = FontSelectionValue(300); + +inline constexpr FontSelectionValue kExtraLightWeightValue = + FontSelectionValue(200); + +inline constexpr FontSelectionValue kThinWeightValue = FontSelectionValue(100); + +static constexpr inline bool isFontWeightBold(FontSelectionValue fontWeight) { + return fontWeight >= kBoldThreshold; +} + +inline constexpr FontSelectionValue kUpperWeightSearchThreshold = + FontSelectionValue(500); + +inline constexpr FontSelectionValue kLowerWeightSearchThreshold = + FontSelectionValue(400); + +inline constexpr FontSelectionValue kUltraCondensedWidthValue = + FontSelectionValue(50); + +inline constexpr FontSelectionValue kExtraCondensedWidthValue = + FontSelectionValue(62.5f); + +inline constexpr FontSelectionValue kCondensedWidthValue = + FontSelectionValue(75); + +inline constexpr FontSelectionValue kSemiCondensedWidthValue = + FontSelectionValue(87.5f); + +inline constexpr FontSelectionValue kNormalWidthValue = FontSelectionValue(100); + +inline constexpr FontSelectionValue kSemiExpandedWidthValue = + FontSelectionValue(112.5f); + +inline constexpr FontSelectionValue kExpandedWidthValue = + FontSelectionValue(125); + +inline constexpr FontSelectionValue kExtraExpandedWidthValue = + FontSelectionValue(150); + +inline constexpr FontSelectionValue kUltraExpandedWidthValue = + FontSelectionValue(200); + +struct FontSelectionRange { + enum RangeType { kSetFromAuto, kSetExplicitly }; + + explicit FontSelectionRange(FontSelectionValue single_value) + : minimum(single_value), maximum(single_value) {} + + FontSelectionRange(const FontSelectionValue& minimum, + const FontSelectionValue maximum) + : minimum(minimum), maximum(maximum) {} + + FontSelectionRange(const FontSelectionValue& minimum, + const FontSelectionValue& maximum, + RangeType type) + : minimum(minimum), maximum(maximum), type(type) {} + + bool operator==(const FontSelectionRange& other) const { + return minimum == other.minimum && maximum == other.maximum; + } + + bool IsValid() const { return minimum <= maximum; } + + bool IsRange() const { return maximum > minimum; } + + bool IsRangeSetFromAuto() const { return type == kSetFromAuto; } + + void Expand(const FontSelectionRange& other) { + DCHECK(other.IsValid()); + if (!IsValid()) { + *this = other; + } else { + minimum = std::min(minimum, other.minimum); + maximum = std::max(maximum, other.maximum); + } + DCHECK(IsValid()); + } + + bool Includes(FontSelectionValue target) const { + return target >= minimum && target <= maximum; + } + + uint32_t UniqueValue() const { + return minimum.RawValue() << 16 | maximum.RawValue(); + } + + FontSelectionValue clampToRange(FontSelectionValue selection_value) const { + return std::clamp(selection_value, minimum, maximum); + } + + FontSelectionValue minimum{FontSelectionValue(1)}; + FontSelectionValue maximum{FontSelectionValue(0)}; + + RangeType type = kSetFromAuto; +}; + +struct FontSelectionRequest { + FontSelectionRequest() = default; + + FontSelectionRequest(FontSelectionValue weight, + FontSelectionValue width, + FontSelectionValue slope) + : weight(weight), width(width), slope(slope) {} + + unsigned GetHash() const; + + bool operator==(const FontSelectionRequest& other) const { + return weight == other.weight && width == other.width && + slope == other.slope; + } + + bool operator!=(const FontSelectionRequest& other) const { + return !operator==(other); + } + + std::string ToString() const; + + FontSelectionValue weight; + FontSelectionValue width; + FontSelectionValue slope; +}; + +} + +#endif // WEBF_CORE_PLATFORM_FONTS_FONT_SELECTION_TYPES_H_ diff --git a/bridge/core/style/font_size_style.h b/bridge/core/style/font_size_style.h new file mode 100644 index 000000000..69f377767 --- /dev/null +++ b/bridge/core/style/font_size_style.h @@ -0,0 +1,50 @@ +// Copyright 2023 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef WEBF_CORE_STYLE_FONT_SIZE_STYLE_H_ +#define WEBF_CORE_STYLE_FONT_SIZE_STYLE_H_ + +#include "foundation/macros.h" +#include "core/platform/fonts/font.h" +#include "core/platform/geometry/length.h" + +namespace webf { + +// FontSizeStyle contains the subset of ComputedStyle/ComputedStyleBuilder +// which is needed to resolve units within CSSToLengthConversionData and +// friends. +class FontSizeStyle { + WEBF_STACK_ALLOCATED(); + + public: + FontSizeStyle(const Font& font, + const Length& specified_line_height, + float effective_zoom) + : font_(font), + specified_line_height_(specified_line_height), + effective_zoom_(effective_zoom) {} + + bool operator==(const FontSizeStyle& o) const { + return (font_ == o.font_ && + specified_line_height_ == o.specified_line_height_ && + effective_zoom_ == o.effective_zoom_); + } + bool operator!=(const FontSizeStyle& o) const { return !(*this == o); } + + const Font& GetFont() const { return font_; } + const Length& SpecifiedLineHeight() const { return specified_line_height_; } + float SpecifiedFontSize() const { + return font_.GetFontDescription().SpecifiedSize(); + } + float EffectiveZoom() const { return effective_zoom_; } + + private: + const Font& font_; + const Length& specified_line_height_; + const float effective_zoom_; +}; + +} + +#endif // WEBF_CORE_STYLE_FONT_SIZE_STYLE_H_ diff --git a/bridge/test/test.cmake b/bridge/test/test.cmake index 4521a0bfa..130911811 100644 --- a/bridge/test/test.cmake +++ b/bridge/test/test.cmake @@ -44,7 +44,7 @@ list(APPEND WEBF_UNIT_TEST_SOURCEURCE ./core/css/parser/css_parser_token_stream_test.cc ./core/css/parser/css_parser_local_context_test.cc ./core/css/parser/css_property_parser_test.cc -# ./core/css/css_primitive_value_test.cc + ./core/css/css_primitive_value_test.cc ./core/css/css_test_helpers.cc )