xref: /aosp_15_r20/frameworks/base/libs/hwui/hwui/PaintImpl.cpp (revision d57664e9bc4670b3ecf6748a746a57c557b6bc9e)
1 /*
2  * Copyright (C) 2013 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #include "Paint.h"
18 #include "BlurDrawLooper.h"
19 
20 namespace android {
21 
Paint()22 Paint::Paint()
23         : SkPaint()
24         , mLetterSpacing(0)
25         , mWordSpacing(0)
26         , mFontFeatureSettings()
27         , mMinikinLocaleListId(0)
28         , mFamilyVariant(minikin::FamilyVariant::DEFAULT) {
29     // SkPaint::antialiasing defaults to false, but
30     // SkFont::edging defaults to kAntiAlias. To keep them
31     // insync, we manually set the font to kAilas.
32     mFont.setEdging(SkFont::Edging::kAlias);
33 }
34 
Paint(const Paint & paint)35 Paint::Paint(const Paint& paint)
36         : SkPaint(paint)
37         , mFont(paint.mFont)
38         , mLooper(paint.mLooper)
39         , mLetterSpacing(paint.mLetterSpacing)
40         , mWordSpacing(paint.mWordSpacing)
41         , mFontFeatureSettings(paint.mFontFeatureSettings)
42         , mFontVariationOverride(paint.mFontVariationOverride)
43         , mMinikinLocaleListId(paint.mMinikinLocaleListId)
44         , mFamilyVariant(paint.mFamilyVariant)
45         , mHyphenEdit(paint.mHyphenEdit)
46         , mTypeface(paint.mTypeface)
47         , mAlign(paint.mAlign)
48         , mFilterBitmap(paint.mFilterBitmap)
49         , mStrikeThru(paint.mStrikeThru)
50         , mUnderline(paint.mUnderline)
51         , mDevKern(paint.mDevKern)
52         , mRunFlag(paint.mRunFlag)
53         , mVerticalText(paint.mVerticalText) {}
54 
~Paint()55 Paint::~Paint() {}
56 
operator =(const Paint & other)57 Paint& Paint::operator=(const Paint& other) {
58     SkPaint::operator=(other);
59     mFont = other.mFont;
60     mLooper = other.mLooper;
61     mLetterSpacing = other.mLetterSpacing;
62     mWordSpacing = other.mWordSpacing;
63     mFontFeatureSettings = other.mFontFeatureSettings;
64     mFontVariationOverride = other.mFontVariationOverride;
65     mMinikinLocaleListId = other.mMinikinLocaleListId;
66     mFamilyVariant = other.mFamilyVariant;
67     mHyphenEdit = other.mHyphenEdit;
68     mTypeface = other.mTypeface;
69     mAlign = other.mAlign;
70     mFilterBitmap = other.mFilterBitmap;
71     mStrikeThru = other.mStrikeThru;
72     mUnderline = other.mUnderline;
73     mDevKern = other.mDevKern;
74     mRunFlag = other.mRunFlag;
75     mVerticalText = other.mVerticalText;
76     return *this;
77 }
78 
operator ==(const Paint & a,const Paint & b)79 bool operator==(const Paint& a, const Paint& b) {
80     return static_cast<const SkPaint&>(a) == static_cast<const SkPaint&>(b) && a.mFont == b.mFont &&
81            a.mLooper == b.mLooper && a.mLetterSpacing == b.mLetterSpacing &&
82            a.mWordSpacing == b.mWordSpacing && a.mFontFeatureSettings == b.mFontFeatureSettings &&
83            a.mFontVariationOverride == b.mFontVariationOverride &&
84            a.mMinikinLocaleListId == b.mMinikinLocaleListId &&
85            a.mFamilyVariant == b.mFamilyVariant && a.mHyphenEdit == b.mHyphenEdit &&
86            a.mTypeface == b.mTypeface && a.mAlign == b.mAlign &&
87            a.mFilterBitmap == b.mFilterBitmap && a.mStrikeThru == b.mStrikeThru &&
88            a.mUnderline == b.mUnderline && a.mDevKern == b.mDevKern && a.mRunFlag == b.mRunFlag &&
89            a.mVerticalText == b.mVerticalText;
90 }
91 
reset()92 void Paint::reset() {
93     SkPaint::reset();
94 
95     mFont = SkFont();
96     mFont.setEdging(SkFont::Edging::kAlias);
97     mLooper.reset();
98 
99     mFilterBitmap = false;
100     mStrikeThru = false;
101     mUnderline = false;
102     mDevKern = false;
103     mVerticalText = false;
104     mRunFlag = minikin::RunFlag::NONE;
105 }
106 
setLooper(sk_sp<BlurDrawLooper> looper)107 void Paint::setLooper(sk_sp<BlurDrawLooper> looper) {
108     mLooper = std::move(looper);
109 }
110 
setAntiAlias(bool aa)111 void Paint::setAntiAlias(bool aa) {
112     // Java does not support/understand subpixel(lcd) antialiasing
113     SkASSERT(mFont.getEdging() != SkFont::Edging::kSubpixelAntiAlias);
114     // JavaPaint antialiasing affects both the SkPaint and SkFont settings.
115     SkPaint::setAntiAlias(aa);
116     mFont.setEdging(aa ? SkFont::Edging::kAntiAlias : SkFont::Edging::kAlias);
117 }
118 
119 ////////////////// Java flags compatibility //////////////////
120 
121 /*  Flags are tricky. Java has its own idea of the "paint" flags, but they don't really
122     match up with skia anymore, so we have to do some shuffling in get/set flags()
123 
124 	3 flags apply to SkPaint (antialias, dither, filter -> enum)
125     5 flags (merged with antialias) are for SkFont
126     2 flags are for minikin::Paint (underline and strikethru)
127 */
128 
129 // flags relating to SkPaint
130 static const uint32_t sAntiAliasFlag    = 0x01;   // affects paint and font-edging
131 static const uint32_t sFilterBitmapFlag = 0x02;   // maps to enum
132 static const uint32_t sDitherFlag       = 0x04;
133 // flags relating to SkFont
134 static const uint32_t sFakeBoldFlag     = 0x020;
135 static const uint32_t sLinearMetrics    = 0x040;
136 static const uint32_t sSubpixelMetrics  = 0x080;
137 static const uint32_t sEmbeddedBitmaps  = 0x400;
138 static const uint32_t sForceAutoHinting = 0x800;
139 // flags related to minikin::Paint
140 static const uint32_t sUnderlineFlag    = 0x08;
141 static const uint32_t sStrikeThruFlag   = 0x10;
142 static const uint32_t sVerticalTextFlag = 0x1000;
143 static const uint32_t sTextRunLeftEdge = 0x2000;
144 static const uint32_t sTextRunRightEdge = 0x4000;
145 // flags no longer supported on native side (but mirrored for compatibility)
146 static const uint32_t sDevKernFlag      = 0x100;
147 
paintToLegacyFlags(const SkPaint & paint)148 static uint32_t paintToLegacyFlags(const SkPaint& paint) {
149     uint32_t flags = 0;
150     flags |= -(int)paint.isAntiAlias() & sAntiAliasFlag;
151     flags |= -(int)paint.isDither()    & sDitherFlag;
152     return flags;
153 }
154 
fontToLegacyFlags(const SkFont & font)155 static uint32_t fontToLegacyFlags(const SkFont& font) {
156     uint32_t flags = 0;
157     flags |= -(int)font.isEmbolden()         & sFakeBoldFlag;
158     flags |= -(int)font.isLinearMetrics()    & sLinearMetrics;
159     flags |= -(int)font.isSubpixel()         & sSubpixelMetrics;
160     flags |= -(int)font.isEmbeddedBitmaps()  & sEmbeddedBitmaps;
161     flags |= -(int)font.isForceAutoHinting() & sForceAutoHinting;
162     return flags;
163 }
164 
applyLegacyFlagsToPaint(uint32_t flags,SkPaint * paint)165 static void applyLegacyFlagsToPaint(uint32_t flags, SkPaint* paint) {
166     paint->setAntiAlias((flags & sAntiAliasFlag) != 0);
167     paint->setDither   ((flags & sDitherFlag) != 0);
168 }
169 
applyLegacyFlagsToFont(uint32_t flags,SkFont * font)170 static void applyLegacyFlagsToFont(uint32_t flags, SkFont* font) {
171     font->setEmbolden        ((flags & sFakeBoldFlag) != 0);
172     font->setLinearMetrics   ((flags & sLinearMetrics) != 0);
173     font->setSubpixel        ((flags & sSubpixelMetrics) != 0);
174     font->setEmbeddedBitmaps ((flags & sEmbeddedBitmaps) != 0);
175     font->setForceAutoHinting((flags & sForceAutoHinting) != 0);
176 
177     if (flags & sAntiAliasFlag) {
178         font->setEdging(SkFont::Edging::kAntiAlias);
179     } else {
180         font->setEdging(SkFont::Edging::kAlias);
181     }
182 }
183 
GetSkPaintJavaFlags(const SkPaint & paint)184 uint32_t Paint::GetSkPaintJavaFlags(const SkPaint& paint) {
185     return paintToLegacyFlags(paint);
186 }
187 
SetSkPaintJavaFlags(SkPaint * paint,uint32_t flags)188 void Paint::SetSkPaintJavaFlags(SkPaint* paint, uint32_t flags) {
189     applyLegacyFlagsToPaint(flags, paint);
190 }
191 
getJavaFlags() const192 uint32_t Paint::getJavaFlags() const {
193     uint32_t flags = paintToLegacyFlags(*this) | fontToLegacyFlags(mFont);
194     flags |= -(int)mStrikeThru   & sStrikeThruFlag;
195     flags |= -(int)mUnderline    & sUnderlineFlag;
196     flags |= -(int)mDevKern      & sDevKernFlag;
197     flags |= -(int)mFilterBitmap & sFilterBitmapFlag;
198     flags |= -(int)mVerticalText & sVerticalTextFlag;
199     if (mRunFlag & minikin::RunFlag::LEFT_EDGE) {
200         flags |= sTextRunLeftEdge;
201     }
202     if (mRunFlag & minikin::RunFlag::RIGHT_EDGE) {
203         flags |= sTextRunRightEdge;
204     }
205     return flags;
206 }
207 
setJavaFlags(uint32_t flags)208 void Paint::setJavaFlags(uint32_t flags) {
209     applyLegacyFlagsToPaint(flags, this);
210     applyLegacyFlagsToFont(flags, &mFont);
211     mStrikeThru   = (flags & sStrikeThruFlag) != 0;
212     mUnderline    = (flags & sUnderlineFlag) != 0;
213     mDevKern      = (flags & sDevKernFlag) != 0;
214     mFilterBitmap = (flags & sFilterBitmapFlag) != 0;
215     mVerticalText = (flags & sVerticalTextFlag) != 0;
216 
217     std::underlying_type<minikin::RunFlag>::type rawFlag = minikin::RunFlag::NONE;
218     if (flags & sTextRunLeftEdge) {
219         rawFlag |= minikin::RunFlag::LEFT_EDGE;
220     }
221     if (flags & sTextRunRightEdge) {
222         rawFlag |= minikin::RunFlag::RIGHT_EDGE;
223     }
224     mRunFlag = static_cast<minikin::RunFlag>(rawFlag);
225 }
226 
227 }  // namespace android
228