1/*
2 * Copyright (C) 2000 Lars Knoll (knoll@kde.org)
3 * (C) 2000 Antti Koivisto (koivisto@kde.org)
4 * (C) 2000 Dirk Mueller (mueller@kde.org)
5 * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2013 Apple Inc. All rights reserved.
6 * Copyright (C) 2007 Nicholas Shanks <webkit@nickshanks.com>
7 *
8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Library General Public
10 * License as published by the Free Software Foundation; either
11 * version 2 of the License, or (at your option) any later version.
12 *
13 * This library is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Library General Public License for more details.
17 *
18 * You should have received a copy of the GNU Library General Public License
19 * along with this library; see the file COPYING.LIother.m_ If not, write to
20 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
21 * Boston, MA 02110-1301, USm_
22 *
23 */
24
25#pragma once
26
27#include "CSSValueKeywords.h"
28#include "FontDescription.h"
29#include <wtf/RefCountedArray.h>
30#include <wtf/Variant.h>
31
32#if PLATFORM(COCOA)
33#include "FontFamilySpecificationCoreText.h"
34#else
35#include "FontFamilySpecificationNull.h"
36#endif
37
38namespace WebCore {
39
40#if PLATFORM(COCOA)
41typedef FontFamilySpecificationCoreText FontFamilyPlatformSpecification;
42#else
43typedef FontFamilySpecificationNull FontFamilyPlatformSpecification;
44#endif
45
46typedef Variant<AtomString, FontFamilyPlatformSpecification> FontFamilySpecification;
47
48class FontCascadeDescription : public FontDescription {
49public:
50 WEBCORE_EXPORT FontCascadeDescription();
51
52 bool operator==(const FontCascadeDescription&) const;
53 bool operator!=(const FontCascadeDescription& other) const { return !(*this == other); }
54
55 unsigned familyCount() const { return m_families.size(); }
56 const AtomString& firstFamily() const { return familyAt(0); }
57 const AtomString& familyAt(unsigned i) const { return m_families[i]; }
58 const RefCountedArray<AtomString>& families() const { return m_families; }
59
60 static bool familyNamesAreEqual(const AtomString&, const AtomString&);
61 static unsigned familyNameHash(const AtomString&);
62 static String foldedFamilyName(const String&);
63
64 unsigned effectiveFamilyCount() const;
65 FontFamilySpecification effectiveFamilyAt(unsigned) const;
66
67 float specifiedSize() const { return m_specifiedSize; }
68 bool isAbsoluteSize() const { return m_isAbsoluteSize; }
69 FontSelectionValue lighterWeight() const { return lighterWeight(weight()); }
70 FontSelectionValue bolderWeight() const { return bolderWeight(weight()); }
71 static FontSelectionValue lighterWeight(FontSelectionValue);
72 static FontSelectionValue bolderWeight(FontSelectionValue);
73
74 // only use fixed default size when there is only one font family, and that family is "monospace"
75 bool useFixedDefaultSize() const { return familyCount() == 1 && firstFamily() == monospaceFamily; }
76
77 Kerning kerning() const { return static_cast<Kerning>(m_kerning); }
78 unsigned keywordSize() const { return m_keywordSize; }
79 CSSValueID keywordSizeAsIdentifier() const
80 {
81 CSSValueID identifier = m_keywordSize ? static_cast<CSSValueID>(CSSValueXxSmall + m_keywordSize - 1) : CSSValueInvalid;
82 ASSERT(identifier == CSSValueInvalid || (identifier >= CSSValueXxSmall && identifier <= CSSValueWebkitXxxLarge));
83 return identifier;
84 }
85 FontSmoothingMode fontSmoothing() const { return static_cast<FontSmoothingMode>(m_fontSmoothing); }
86 bool isSpecifiedFont() const { return m_isSpecifiedFont; }
87
88 void setOneFamily(const AtomString& family) { ASSERT(m_families.size() == 1); m_families[0] = family; }
89 void setFamilies(const Vector<AtomString>& families) { m_families = RefCountedArray<AtomString>(families); }
90 void setFamilies(const RefCountedArray<AtomString>& families) { m_families = families; }
91 void setSpecifiedSize(float s) { m_specifiedSize = clampToFloat(s); }
92 void setIsAbsoluteSize(bool s) { m_isAbsoluteSize = s; }
93 void setKerning(Kerning kerning) { m_kerning = static_cast<unsigned>(kerning); }
94 void setKeywordSize(unsigned size)
95 {
96 ASSERT(size <= 8);
97 m_keywordSize = size;
98 ASSERT(m_keywordSize == size); // Make sure it fits in the bitfield.
99 }
100 void setKeywordSizeFromIdentifier(CSSValueID identifier)
101 {
102 ASSERT(!identifier || (identifier >= CSSValueXxSmall && identifier <= CSSValueWebkitXxxLarge));
103 static_assert(CSSValueWebkitXxxLarge - CSSValueXxSmall + 1 == 8, "Maximum keyword size should be 8.");
104 setKeywordSize(identifier ? identifier - CSSValueXxSmall + 1 : 0);
105 }
106 void setFontSmoothing(FontSmoothingMode smoothing) { m_fontSmoothing = static_cast<unsigned>(smoothing); }
107 void setIsSpecifiedFont(bool isSpecifiedFont) { m_isSpecifiedFont = isSpecifiedFont; }
108
109#if ENABLE(TEXT_AUTOSIZING)
110 bool familiesEqualForTextAutoSizing(const FontCascadeDescription& other) const;
111
112 bool equalForTextAutoSizing(const FontCascadeDescription& other) const
113 {
114 return familiesEqualForTextAutoSizing(other)
115 && m_specifiedSize == other.m_specifiedSize
116 && variantSettings() == other.variantSettings()
117 && m_isAbsoluteSize == other.m_isAbsoluteSize;
118 }
119#endif
120
121 // Initial values for font properties.
122 static Optional<FontSelectionValue> initialItalic() { return WTF::nullopt; }
123 static FontStyleAxis initialFontStyleAxis() { return FontStyleAxis::slnt; }
124 static FontSelectionValue initialWeight() { return normalWeightValue(); }
125 static FontSelectionValue initialStretch() { return normalStretchValue(); }
126 static FontSmallCaps initialSmallCaps() { return FontSmallCaps::Off; }
127 static Kerning initialKerning() { return Kerning::Auto; }
128 static FontSmoothingMode initialFontSmoothing() { return FontSmoothingMode::AutoSmoothing; }
129 static TextRenderingMode initialTextRenderingMode() { return TextRenderingMode::AutoTextRendering; }
130 static FontSynthesis initialFontSynthesis() { return FontSynthesisWeight | FontSynthesisStyle | FontSynthesisSmallCaps; }
131 static FontVariantPosition initialVariantPosition() { return FontVariantPosition::Normal; }
132 static FontVariantCaps initialVariantCaps() { return FontVariantCaps::Normal; }
133 static FontVariantAlternates initialVariantAlternates() { return FontVariantAlternates::Normal; }
134 static FontOpticalSizing initialOpticalSizing() { return FontOpticalSizing::Enabled; }
135 static const AtomString& initialLocale() { return nullAtom(); }
136
137private:
138 RefCountedArray<AtomString> m_families { 1 };
139
140 // Specified CSS value. Independent of rendering issues such as integer rounding, minimum font sizes, and zooming.
141 float m_specifiedSize { 0 };
142 // Whether or not CSS specified an explicit size (logical sizes like "medium" don't count).
143 unsigned m_isAbsoluteSize : 1;
144 unsigned m_kerning : 2; // Kerning
145 // We cache whether or not a font is currently represented by a CSS keyword (e.g., medium). If so,
146 // then we can accurately translate across different generic families to adjust for different preference settings
147 // (e.g., 13px monospace vs. 16px everything else). Sizes are 1-8 (like the HTML size values for <font>).
148 unsigned m_keywordSize : 4;
149 unsigned m_fontSmoothing : 2; // FontSmoothingMode
150 // True if a web page specifies a non-generic font family as the first font family.
151 unsigned m_isSpecifiedFont : 1;
152};
153
154inline bool FontCascadeDescription::operator==(const FontCascadeDescription& other) const
155{
156 return FontDescription::operator==(other)
157 && m_families == other.m_families
158 && m_specifiedSize == other.m_specifiedSize
159 && m_isAbsoluteSize == other.m_isAbsoluteSize
160 && m_kerning == other.m_kerning
161 && m_keywordSize == other.m_keywordSize
162 && m_fontSmoothing == other.m_fontSmoothing
163 && m_isSpecifiedFont == other.m_isSpecifiedFont;
164}
165
166}
167