1cb93a386Sopenharmony_ci// Copyright 2019 Google LLC.
2cb93a386Sopenharmony_ci#include "include/core/SkColor.h"
3cb93a386Sopenharmony_ci#include "include/core/SkFontStyle.h"
4cb93a386Sopenharmony_ci#include "modules/skparagraph/include/TextStyle.h"
5cb93a386Sopenharmony_ci#include "modules/skparagraph/src/Run.h"
6cb93a386Sopenharmony_ci
7cb93a386Sopenharmony_cinamespace skia {
8cb93a386Sopenharmony_cinamespace textlayout {
9cb93a386Sopenharmony_ci
10cb93a386Sopenharmony_ciconst std::vector<SkString>* TextStyle::kDefaultFontFamilies =
11cb93a386Sopenharmony_ci        new std::vector<SkString>{SkString(DEFAULT_FONT_FAMILY)};
12cb93a386Sopenharmony_ci
13cb93a386Sopenharmony_ciTextStyle TextStyle::cloneForPlaceholder() {
14cb93a386Sopenharmony_ci    TextStyle result;
15cb93a386Sopenharmony_ci    result.fColor = fColor;
16cb93a386Sopenharmony_ci    result.fFontSize = fFontSize;
17cb93a386Sopenharmony_ci    result.fFontFamilies = fFontFamilies;
18cb93a386Sopenharmony_ci    result.fDecoration = fDecoration;
19cb93a386Sopenharmony_ci    result.fHasBackground = fHasBackground;
20cb93a386Sopenharmony_ci    result.fHasForeground = fHasForeground;
21cb93a386Sopenharmony_ci    result.fBackground = fBackground;
22cb93a386Sopenharmony_ci    result.fForeground = fForeground;
23cb93a386Sopenharmony_ci    result.fHeightOverride = fHeightOverride;
24cb93a386Sopenharmony_ci    result.fIsPlaceholder = true;
25cb93a386Sopenharmony_ci    result.fFontFeatures = fFontFeatures;
26cb93a386Sopenharmony_ci    result.fHalfLeading = fHalfLeading;
27cb93a386Sopenharmony_ci    result.fBaselineShift = fBaselineShift;
28cb93a386Sopenharmony_ci    result.fFontArguments = fFontArguments;
29cb93a386Sopenharmony_ci    result.fBackgroundRect = fBackgroundRect;
30cb93a386Sopenharmony_ci    result.fStyleId = fStyleId;
31cb93a386Sopenharmony_ci    return result;
32cb93a386Sopenharmony_ci}
33cb93a386Sopenharmony_ci
34cb93a386Sopenharmony_cibool TextStyle::equals(const TextStyle& other) const {
35cb93a386Sopenharmony_ci
36cb93a386Sopenharmony_ci    if (fIsPlaceholder || other.fIsPlaceholder) {
37cb93a386Sopenharmony_ci        return false;
38cb93a386Sopenharmony_ci    }
39cb93a386Sopenharmony_ci
40cb93a386Sopenharmony_ci    if (fColor != other.fColor) {
41cb93a386Sopenharmony_ci        return false;
42cb93a386Sopenharmony_ci    }
43cb93a386Sopenharmony_ci    if (!(fDecoration == other.fDecoration)) {
44cb93a386Sopenharmony_ci        return false;
45cb93a386Sopenharmony_ci    }
46cb93a386Sopenharmony_ci    if (!(fFontStyle == other.fFontStyle)) {
47cb93a386Sopenharmony_ci        return false;
48cb93a386Sopenharmony_ci    }
49cb93a386Sopenharmony_ci    if (fFontFamilies != other.fFontFamilies) {
50cb93a386Sopenharmony_ci        return false;
51cb93a386Sopenharmony_ci    }
52cb93a386Sopenharmony_ci    if (fLetterSpacing != other.fLetterSpacing) {
53cb93a386Sopenharmony_ci        return false;
54cb93a386Sopenharmony_ci    }
55cb93a386Sopenharmony_ci    if (fWordSpacing != other.fWordSpacing) {
56cb93a386Sopenharmony_ci        return false;
57cb93a386Sopenharmony_ci    }
58cb93a386Sopenharmony_ci    if (fHeight != other.fHeight) {
59cb93a386Sopenharmony_ci        return false;
60cb93a386Sopenharmony_ci    }
61cb93a386Sopenharmony_ci    if (fHeightOverride != other.fHeightOverride) {
62cb93a386Sopenharmony_ci        return false;
63cb93a386Sopenharmony_ci    }
64cb93a386Sopenharmony_ci    if (fHalfLeading != other.fHalfLeading) {
65cb93a386Sopenharmony_ci        return false;
66cb93a386Sopenharmony_ci    }
67cb93a386Sopenharmony_ci    if (fBaselineShift != other.fBaselineShift) {
68cb93a386Sopenharmony_ci        return false;
69cb93a386Sopenharmony_ci    }
70cb93a386Sopenharmony_ci    if (fFontSize != other.fFontSize) {
71cb93a386Sopenharmony_ci        return false;
72cb93a386Sopenharmony_ci    }
73cb93a386Sopenharmony_ci    if (fLocale != other.fLocale) {
74cb93a386Sopenharmony_ci        return false;
75cb93a386Sopenharmony_ci    }
76cb93a386Sopenharmony_ci    if (fHasForeground != other.fHasForeground || fForeground != other.fForeground) {
77cb93a386Sopenharmony_ci        return false;
78cb93a386Sopenharmony_ci    }
79cb93a386Sopenharmony_ci    if (fHasBackground != other.fHasBackground || fBackground != other.fBackground) {
80cb93a386Sopenharmony_ci        return false;
81cb93a386Sopenharmony_ci    }
82cb93a386Sopenharmony_ci    if (fTextShadows.size() != other.fTextShadows.size()) {
83cb93a386Sopenharmony_ci        return false;
84cb93a386Sopenharmony_ci    }
85cb93a386Sopenharmony_ci    for (size_t i = 0; i < fTextShadows.size(); ++i) {
86cb93a386Sopenharmony_ci        if (fTextShadows[i] != other.fTextShadows[i]) {
87cb93a386Sopenharmony_ci            return false;
88cb93a386Sopenharmony_ci        }
89cb93a386Sopenharmony_ci    }
90cb93a386Sopenharmony_ci    if (fFontFeatures.size() != other.fFontFeatures.size()) {
91cb93a386Sopenharmony_ci        return false;
92cb93a386Sopenharmony_ci    }
93cb93a386Sopenharmony_ci    for (size_t i = 0; i < fFontFeatures.size(); ++i) {
94cb93a386Sopenharmony_ci        if (!(fFontFeatures[i] == other.fFontFeatures[i])) {
95cb93a386Sopenharmony_ci            return false;
96cb93a386Sopenharmony_ci        }
97cb93a386Sopenharmony_ci    }
98cb93a386Sopenharmony_ci    if (fFontArguments != other.fFontArguments) {
99cb93a386Sopenharmony_ci        return false;
100cb93a386Sopenharmony_ci    }
101cb93a386Sopenharmony_ci    if (fStyleId != other.fStyleId || fBackgroundRect != other.fBackgroundRect) {
102cb93a386Sopenharmony_ci        return false;
103cb93a386Sopenharmony_ci    }
104cb93a386Sopenharmony_ci
105cb93a386Sopenharmony_ci    return true;
106cb93a386Sopenharmony_ci}
107cb93a386Sopenharmony_ci
108cb93a386Sopenharmony_cibool TextStyle::equalsByFonts(const TextStyle& that) const {
109cb93a386Sopenharmony_ci
110cb93a386Sopenharmony_ci    return !fIsPlaceholder && !that.fIsPlaceholder &&
111cb93a386Sopenharmony_ci           fFontStyle == that.fFontStyle &&
112cb93a386Sopenharmony_ci           fFontFamilies == that.fFontFamilies &&
113cb93a386Sopenharmony_ci           fFontFeatures == that.fFontFeatures &&
114cb93a386Sopenharmony_ci           fFontArguments == that.getFontArguments() &&
115cb93a386Sopenharmony_ci           nearlyEqual(fLetterSpacing, that.fLetterSpacing) &&
116cb93a386Sopenharmony_ci           nearlyEqual(fWordSpacing, that.fWordSpacing) &&
117cb93a386Sopenharmony_ci           nearlyEqual(fHeight, that.fHeight) &&
118cb93a386Sopenharmony_ci           nearlyEqual(fBaselineShift, that.fBaselineShift) &&
119cb93a386Sopenharmony_ci           nearlyEqual(fFontSize, that.fFontSize) &&
120cb93a386Sopenharmony_ci           fLocale == that.fLocale &&
121cb93a386Sopenharmony_ci           fStyleId == that.fStyleId &&
122cb93a386Sopenharmony_ci           fBackgroundRect == that.fBackgroundRect;
123cb93a386Sopenharmony_ci}
124cb93a386Sopenharmony_ci
125cb93a386Sopenharmony_cibool TextStyle::matchOneAttribute(StyleType styleType, const TextStyle& other) const {
126cb93a386Sopenharmony_ci    switch (styleType) {
127cb93a386Sopenharmony_ci        case kForeground:
128cb93a386Sopenharmony_ci            return (!fHasForeground && !other.fHasForeground && fColor == other.fColor) ||
129cb93a386Sopenharmony_ci                   ( fHasForeground &&  other.fHasForeground && fForeground == other.fForeground);
130cb93a386Sopenharmony_ci
131cb93a386Sopenharmony_ci        case kBackground:
132cb93a386Sopenharmony_ci            return (!fHasBackground && !other.fHasBackground) ||
133cb93a386Sopenharmony_ci                   ( fHasBackground &&  other.fHasBackground && fBackground == other.fBackground);
134cb93a386Sopenharmony_ci
135cb93a386Sopenharmony_ci        case kShadow:
136cb93a386Sopenharmony_ci            if (fTextShadows.size() != other.fTextShadows.size()) {
137cb93a386Sopenharmony_ci                return false;
138cb93a386Sopenharmony_ci            }
139cb93a386Sopenharmony_ci
140cb93a386Sopenharmony_ci            for (int32_t i = 0; i < SkToInt(fTextShadows.size()); ++i) {
141cb93a386Sopenharmony_ci                if (fTextShadows[i] != other.fTextShadows[i]) {
142cb93a386Sopenharmony_ci                    return false;
143cb93a386Sopenharmony_ci                }
144cb93a386Sopenharmony_ci            }
145cb93a386Sopenharmony_ci            return true;
146cb93a386Sopenharmony_ci
147cb93a386Sopenharmony_ci        case kDecorations:
148cb93a386Sopenharmony_ci            return this->fDecoration == other.fDecoration;
149cb93a386Sopenharmony_ci
150cb93a386Sopenharmony_ci        case kLetterSpacing:
151cb93a386Sopenharmony_ci            return fLetterSpacing == other.fLetterSpacing;
152cb93a386Sopenharmony_ci
153cb93a386Sopenharmony_ci        case kWordSpacing:
154cb93a386Sopenharmony_ci            return fWordSpacing == other.fWordSpacing;
155cb93a386Sopenharmony_ci
156cb93a386Sopenharmony_ci        case kAllAttributes:
157cb93a386Sopenharmony_ci            return this->equals(other);
158cb93a386Sopenharmony_ci
159cb93a386Sopenharmony_ci        case kFont:
160cb93a386Sopenharmony_ci            // TODO: should not we take typefaces in account?
161cb93a386Sopenharmony_ci            return fFontStyle == other.fFontStyle &&
162cb93a386Sopenharmony_ci                   fLocale == other.fLocale &&
163cb93a386Sopenharmony_ci                   fFontFamilies == other.fFontFamilies &&
164cb93a386Sopenharmony_ci                   fFontSize == other.fFontSize &&
165cb93a386Sopenharmony_ci                   fHeight == other.fHeight &&
166cb93a386Sopenharmony_ci                   fHalfLeading == other.fHalfLeading &&
167cb93a386Sopenharmony_ci                   fBaselineShift == other.fBaselineShift &&
168cb93a386Sopenharmony_ci                   fFontArguments == other.fFontArguments &&
169cb93a386Sopenharmony_ci                   fStyleId == other.fStyleId &&
170cb93a386Sopenharmony_ci                   fBackgroundRect == other.fBackgroundRect;
171cb93a386Sopenharmony_ci        default:
172cb93a386Sopenharmony_ci            SkASSERT(false);
173cb93a386Sopenharmony_ci            return false;
174cb93a386Sopenharmony_ci    }
175cb93a386Sopenharmony_ci}
176cb93a386Sopenharmony_ci
177cb93a386Sopenharmony_ci#ifndef USE_SKIA_TXT
178cb93a386Sopenharmony_civoid TextStyle::getFontMetrics(SkFontMetrics* metrics) const {
179cb93a386Sopenharmony_ci#else
180cb93a386Sopenharmony_civoid TextStyle::getFontMetrics(RSFontMetrics* metrics) const {
181cb93a386Sopenharmony_ci#endif
182cb93a386Sopenharmony_ci#ifndef USE_SKIA_TXT
183cb93a386Sopenharmony_ci    SkFont font(fTypeface, fFontSize);
184cb93a386Sopenharmony_ci    font.setEdging(SkFont::Edging::kAntiAlias);
185cb93a386Sopenharmony_ci    font.setSubpixel(true);
186cb93a386Sopenharmony_ci    font.setHinting(SkFontHinting::kSlight);
187cb93a386Sopenharmony_ci#ifdef OHOS_SUPPORT
188cb93a386Sopenharmony_ci    auto compressFont = font;
189cb93a386Sopenharmony_ci    scaleFontWithCompressionConfig(compressFont, ScaleOP::COMPRESS);
190cb93a386Sopenharmony_ci    compressFont.getMetrics(metrics);
191cb93a386Sopenharmony_ci    metricsIncludeFontPadding(metrics, font);
192cb93a386Sopenharmony_ci#else
193cb93a386Sopenharmony_ci    font.getMetrics(metrics);
194cb93a386Sopenharmony_ci#endif
195cb93a386Sopenharmony_ci#else
196cb93a386Sopenharmony_ci    RSFont font(fTypeface, fFontSize, 1, 0);
197cb93a386Sopenharmony_ci    font.SetEdging(RSDrawing::FontEdging::ANTI_ALIAS);
198cb93a386Sopenharmony_ci    font.SetHinting(RSDrawing::FontHinting::SLIGHT);
199cb93a386Sopenharmony_ci    font.SetSubpixel(true);
200cb93a386Sopenharmony_ci#ifdef OHOS_SUPPORT
201cb93a386Sopenharmony_ci    auto compressFont = font;
202cb93a386Sopenharmony_ci    scaleFontWithCompressionConfig(compressFont, ScaleOP::COMPRESS);
203cb93a386Sopenharmony_ci    compressFont.GetMetrics(metrics);
204cb93a386Sopenharmony_ci    metricsIncludeFontPadding(metrics, font);
205cb93a386Sopenharmony_ci#else
206cb93a386Sopenharmony_ci    font.GetMetrics(metrics);
207cb93a386Sopenharmony_ci#endif
208cb93a386Sopenharmony_ci#endif
209cb93a386Sopenharmony_ci    if (fHeightOverride) {
210cb93a386Sopenharmony_ci        auto multiplier = fHeight * fFontSize;
211cb93a386Sopenharmony_ci        auto height = metrics->fDescent - metrics->fAscent + metrics->fLeading;
212cb93a386Sopenharmony_ci        metrics->fAscent = (metrics->fAscent - metrics->fLeading / 2) * multiplier / height;
213cb93a386Sopenharmony_ci        metrics->fDescent = (metrics->fDescent + metrics->fLeading / 2) * multiplier / height;
214cb93a386Sopenharmony_ci
215cb93a386Sopenharmony_ci    } else {
216cb93a386Sopenharmony_ci        metrics->fAscent = (metrics->fAscent - metrics->fLeading / 2);
217cb93a386Sopenharmony_ci        metrics->fDescent = (metrics->fDescent + metrics->fLeading / 2);
218cb93a386Sopenharmony_ci    }
219cb93a386Sopenharmony_ci    // If we shift the baseline we need to make sure the shifted text fits the line
220cb93a386Sopenharmony_ci    metrics->fAscent += fBaselineShift;
221cb93a386Sopenharmony_ci    metrics->fDescent += fBaselineShift;
222cb93a386Sopenharmony_ci}
223cb93a386Sopenharmony_ci
224cb93a386Sopenharmony_civoid TextStyle::setFontArguments(const std::optional<SkFontArguments>& args) {
225cb93a386Sopenharmony_ci    if (!args) {
226cb93a386Sopenharmony_ci        fFontArguments.reset();
227cb93a386Sopenharmony_ci        return;
228cb93a386Sopenharmony_ci    }
229cb93a386Sopenharmony_ci
230cb93a386Sopenharmony_ci    fFontArguments.emplace(*args);
231cb93a386Sopenharmony_ci}
232cb93a386Sopenharmony_ci
233cb93a386Sopenharmony_cibool PlaceholderStyle::equals(const PlaceholderStyle& other) const {
234cb93a386Sopenharmony_ci    return nearlyEqual(fWidth, other.fWidth) &&
235cb93a386Sopenharmony_ci           nearlyEqual(fHeight, other.fHeight) &&
236cb93a386Sopenharmony_ci           fAlignment == other.fAlignment &&
237cb93a386Sopenharmony_ci           fBaseline == other.fBaseline &&
238cb93a386Sopenharmony_ci           (fAlignment != PlaceholderAlignment::kBaseline ||
239cb93a386Sopenharmony_ci            nearlyEqual(fBaselineOffset, other.fBaselineOffset));
240cb93a386Sopenharmony_ci}
241cb93a386Sopenharmony_ci
242cb93a386Sopenharmony_ci}  // namespace textlayout
243cb93a386Sopenharmony_ci}  // namespace skia
244