* 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 <webkit@nickshanks.com>
*
* 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 THIRD_PARTY_BLINK_RENDERER_PLATFORM_FONTS_FONT_DESCRIPTION_H_
#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_FONTS_FONT_DESCRIPTION_H_
#include <unicode/uscript.h>
#include "base/memory/scoped_refptr.h"
#include "third_party/blink/renderer/platform/font_family_names.h"
#include "third_party/blink/renderer/platform/fonts/font_cache_key.h"
#include "third_party/blink/renderer/platform/fonts/font_family.h"
#include "third_party/blink/renderer/platform/fonts/font_optical_sizing.h"
#include "third_party/blink/renderer/platform/fonts/font_orientation.h"
#include "third_party/blink/renderer/platform/fonts/font_palette.h"
#include "third_party/blink/renderer/platform/fonts/font_selection_types.h"
#include "third_party/blink/renderer/platform/fonts/font_size_adjust.h"
#include "third_party/blink/renderer/platform/fonts/font_smoothing_mode.h"
#include "third_party/blink/renderer/platform/fonts/font_variant_alternates.h"
#include "third_party/blink/renderer/platform/fonts/font_variant_east_asian.h"
#include "third_party/blink/renderer/platform/fonts/font_variant_emoji.h"
#include "third_party/blink/renderer/platform/fonts/font_variant_numeric.h"
#include "third_party/blink/renderer/platform/fonts/font_width_variant.h"
#include "third_party/blink/renderer/platform/fonts/opentype/font_settings.h"
#include "third_party/blink/renderer/platform/fonts/shaping/text_spacing_trim.h"
#include "third_party/blink/renderer/platform/fonts/text_rendering_mode.h"
#include "third_party/blink/renderer/platform/fonts/typesetting_features.h"
#include "third_party/blink/renderer/platform/geometry/length.h"
#include "third_party/blink/renderer/platform/text/layout_locale.h"
#include "third_party/blink/renderer/platform/wtf/allocator/allocator.h"
#include "third_party/blink/renderer/platform/wtf/math_extras.h"
#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
#include "third_party/skia/include/core/SkFontStyle.h"
namespace blink {
typedef struct { uint32_t parts[2]; } FieldsAsUnsignedType;
class PLATFORM_EXPORT 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 String ToString(GenericFamilyType);
enum LigaturesState {
kNormalLigaturesState,
kDisabledLigaturesState,
kEnabledLigaturesState
};
static String ToString(LigaturesState);
enum Kerning { kAutoKerning, kNormalKerning, kNoneKerning };
static String ToString(Kerning);
static 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(HashTableDeletedValueType);
FontDescription& operator=(const FontDescription&);
bool operator==(const FontDescription&) const;
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;
unsigned is_absolute : 1;
float value;
};
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_; }
float AdjustedSpecifiedSize() const;
float ComputedSize() const { return computed_size_; }
FontSizeAdjust SizeAdjust() const { return size_adjust_; }
bool HasSizeAdjust() const { return !!size_adjust_; }
FontDescription SizeAdjustedFontDescription(float size_adjust) const;
float AdjustedSize() const { return adjusted_size_; }
int ComputedPixelSize() const { return int(computed_size_ + 0.5f); }
FontVariantCaps VariantCaps() const {
return static_cast<FontVariantCaps>(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<GenericFamilyType>(fields_.generic_family_);
}
bool IsMonospace() const {
return Family().FamilyName() == font_family_names::kMonospace &&
Family().FamilyIsGeneric() && !Family().Next();
}
Kerning GetKerning() const { return static_cast<Kerning>(fields_.kerning_); }
TextSpacingTrim GetTextSpacingTrim() const {
return static_cast<TextSpacingTrim>(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<LigaturesState>(fields_.common_ligatures_state_);
}
LigaturesState DiscretionaryLigaturesState() const {
return static_cast<LigaturesState>(fields_.discretionary_ligatures_state_);
}
LigaturesState HistoricalLigaturesState() const {
return static_cast<LigaturesState>(fields_.historical_ligatures_state_);
}
LigaturesState ContextualLigaturesState() const {
return static_cast<LigaturesState>(fields_.contextual_ligatures_state_);
}
unsigned KeywordSize() const { return fields_.keyword_size_; }
FontSmoothingMode FontSmoothing() const {
return static_cast<FontSmoothingMode>(fields_.font_smoothing_);
}
OpticalSizing FontOpticalSizing() const {
return static_cast<OpticalSizing>(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<TextRenderingMode>(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<FontSynthesisWeight>(fields_.font_synthesis_weight_);
}
bool SyntheticBoldAllowed() const {
return fields_.font_synthesis_weight_ == kAutoFontSynthesisWeight;
}
FontSynthesisStyle GetFontSynthesisStyle() const {
return static_cast<FontSynthesisStyle>(fields_.font_synthesis_style_);
}
bool SyntheticItalicAllowed() const {
return fields_.font_synthesis_style_ == kAutoFontSynthesisStyle;
}
FontSynthesisSmallCaps GetFontSynthesisSmallCaps() const {
return static_cast<FontSynthesisSmallCaps>(
fields_.font_synthesis_small_caps_);
}
FontSelectionRequest GetFontSelectionRequest() const;
float WordSpacing() const;
const Length& ComputedWordSpacing() const { return word_spacing_; }
float LetterSpacing() const;
const Length& ComputedLetterSpacing() const { return letter_spacing_; }
FontOrientation Orientation() const {
return static_cast<FontOrientation>(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<FontWidthVariant>(fields_.width_variant_);
}
const FontFeatureSettings* FeatureSettings() const {
return feature_settings_.get();
}
const FontVariationSettings* VariationSettings() const {
return variation_settings_.get();
}
const AtomicString& FontLanguageOverride() const {
return language_override_;
}
FontVariantPosition VariantPosition() const {
return static_cast<FontVariantPosition>(fields_.variant_position_);
}
FontVariantEmoji VariantEmoji() const {
return static_cast<FontVariantEmoji>(fields_.variant_emoji_);
}
float EffectiveFontSize()
const;
FontCacheKey CacheKey(const FontFaceCreationParams&,
bool is_unique_match) const;
void SetFamily(const FontFamily& family) { family_list_ = family; }
void SetComputedSize(float s) { computed_size_ = ClampTo<float>(s); }
void SetSpecifiedSize(float s) { specified_size_ = ClampTo<float>(s); }
void SetAdjustedSize(float s) { adjusted_size_ = ClampTo<float>(s); }
void SetSizeAdjust(const FontSizeAdjust& size_adjust) {
size_adjust_ = size_adjust;
}
void SetResolvedFontFeatures(
const ResolvedFontFeatures&& resolved_font_features) {
resolved_font_features_ = std::move(resolved_font_features);
}
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<unsigned>(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<const FontPalette> palette) {
font_palette_ = std::move(palette);
}
void SetFontVariantAlternates(
scoped_refptr<const FontVariantAlternates> 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<const LayoutLocale> 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<const FontFeatureSettings> settings) {
feature_settings_ = std::move(settings);
}
void SetVariationSettings(
scoped_refptr<const FontVariationSettings> settings) {
variation_settings_ = std::move(settings);
}
void SetFontLanguageOverride(const AtomicString& value) {
language_override_ = value;
}
void SetVariantPosition(FontVariantPosition variant_position) {
fields_.variant_position_ = variant_position;
}
void SetVariantEmoji(FontVariantEmoji variant_emoji) {
fields_.variant_emoji_ = variant_emoji;
}
void SetWordSpacing(const Length& s) { word_spacing_ = s; }
#if BUILDFLAG(ARKWEB_COMPOSITE_RENDER)
void SetFixedFontSize(int s) { fixed_font_size_ = s; }
#endif
void SetLetterSpacing(const Length& s) {
letter_spacing_ = s;
UpdateTypesettingFeatures();
}
TypesettingFeatures GetTypesettingFeatures() const {
return static_cast<TypesettingFeatures>(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<HashCategory>(fields_.hash_category_);
}
bool IsHashTableEmptyValue() const {
return GetHashCategory() == kHashEmptyValue;
}
bool IsHashTableDeletedValue() const {
return GetHashCategory() == kHashDeletedValue;
}
bool HasLanguageOverride() const { return !language_override_.empty(); }
unsigned StyleHashWithoutFamilyList() const;
unsigned GetHash() const;
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;
ResolvedFontFeatures ResolveFontFeatures() const;
void MergeFontFeatureSettingsWithDescriptor(const FontFeatureSettings*);
void MergeFontVariationSettingsWithDescriptor(const FontVariationSettings*);
String ToString() const;
private:
void UpdateSyntheticOblique();
FontFamily family_list_;
scoped_refptr<const FontFeatureSettings> feature_settings_;
scoped_refptr<const FontVariationSettings> variation_settings_;
scoped_refptr<const LayoutLocale> locale_;
scoped_refptr<const FontPalette> font_palette_;
scoped_refptr<const FontVariantAlternates> font_variant_alternates_;
void UpdateTypesettingFeatures();
float specified_size_;
float computed_size_;
float adjusted_size_;
Length letter_spacing_;
Length word_spacing_;
#if BUILDFLAG(ARKWEB_COMPOSITE_RENDER)
int fixed_font_size_;
#endif
FontSizeAdjust size_adjust_;
ResolvedFontFeatures resolved_font_features_;
FontSelectionRequest font_selection_request_;
FontSelectionValue original_slope;
struct BitFields {
DISALLOW_NEW();
String ToString() const;
unsigned orientation_ : kFontOrientationBitCount;
unsigned width_variant_ : 2;
unsigned variant_caps_ : 3;
unsigned
is_absolute_size_ : 1;
unsigned generic_family_ : 3;
unsigned kerning_ : 2;
unsigned common_ligatures_state_ : 2;
unsigned discretionary_ligatures_state_ : 2;
unsigned historical_ligatures_state_ : 2;
unsigned contextual_ligatures_state_ : 2;
unsigned keyword_size_ : 4;
unsigned font_smoothing_ : 2;
unsigned text_rendering_ : 2;
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;
};
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_;
AtomicString language_override_;
};
template <>
struct HashTraits<FontDescription>
: SimpleClassHashTraits<blink::FontDescription> {
static FontDescription EmptyValue() {
return FontDescription::CreateHashTableEmptyValue();
}
};
}
#endif