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