blob: 281ecd27d780a610ea42921e39941827552fae8e [file] [log] [blame]
Behdad Esfahbod6ba30b82014-07-15 16:22:32 -04001/*
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
Andreas Gampeed6b9df2014-11-20 22:02:20 -080017#ifndef ANDROID_GRAPHICS_PAINT_H_
18#define ANDROID_GRAPHICS_PAINT_H_
Behdad Esfahbod6ba30b82014-07-15 16:22:32 -040019
Seigo Nonaka318ca042017-08-01 16:36:18 -070020#include "Typeface.h"
21
sergeyvdccca442016-03-21 15:38:21 -070022#include <cutils/compiler.h>
23
Mike Reedc2dbc032019-07-25 12:28:29 -040024#include <SkDrawLooper.h>
Mike Reedf6d86ac2019-01-18 14:13:23 -050025#include <SkFont.h>
Behdad Esfahbod6ba30b82014-07-15 16:22:32 -040026#include <SkPaint.h>
Behdad Esfahbod805f6eb2014-07-29 18:43:03 -040027#include <string>
Behdad Esfahbod6ba30b82014-07-15 16:22:32 -040028
Derek Sollenberger6f030232014-08-07 08:10:39 -040029#include <minikin/FontFamily.h>
Seigo Nonaka0ca492f2018-05-25 14:52:22 -070030#include <minikin/FamilyVariant.h>
Seigo Nonakafb1b4792019-03-08 14:05:08 -080031#include <minikin/Hyphenator.h>
Derek Sollenberger6f030232014-08-07 08:10:39 -040032
Behdad Esfahbod6ba30b82014-07-15 16:22:32 -040033namespace android {
34
sergeyvdccca442016-03-21 15:38:21 -070035class ANDROID_API Paint : public SkPaint {
Behdad Esfahbod6ba30b82014-07-15 16:22:32 -040036public:
Roozbeh Pournaderca8a04a2017-06-06 18:30:29 -070037 // Default values for underlined and strikethrough text,
38 // as defined by Skia in SkTextFormatParams.h.
John Reck1bcacfd2017-11-03 10:12:19 -070039 constexpr static float kStdStrikeThru_Offset = (-6.0f / 21.0f);
40 constexpr static float kStdUnderline_Offset = (1.0f / 9.0f);
Roozbeh Pournaderca8a04a2017-06-06 18:30:29 -070041 constexpr static float kStdUnderline_Thickness = (1.0f / 18.0f);
42
43 constexpr static float kStdUnderline_Top =
44 kStdUnderline_Offset - 0.5f * kStdUnderline_Thickness;
45
Roozbeh Pournader1378a9d2017-07-13 12:45:20 -070046 constexpr static float kStdStrikeThru_Thickness = kStdUnderline_Thickness;
47 constexpr static float kStdStrikeThru_Top =
48 kStdStrikeThru_Offset - 0.5f * kStdStrikeThru_Thickness;
49
Behdad Esfahbod6ba30b82014-07-15 16:22:32 -040050 Paint();
51 Paint(const Paint& paint);
52 ~Paint();
53
54 Paint& operator=(const Paint& other);
55
56 friend bool operator==(const Paint& a, const Paint& b);
John Reck1bcacfd2017-11-03 10:12:19 -070057 friend bool operator!=(const Paint& a, const Paint& b) { return !(a == b); }
Behdad Esfahbod6ba30b82014-07-15 16:22:32 -040058
Mike Reedf6d86ac2019-01-18 14:13:23 -050059 SkFont& getSkFont() { return mFont; }
60 const SkFont& getSkFont() const { return mFont; }
61
Mike Reedc2dbc032019-07-25 12:28:29 -040062 SkDrawLooper* getLooper() const { return mLooper.get(); }
63 void setLooper(sk_sp<SkDrawLooper> looper) { mLooper = std::move(looper); }
64
Mike Reedf6d86ac2019-01-18 14:13:23 -050065 // These shadow the methods on SkPaint, but we need to so we can keep related
66 // attributes in-sync.
67
68 void reset();
69 void setAntiAlias(bool);
70
Mike Reedc2dbc032019-07-25 12:28:29 -040071 bool nothingToDraw() const { return !mLooper && SkPaint::nothingToDraw(); }
72
Mike Reedf6d86ac2019-01-18 14:13:23 -050073 // End method shadowing
74
John Reck1bcacfd2017-11-03 10:12:19 -070075 void setLetterSpacing(float letterSpacing) { mLetterSpacing = letterSpacing; }
Behdad Esfahbodfa80f742014-07-17 19:10:39 -040076
John Reck1bcacfd2017-11-03 10:12:19 -070077 float getLetterSpacing() const { return mLetterSpacing; }
Behdad Esfahbodfa80f742014-07-17 19:10:39 -040078
John Reck1bcacfd2017-11-03 10:12:19 -070079 void setWordSpacing(float wordSpacing) { mWordSpacing = wordSpacing; }
Seigo Nonaka219e2c792016-11-15 19:01:45 +090080
John Reck1bcacfd2017-11-03 10:12:19 -070081 float getWordSpacing() const { return mWordSpacing; }
Seigo Nonaka219e2c792016-11-15 19:01:45 +090082
sergeyvdccca442016-03-21 15:38:21 -070083 void setFontFeatureSettings(const std::string& fontFeatureSettings) {
Behdad Esfahbod805f6eb2014-07-29 18:43:03 -040084 mFontFeatureSettings = fontFeatureSettings;
85 }
86
John Reck1bcacfd2017-11-03 10:12:19 -070087 std::string getFontFeatureSettings() const { return mFontFeatureSettings; }
Behdad Esfahbod805f6eb2014-07-29 18:43:03 -040088
Seigo Nonaka20866c12017-10-26 16:02:01 -070089 void setMinikinLocaleListId(uint32_t minikinLocaleListId) {
90 mMinikinLocaleListId = minikinLocaleListId;
Derek Sollenberger6f030232014-08-07 08:10:39 -040091 }
92
Seigo Nonaka20866c12017-10-26 16:02:01 -070093 uint32_t getMinikinLocaleListId() const { return mMinikinLocaleListId; }
Derek Sollenberger6f030232014-08-07 08:10:39 -040094
Seigo Nonaka0ca492f2018-05-25 14:52:22 -070095 void setFamilyVariant(minikin::FamilyVariant variant) { mFamilyVariant = variant; }
Derek Sollenberger6f030232014-08-07 08:10:39 -040096
Seigo Nonaka0ca492f2018-05-25 14:52:22 -070097 minikin::FamilyVariant getFamilyVariant() const { return mFamilyVariant; }
Derek Sollenberger6f030232014-08-07 08:10:39 -040098
Seigo Nonakafb1b4792019-03-08 14:05:08 -080099 void setStartHyphenEdit(uint32_t startHyphen) {
100 mHyphenEdit = minikin::packHyphenEdit(
101 static_cast<minikin::StartHyphenEdit>(startHyphen),
102 minikin::endHyphenEdit(mHyphenEdit));
103 }
Raph Levien210a1892015-03-09 14:42:14 -0700104
Seigo Nonakafb1b4792019-03-08 14:05:08 -0800105 void setEndHyphenEdit(uint32_t endHyphen) {
106 mHyphenEdit = minikin::packHyphenEdit(
107 minikin::startHyphenEdit(mHyphenEdit),
108 static_cast<minikin::EndHyphenEdit>(endHyphen));
109 }
110
111 minikin::StartHyphenEdit getStartHyphenEdit() const {
112 return minikin::startHyphenEdit(mHyphenEdit);
113 }
114
115 minikin::EndHyphenEdit getEndHyphenEdit() const {
116 return minikin::endHyphenEdit(mHyphenEdit);
117 }
Raph Levien210a1892015-03-09 14:42:14 -0700118
John Reck1bcacfd2017-11-03 10:12:19 -0700119 void setAndroidTypeface(Typeface* typeface) { mTypeface = typeface; }
Seigo Nonaka318ca042017-08-01 16:36:18 -0700120
John Reck1bcacfd2017-11-03 10:12:19 -0700121 const Typeface* getAndroidTypeface() const { return mTypeface; }
Seigo Nonaka318ca042017-08-01 16:36:18 -0700122
Mike Reed16c142b2018-10-25 14:19:45 -0400123 enum Align {
124 kLeft_Align,
125 kCenter_Align,
126 kRight_Align,
127 };
128 Align getTextAlign() const { return mAlign; }
129 void setTextAlign(Align align) { mAlign = align; }
130
Mike Reedf6d86ac2019-01-18 14:13:23 -0500131 bool isStrikeThru() const { return mStrikeThru; }
132 void setStrikeThru(bool st) { mStrikeThru = st; }
133
134 bool isUnderline() const { return mUnderline; }
135 void setUnderline(bool u) { mUnderline = u; }
136
137 bool isDevKern() const { return mDevKern; }
138 void setDevKern(bool d) { mDevKern = d; }
139
140 // The Java flags (Paint.java) no longer fit into the native apis directly.
141 // These methods handle converting to and from them and the native representations
142 // in android::Paint.
143
144 uint32_t getJavaFlags() const;
145 void setJavaFlags(uint32_t);
146
147 // Helpers that return or apply legacy java flags to SkPaint, ignoring all flags
148 // that are meant for SkFont or Paint (e.g. underline, strikethru)
149 // The only respected flags are : [ antialias, dither, filterBitmap ]
150 static uint32_t GetSkPaintJavaFlags(const SkPaint&);
151 static void SetSkPaintJavaFlags(SkPaint*, uint32_t flags);
152
Behdad Esfahbod6ba30b82014-07-15 16:22:32 -0400153private:
Mike Reedf6d86ac2019-01-18 14:13:23 -0500154 SkFont mFont;
Mike Reedc2dbc032019-07-25 12:28:29 -0400155 sk_sp<SkDrawLooper> mLooper;
Mike Reedf6d86ac2019-01-18 14:13:23 -0500156
Raph Levien210a1892015-03-09 14:42:14 -0700157 float mLetterSpacing = 0;
Seigo Nonaka219e2c792016-11-15 19:01:45 +0900158 float mWordSpacing = 0;
Behdad Esfahbod805f6eb2014-07-29 18:43:03 -0400159 std::string mFontFeatureSettings;
Seigo Nonaka20866c12017-10-26 16:02:01 -0700160 uint32_t mMinikinLocaleListId;
Seigo Nonaka0ca492f2018-05-25 14:52:22 -0700161 minikin::FamilyVariant mFamilyVariant;
Raph Levien210a1892015-03-09 14:42:14 -0700162 uint32_t mHyphenEdit = 0;
Seigo Nonaka20866c12017-10-26 16:02:01 -0700163 // The native Typeface object has the same lifetime of the Java Typeface
164 // object. The Java Paint object holds a strong reference to the Java Typeface
165 // object. Thus, following pointer can never be a dangling pointer. Note that
166 // nullptr is valid: it means the default typeface.
Seigo Nonaka318ca042017-08-01 16:36:18 -0700167 const Typeface* mTypeface = nullptr;
Mike Reed16c142b2018-10-25 14:19:45 -0400168 Align mAlign = kLeft_Align;
Mike Reedf6d86ac2019-01-18 14:13:23 -0500169 bool mStrikeThru = false;
170 bool mUnderline = false;
171 bool mDevKern = false;
Behdad Esfahbod6ba30b82014-07-15 16:22:32 -0400172};
173
174} // namespace android
175
John Reck1bcacfd2017-11-03 10:12:19 -0700176#endif // ANDROID_GRAPHICS_PAINT_H_