1 | /* |
2 | * Copyright (C) 2018 Apple Inc. All rights reserved. |
3 | * |
4 | * Redistribution and use in source and binary forms, with or without |
5 | * modification, are permitted provided that the following conditions |
6 | * are met: |
7 | * 1. Redistributions of source code must retain the above copyright |
8 | * notice, this list of conditions and the following disclaimer. |
9 | * 2. Redistributions in binary form must reproduce the above copyright |
10 | * notice, this list of conditions and the following disclaimer in the |
11 | * documentation and/or other materials provided with the distribution. |
12 | * |
13 | * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' |
14 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, |
15 | * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR |
16 | * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS |
17 | * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR |
18 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF |
19 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS |
20 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN |
21 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
22 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF |
23 | * THE POSSIBILITY OF SUCH DAMAGE. |
24 | */ |
25 | |
26 | #include "config.h" |
27 | #include "FontAttributeChanges.h" |
28 | |
29 | #include "CSSPropertyNames.h" |
30 | #include "CSSShadowValue.h" |
31 | #include "CSSValueKeywords.h" |
32 | #include "CSSValueList.h" |
33 | #include "CSSValuePool.h" |
34 | #include "EditAction.h" |
35 | #include "EditingStyle.h" |
36 | #include "StyleProperties.h" |
37 | |
38 | namespace WebCore { |
39 | |
40 | #if !PLATFORM(COCOA) |
41 | |
42 | const String& FontChanges::platformFontFamilyNameForCSS() const |
43 | { |
44 | return m_fontFamily; |
45 | } |
46 | |
47 | #endif |
48 | |
49 | Ref<EditingStyle> FontChanges::createEditingStyle() const |
50 | { |
51 | auto properties = createStyleProperties(); |
52 | return EditingStyle::create(properties.ptr()); |
53 | } |
54 | |
55 | Ref<MutableStyleProperties> FontChanges::createStyleProperties() const |
56 | { |
57 | String familyNameForCSS; |
58 | if (!!m_fontFamily) |
59 | familyNameForCSS = platformFontFamilyNameForCSS(); |
60 | |
61 | auto style = MutableStyleProperties::create(); |
62 | auto& cssValuePool = CSSValuePool::singleton(); |
63 | |
64 | if (!!familyNameForCSS) |
65 | style->setProperty(CSSPropertyFontFamily, cssValuePool.createFontFamilyValue(familyNameForCSS)); |
66 | |
67 | if (m_italic) |
68 | style->setProperty(CSSPropertyFontStyle, *m_italic ? CSSValueItalic : CSSValueNormal); |
69 | |
70 | if (m_bold) |
71 | style->setProperty(CSSPropertyFontWeight, *m_bold ? CSSValueBold : CSSValueNormal); |
72 | |
73 | if (m_fontSize) |
74 | style->setProperty(CSSPropertyFontSize, cssValuePool.createValue(*m_fontSize, CSSPrimitiveValue::CSS_PX)); |
75 | |
76 | if (m_fontSizeDelta) |
77 | style->setProperty(CSSPropertyWebkitFontSizeDelta, cssValuePool.createValue(*m_fontSizeDelta, CSSPrimitiveValue::CSS_PX)); |
78 | |
79 | return style; |
80 | } |
81 | |
82 | static RefPtr<CSSValueList> cssValueListForShadow(const FontShadow& shadow) |
83 | { |
84 | if (shadow.offset.isZero() && !shadow.blurRadius) |
85 | return nullptr; |
86 | |
87 | auto list = CSSValueList::createCommaSeparated(); |
88 | auto& cssValuePool = CSSValuePool::singleton(); |
89 | auto width = cssValuePool.createValue(shadow.offset.width(), CSSPrimitiveValue::CSS_PX); |
90 | auto height = cssValuePool.createValue(shadow.offset.height(), CSSPrimitiveValue::CSS_PX); |
91 | auto blurRadius = cssValuePool.createValue(shadow.blurRadius, CSSPrimitiveValue::CSS_PX); |
92 | auto color = cssValuePool.createValue(shadow.color); |
93 | list->prepend(CSSShadowValue::create(WTFMove(width), WTFMove(height), WTFMove(blurRadius), { }, { }, WTFMove(color))); |
94 | return list.ptr(); |
95 | } |
96 | |
97 | EditAction FontAttributeChanges::editAction() const |
98 | { |
99 | if (!m_verticalAlign && !m_backgroundColor && !m_shadow && !m_strikeThrough && !m_underline) { |
100 | if (m_foregroundColor && m_fontChanges.isEmpty()) |
101 | return EditAction::SetColor; |
102 | |
103 | if (!m_foregroundColor && !m_fontChanges.isEmpty()) |
104 | return EditAction::SetFont; |
105 | } |
106 | return EditAction::ChangeAttributes; |
107 | } |
108 | |
109 | Ref<EditingStyle> FontAttributeChanges::createEditingStyle() const |
110 | { |
111 | auto style = m_fontChanges.createStyleProperties(); |
112 | auto& cssValuePool = CSSValuePool::singleton(); |
113 | |
114 | if (m_backgroundColor) |
115 | style->setProperty(CSSPropertyBackgroundColor, cssValuePool.createValue(*m_backgroundColor)); |
116 | |
117 | if (m_foregroundColor) |
118 | style->setProperty(CSSPropertyColor, cssValuePool.createValue(*m_foregroundColor)); |
119 | |
120 | if (m_shadow) { |
121 | if (auto shadowValue = cssValueListForShadow(*m_shadow)) |
122 | style->setProperty(CSSPropertyTextShadow, WTFMove(shadowValue)); |
123 | else |
124 | style->setProperty(CSSPropertyTextShadow, CSSValueNone); |
125 | } |
126 | |
127 | if (m_verticalAlign) { |
128 | switch (*m_verticalAlign) { |
129 | case VerticalAlignChange::Superscript: |
130 | style->setProperty(CSSPropertyVerticalAlign, CSSValueSuper); |
131 | break; |
132 | case VerticalAlignChange::Subscript: |
133 | style->setProperty(CSSPropertyVerticalAlign, CSSValueSub); |
134 | break; |
135 | case VerticalAlignChange::Baseline: |
136 | style->setProperty(CSSPropertyVerticalAlign, CSSValueBaseline); |
137 | break; |
138 | default: |
139 | ASSERT_NOT_REACHED(); |
140 | } |
141 | } |
142 | |
143 | auto editingStyle = EditingStyle::create(style.ptr()); |
144 | |
145 | if (m_strikeThrough) |
146 | editingStyle->setStrikeThroughChange(*m_strikeThrough ? TextDecorationChange::Add : TextDecorationChange::Remove); |
147 | |
148 | if (m_underline) |
149 | editingStyle->setUnderlineChange(*m_underline ? TextDecorationChange::Add : TextDecorationChange::Remove); |
150 | |
151 | return editingStyle; |
152 | } |
153 | |
154 | } // namespace WebCore |
155 | |