1 /*
2  * Copyright (c) 2023 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include "rosen_text/text_style.h"
17 
18 #include <sstream>
19 
20 namespace OHOS {
21 namespace Rosen {
SetFeature(std::string tag,int value)22 void FontFeatures::SetFeature(std::string tag, int value)
23 {
24     featureSet_.emplace_back(std::make_pair(tag, value));
25 }
26 
GetFeatureSettings() const27 std::string FontFeatures::GetFeatureSettings() const
28 {
29     if (featureSet_.empty()) {
30         return "";
31     }
32 
33     std::stringstream ss;
34     for (const auto &[tag, value] : featureSet_) {
35         if (ss.tellp()) {
36             ss << ',';
37         }
38         ss << tag << '=' << value;
39     }
40     return ss.str();
41 }
42 
GetFontFeatures() const43 const std::vector<std::pair<std::string, int>>& FontFeatures::GetFontFeatures() const
44 {
45     return featureSet_;
46 }
47 
operator ==(const FontFeatures & rhs) const48 bool FontFeatures::operator ==(const FontFeatures& rhs) const
49 {
50     return featureSet_ == rhs.featureSet_;
51 }
52 
Clear()53 void FontFeatures::Clear()
54 {
55     featureSet_.clear();
56 }
57 
SetAxisValue(const std::string & tag,float value)58 void FontVariations::SetAxisValue(const std::string& tag, float value)
59 {
60     axis_[tag] = value;
61 }
62 
GetAxisValues() const63 const std::map<std::string, float>& FontVariations::GetAxisValues() const
64 {
65     return axis_;
66 }
67 
operator ==(const FontVariations & rhs) const68 bool FontVariations::operator ==(const FontVariations& rhs) const
69 {
70     return axis_ == rhs.axis_;
71 }
72 
Clear()73 void FontVariations::Clear()
74 {
75     axis_.clear();
76 }
77 
TextShadow()78 TextShadow::TextShadow()
79 {
80 }
81 
TextShadow(Drawing::Color shadowColor,Drawing::Point shadowOffset,double shadowBlurRadius)82 TextShadow::TextShadow(Drawing::Color shadowColor, Drawing::Point shadowOffset, double shadowBlurRadius)
83 {
84     color = shadowColor;
85     offset = shadowOffset;
86     blurRadius = shadowBlurRadius;
87 }
88 
operator ==(const TextShadow & rhs) const89 bool TextShadow::operator ==(const TextShadow& rhs) const
90 {
91     return color == rhs.color && offset == rhs.offset && blurRadius == rhs.blurRadius;
92 }
93 
operator !=(const TextShadow & rhs) const94 bool TextShadow::operator !=(const TextShadow& rhs) const
95 {
96     return !(*this == rhs);
97 }
98 
HasShadow() const99 bool TextShadow::HasShadow() const
100 {
101     return offset.GetX() != 0 || offset.GetY() != 0 || fabs(blurRadius) >= DBL_EPSILON;
102 }
103 
operator ==(const RectStyle & rhs) const104 bool RectStyle::operator ==(const RectStyle& rhs) const
105 {
106     return color == rhs.color && leftTopRadius == rhs.leftTopRadius &&
107         rightTopRadius == rhs.rightTopRadius &&
108         rightBottomRadius == rhs.rightBottomRadius &&
109         leftBottomRadius == rhs.leftBottomRadius;
110 }
111 
operator !=(const RectStyle & rhs) const112 bool RectStyle::operator !=(const RectStyle& rhs) const
113 {
114     return !(*this == rhs);
115 }
116 
operator ==(const TextStyle & rhs) const117 bool TextStyle::operator ==(const TextStyle& rhs) const
118 {
119     return color == rhs.color &&
120         decoration == rhs.decoration &&
121         decorationColor == rhs.decorationColor &&
122         decorationStyle == rhs.decorationStyle &&
123         decorationThicknessScale == rhs.decorationThicknessScale &&
124         fontWeight == rhs.fontWeight &&
125         fontStyle == rhs.fontStyle &&
126         baseline == rhs.baseline &&
127         fontFamilies == rhs.fontFamilies &&
128         fontSize == rhs.fontSize &&
129         letterSpacing == rhs.letterSpacing &&
130         wordSpacing == rhs.wordSpacing &&
131         heightScale == rhs.heightScale &&
132         halfLeading == rhs.halfLeading &&
133         heightOnly == rhs.heightOnly &&
134         locale == rhs.locale &&
135         foregroundBrush == rhs.foregroundBrush &&
136         foregroundPen == rhs.foregroundPen &&
137         backgroundBrush == rhs.backgroundBrush &&
138         backgroundPen == rhs.backgroundPen &&
139         backgroundRect == rhs.backgroundRect &&
140         styleId == rhs.styleId &&
141         shadows == rhs.shadows &&
142         fontFeatures == rhs.fontFeatures &&
143         fontVariations == rhs.fontVariations;
144 }
145 
EqualByFonts(const TextStyle & rhs) const146 bool TextStyle::EqualByFonts(const TextStyle &rhs) const
147 {
148     return !isPlaceholder && !rhs.isPlaceholder &&
149         fontStyle == rhs.fontStyle &&
150         fontFamilies == rhs.fontFamilies &&
151         fontFeatures == rhs.fontFeatures &&
152         fontVariations == rhs.fontVariations &&
153         Drawing::IsScalarAlmostEqual(letterSpacing, rhs.letterSpacing) &&
154         Drawing::IsScalarAlmostEqual(wordSpacing, rhs.wordSpacing) &&
155         Drawing::IsScalarAlmostEqual(heightScale, rhs.heightScale) &&
156         Drawing::IsScalarAlmostEqual(baseLineShift, rhs.baseLineShift) &&
157         Drawing::IsScalarAlmostEqual(fontSize, rhs.fontSize) &&
158         locale == rhs.locale;
159 }
160 
MatchOneAttribute(StyleType styleType,const TextStyle & rhs) const161 bool TextStyle::MatchOneAttribute(StyleType styleType, const TextStyle &rhs) const
162 {
163     switch (styleType) {
164         case FOREGROUND:
165             return (!foregroundBrush.has_value() && !rhs.foregroundBrush.has_value() &&
166                 !foregroundPen.has_value() && !rhs.foregroundPen.has_value() && color == rhs.color) ||
167                 (foregroundBrush == rhs.foregroundBrush &&
168                 foregroundPen == rhs.foregroundPen);
169         case BACKGROUND:
170             return backgroundBrush == rhs.backgroundBrush &&
171                 backgroundPen == rhs.backgroundPen;
172         case SHADOW:
173             return shadows == rhs.shadows;
174         case DECORATIONS:
175             return decoration == rhs.decoration &&
176                 decorationColor == rhs.decorationColor &&
177                 decorationStyle == rhs.decorationStyle &&
178                 Drawing::IsScalarAlmostEqual(decorationThicknessScale,
179                     rhs.decorationThicknessScale);
180         case LETTER_SPACING:
181             return Drawing::IsScalarAlmostEqual(letterSpacing, rhs.letterSpacing);
182 
183         case WORD_SPACING:
184             return Drawing::IsScalarAlmostEqual(wordSpacing, rhs.wordSpacing);
185 
186         case ALL_ATTRIBUTES:
187             return *this == rhs;
188 
189         case FONT:
190             return fontStyle == rhs.fontStyle &&
191                 locale == rhs.locale &&
192                 fontFamilies == rhs.fontFamilies &&
193                 Drawing::IsScalarAlmostEqual(fontSize, rhs.fontSize) &&
194                 Drawing::IsScalarAlmostEqual(heightScale, rhs.heightScale) &&
195                 halfLeading == rhs.halfLeading &&
196                 Drawing::IsScalarAlmostEqual(baseLineShift, rhs.baseLineShift);
197         default:
198             return false;
199     }
200 }
201 } // namespace Rosen
202 } // namespace OHOS
203