summaryrefslogtreecommitdiff
path: root/libs/hwui
diff options
context:
space:
mode:
Diffstat (limited to 'libs/hwui')
-rw-r--r--libs/hwui/FeatureFlags.h8
-rw-r--r--libs/hwui/hwui/MinikinUtils.cpp10
-rw-r--r--libs/hwui/hwui/Paint.h5
-rw-r--r--libs/hwui/hwui/PaintImpl.cpp36
-rw-r--r--libs/hwui/jni/android_graphics_Canvas.cpp26
5 files changed, 73 insertions, 12 deletions
diff --git a/libs/hwui/FeatureFlags.h b/libs/hwui/FeatureFlags.h
index 00d049cde925..6ebfc63bdf26 100644
--- a/libs/hwui/FeatureFlags.h
+++ b/libs/hwui/FeatureFlags.h
@@ -41,6 +41,14 @@ inline bool deprecate_ui_fonts() {
#endif // __ANDROID__
}
+inline bool inter_character_justification() {
+#ifdef __ANDROID__
+ return com_android_text_flags_inter_character_justification();
+#else
+ return true;
+#endif // __ANDROID__
+}
+
} // namespace text_feature
} // namespace android
diff --git a/libs/hwui/hwui/MinikinUtils.cpp b/libs/hwui/hwui/MinikinUtils.cpp
index 833069f363c8..56133699d5f5 100644
--- a/libs/hwui/hwui/MinikinUtils.cpp
+++ b/libs/hwui/hwui/MinikinUtils.cpp
@@ -72,10 +72,13 @@ minikin::Layout MinikinUtils::doLayout(const Paint* paint, minikin::Bidi bidiFla
const minikin::Range contextRange(contextStart, contextStart + contextCount);
const minikin::StartHyphenEdit startHyphen = paint->getStartHyphenEdit();
const minikin::EndHyphenEdit endHyphen = paint->getEndHyphenEdit();
+ const minikin::RunFlag minikinRunFlag = text_feature::inter_character_justification()
+ ? paint->getRunFlag()
+ : minikin::RunFlag::NONE;
if (mt == nullptr) {
return minikin::Layout(textBuf.substr(contextRange), range - contextStart, bidiFlags,
- minikinPaint, startHyphen, endHyphen);
+ minikinPaint, startHyphen, endHyphen, minikinRunFlag);
} else {
return mt->buildLayout(textBuf, range, contextRange, minikinPaint, startHyphen, endHyphen);
}
@@ -102,9 +105,12 @@ float MinikinUtils::measureText(const Paint* paint, minikin::Bidi bidiFlags,
const minikin::Range range(start, start + count);
const minikin::StartHyphenEdit startHyphen = paint->getStartHyphenEdit();
const minikin::EndHyphenEdit endHyphen = paint->getEndHyphenEdit();
+ const minikin::RunFlag minikinRunFlag = text_feature::inter_character_justification()
+ ? paint->getRunFlag()
+ : minikin::RunFlag::NONE;
return minikin::Layout::measureText(textBuf, range, bidiFlags, minikinPaint, startHyphen,
- endHyphen, advances, bounds, clusterCount);
+ endHyphen, advances, bounds, clusterCount, minikinRunFlag);
}
minikin::MinikinExtent MinikinUtils::getFontExtent(const Paint* paint, minikin::Bidi bidiFlags,
diff --git a/libs/hwui/hwui/Paint.h b/libs/hwui/hwui/Paint.h
index ef4dce57bf46..708f96e5a070 100644
--- a/libs/hwui/hwui/Paint.h
+++ b/libs/hwui/hwui/Paint.h
@@ -25,6 +25,7 @@
#include <minikin/FontFamily.h>
#include <minikin/FontFeature.h>
#include <minikin/Hyphenator.h>
+#include <minikin/Layout.h>
#include <string>
@@ -144,6 +145,9 @@ public:
bool isDevKern() const { return mDevKern; }
void setDevKern(bool d) { mDevKern = d; }
+ minikin::RunFlag getRunFlag() const { return mRunFlag; }
+ void setRunFlag(minikin::RunFlag runFlag) { mRunFlag = runFlag; }
+
// Deprecated -- bitmapshaders will be taking this flag explicitly
bool isFilterBitmap() const { return mFilterBitmap; }
void setFilterBitmap(bool filter) { mFilterBitmap = filter; }
@@ -188,6 +192,7 @@ private:
bool mStrikeThru = false;
bool mUnderline = false;
bool mDevKern = false;
+ minikin::RunFlag mRunFlag = minikin::RunFlag::NONE;
};
} // namespace android
diff --git a/libs/hwui/hwui/PaintImpl.cpp b/libs/hwui/hwui/PaintImpl.cpp
index aac928f85924..c32ea01db7b7 100644
--- a/libs/hwui/hwui/PaintImpl.cpp
+++ b/libs/hwui/hwui/PaintImpl.cpp
@@ -47,8 +47,8 @@ Paint::Paint(const Paint& paint)
, mFilterBitmap(paint.mFilterBitmap)
, mStrikeThru(paint.mStrikeThru)
, mUnderline(paint.mUnderline)
- , mDevKern(paint.mDevKern) {}
-
+ , mDevKern(paint.mDevKern)
+ , mRunFlag(paint.mRunFlag) {}
Paint::~Paint() {}
@@ -68,21 +68,19 @@ Paint& Paint::operator=(const Paint& other) {
mStrikeThru = other.mStrikeThru;
mUnderline = other.mUnderline;
mDevKern = other.mDevKern;
+ mRunFlag = other.mRunFlag;
return *this;
}
bool operator==(const Paint& a, const Paint& b) {
- return static_cast<const SkPaint&>(a) == static_cast<const SkPaint&>(b) &&
- a.mFont == b.mFont &&
- a.mLooper == b.mLooper &&
- a.mLetterSpacing == b.mLetterSpacing && a.mWordSpacing == b.mWordSpacing &&
- a.mFontFeatureSettings == b.mFontFeatureSettings &&
+ return static_cast<const SkPaint&>(a) == static_cast<const SkPaint&>(b) && a.mFont == b.mFont &&
+ a.mLooper == b.mLooper && a.mLetterSpacing == b.mLetterSpacing &&
+ a.mWordSpacing == b.mWordSpacing && a.mFontFeatureSettings == b.mFontFeatureSettings &&
a.mMinikinLocaleListId == b.mMinikinLocaleListId &&
a.mFamilyVariant == b.mFamilyVariant && a.mHyphenEdit == b.mHyphenEdit &&
a.mTypeface == b.mTypeface && a.mAlign == b.mAlign &&
- a.mFilterBitmap == b.mFilterBitmap &&
- a.mStrikeThru == b.mStrikeThru && a.mUnderline == b.mUnderline &&
- a.mDevKern == b.mDevKern;
+ a.mFilterBitmap == b.mFilterBitmap && a.mStrikeThru == b.mStrikeThru &&
+ a.mUnderline == b.mUnderline && a.mDevKern == b.mDevKern && a.mRunFlag == b.mRunFlag;
}
void Paint::reset() {
@@ -96,6 +94,7 @@ void Paint::reset() {
mStrikeThru = false;
mUnderline = false;
mDevKern = false;
+ mRunFlag = minikin::RunFlag::NONE;
}
void Paint::setLooper(sk_sp<BlurDrawLooper> looper) {
@@ -133,6 +132,8 @@ static const uint32_t sForceAutoHinting = 0x800;
// flags related to minikin::Paint
static const uint32_t sUnderlineFlag = 0x08;
static const uint32_t sStrikeThruFlag = 0x10;
+static const uint32_t sTextRunLeftEdge = 0x2000;
+static const uint32_t sTextRunRightEdge = 0x4000;
// flags no longer supported on native side (but mirrored for compatibility)
static const uint32_t sDevKernFlag = 0x100;
@@ -186,6 +187,12 @@ uint32_t Paint::getJavaFlags() const {
flags |= -(int)mUnderline & sUnderlineFlag;
flags |= -(int)mDevKern & sDevKernFlag;
flags |= -(int)mFilterBitmap & sFilterBitmapFlag;
+ if (mRunFlag & minikin::RunFlag::LEFT_EDGE) {
+ flags |= sTextRunLeftEdge;
+ }
+ if (mRunFlag & minikin::RunFlag::RIGHT_EDGE) {
+ flags |= sTextRunRightEdge;
+ }
return flags;
}
@@ -196,6 +203,15 @@ void Paint::setJavaFlags(uint32_t flags) {
mUnderline = (flags & sUnderlineFlag) != 0;
mDevKern = (flags & sDevKernFlag) != 0;
mFilterBitmap = (flags & sFilterBitmapFlag) != 0;
+
+ std::underlying_type<minikin::RunFlag>::type rawFlag = minikin::RunFlag::NONE;
+ if (flags & sTextRunLeftEdge) {
+ rawFlag |= minikin::RunFlag::LEFT_EDGE;
+ }
+ if (flags & sTextRunRightEdge) {
+ rawFlag |= minikin::RunFlag::RIGHT_EDGE;
+ }
+ mRunFlag = static_cast<minikin::RunFlag>(rawFlag);
}
} // namespace android
diff --git a/libs/hwui/jni/android_graphics_Canvas.cpp b/libs/hwui/jni/android_graphics_Canvas.cpp
index 8ba750372d18..d5725935551a 100644
--- a/libs/hwui/jni/android_graphics_Canvas.cpp
+++ b/libs/hwui/jni/android_graphics_Canvas.cpp
@@ -613,6 +613,12 @@ static void drawTextChars(JNIEnv* env, jobject, jlong canvasHandle, jcharArray c
Paint* paint = reinterpret_cast<Paint*>(paintHandle);
const Typeface* typeface = paint->getAndroidTypeface();
ScopedCharArrayRO text(env, charArray);
+
+ // The drawText API is designed to draw entire line, so ignore the text run flag and draw the
+ // text as entire line mode.
+ const minikin::RunFlag originalRunFlag = paint->getRunFlag();
+ paint->setRunFlag(minikin::RunFlag::WHOLE_LINE);
+
// drawTextString and drawTextChars doesn't use context info
get_canvas(canvasHandle)->drawText(
text.get() + index, count, // text buffer
@@ -620,6 +626,7 @@ static void drawTextChars(JNIEnv* env, jobject, jlong canvasHandle, jcharArray c
0, count, // context range
x, y, // draw position
static_cast<minikin::Bidi>(bidiFlags), *paint, typeface, nullptr /* measured text */);
+ paint->setRunFlag(originalRunFlag);
}
static void drawTextString(JNIEnv* env, jobject, jlong canvasHandle, jstring strObj,
@@ -629,6 +636,12 @@ static void drawTextString(JNIEnv* env, jobject, jlong canvasHandle, jstring str
Paint* paint = reinterpret_cast<Paint*>(paintHandle);
const Typeface* typeface = paint->getAndroidTypeface();
const int count = end - start;
+
+ // The drawText API is designed to draw entire line, so ignore the text run flag and draw the
+ // text as entire line mode.
+ const minikin::RunFlag originalRunFlag = paint->getRunFlag();
+ paint->setRunFlag(minikin::RunFlag::WHOLE_LINE);
+
// drawTextString and drawTextChars doesn't use context info
get_canvas(canvasHandle)->drawText(
text.get() + start, count, // text buffer
@@ -636,6 +649,7 @@ static void drawTextString(JNIEnv* env, jobject, jlong canvasHandle, jstring str
0, count, // context range
x, y, // draw position
static_cast<minikin::Bidi>(bidiFlags), *paint, typeface, nullptr /* measured text */);
+ paint->setRunFlag(originalRunFlag);
}
static void drawTextRunChars(JNIEnv* env, jobject, jlong canvasHandle, jcharArray charArray,
@@ -681,9 +695,15 @@ static void drawTextOnPathChars(JNIEnv* env, jobject, jlong canvasHandle, jcharA
jchar* jchars = env->GetCharArrayElements(text, NULL);
+ // The drawText API is designed to draw entire line, so ignore the text run flag and draw the
+ // text as entire line mode.
+ const minikin::RunFlag originalRunFlag = paint->getRunFlag();
+ paint->setRunFlag(minikin::RunFlag::WHOLE_LINE);
+
get_canvas(canvasHandle)->drawTextOnPath(jchars + index, count,
static_cast<minikin::Bidi>(bidiFlags), *path, hOffset, vOffset, *paint, typeface);
+ paint->setRunFlag(originalRunFlag);
env->ReleaseCharArrayElements(text, jchars, 0);
}
@@ -697,9 +717,15 @@ static void drawTextOnPathString(JNIEnv* env, jobject, jlong canvasHandle, jstri
const jchar* jchars = env->GetStringChars(text, NULL);
int count = env->GetStringLength(text);
+ // The drawText API is designed to draw entire line, so ignore the text run flag and draw the
+ // text as entire line mode.
+ const minikin::RunFlag originalRunFlag = paint->getRunFlag();
+ paint->setRunFlag(minikin::RunFlag::WHOLE_LINE);
+
get_canvas(canvasHandle)->drawTextOnPath(jchars, count, static_cast<minikin::Bidi>(bidiFlags),
*path, hOffset, vOffset, *paint, typeface);
+ paint->setRunFlag(originalRunFlag);
env->ReleaseStringChars(text, jchars);
}