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 | |
38 | namespace WebCore { |
39 | |
40 | #if PLATFORM(COCOA) |
41 | typedef FontFamilySpecificationCoreText FontFamilyPlatformSpecification; |
42 | #else |
43 | typedef FontFamilySpecificationNull FontFamilyPlatformSpecification; |
44 | #endif |
45 | |
46 | typedef Variant<AtomicString, FontFamilyPlatformSpecification> FontFamilySpecification; |
47 | |
48 | class FontCascadeDescription : public FontDescription { |
49 | public: |
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 AtomicString& firstFamily() const { return familyAt(0); } |
57 | const AtomicString& familyAt(unsigned i) const { return m_families[i]; } |
58 | const RefCountedArray<AtomicString>& families() const { return m_families; } |
59 | |
60 | static bool familyNamesAreEqual(const AtomicString&, const AtomicString&); |
61 | static unsigned familyNameHash(const AtomicString&); |
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 AtomicString& family) { ASSERT(m_families.size() == 1); m_families[0] = family; } |
89 | void setFamilies(const Vector<AtomicString>& families) { m_families = RefCountedArray<AtomicString>(families); } |
90 | void setFamilies(const RefCountedArray<AtomicString>& 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 AtomicString& initialLocale() { return nullAtom(); } |
136 | |
137 | private: |
138 | RefCountedArray<AtomicString> 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 | |
154 | inline 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 | |