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
38namespace WebCore {
39
40#if !PLATFORM(COCOA)
41
42const String& FontChanges::platformFontFamilyNameForCSS() const
43{
44 return m_fontFamily;
45}
46
47#endif
48
49Ref<EditingStyle> FontChanges::createEditingStyle() const
50{
51 auto properties = createStyleProperties();
52 return EditingStyle::create(properties.ptr());
53}
54
55Ref<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
82static 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
97EditAction 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
109Ref<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