| 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 | |