• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2019 Google LLC.
2 #include "include/core/SkColor.h"
3 #include "include/core/SkFontStyle.h"
4 #include "modules/skparagraph/include/TextStyle.h"
5 
6 namespace skia {
7 namespace textlayout {
8 
TextStyle()9 TextStyle::TextStyle() : fFontStyle() {
10     fFontFamilies.reserve(1);
11     fFontFamilies.emplace_back(DEFAULT_FONT_FAMILY);
12     fColor = SK_ColorWHITE;
13     fDecoration.fType = TextDecoration::kNoDecoration;
14     // Does not make sense to draw a transparent object, so we use it as a default
15     // value to indicate no decoration color was set.
16     fDecoration.fColor = SK_ColorTRANSPARENT;
17     fDecoration.fStyle = TextDecorationStyle::kSolid;
18     // Thickness is applied as a multiplier to the default thickness of the font.
19     fDecoration.fThicknessMultiplier = 1.0;
20     fFontSize = 14.0;
21     fLetterSpacing = 0.0;
22     fWordSpacing = 0.0;
23     fHeight = 1.0;
24     fHeightOverride = false;
25     fHasBackground = false;
26     fHasForeground = false;
27     fTextBaseline = TextBaseline::kAlphabetic;
28     fLocale = "";
29 }
30 
equals(const TextStyle & other) const31 bool TextStyle::equals(const TextStyle& other) const {
32     if (fColor != other.fColor) {
33         return false;
34     }
35     if (!(fDecoration == other.fDecoration)) {
36         return false;
37     }
38     if (!(fFontStyle == other.fFontStyle)) {
39         return false;
40     }
41     if (fFontFamilies != other.fFontFamilies) {
42         return false;
43     }
44     if (fLetterSpacing != other.fLetterSpacing) {
45         return false;
46     }
47     if (fWordSpacing != other.fWordSpacing) {
48         return false;
49     }
50     if (fHeight != other.fHeight) {
51         return false;
52     }
53     if (fFontSize != other.fFontSize) {
54         return false;
55     }
56     if (fLocale != other.fLocale) {
57         return false;
58     }
59     if (fHasForeground != other.fHasForeground || fForeground != other.fForeground) {
60         return false;
61     }
62     if (fHasBackground != other.fHasBackground || fBackground != other.fBackground) {
63         return false;
64     }
65     if (fTextShadows.size() != other.fTextShadows.size()) {
66         return false;
67     }
68 
69     for (int32_t i = 0; i < (int32_t)fTextShadows.size(); ++i) {
70         if (fTextShadows[i] != other.fTextShadows[i]) {
71             return false;
72         }
73     }
74 
75     return true;
76 }
77 
matchOneAttribute(StyleType styleType,const TextStyle & other) const78 bool TextStyle::matchOneAttribute(StyleType styleType, const TextStyle& other) const {
79     switch (styleType) {
80         case kForeground:
81             if (fHasForeground) {
82                 return other.fHasForeground && fForeground == other.fForeground;
83             } else {
84                 return !other.fHasForeground && fColor == other.fColor;
85             }
86 
87         case kBackground:
88             return (fHasBackground == other.fHasBackground && fBackground == other.fBackground);
89 
90         case kShadow:
91             if (fTextShadows.size() != other.fTextShadows.size()) {
92                 return false;
93             }
94 
95             for (int32_t i = 0; i < SkToInt(fTextShadows.size()); ++i) {
96                 if (fTextShadows[i] != other.fTextShadows[i]) {
97                     return false;
98                 }
99             }
100             return true;
101 
102         case kDecorations:
103             return this->fDecoration == other.fDecoration;
104 
105         case kLetterSpacing:
106             return fLetterSpacing == other.fLetterSpacing;
107 
108         case kWordSpacing:
109             return fWordSpacing == other.fWordSpacing;
110 
111         case kAllAttributes:
112             return this->equals(other);
113 
114         case kFont:
115             // TODO: should not we take typefaces in account?
116             return fFontStyle == other.fFontStyle && fFontFamilies == other.fFontFamilies &&
117                    fFontSize == other.fFontSize && fHeight == other.fHeight;
118 
119         default:
120             SkASSERT(false);
121             return false;
122     }
123 }
124 
getFontMetrics(SkFontMetrics * metrics) const125 void TextStyle::getFontMetrics(SkFontMetrics* metrics) const {
126     SkFont font(fTypeface, fFontSize);
127     font.getMetrics(metrics);
128     if (fHeightOverride) {
129         auto multiplier = fHeight * fFontSize;
130         auto height = metrics->fDescent - metrics->fAscent + metrics->fLeading;
131         metrics->fAscent = (metrics->fAscent - metrics->fLeading / 2) * multiplier / height;
132         metrics->fDescent = (metrics->fDescent + metrics->fLeading / 2) * multiplier / height;
133 
134     } else {
135         metrics->fAscent = (metrics->fAscent - metrics->fLeading / 2);
136         metrics->fDescent = (metrics->fDescent + metrics->fLeading / 2);
137     }
138 }
139 
140 }  // namespace textlayout
141 }  // namespace skia
142