Merge "Reland: Move text logic from jni to hwui level" into nyc-dev
am: d8e91f6
* commit 'd8e91f65ae038a5223d6efd4ca4e382c7764bd4e':
Reland: Move text logic from jni to hwui level
This commit is contained in:
@@ -117,13 +117,10 @@ LOCAL_SRC_FILES:= \
|
|||||||
android/graphics/Interpolator.cpp \
|
android/graphics/Interpolator.cpp \
|
||||||
android/graphics/MaskFilter.cpp \
|
android/graphics/MaskFilter.cpp \
|
||||||
android/graphics/Matrix.cpp \
|
android/graphics/Matrix.cpp \
|
||||||
android/graphics/MinikinSkia.cpp \
|
|
||||||
android/graphics/MinikinUtils.cpp \
|
|
||||||
android/graphics/Movie.cpp \
|
android/graphics/Movie.cpp \
|
||||||
android/graphics/NinePatch.cpp \
|
android/graphics/NinePatch.cpp \
|
||||||
android/graphics/NinePatchPeeker.cpp \
|
android/graphics/NinePatchPeeker.cpp \
|
||||||
android/graphics/Paint.cpp \
|
android/graphics/Paint.cpp \
|
||||||
android/graphics/PaintImpl.cpp \
|
|
||||||
android/graphics/Path.cpp \
|
android/graphics/Path.cpp \
|
||||||
android/graphics/PathMeasure.cpp \
|
android/graphics/PathMeasure.cpp \
|
||||||
android/graphics/PathEffect.cpp \
|
android/graphics/PathEffect.cpp \
|
||||||
@@ -135,7 +132,6 @@ LOCAL_SRC_FILES:= \
|
|||||||
android/graphics/Shader.cpp \
|
android/graphics/Shader.cpp \
|
||||||
android/graphics/SurfaceTexture.cpp \
|
android/graphics/SurfaceTexture.cpp \
|
||||||
android/graphics/Typeface.cpp \
|
android/graphics/Typeface.cpp \
|
||||||
android/graphics/TypefaceImpl.cpp \
|
|
||||||
android/graphics/Utils.cpp \
|
android/graphics/Utils.cpp \
|
||||||
android/graphics/Xfermode.cpp \
|
android/graphics/Xfermode.cpp \
|
||||||
android/graphics/YuvToJpegEncoder.cpp \
|
android/graphics/YuvToJpegEncoder.cpp \
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
#define LOG_TAG "Bitmap"
|
#define LOG_TAG "Bitmap"
|
||||||
#include "Bitmap.h"
|
#include "Bitmap.h"
|
||||||
|
|
||||||
#include "Paint.h"
|
|
||||||
#include "SkBitmap.h"
|
#include "SkBitmap.h"
|
||||||
#include "SkPixelRef.h"
|
#include "SkPixelRef.h"
|
||||||
#include "SkImageEncoder.h"
|
#include "SkImageEncoder.h"
|
||||||
@@ -18,6 +17,7 @@
|
|||||||
#include "android_nio_utils.h"
|
#include "android_nio_utils.h"
|
||||||
#include "CreateJavaOutputStreamAdaptor.h"
|
#include "CreateJavaOutputStreamAdaptor.h"
|
||||||
#include <Caches.h>
|
#include <Caches.h>
|
||||||
|
#include <hwui/Paint.h>
|
||||||
|
|
||||||
#include "core_jni_helpers.h"
|
#include "core_jni_helpers.h"
|
||||||
|
|
||||||
|
|||||||
@@ -3,8 +3,8 @@
|
|||||||
|
|
||||||
#include "SkCamera.h"
|
#include "SkCamera.h"
|
||||||
|
|
||||||
#include "Canvas.h"
|
|
||||||
#include "GraphicsJNI.h"
|
#include "GraphicsJNI.h"
|
||||||
|
#include <hwui/Canvas.h>
|
||||||
|
|
||||||
static jfieldID gNativeInstanceFieldID;
|
static jfieldID gNativeInstanceFieldID;
|
||||||
|
|
||||||
|
|||||||
@@ -16,9 +16,9 @@
|
|||||||
|
|
||||||
#include "jni.h"
|
#include "jni.h"
|
||||||
#include "GraphicsJNI.h"
|
#include "GraphicsJNI.h"
|
||||||
#include "Paint.h"
|
|
||||||
#include <core_jni_helpers.h>
|
#include <core_jni_helpers.h>
|
||||||
|
|
||||||
|
#include <hwui/Paint.h>
|
||||||
#include <utils/RefBase.h>
|
#include <utils/RefBase.h>
|
||||||
#include <CanvasProperty.h>
|
#include <CanvasProperty.h>
|
||||||
|
|
||||||
|
|||||||
@@ -31,9 +31,9 @@
|
|||||||
#include <androidfw/AssetManager.h>
|
#include <androidfw/AssetManager.h>
|
||||||
#include "Utils.h"
|
#include "Utils.h"
|
||||||
|
|
||||||
#include "TypefaceImpl.h"
|
#include <hwui/MinikinSkia.h>
|
||||||
|
#include <hwui/TypefaceImpl.h>
|
||||||
#include <minikin/FontFamily.h>
|
#include <minikin/FontFamily.h>
|
||||||
#include "MinikinSkia.h"
|
|
||||||
|
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
|
||||||
|
|||||||
@@ -7,13 +7,13 @@
|
|||||||
#include "JNIHelp.h"
|
#include "JNIHelp.h"
|
||||||
#include "GraphicsJNI.h"
|
#include "GraphicsJNI.h"
|
||||||
|
|
||||||
#include "Canvas.h"
|
|
||||||
#include "SkCanvas.h"
|
#include "SkCanvas.h"
|
||||||
#include "SkDevice.h"
|
#include "SkDevice.h"
|
||||||
#include "SkMath.h"
|
#include "SkMath.h"
|
||||||
#include "SkRegion.h"
|
#include "SkRegion.h"
|
||||||
#include <android_runtime/AndroidRuntime.h>
|
#include <android_runtime/AndroidRuntime.h>
|
||||||
#include <cutils/ashmem.h>
|
#include <cutils/ashmem.h>
|
||||||
|
#include <hwui/Canvas.h>
|
||||||
|
|
||||||
#include <Caches.h>
|
#include <Caches.h>
|
||||||
#include <TextureCache.h>
|
#include <TextureCache.h>
|
||||||
|
|||||||
@@ -11,8 +11,8 @@
|
|||||||
#include "SkPoint.h"
|
#include "SkPoint.h"
|
||||||
#include "SkRect.h"
|
#include "SkRect.h"
|
||||||
#include "SkImageDecoder.h"
|
#include "SkImageDecoder.h"
|
||||||
#include <Canvas.h>
|
|
||||||
#include <jni.h>
|
#include <jni.h>
|
||||||
|
#include <hwui/Canvas.h>
|
||||||
|
|
||||||
class SkBitmapRegionDecoder;
|
class SkBitmapRegionDecoder;
|
||||||
class SkCanvas;
|
class SkCanvas;
|
||||||
|
|||||||
@@ -1,7 +1,5 @@
|
|||||||
#include "Canvas.h"
|
|
||||||
#include "CreateJavaOutputStreamAdaptor.h"
|
#include "CreateJavaOutputStreamAdaptor.h"
|
||||||
#include "GraphicsJNI.h"
|
#include "GraphicsJNI.h"
|
||||||
#include "Paint.h"
|
|
||||||
#include "ScopedLocalRef.h"
|
#include "ScopedLocalRef.h"
|
||||||
#include "SkFrontBufferedStream.h"
|
#include "SkFrontBufferedStream.h"
|
||||||
#include "SkMovie.h"
|
#include "SkMovie.h"
|
||||||
@@ -12,6 +10,8 @@
|
|||||||
|
|
||||||
#include <androidfw/Asset.h>
|
#include <androidfw/Asset.h>
|
||||||
#include <androidfw/ResourceTypes.h>
|
#include <androidfw/ResourceTypes.h>
|
||||||
|
#include <hwui/Canvas.h>
|
||||||
|
#include <hwui/Paint.h>
|
||||||
#include <jni.h>
|
#include <jni.h>
|
||||||
#include <netinet/in.h>
|
#include <netinet/in.h>
|
||||||
|
|
||||||
|
|||||||
@@ -19,12 +19,12 @@
|
|||||||
#define LOG_NDEBUG 1
|
#define LOG_NDEBUG 1
|
||||||
|
|
||||||
#include <androidfw/ResourceTypes.h>
|
#include <androidfw/ResourceTypes.h>
|
||||||
|
#include <hwui/Canvas.h>
|
||||||
|
#include <hwui/Paint.h>
|
||||||
#include <utils/Log.h>
|
#include <utils/Log.h>
|
||||||
|
|
||||||
#include <ResourceCache.h>
|
#include <ResourceCache.h>
|
||||||
|
|
||||||
#include "Paint.h"
|
|
||||||
#include "Canvas.h"
|
|
||||||
#include "SkCanvas.h"
|
#include "SkCanvas.h"
|
||||||
#include "SkRegion.h"
|
#include "SkRegion.h"
|
||||||
#include "GraphicsJNI.h"
|
#include "GraphicsJNI.h"
|
||||||
|
|||||||
@@ -37,13 +37,13 @@
|
|||||||
#include "unicode/ushape.h"
|
#include "unicode/ushape.h"
|
||||||
#include "utils/Blur.h"
|
#include "utils/Blur.h"
|
||||||
|
|
||||||
|
#include <hwui/MinikinSkia.h>
|
||||||
|
#include <hwui/MinikinUtils.h>
|
||||||
|
#include <hwui/Paint.h>
|
||||||
|
#include <hwui/TypefaceImpl.h>
|
||||||
#include <minikin/GraphemeBreak.h>
|
#include <minikin/GraphemeBreak.h>
|
||||||
#include <minikin/Measurement.h>
|
#include <minikin/Measurement.h>
|
||||||
#include <unicode/utf16.h>
|
#include <unicode/utf16.h>
|
||||||
#include "MinikinSkia.h"
|
|
||||||
#include "MinikinUtils.h"
|
|
||||||
#include "Paint.h"
|
|
||||||
#include "TypefaceImpl.h"
|
|
||||||
|
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
|
|||||||
@@ -14,11 +14,11 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "Canvas.h"
|
|
||||||
#include "Picture.h"
|
#include "Picture.h"
|
||||||
#include "SkStream.h"
|
#include "SkStream.h"
|
||||||
|
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
#include <hwui/Canvas.h>
|
||||||
|
|
||||||
namespace android {
|
namespace android {
|
||||||
|
|
||||||
|
|||||||
@@ -22,10 +22,11 @@
|
|||||||
|
|
||||||
#include "jni.h"
|
#include "jni.h"
|
||||||
#include "GraphicsJNI.h"
|
#include "GraphicsJNI.h"
|
||||||
#include "Paint.h"
|
|
||||||
#include "SkLayerRasterizer.h"
|
#include "SkLayerRasterizer.h"
|
||||||
#include "core_jni_helpers.h"
|
#include "core_jni_helpers.h"
|
||||||
|
|
||||||
|
#include <hwui/Paint.h>
|
||||||
|
|
||||||
// Rasterizer.java holds a pointer (jlong) to this guy
|
// Rasterizer.java holds a pointer (jlong) to this guy
|
||||||
class NativeRasterizer {
|
class NativeRasterizer {
|
||||||
public:
|
public:
|
||||||
|
|||||||
@@ -20,9 +20,9 @@
|
|||||||
#include "GraphicsJNI.h"
|
#include "GraphicsJNI.h"
|
||||||
#include "ScopedPrimitiveArray.h"
|
#include "ScopedPrimitiveArray.h"
|
||||||
#include "SkTypeface.h"
|
#include "SkTypeface.h"
|
||||||
#include "TypefaceImpl.h"
|
|
||||||
#include <android_runtime/android_util_AssetManager.h>
|
#include <android_runtime/android_util_AssetManager.h>
|
||||||
#include <androidfw/AssetManager.h>
|
#include <androidfw/AssetManager.h>
|
||||||
|
#include <hwui/TypefaceImpl.h>
|
||||||
|
|
||||||
using namespace android;
|
using namespace android;
|
||||||
|
|
||||||
@@ -58,7 +58,12 @@ static jint Typeface_getStyle(JNIEnv* env, jobject obj, jlong faceHandle) {
|
|||||||
|
|
||||||
static jlong Typeface_createFromArray(JNIEnv *env, jobject, jlongArray familyArray) {
|
static jlong Typeface_createFromArray(JNIEnv *env, jobject, jlongArray familyArray) {
|
||||||
ScopedLongArrayRO families(env, familyArray);
|
ScopedLongArrayRO families(env, familyArray);
|
||||||
return reinterpret_cast<jlong>(TypefaceImpl_createFromFamilies(families.get(), families.size()));
|
std::vector<FontFamily*> familyVec;
|
||||||
|
for (size_t i = 0; i < families.size(); i++) {
|
||||||
|
FontFamily* family = reinterpret_cast<FontFamily*>(families[i]);
|
||||||
|
familyVec.push_back(family);
|
||||||
|
}
|
||||||
|
return reinterpret_cast<jlong>(TypefaceImpl_createFromFamilies(familyVec));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void Typeface_setDefault(JNIEnv *env, jobject, jlong faceHandle) {
|
static void Typeface_setDefault(JNIEnv *env, jobject, jlong faceHandle) {
|
||||||
|
|||||||
@@ -19,7 +19,6 @@
|
|||||||
#include "core_jni_helpers.h"
|
#include "core_jni_helpers.h"
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include "Canvas.h"
|
|
||||||
#include "CreateJavaOutputStreamAdaptor.h"
|
#include "CreateJavaOutputStreamAdaptor.h"
|
||||||
|
|
||||||
#include "SkDocument.h"
|
#include "SkDocument.h"
|
||||||
@@ -28,6 +27,8 @@
|
|||||||
#include "SkStream.h"
|
#include "SkStream.h"
|
||||||
#include "SkRect.h"
|
#include "SkRect.h"
|
||||||
|
|
||||||
|
#include <hwui/Canvas.h>
|
||||||
|
|
||||||
namespace android {
|
namespace android {
|
||||||
|
|
||||||
struct PageRecord {
|
struct PageRecord {
|
||||||
|
|||||||
@@ -19,15 +19,14 @@
|
|||||||
#include "core_jni_helpers.h"
|
#include "core_jni_helpers.h"
|
||||||
|
|
||||||
#include <androidfw/ResourceTypes.h>
|
#include <androidfw/ResourceTypes.h>
|
||||||
#include <Canvas.h>
|
#include <hwui/Canvas.h>
|
||||||
|
#include <hwui/Paint.h>
|
||||||
|
#include <hwui/TypefaceImpl.h>
|
||||||
|
#include <minikin/Layout.h>
|
||||||
|
|
||||||
#include "Bitmap.h"
|
#include "Bitmap.h"
|
||||||
#include "SkDrawFilter.h"
|
#include "SkDrawFilter.h"
|
||||||
#include "SkGraphics.h"
|
#include "SkGraphics.h"
|
||||||
#include "Paint.h"
|
|
||||||
#include "TypefaceImpl.h"
|
|
||||||
|
|
||||||
#include "MinikinUtils.h"
|
|
||||||
|
|
||||||
namespace android {
|
namespace android {
|
||||||
|
|
||||||
@@ -475,111 +474,13 @@ static void drawBitmapMesh(JNIEnv* env, jobject, jlong canvasHandle, jobject jbi
|
|||||||
vertA.ptr(), colorA.ptr(), paint);
|
vertA.ptr(), colorA.ptr(), paint);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void simplifyPaint(int color, SkPaint* paint) {
|
|
||||||
paint->setColor(color);
|
|
||||||
paint->setShader(nullptr);
|
|
||||||
paint->setColorFilter(nullptr);
|
|
||||||
paint->setLooper(nullptr);
|
|
||||||
paint->setStrokeWidth(4 + 0.04 * paint->getTextSize());
|
|
||||||
paint->setStrokeJoin(SkPaint::kRound_Join);
|
|
||||||
paint->setLooper(nullptr);
|
|
||||||
}
|
|
||||||
|
|
||||||
class DrawTextFunctor {
|
|
||||||
public:
|
|
||||||
DrawTextFunctor(const Layout& layout, Canvas* canvas, uint16_t* glyphs, float* pos,
|
|
||||||
const SkPaint& paint, float x, float y, MinikinRect& bounds,
|
|
||||||
float totalAdvance)
|
|
||||||
: layout(layout), canvas(canvas), glyphs(glyphs), pos(pos), paint(paint),
|
|
||||||
x(x), y(y), bounds(bounds), totalAdvance(totalAdvance) { }
|
|
||||||
|
|
||||||
void operator()(size_t start, size_t end) {
|
|
||||||
if (canvas->drawTextAbsolutePos()) {
|
|
||||||
for (size_t i = start; i < end; i++) {
|
|
||||||
glyphs[i] = layout.getGlyphId(i);
|
|
||||||
pos[2 * i] = x + layout.getX(i);
|
|
||||||
pos[2 * i + 1] = y + layout.getY(i);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
for (size_t i = start; i < end; i++) {
|
|
||||||
glyphs[i] = layout.getGlyphId(i);
|
|
||||||
pos[2 * i] = layout.getX(i);
|
|
||||||
pos[2 * i + 1] = layout.getY(i);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t glyphCount = end - start;
|
|
||||||
|
|
||||||
if (CC_UNLIKELY(canvas->isHighContrastText() && paint.getAlpha() != 0)) {
|
|
||||||
// high contrast draw path
|
|
||||||
int color = paint.getColor();
|
|
||||||
int channelSum = SkColorGetR(color) + SkColorGetG(color) + SkColorGetB(color);
|
|
||||||
bool darken = channelSum < (128 * 3);
|
|
||||||
|
|
||||||
// outline
|
|
||||||
SkPaint outlinePaint(paint);
|
|
||||||
simplifyPaint(darken ? SK_ColorWHITE : SK_ColorBLACK, &outlinePaint);
|
|
||||||
outlinePaint.setStyle(SkPaint::kStrokeAndFill_Style);
|
|
||||||
canvas->drawText(glyphs + start, pos + (2 * start), glyphCount, outlinePaint, x, y,
|
|
||||||
bounds.mLeft, bounds.mTop, bounds.mRight, bounds.mBottom, totalAdvance);
|
|
||||||
|
|
||||||
// inner
|
|
||||||
SkPaint innerPaint(paint);
|
|
||||||
simplifyPaint(darken ? SK_ColorBLACK : SK_ColorWHITE, &innerPaint);
|
|
||||||
innerPaint.setStyle(SkPaint::kFill_Style);
|
|
||||||
canvas->drawText(glyphs + start, pos + (2 * start), glyphCount, innerPaint, x, y,
|
|
||||||
bounds.mLeft, bounds.mTop, bounds.mRight, bounds.mBottom, totalAdvance);
|
|
||||||
} else {
|
|
||||||
// standard draw path
|
|
||||||
canvas->drawText(glyphs + start, pos + (2 * start), glyphCount, paint, x, y,
|
|
||||||
bounds.mLeft, bounds.mTop, bounds.mRight, bounds.mBottom,
|
|
||||||
totalAdvance);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
private:
|
|
||||||
const Layout& layout;
|
|
||||||
Canvas* canvas;
|
|
||||||
uint16_t* glyphs;
|
|
||||||
float* pos;
|
|
||||||
const SkPaint& paint;
|
|
||||||
float x;
|
|
||||||
float y;
|
|
||||||
MinikinRect& bounds;
|
|
||||||
float totalAdvance;
|
|
||||||
};
|
|
||||||
|
|
||||||
void drawText(Canvas* canvas, const uint16_t* text, int start, int count, int contextCount,
|
|
||||||
float x, float y, int bidiFlags, const Paint& origPaint, TypefaceImpl* typeface) {
|
|
||||||
// minikin may modify the original paint
|
|
||||||
Paint paint(origPaint);
|
|
||||||
|
|
||||||
Layout layout;
|
|
||||||
MinikinUtils::doLayout(&layout, &paint, bidiFlags, typeface, text, start, count, contextCount);
|
|
||||||
|
|
||||||
size_t nGlyphs = layout.nGlyphs();
|
|
||||||
std::unique_ptr<uint16_t[]> glyphs(new uint16_t[nGlyphs]);
|
|
||||||
std::unique_ptr<float[]> pos(new float[nGlyphs * 2]);
|
|
||||||
|
|
||||||
x += MinikinUtils::xOffsetForTextAlign(&paint, layout);
|
|
||||||
|
|
||||||
MinikinRect bounds;
|
|
||||||
layout.getBounds(&bounds);
|
|
||||||
if (!canvas->drawTextAbsolutePos()) {
|
|
||||||
bounds.offset(x, y);
|
|
||||||
}
|
|
||||||
|
|
||||||
DrawTextFunctor f(layout, canvas, glyphs.get(), pos.get(),
|
|
||||||
paint, x, y, bounds, layout.getAdvance());
|
|
||||||
MinikinUtils::forFontRun(layout, &paint, f);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void drawTextChars(JNIEnv* env, jobject, jlong canvasHandle, jcharArray text,
|
static void drawTextChars(JNIEnv* env, jobject, jlong canvasHandle, jcharArray text,
|
||||||
jint index, jint count, jfloat x, jfloat y, jint bidiFlags,
|
jint index, jint count, jfloat x, jfloat y, jint bidiFlags,
|
||||||
jlong paintHandle, jlong typefaceHandle) {
|
jlong paintHandle, jlong typefaceHandle) {
|
||||||
Paint* paint = reinterpret_cast<Paint*>(paintHandle);
|
Paint* paint = reinterpret_cast<Paint*>(paintHandle);
|
||||||
TypefaceImpl* typeface = reinterpret_cast<TypefaceImpl*>(typefaceHandle);
|
TypefaceImpl* typeface = reinterpret_cast<TypefaceImpl*>(typefaceHandle);
|
||||||
jchar* jchars = env->GetCharArrayElements(text, NULL);
|
jchar* jchars = env->GetCharArrayElements(text, NULL);
|
||||||
drawText(get_canvas(canvasHandle), jchars + index, 0, count, count, x, y,
|
get_canvas(canvasHandle)->drawText(jchars + index, 0, count, count, x, y,
|
||||||
bidiFlags, *paint, typeface);
|
bidiFlags, *paint, typeface);
|
||||||
env->ReleaseCharArrayElements(text, jchars, JNI_ABORT);
|
env->ReleaseCharArrayElements(text, jchars, JNI_ABORT);
|
||||||
}
|
}
|
||||||
@@ -591,7 +492,7 @@ static void drawTextString(JNIEnv* env, jobject, jlong canvasHandle, jstring tex
|
|||||||
TypefaceImpl* typeface = reinterpret_cast<TypefaceImpl*>(typefaceHandle);
|
TypefaceImpl* typeface = reinterpret_cast<TypefaceImpl*>(typefaceHandle);
|
||||||
const int count = end - start;
|
const int count = end - start;
|
||||||
const jchar* jchars = env->GetStringChars(text, NULL);
|
const jchar* jchars = env->GetStringChars(text, NULL);
|
||||||
drawText(get_canvas(canvasHandle), jchars + start, 0, count, count, x, y,
|
get_canvas(canvasHandle)->drawText(jchars + start, 0, count, count, x, y,
|
||||||
bidiFlags, *paint, typeface);
|
bidiFlags, *paint, typeface);
|
||||||
env->ReleaseStringChars(text, jchars);
|
env->ReleaseStringChars(text, jchars);
|
||||||
}
|
}
|
||||||
@@ -604,7 +505,7 @@ static void drawTextRunChars(JNIEnv* env, jobject, jlong canvasHandle, jcharArra
|
|||||||
|
|
||||||
const int bidiFlags = isRtl ? kBidi_Force_RTL : kBidi_Force_LTR;
|
const int bidiFlags = isRtl ? kBidi_Force_RTL : kBidi_Force_LTR;
|
||||||
jchar* jchars = env->GetCharArrayElements(text, NULL);
|
jchar* jchars = env->GetCharArrayElements(text, NULL);
|
||||||
drawText(get_canvas(canvasHandle), jchars + contextIndex, index - contextIndex, count,
|
get_canvas(canvasHandle)->drawText(jchars + contextIndex, index - contextIndex, count,
|
||||||
contextCount, x, y, bidiFlags, *paint, typeface);
|
contextCount, x, y, bidiFlags, *paint, typeface);
|
||||||
env->ReleaseCharArrayElements(text, jchars, JNI_ABORT);
|
env->ReleaseCharArrayElements(text, jchars, JNI_ABORT);
|
||||||
}
|
}
|
||||||
@@ -620,53 +521,11 @@ static void drawTextRunString(JNIEnv* env, jobject obj, jlong canvasHandle, jstr
|
|||||||
jint count = end - start;
|
jint count = end - start;
|
||||||
jint contextCount = contextEnd - contextStart;
|
jint contextCount = contextEnd - contextStart;
|
||||||
const jchar* jchars = env->GetStringChars(text, NULL);
|
const jchar* jchars = env->GetStringChars(text, NULL);
|
||||||
drawText(get_canvas(canvasHandle), jchars + contextStart, start - contextStart, count,
|
get_canvas(canvasHandle)->drawText(jchars + contextStart, start - contextStart, count,
|
||||||
contextCount, x, y, bidiFlags, *paint, typeface);
|
contextCount, x, y, bidiFlags, *paint, typeface);
|
||||||
env->ReleaseStringChars(text, jchars);
|
env->ReleaseStringChars(text, jchars);
|
||||||
}
|
}
|
||||||
|
|
||||||
class DrawTextOnPathFunctor {
|
|
||||||
public:
|
|
||||||
DrawTextOnPathFunctor(const Layout& layout, Canvas* canvas, float hOffset,
|
|
||||||
float vOffset, const Paint& paint, const SkPath& path)
|
|
||||||
: layout(layout), canvas(canvas), hOffset(hOffset), vOffset(vOffset),
|
|
||||||
paint(paint), path(path) {
|
|
||||||
}
|
|
||||||
void operator()(size_t start, size_t end) {
|
|
||||||
uint16_t glyphs[1];
|
|
||||||
for (size_t i = start; i < end; i++) {
|
|
||||||
glyphs[0] = layout.getGlyphId(i);
|
|
||||||
float x = hOffset + layout.getX(i);
|
|
||||||
float y = vOffset + layout.getY(i);
|
|
||||||
canvas->drawTextOnPath(glyphs, 1, path, x, y, paint);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
private:
|
|
||||||
const Layout& layout;
|
|
||||||
Canvas* canvas;
|
|
||||||
float hOffset;
|
|
||||||
float vOffset;
|
|
||||||
const Paint& paint;
|
|
||||||
const SkPath& path;
|
|
||||||
};
|
|
||||||
|
|
||||||
static void drawTextOnPath(Canvas* canvas, const uint16_t* text, int count, int bidiFlags,
|
|
||||||
const SkPath& path, float hOffset, float vOffset,
|
|
||||||
const Paint& paint, TypefaceImpl* typeface) {
|
|
||||||
Paint paintCopy(paint);
|
|
||||||
Layout layout;
|
|
||||||
MinikinUtils::doLayout(&layout, &paintCopy, bidiFlags, typeface, text, 0, count, count);
|
|
||||||
hOffset += MinikinUtils::hOffsetForTextAlign(&paintCopy, layout, path);
|
|
||||||
|
|
||||||
// Set align to left for drawing, as we don't want individual
|
|
||||||
// glyphs centered or right-aligned; the offset above takes
|
|
||||||
// care of all alignment.
|
|
||||||
paintCopy.setTextAlign(Paint::kLeft_Align);
|
|
||||||
|
|
||||||
DrawTextOnPathFunctor f(layout, canvas, hOffset, vOffset, paintCopy, path);
|
|
||||||
MinikinUtils::forFontRun(layout, &paintCopy, f);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void drawTextOnPathChars(JNIEnv* env, jobject, jlong canvasHandle, jcharArray text,
|
static void drawTextOnPathChars(JNIEnv* env, jobject, jlong canvasHandle, jcharArray text,
|
||||||
jint index, jint count, jlong pathHandle, jfloat hOffset,
|
jint index, jint count, jlong pathHandle, jfloat hOffset,
|
||||||
jfloat vOffset, jint bidiFlags, jlong paintHandle,
|
jfloat vOffset, jint bidiFlags, jlong paintHandle,
|
||||||
@@ -677,7 +536,7 @@ static void drawTextOnPathChars(JNIEnv* env, jobject, jlong canvasHandle, jcharA
|
|||||||
|
|
||||||
jchar* jchars = env->GetCharArrayElements(text, NULL);
|
jchar* jchars = env->GetCharArrayElements(text, NULL);
|
||||||
|
|
||||||
drawTextOnPath(get_canvas(canvasHandle), jchars + index, count, bidiFlags, *path,
|
get_canvas(canvasHandle)->drawTextOnPath(jchars + index, count, bidiFlags, *path,
|
||||||
hOffset, vOffset, *paint, typeface);
|
hOffset, vOffset, *paint, typeface);
|
||||||
|
|
||||||
env->ReleaseCharArrayElements(text, jchars, 0);
|
env->ReleaseCharArrayElements(text, jchars, 0);
|
||||||
@@ -693,7 +552,7 @@ static void drawTextOnPathString(JNIEnv* env, jobject, jlong canvasHandle, jstri
|
|||||||
const jchar* jchars = env->GetStringChars(text, NULL);
|
const jchar* jchars = env->GetStringChars(text, NULL);
|
||||||
int count = env->GetStringLength(text);
|
int count = env->GetStringLength(text);
|
||||||
|
|
||||||
drawTextOnPath(get_canvas(canvasHandle), jchars, count, bidiFlags, *path,
|
get_canvas(canvasHandle)->drawTextOnPath(jchars, count, bidiFlags, *path,
|
||||||
hOffset, vOffset, *paint, typeface);
|
hOffset, vOffset, *paint, typeface);
|
||||||
|
|
||||||
env->ReleaseStringChars(text, jchars);
|
env->ReleaseStringChars(text, jchars);
|
||||||
|
|||||||
@@ -19,9 +19,10 @@
|
|||||||
#include "core_jni_helpers.h"
|
#include "core_jni_helpers.h"
|
||||||
#include "log/log.h"
|
#include "log/log.h"
|
||||||
|
|
||||||
#include "Paint.h"
|
|
||||||
#include "VectorDrawable.h"
|
#include "VectorDrawable.h"
|
||||||
|
|
||||||
|
#include <hwui/Paint.h>
|
||||||
|
|
||||||
namespace android {
|
namespace android {
|
||||||
using namespace uirenderer;
|
using namespace uirenderer;
|
||||||
using namespace uirenderer::VectorDrawable;
|
using namespace uirenderer::VectorDrawable;
|
||||||
|
|||||||
@@ -32,10 +32,12 @@
|
|||||||
|
|
||||||
#include "SkPaint.h"
|
#include "SkPaint.h"
|
||||||
#include "SkTypeface.h"
|
#include "SkTypeface.h"
|
||||||
#include "MinikinSkia.h"
|
#include <hwui/MinikinSkia.h>
|
||||||
#include "MinikinUtils.h"
|
#include <hwui/MinikinUtils.h>
|
||||||
#include "Paint.h"
|
#include <hwui/Paint.h>
|
||||||
#include "minikin/LineBreaker.h"
|
#include <minikin/FontCollection.h>
|
||||||
|
#include <minikin/LineBreaker.h>
|
||||||
|
#include <minikin/MinikinFont.h>
|
||||||
|
|
||||||
namespace android {
|
namespace android {
|
||||||
|
|
||||||
|
|||||||
@@ -28,11 +28,11 @@
|
|||||||
#include <SkRegion.h>
|
#include <SkRegion.h>
|
||||||
|
|
||||||
|
|
||||||
#include <Canvas.h>
|
|
||||||
#include <Rect.h>
|
#include <Rect.h>
|
||||||
#include <RenderNode.h>
|
#include <RenderNode.h>
|
||||||
#include <CanvasProperty.h>
|
#include <CanvasProperty.h>
|
||||||
#include <Paint.h>
|
#include <hwui/Canvas.h>
|
||||||
|
#include <hwui/Paint.h>
|
||||||
#include <renderthread/RenderProxy.h>
|
#include <renderthread/RenderProxy.h>
|
||||||
|
|
||||||
#include "core_jni_helpers.h"
|
#include "core_jni_helpers.h"
|
||||||
|
|||||||
@@ -24,8 +24,8 @@
|
|||||||
#include <android_runtime/android_graphics_SurfaceTexture.h>
|
#include <android_runtime/android_graphics_SurfaceTexture.h>
|
||||||
|
|
||||||
#include <gui/GLConsumer.h>
|
#include <gui/GLConsumer.h>
|
||||||
|
#include <hwui/Paint.h>
|
||||||
|
|
||||||
#include <Paint.h>
|
|
||||||
#include <SkBitmap.h>
|
#include <SkBitmap.h>
|
||||||
#include <SkCanvas.h>
|
#include <SkCanvas.h>
|
||||||
#include <SkMatrix.h>
|
#include <SkMatrix.h>
|
||||||
|
|||||||
@@ -30,7 +30,7 @@
|
|||||||
#include <RenderNode.h>
|
#include <RenderNode.h>
|
||||||
#include <renderthread/CanvasContext.h>
|
#include <renderthread/CanvasContext.h>
|
||||||
#include <TreeInfo.h>
|
#include <TreeInfo.h>
|
||||||
#include <Paint.h>
|
#include <hwui/Paint.h>
|
||||||
|
|
||||||
#include "core_jni_helpers.h"
|
#include "core_jni_helpers.h"
|
||||||
|
|
||||||
|
|||||||
@@ -12,6 +12,11 @@ HWUI_ENABLE_OPENGL_VALIDATION := true
|
|||||||
hwui_src_files := \
|
hwui_src_files := \
|
||||||
font/CacheTexture.cpp \
|
font/CacheTexture.cpp \
|
||||||
font/Font.cpp \
|
font/Font.cpp \
|
||||||
|
hwui/Canvas.cpp \
|
||||||
|
hwui/MinikinSkia.cpp \
|
||||||
|
hwui/MinikinUtils.cpp \
|
||||||
|
hwui/PaintImpl.cpp \
|
||||||
|
hwui/TypefaceImpl.cpp \
|
||||||
renderstate/Blend.cpp \
|
renderstate/Blend.cpp \
|
||||||
renderstate/MeshState.cpp \
|
renderstate/MeshState.cpp \
|
||||||
renderstate/OffscreenBufferPool.cpp \
|
renderstate/OffscreenBufferPool.cpp \
|
||||||
@@ -41,7 +46,6 @@ hwui_src_files := \
|
|||||||
AnimatorManager.cpp \
|
AnimatorManager.cpp \
|
||||||
AssetAtlas.cpp \
|
AssetAtlas.cpp \
|
||||||
Caches.cpp \
|
Caches.cpp \
|
||||||
Canvas.cpp \
|
|
||||||
CanvasState.cpp \
|
CanvasState.cpp \
|
||||||
ClipArea.cpp \
|
ClipArea.cpp \
|
||||||
DamageAccumulator.cpp \
|
DamageAccumulator.cpp \
|
||||||
@@ -143,7 +147,9 @@ endef
|
|||||||
|
|
||||||
hwui_c_includes += \
|
hwui_c_includes += \
|
||||||
external/skia/include/private \
|
external/skia/include/private \
|
||||||
external/skia/src/core
|
external/skia/src/core \
|
||||||
|
external/harfbuzz_ng/src \
|
||||||
|
external/freetype/include
|
||||||
|
|
||||||
ifneq (false,$(ANDROID_ENABLE_RENDERSCRIPT))
|
ifneq (false,$(ANDROID_ENABLE_RENDERSCRIPT))
|
||||||
hwui_cflags += -DANDROID_ENABLE_RENDERSCRIPT
|
hwui_cflags += -DANDROID_ENABLE_RENDERSCRIPT
|
||||||
|
|||||||
@@ -1,66 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2015 The Android Open Source Project
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "Canvas.h"
|
|
||||||
|
|
||||||
#include "DisplayListCanvas.h"
|
|
||||||
#include "RecordingCanvas.h"
|
|
||||||
#include <SkDrawFilter.h>
|
|
||||||
|
|
||||||
namespace android {
|
|
||||||
|
|
||||||
Canvas* Canvas::create_recording_canvas(int width, int height) {
|
|
||||||
#if HWUI_NEW_OPS
|
|
||||||
return new uirenderer::RecordingCanvas(width, height);
|
|
||||||
#else
|
|
||||||
return new uirenderer::DisplayListCanvas(width, height);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
void Canvas::drawTextDecorations(float x, float y, float length, const SkPaint& paint) {
|
|
||||||
uint32_t flags;
|
|
||||||
SkDrawFilter* drawFilter = getDrawFilter();
|
|
||||||
if (drawFilter) {
|
|
||||||
SkPaint paintCopy(paint);
|
|
||||||
drawFilter->filter(&paintCopy, SkDrawFilter::kText_Type);
|
|
||||||
flags = paintCopy.getFlags();
|
|
||||||
} else {
|
|
||||||
flags = paint.getFlags();
|
|
||||||
}
|
|
||||||
if (flags & (SkPaint::kUnderlineText_Flag | SkPaint::kStrikeThruText_Flag)) {
|
|
||||||
// Same values used by Skia
|
|
||||||
const float kStdStrikeThru_Offset = (-6.0f / 21.0f);
|
|
||||||
const float kStdUnderline_Offset = (1.0f / 9.0f);
|
|
||||||
const float kStdUnderline_Thickness = (1.0f / 18.0f);
|
|
||||||
|
|
||||||
SkScalar left = x;
|
|
||||||
SkScalar right = x + length;
|
|
||||||
float textSize = paint.getTextSize();
|
|
||||||
float strokeWidth = fmax(textSize * kStdUnderline_Thickness, 1.0f);
|
|
||||||
if (flags & SkPaint::kUnderlineText_Flag) {
|
|
||||||
SkScalar top = y + textSize * kStdUnderline_Offset - 0.5f * strokeWidth;
|
|
||||||
SkScalar bottom = y + textSize * kStdUnderline_Offset + 0.5f * strokeWidth;
|
|
||||||
drawRect(left, top, right, bottom, paint);
|
|
||||||
}
|
|
||||||
if (flags & SkPaint::kStrikeThruText_Flag) {
|
|
||||||
SkScalar top = y + textSize * kStdStrikeThru_Offset - 0.5f * strokeWidth;
|
|
||||||
SkScalar bottom = y + textSize * kStdStrikeThru_Offset + 0.5f * strokeWidth;
|
|
||||||
drawRect(left, top, right, bottom, paint);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace android
|
|
||||||
@@ -14,8 +14,8 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "Canvas.h"
|
|
||||||
#include "CanvasState.h"
|
#include "CanvasState.h"
|
||||||
|
#include "hwui/Canvas.h"
|
||||||
#include "utils/MathUtils.h"
|
#include "utils/MathUtils.h"
|
||||||
|
|
||||||
namespace android {
|
namespace android {
|
||||||
|
|||||||
@@ -418,7 +418,7 @@ void DisplayListCanvas::drawVectorDrawable(VectorDrawableRoot* tree) {
|
|||||||
addDrawOp(new (alloc()) DrawVectorDrawableOp(tree));
|
addDrawOp(new (alloc()) DrawVectorDrawableOp(tree));
|
||||||
}
|
}
|
||||||
|
|
||||||
void DisplayListCanvas::drawTextOnPath(const uint16_t* glyphs, int count,
|
void DisplayListCanvas::drawGlyphsOnPath(const uint16_t* glyphs, int count,
|
||||||
const SkPath& path, float hOffset, float vOffset, const SkPaint& paint) {
|
const SkPath& path, float hOffset, float vOffset, const SkPaint& paint) {
|
||||||
if (!glyphs || count <= 0) return;
|
if (!glyphs || count <= 0) return;
|
||||||
|
|
||||||
@@ -429,7 +429,7 @@ void DisplayListCanvas::drawTextOnPath(const uint16_t* glyphs, int count,
|
|||||||
addDrawOp(op);
|
addDrawOp(op);
|
||||||
}
|
}
|
||||||
|
|
||||||
void DisplayListCanvas::drawText(const uint16_t* glyphs, const float* positions,
|
void DisplayListCanvas::drawGlyphs(const uint16_t* glyphs, const float* positions,
|
||||||
int count, const SkPaint& paint, float x, float y,
|
int count, const SkPaint& paint, float x, float y,
|
||||||
float boundsLeft, float boundsTop, float boundsRight, float boundsBottom,
|
float boundsLeft, float boundsTop, float boundsRight, float boundsBottom,
|
||||||
float totalAdvance) {
|
float totalAdvance) {
|
||||||
|
|||||||
@@ -17,12 +17,12 @@
|
|||||||
#ifndef ANDROID_HWUI_DISPLAY_LIST_RENDERER_H
|
#ifndef ANDROID_HWUI_DISPLAY_LIST_RENDERER_H
|
||||||
#define ANDROID_HWUI_DISPLAY_LIST_RENDERER_H
|
#define ANDROID_HWUI_DISPLAY_LIST_RENDERER_H
|
||||||
|
|
||||||
#include "Canvas.h"
|
|
||||||
#include "CanvasState.h"
|
#include "CanvasState.h"
|
||||||
#include "DisplayList.h"
|
#include "DisplayList.h"
|
||||||
#include "RenderNode.h"
|
#include "RenderNode.h"
|
||||||
#include "ResourceCache.h"
|
#include "ResourceCache.h"
|
||||||
#include "SkiaCanvasProxy.h"
|
#include "SkiaCanvasProxy.h"
|
||||||
|
#include "hwui/Canvas.h"
|
||||||
#include "utils/Macros.h"
|
#include "utils/Macros.h"
|
||||||
|
|
||||||
#include <SkDrawFilter.h>
|
#include <SkDrawFilter.h>
|
||||||
@@ -209,10 +209,10 @@ public:
|
|||||||
virtual void drawVectorDrawable(VectorDrawableRoot* tree) override;
|
virtual void drawVectorDrawable(VectorDrawableRoot* tree) override;
|
||||||
|
|
||||||
// Text
|
// Text
|
||||||
virtual void drawText(const uint16_t* glyphs, const float* positions, int count,
|
virtual void drawGlyphs(const uint16_t* glyphs, const float* positions, int count,
|
||||||
const SkPaint& paint, float x, float y, float boundsLeft, float boundsTop,
|
const SkPaint& paint, float x, float y, float boundsLeft, float boundsTop,
|
||||||
float boundsRight, float boundsBottom, float totalAdvance) override;
|
float boundsRight, float boundsBottom, float totalAdvance) override;
|
||||||
virtual void drawTextOnPath(const uint16_t* glyphs, int count, const SkPath& path,
|
virtual void drawGlyphsOnPath(const uint16_t* glyphs, int count, const SkPath& path,
|
||||||
float hOffset, float vOffset, const SkPaint& paint) override;
|
float hOffset, float vOffset, const SkPaint& paint) override;
|
||||||
virtual bool drawTextAbsolutePos() const override { return false; }
|
virtual bool drawTextAbsolutePos() const override { return false; }
|
||||||
|
|
||||||
|
|||||||
@@ -16,11 +16,11 @@
|
|||||||
|
|
||||||
#include "FrameBuilder.h"
|
#include "FrameBuilder.h"
|
||||||
|
|
||||||
#include "Canvas.h"
|
|
||||||
#include "LayerUpdateQueue.h"
|
#include "LayerUpdateQueue.h"
|
||||||
#include "RenderNode.h"
|
#include "RenderNode.h"
|
||||||
#include "VectorDrawable.h"
|
#include "VectorDrawable.h"
|
||||||
#include "renderstate/OffscreenBufferPool.h"
|
#include "renderstate/OffscreenBufferPool.h"
|
||||||
|
#include "hwui/Canvas.h"
|
||||||
#include "utils/FatVector.h"
|
#include "utils/FatVector.h"
|
||||||
#include "utils/PaintUtils.h"
|
#include "utils/PaintUtils.h"
|
||||||
#include "utils/TraceUtils.h"
|
#include "utils/TraceUtils.h"
|
||||||
|
|||||||
@@ -17,7 +17,6 @@
|
|||||||
#include <GpuMemoryTracker.h>
|
#include <GpuMemoryTracker.h>
|
||||||
#include "OpenGLRenderer.h"
|
#include "OpenGLRenderer.h"
|
||||||
|
|
||||||
#include "Canvas.h"
|
|
||||||
#include "DeferredDisplayList.h"
|
#include "DeferredDisplayList.h"
|
||||||
#include "GammaFontRenderer.h"
|
#include "GammaFontRenderer.h"
|
||||||
#include "Glop.h"
|
#include "Glop.h"
|
||||||
@@ -32,6 +31,7 @@
|
|||||||
#include "SkiaShader.h"
|
#include "SkiaShader.h"
|
||||||
#include "Vector.h"
|
#include "Vector.h"
|
||||||
#include "VertexBuffer.h"
|
#include "VertexBuffer.h"
|
||||||
|
#include "hwui/Canvas.h"
|
||||||
#include "utils/GLUtils.h"
|
#include "utils/GLUtils.h"
|
||||||
#include "utils/PaintUtils.h"
|
#include "utils/PaintUtils.h"
|
||||||
#include "utils/TraceUtils.h"
|
#include "utils/TraceUtils.h"
|
||||||
|
|||||||
@@ -514,7 +514,7 @@ void RecordingCanvas::drawNinePatch(const SkBitmap& bitmap, const android::Res_p
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Text
|
// Text
|
||||||
void RecordingCanvas::drawText(const uint16_t* glyphs, const float* positions, int glyphCount,
|
void RecordingCanvas::drawGlyphs(const uint16_t* glyphs, const float* positions, int glyphCount,
|
||||||
const SkPaint& paint, float x, float y, float boundsLeft, float boundsTop,
|
const SkPaint& paint, float x, float y, float boundsLeft, float boundsTop,
|
||||||
float boundsRight, float boundsBottom, float totalAdvance) {
|
float boundsRight, float boundsBottom, float totalAdvance) {
|
||||||
if (!glyphs || !positions || glyphCount <= 0 || PaintUtils::paintWillNotDrawText(paint)) return;
|
if (!glyphs || !positions || glyphCount <= 0 || PaintUtils::paintWillNotDrawText(paint)) return;
|
||||||
@@ -530,7 +530,7 @@ void RecordingCanvas::drawText(const uint16_t* glyphs, const float* positions, i
|
|||||||
drawTextDecorations(x, y, totalAdvance, paint);
|
drawTextDecorations(x, y, totalAdvance, paint);
|
||||||
}
|
}
|
||||||
|
|
||||||
void RecordingCanvas::drawTextOnPath(const uint16_t* glyphs, int glyphCount, const SkPath& path,
|
void RecordingCanvas::drawGlyphsOnPath(const uint16_t* glyphs, int glyphCount, const SkPath& path,
|
||||||
float hOffset, float vOffset, const SkPaint& paint) {
|
float hOffset, float vOffset, const SkPaint& paint) {
|
||||||
if (!glyphs || glyphCount <= 0 || PaintUtils::paintWillNotDrawText(paint)) return;
|
if (!glyphs || glyphCount <= 0 || PaintUtils::paintWillNotDrawText(paint)) return;
|
||||||
glyphs = refBuffer<glyph_t>(glyphs, glyphCount);
|
glyphs = refBuffer<glyph_t>(glyphs, glyphCount);
|
||||||
|
|||||||
@@ -17,12 +17,12 @@
|
|||||||
#ifndef ANDROID_HWUI_RECORDING_CANVAS_H
|
#ifndef ANDROID_HWUI_RECORDING_CANVAS_H
|
||||||
#define ANDROID_HWUI_RECORDING_CANVAS_H
|
#define ANDROID_HWUI_RECORDING_CANVAS_H
|
||||||
|
|
||||||
#include "Canvas.h"
|
|
||||||
#include "CanvasState.h"
|
#include "CanvasState.h"
|
||||||
#include "DisplayList.h"
|
#include "DisplayList.h"
|
||||||
#include "ResourceCache.h"
|
#include "ResourceCache.h"
|
||||||
#include "SkiaCanvasProxy.h"
|
#include "SkiaCanvasProxy.h"
|
||||||
#include "Snapshot.h"
|
#include "Snapshot.h"
|
||||||
|
#include "hwui/Canvas.h"
|
||||||
#include "utils/LinearAllocator.h"
|
#include "utils/LinearAllocator.h"
|
||||||
#include "utils/Macros.h"
|
#include "utils/Macros.h"
|
||||||
#include "utils/NinePatch.h"
|
#include "utils/NinePatch.h"
|
||||||
@@ -191,10 +191,10 @@ public:
|
|||||||
const SkPaint* paint) override;
|
const SkPaint* paint) override;
|
||||||
|
|
||||||
// Text
|
// Text
|
||||||
virtual void drawText(const uint16_t* glyphs, const float* positions, int glyphCount,
|
virtual void drawGlyphs(const uint16_t* glyphs, const float* positions, int glyphCount,
|
||||||
const SkPaint& paint, float x, float y, float boundsLeft, float boundsTop,
|
const SkPaint& paint, float x, float y, float boundsLeft, float boundsTop,
|
||||||
float boundsRight, float boundsBottom, float totalAdvance) override;
|
float boundsRight, float boundsBottom, float totalAdvance) override;
|
||||||
virtual void drawTextOnPath(const uint16_t* glyphs, int glyphCount, const SkPath& path,
|
virtual void drawGlyphsOnPath(const uint16_t* glyphs, int glyphCount, const SkPath& path,
|
||||||
float hOffset, float vOffset, const SkPaint& paint) override;
|
float hOffset, float vOffset, const SkPaint& paint) override;
|
||||||
virtual bool drawTextAbsolutePos() const override { return false; }
|
virtual bool drawTextAbsolutePos() const override { return false; }
|
||||||
|
|
||||||
|
|||||||
@@ -23,9 +23,9 @@
|
|||||||
#include <SkPath.h>
|
#include <SkPath.h>
|
||||||
#include <SkPathOps.h>
|
#include <SkPathOps.h>
|
||||||
|
|
||||||
#include "Canvas.h"
|
|
||||||
#include "Matrix.h"
|
#include "Matrix.h"
|
||||||
#include "OpenGLRenderer.h"
|
#include "OpenGLRenderer.h"
|
||||||
|
#include "hwui/Canvas.h"
|
||||||
#include "utils/MathUtils.h"
|
#include "utils/MathUtils.h"
|
||||||
|
|
||||||
namespace android {
|
namespace android {
|
||||||
|
|||||||
@@ -14,10 +14,10 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "Canvas.h"
|
|
||||||
#include "CanvasProperty.h"
|
#include "CanvasProperty.h"
|
||||||
#include "Layer.h"
|
#include "Layer.h"
|
||||||
#include "RenderNode.h"
|
#include "RenderNode.h"
|
||||||
|
#include "hwui/Canvas.h"
|
||||||
|
|
||||||
#include <SkCanvas.h>
|
#include <SkCanvas.h>
|
||||||
#include <SkClipStack.h>
|
#include <SkClipStack.h>
|
||||||
@@ -147,11 +147,11 @@ public:
|
|||||||
float dstLeft, float dstTop, float dstRight, float dstBottom,
|
float dstLeft, float dstTop, float dstRight, float dstBottom,
|
||||||
const SkPaint* paint) override;
|
const SkPaint* paint) override;
|
||||||
|
|
||||||
virtual void drawText(const uint16_t* text, const float* positions, int count,
|
virtual void drawGlyphs(const uint16_t* text, const float* positions, int count,
|
||||||
const SkPaint& paint, float x, float y,
|
const SkPaint& paint, float x, float y,
|
||||||
float boundsLeft, float boundsTop, float boundsRight, float boundsBottom,
|
float boundsLeft, float boundsTop, float boundsRight, float boundsBottom,
|
||||||
float totalAdvance) override;
|
float totalAdvance) override;
|
||||||
virtual void drawTextOnPath(const uint16_t* glyphs, int count, const SkPath& path,
|
virtual void drawGlyphsOnPath(const uint16_t* glyphs, int count, const SkPath& path,
|
||||||
float hOffset, float vOffset, const SkPaint& paint) override;
|
float hOffset, float vOffset, const SkPaint& paint) override;
|
||||||
|
|
||||||
virtual bool drawTextAbsolutePos() const override { return true; }
|
virtual bool drawTextAbsolutePos() const override { return true; }
|
||||||
@@ -757,7 +757,7 @@ void SkiaCanvas::drawVectorDrawable(VectorDrawableRoot* vectorDrawable) {
|
|||||||
// Canvas draw operations: Text
|
// Canvas draw operations: Text
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
void SkiaCanvas::drawText(const uint16_t* text, const float* positions, int count,
|
void SkiaCanvas::drawGlyphs(const uint16_t* text, const float* positions, int count,
|
||||||
const SkPaint& paint, float x, float y,
|
const SkPaint& paint, float x, float y,
|
||||||
float boundsLeft, float boundsTop, float boundsRight, float boundsBottom,
|
float boundsLeft, float boundsTop, float boundsRight, float boundsBottom,
|
||||||
float totalAdvance) {
|
float totalAdvance) {
|
||||||
@@ -772,7 +772,7 @@ void SkiaCanvas::drawText(const uint16_t* text, const float* positions, int coun
|
|||||||
drawTextDecorations(x, y, totalAdvance, paint);
|
drawTextDecorations(x, y, totalAdvance, paint);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SkiaCanvas::drawTextOnPath(const uint16_t* glyphs, int count, const SkPath& path,
|
void SkiaCanvas::drawGlyphsOnPath(const uint16_t* glyphs, int count, const SkPath& path,
|
||||||
float hOffset, float vOffset, const SkPaint& paint) {
|
float hOffset, float vOffset, const SkPaint& paint) {
|
||||||
mCanvas->drawTextOnPathHV(glyphs, count << 1, path, hOffset, vOffset, paint);
|
mCanvas->drawTextOnPathHV(glyphs, count << 1, path, hOffset, vOffset, paint);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -290,7 +290,7 @@ void SkiaCanvasProxy::onDrawText(const void* text, size_t byteLength, SkScalar x
|
|||||||
}
|
}
|
||||||
|
|
||||||
static_assert(sizeof(SkPoint) == sizeof(float)*2, "SkPoint is no longer two floats");
|
static_assert(sizeof(SkPoint) == sizeof(float)*2, "SkPoint is no longer two floats");
|
||||||
mCanvas->drawText(glyphs.glyphIDs, &pointStorage[0].fX, glyphs.count, glyphs.paint,
|
mCanvas->drawGlyphs(glyphs.glyphIDs, &pointStorage[0].fX, glyphs.count, glyphs.paint,
|
||||||
x, y, bounds.fLeft, bounds.fTop, bounds.fRight, bounds.fBottom, 0);
|
x, y, bounds.fLeft, bounds.fTop, bounds.fRight, bounds.fBottom, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -326,7 +326,7 @@ void SkiaCanvasProxy::onDrawPosText(const void* text, size_t byteLength, const S
|
|||||||
bounds.offset(x, y);
|
bounds.offset(x, y);
|
||||||
|
|
||||||
static_assert(sizeof(SkPoint) == sizeof(float)*2, "SkPoint is no longer two floats");
|
static_assert(sizeof(SkPoint) == sizeof(float)*2, "SkPoint is no longer two floats");
|
||||||
mCanvas->drawText(glyphs.glyphIDs, &posArray[0].fX, glyphs.count, glyphs.paint, x, y,
|
mCanvas->drawGlyphs(glyphs.glyphIDs, &posArray[0].fX, glyphs.count, glyphs.paint, x, y,
|
||||||
bounds.fLeft, bounds.fTop, bounds.fRight, bounds.fBottom, 0);
|
bounds.fLeft, bounds.fTop, bounds.fRight, bounds.fBottom, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -344,7 +344,7 @@ void SkiaCanvasProxy::onDrawTextOnPath(const void* text, size_t byteLength, cons
|
|||||||
const SkMatrix* matrix, const SkPaint& origPaint) {
|
const SkMatrix* matrix, const SkPaint& origPaint) {
|
||||||
// convert to glyphIDs if necessary
|
// convert to glyphIDs if necessary
|
||||||
GlyphIDConverter glyphs(text, byteLength, origPaint);
|
GlyphIDConverter glyphs(text, byteLength, origPaint);
|
||||||
mCanvas->drawTextOnPath(glyphs.glyphIDs, glyphs.count, path, 0, 0, glyphs.paint);
|
mCanvas->drawGlyphsOnPath(glyphs.glyphIDs, glyphs.count, path, 0, 0, glyphs.paint);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SkiaCanvasProxy::onDrawTextBlob(const SkTextBlob* blob, SkScalar x, SkScalar y,
|
void SkiaCanvasProxy::onDrawTextBlob(const SkTextBlob* blob, SkScalar x, SkScalar y,
|
||||||
|
|||||||
@@ -20,7 +20,7 @@
|
|||||||
#include <cutils/compiler.h>
|
#include <cutils/compiler.h>
|
||||||
#include <SkCanvas.h>
|
#include <SkCanvas.h>
|
||||||
|
|
||||||
#include "Canvas.h"
|
#include "hwui/Canvas.h"
|
||||||
|
|
||||||
namespace android {
|
namespace android {
|
||||||
namespace uirenderer {
|
namespace uirenderer {
|
||||||
|
|||||||
@@ -16,7 +16,7 @@
|
|||||||
|
|
||||||
#include "Snapshot.h"
|
#include "Snapshot.h"
|
||||||
|
|
||||||
#include "Canvas.h"
|
#include "hwui/Canvas.h"
|
||||||
|
|
||||||
namespace android {
|
namespace android {
|
||||||
namespace uirenderer {
|
namespace uirenderer {
|
||||||
|
|||||||
@@ -17,7 +17,7 @@
|
|||||||
#ifndef ANDROID_HWUI_VPATH_H
|
#ifndef ANDROID_HWUI_VPATH_H
|
||||||
#define ANDROID_HWUI_VPATH_H
|
#define ANDROID_HWUI_VPATH_H
|
||||||
|
|
||||||
#include "Canvas.h"
|
#include "hwui/Canvas.h"
|
||||||
|
|
||||||
#include <SkBitmap.h>
|
#include <SkBitmap.h>
|
||||||
#include <SkColor.h>
|
#include <SkColor.h>
|
||||||
|
|||||||
220
libs/hwui/hwui/Canvas.cpp
Normal file
220
libs/hwui/hwui/Canvas.cpp
Normal file
@@ -0,0 +1,220 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2015 The Android Open Source Project
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "Canvas.h"
|
||||||
|
|
||||||
|
#include "DisplayListCanvas.h"
|
||||||
|
#include "RecordingCanvas.h"
|
||||||
|
#include "MinikinUtils.h"
|
||||||
|
#include "Paint.h"
|
||||||
|
#include "TypefaceImpl.h"
|
||||||
|
|
||||||
|
#include <SkDrawFilter.h>
|
||||||
|
|
||||||
|
namespace android {
|
||||||
|
|
||||||
|
Canvas* Canvas::create_recording_canvas(int width, int height) {
|
||||||
|
#if HWUI_NEW_OPS
|
||||||
|
return new uirenderer::RecordingCanvas(width, height);
|
||||||
|
#else
|
||||||
|
return new uirenderer::DisplayListCanvas(width, height);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void Canvas::drawTextDecorations(float x, float y, float length, const SkPaint& paint) {
|
||||||
|
uint32_t flags;
|
||||||
|
SkDrawFilter* drawFilter = getDrawFilter();
|
||||||
|
if (drawFilter) {
|
||||||
|
SkPaint paintCopy(paint);
|
||||||
|
drawFilter->filter(&paintCopy, SkDrawFilter::kText_Type);
|
||||||
|
flags = paintCopy.getFlags();
|
||||||
|
} else {
|
||||||
|
flags = paint.getFlags();
|
||||||
|
}
|
||||||
|
if (flags & (SkPaint::kUnderlineText_Flag | SkPaint::kStrikeThruText_Flag)) {
|
||||||
|
// Same values used by Skia
|
||||||
|
const float kStdStrikeThru_Offset = (-6.0f / 21.0f);
|
||||||
|
const float kStdUnderline_Offset = (1.0f / 9.0f);
|
||||||
|
const float kStdUnderline_Thickness = (1.0f / 18.0f);
|
||||||
|
|
||||||
|
SkScalar left = x;
|
||||||
|
SkScalar right = x + length;
|
||||||
|
float textSize = paint.getTextSize();
|
||||||
|
float strokeWidth = fmax(textSize * kStdUnderline_Thickness, 1.0f);
|
||||||
|
if (flags & SkPaint::kUnderlineText_Flag) {
|
||||||
|
SkScalar top = y + textSize * kStdUnderline_Offset - 0.5f * strokeWidth;
|
||||||
|
SkScalar bottom = y + textSize * kStdUnderline_Offset + 0.5f * strokeWidth;
|
||||||
|
drawRect(left, top, right, bottom, paint);
|
||||||
|
}
|
||||||
|
if (flags & SkPaint::kStrikeThruText_Flag) {
|
||||||
|
SkScalar top = y + textSize * kStdStrikeThru_Offset - 0.5f * strokeWidth;
|
||||||
|
SkScalar bottom = y + textSize * kStdStrikeThru_Offset + 0.5f * strokeWidth;
|
||||||
|
drawRect(left, top, right, bottom, paint);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void simplifyPaint(int color, SkPaint* paint) {
|
||||||
|
paint->setColor(color);
|
||||||
|
paint->setShader(nullptr);
|
||||||
|
paint->setColorFilter(nullptr);
|
||||||
|
paint->setLooper(nullptr);
|
||||||
|
paint->setStrokeWidth(4 + 0.04 * paint->getTextSize());
|
||||||
|
paint->setStrokeJoin(SkPaint::kRound_Join);
|
||||||
|
paint->setLooper(nullptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
class DrawTextFunctor {
|
||||||
|
public:
|
||||||
|
DrawTextFunctor(const Layout& layout, Canvas* canvas, uint16_t* glyphs, float* pos,
|
||||||
|
const SkPaint& paint, float x, float y, MinikinRect& bounds, float totalAdvance)
|
||||||
|
: layout(layout)
|
||||||
|
, canvas(canvas)
|
||||||
|
, glyphs(glyphs)
|
||||||
|
, pos(pos)
|
||||||
|
, paint(paint)
|
||||||
|
, x(x)
|
||||||
|
, y(y)
|
||||||
|
, bounds(bounds)
|
||||||
|
, totalAdvance(totalAdvance) {
|
||||||
|
}
|
||||||
|
|
||||||
|
void operator()(size_t start, size_t end) {
|
||||||
|
if (canvas->drawTextAbsolutePos()) {
|
||||||
|
for (size_t i = start; i < end; i++) {
|
||||||
|
glyphs[i] = layout.getGlyphId(i);
|
||||||
|
pos[2 * i] = x + layout.getX(i);
|
||||||
|
pos[2 * i + 1] = y + layout.getY(i);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
for (size_t i = start; i < end; i++) {
|
||||||
|
glyphs[i] = layout.getGlyphId(i);
|
||||||
|
pos[2 * i] = layout.getX(i);
|
||||||
|
pos[2 * i + 1] = layout.getY(i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t glyphCount = end - start;
|
||||||
|
|
||||||
|
if (CC_UNLIKELY(canvas->isHighContrastText() && paint.getAlpha() != 0)) {
|
||||||
|
// high contrast draw path
|
||||||
|
int color = paint.getColor();
|
||||||
|
int channelSum = SkColorGetR(color) + SkColorGetG(color) + SkColorGetB(color);
|
||||||
|
bool darken = channelSum < (128 * 3);
|
||||||
|
|
||||||
|
// outline
|
||||||
|
SkPaint outlinePaint(paint);
|
||||||
|
simplifyPaint(darken ? SK_ColorWHITE : SK_ColorBLACK, &outlinePaint);
|
||||||
|
outlinePaint.setStyle(SkPaint::kStrokeAndFill_Style);
|
||||||
|
canvas->drawGlyphs(glyphs + start, pos + (2 * start), glyphCount, outlinePaint, x, y,
|
||||||
|
bounds.mLeft, bounds.mTop, bounds.mRight, bounds.mBottom, totalAdvance);
|
||||||
|
|
||||||
|
// inner
|
||||||
|
SkPaint innerPaint(paint);
|
||||||
|
simplifyPaint(darken ? SK_ColorBLACK : SK_ColorWHITE, &innerPaint);
|
||||||
|
innerPaint.setStyle(SkPaint::kFill_Style);
|
||||||
|
canvas->drawGlyphs(glyphs + start, pos + (2 * start), glyphCount, innerPaint, x, y,
|
||||||
|
bounds.mLeft, bounds.mTop, bounds.mRight, bounds.mBottom, totalAdvance);
|
||||||
|
} else {
|
||||||
|
// standard draw path
|
||||||
|
canvas->drawGlyphs(glyphs + start, pos + (2 * start), glyphCount, paint, x, y,
|
||||||
|
bounds.mLeft, bounds.mTop, bounds.mRight, bounds.mBottom, totalAdvance);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
private:
|
||||||
|
const Layout& layout;
|
||||||
|
Canvas* canvas;
|
||||||
|
uint16_t* glyphs;
|
||||||
|
float* pos;
|
||||||
|
const SkPaint& paint;
|
||||||
|
float x;
|
||||||
|
float y;
|
||||||
|
MinikinRect& bounds;
|
||||||
|
float totalAdvance;
|
||||||
|
};
|
||||||
|
|
||||||
|
void Canvas::drawText(const uint16_t* text, int start, int count, int contextCount,
|
||||||
|
float x, float y, int bidiFlags, const Paint& origPaint, TypefaceImpl* typeface) {
|
||||||
|
// minikin may modify the original paint
|
||||||
|
Paint paint(origPaint);
|
||||||
|
|
||||||
|
Layout layout;
|
||||||
|
MinikinUtils::doLayout(&layout, &paint, bidiFlags, typeface, text, start, count, contextCount);
|
||||||
|
|
||||||
|
size_t nGlyphs = layout.nGlyphs();
|
||||||
|
std::unique_ptr<uint16_t[]> glyphs(new uint16_t[nGlyphs]);
|
||||||
|
std::unique_ptr<float[]> pos(new float[nGlyphs * 2]);
|
||||||
|
|
||||||
|
x += MinikinUtils::xOffsetForTextAlign(&paint, layout);
|
||||||
|
|
||||||
|
MinikinRect bounds;
|
||||||
|
layout.getBounds(&bounds);
|
||||||
|
if (!drawTextAbsolutePos()) {
|
||||||
|
bounds.offset(x, y);
|
||||||
|
}
|
||||||
|
|
||||||
|
DrawTextFunctor f(layout, this, glyphs.get(), pos.get(),
|
||||||
|
paint, x, y, bounds, layout.getAdvance());
|
||||||
|
MinikinUtils::forFontRun(layout, &paint, f);
|
||||||
|
}
|
||||||
|
|
||||||
|
class DrawTextOnPathFunctor {
|
||||||
|
public:
|
||||||
|
DrawTextOnPathFunctor(const Layout& layout, Canvas* canvas, float hOffset,
|
||||||
|
float vOffset, const Paint& paint, const SkPath& path)
|
||||||
|
: layout(layout)
|
||||||
|
, canvas(canvas)
|
||||||
|
, hOffset(hOffset)
|
||||||
|
, vOffset(vOffset)
|
||||||
|
, paint(paint)
|
||||||
|
, path(path) {
|
||||||
|
}
|
||||||
|
|
||||||
|
void operator()(size_t start, size_t end) {
|
||||||
|
uint16_t glyphs[1];
|
||||||
|
for (size_t i = start; i < end; i++) {
|
||||||
|
glyphs[0] = layout.getGlyphId(i);
|
||||||
|
float x = hOffset + layout.getX(i);
|
||||||
|
float y = vOffset + layout.getY(i);
|
||||||
|
canvas->drawGlyphsOnPath(glyphs, 1, path, x, y, paint);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
private:
|
||||||
|
const Layout& layout;
|
||||||
|
Canvas* canvas;
|
||||||
|
float hOffset;
|
||||||
|
float vOffset;
|
||||||
|
const Paint& paint;
|
||||||
|
const SkPath& path;
|
||||||
|
};
|
||||||
|
|
||||||
|
void Canvas::drawTextOnPath(const uint16_t* text, int count, int bidiFlags, const SkPath& path,
|
||||||
|
float hOffset, float vOffset, const Paint& paint, TypefaceImpl* typeface) {
|
||||||
|
Paint paintCopy(paint);
|
||||||
|
Layout layout;
|
||||||
|
MinikinUtils::doLayout(&layout, &paintCopy, bidiFlags, typeface, text, 0, count, count);
|
||||||
|
hOffset += MinikinUtils::hOffsetForTextAlign(&paintCopy, layout, path);
|
||||||
|
|
||||||
|
// Set align to left for drawing, as we don't want individual
|
||||||
|
// glyphs centered or right-aligned; the offset above takes
|
||||||
|
// care of all alignment.
|
||||||
|
paintCopy.setTextAlign(Paint::kLeft_Align);
|
||||||
|
|
||||||
|
DrawTextOnPathFunctor f(layout, this, hOffset, vOffset, paintCopy, path);
|
||||||
|
MinikinUtils::forFontRun(layout, &paintCopy, f);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace android
|
||||||
@@ -59,6 +59,9 @@ class Tree;
|
|||||||
};
|
};
|
||||||
typedef uirenderer::VectorDrawable::Tree VectorDrawableRoot;
|
typedef uirenderer::VectorDrawable::Tree VectorDrawableRoot;
|
||||||
|
|
||||||
|
class Paint;
|
||||||
|
struct TypefaceImpl;
|
||||||
|
|
||||||
class ANDROID_API Canvas {
|
class ANDROID_API Canvas {
|
||||||
public:
|
public:
|
||||||
virtual ~Canvas() {};
|
virtual ~Canvas() {};
|
||||||
@@ -207,12 +210,12 @@ public:
|
|||||||
* drawText: count is of glyphs
|
* drawText: count is of glyphs
|
||||||
* totalAdvance: used to define width of text decorations (underlines, strikethroughs).
|
* totalAdvance: used to define width of text decorations (underlines, strikethroughs).
|
||||||
*/
|
*/
|
||||||
virtual void drawText(const uint16_t* glyphs, const float* positions, int count,
|
virtual void drawGlyphs(const uint16_t* glyphs, const float* positions, int count,
|
||||||
const SkPaint& paint, float x, float y,
|
const SkPaint& paint, float x, float y,
|
||||||
float boundsLeft, float boundsTop, float boundsRight, float boundsBottom,
|
float boundsLeft, float boundsTop, float boundsRight, float boundsBottom,
|
||||||
float totalAdvance) = 0;
|
float totalAdvance) = 0;
|
||||||
/** drawTextOnPath: count is of glyphs */
|
/** drawTextOnPath: count is of glyphs */
|
||||||
virtual void drawTextOnPath(const uint16_t* glyphs, int count, const SkPath& path,
|
virtual void drawGlyphsOnPath(const uint16_t* glyphs, int count, const SkPath& path,
|
||||||
float hOffset, float vOffset, const SkPaint& paint) = 0;
|
float hOffset, float vOffset, const SkPaint& paint) = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -229,6 +232,16 @@ public:
|
|||||||
*/
|
*/
|
||||||
virtual void drawVectorDrawable(VectorDrawableRoot* tree);
|
virtual void drawVectorDrawable(VectorDrawableRoot* tree);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Converts utf16 text to glyphs, calculating position and boundary,
|
||||||
|
* and delegating the final draw to virtual drawGlyphs method.
|
||||||
|
*/
|
||||||
|
void drawText(const uint16_t* text, int start, int count, int contextCount,
|
||||||
|
float x, float y, int bidiFlags, const Paint& origPaint, TypefaceImpl* typeface);
|
||||||
|
|
||||||
|
void drawTextOnPath(const uint16_t* text, int count, int bidiFlags, const SkPath& path,
|
||||||
|
float hOffset, float vOffset, const Paint& paint, TypefaceImpl* typeface);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void drawTextDecorations(float x, float y, float length, const SkPaint& paint);
|
void drawTextDecorations(float x, float y, float length, const SkPaint& paint);
|
||||||
};
|
};
|
||||||
@@ -14,14 +14,12 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <SkTypeface.h>
|
|
||||||
#include <SkPaint.h>
|
|
||||||
|
|
||||||
#define LOG_TAG "Minikin"
|
|
||||||
#include <cutils/log.h>
|
|
||||||
|
|
||||||
#include "MinikinSkia.h"
|
#include "MinikinSkia.h"
|
||||||
|
|
||||||
|
#include <SkPaint.h>
|
||||||
|
#include <SkTypeface.h>
|
||||||
|
#include <cutils/log.h>
|
||||||
|
|
||||||
namespace android {
|
namespace android {
|
||||||
|
|
||||||
MinikinFontSkia::MinikinFontSkia(SkTypeface *typeface) :
|
MinikinFontSkia::MinikinFontSkia(SkTypeface *typeface) :
|
||||||
@@ -17,11 +17,15 @@
|
|||||||
#ifndef _ANDROID_GRAPHICS_MINIKIN_SKIA_H_
|
#ifndef _ANDROID_GRAPHICS_MINIKIN_SKIA_H_
|
||||||
#define _ANDROID_GRAPHICS_MINIKIN_SKIA_H_
|
#define _ANDROID_GRAPHICS_MINIKIN_SKIA_H_
|
||||||
|
|
||||||
|
#include <cutils/compiler.h>
|
||||||
#include <minikin/MinikinFont.h>
|
#include <minikin/MinikinFont.h>
|
||||||
|
|
||||||
|
class SkPaint;
|
||||||
|
class SkTypeface;
|
||||||
|
|
||||||
namespace android {
|
namespace android {
|
||||||
|
|
||||||
class MinikinFontSkia : public MinikinFont {
|
class ANDROID_API MinikinFontSkia : public MinikinFont {
|
||||||
public:
|
public:
|
||||||
// Note: this takes ownership of the reference (will unref on dtor)
|
// Note: this takes ownership of the reference (will unref on dtor)
|
||||||
explicit MinikinFontSkia(SkTypeface *typeface);
|
explicit MinikinFontSkia(SkTypeface *typeface);
|
||||||
@@ -13,16 +13,14 @@
|
|||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
#include "MinikinUtils.h"
|
||||||
|
|
||||||
#define LOG_TAG "Minikin"
|
|
||||||
#include <cutils/log.h>
|
|
||||||
#include <string>
|
|
||||||
|
|
||||||
#include "SkPathMeasure.h"
|
|
||||||
#include "Paint.h"
|
#include "Paint.h"
|
||||||
|
#include "SkPathMeasure.h"
|
||||||
#include "TypefaceImpl.h"
|
#include "TypefaceImpl.h"
|
||||||
|
|
||||||
#include "MinikinUtils.h"
|
#include <cutils/log.h>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
namespace android {
|
namespace android {
|
||||||
|
|
||||||
@@ -24,6 +24,7 @@
|
|||||||
#ifndef _ANDROID_GRAPHICS_MINIKIN_UTILS_H_
|
#ifndef _ANDROID_GRAPHICS_MINIKIN_UTILS_H_
|
||||||
#define _ANDROID_GRAPHICS_MINIKIN_UTILS_H_
|
#define _ANDROID_GRAPHICS_MINIKIN_UTILS_H_
|
||||||
|
|
||||||
|
#include <cutils/compiler.h>
|
||||||
#include <minikin/Layout.h>
|
#include <minikin/Layout.h>
|
||||||
#include "Paint.h"
|
#include "Paint.h"
|
||||||
#include "MinikinSkia.h"
|
#include "MinikinSkia.h"
|
||||||
@@ -33,24 +34,24 @@ namespace android {
|
|||||||
|
|
||||||
class MinikinUtils {
|
class MinikinUtils {
|
||||||
public:
|
public:
|
||||||
static FontStyle prepareMinikinPaint(MinikinPaint* minikinPaint, FontCollection** pFont,
|
ANDROID_API static FontStyle prepareMinikinPaint(MinikinPaint* minikinPaint, FontCollection** pFont,
|
||||||
const Paint* paint, TypefaceImpl* typeface);
|
const Paint* paint, TypefaceImpl* typeface);
|
||||||
|
|
||||||
static void doLayout(Layout* layout, const Paint* paint, int bidiFlags,
|
ANDROID_API static void doLayout(Layout* layout, const Paint* paint, int bidiFlags,
|
||||||
TypefaceImpl* typeface, const uint16_t* buf, size_t start, size_t count,
|
TypefaceImpl* typeface, const uint16_t* buf, size_t start, size_t count,
|
||||||
size_t bufSize);
|
size_t bufSize);
|
||||||
|
|
||||||
static float measureText(const Paint* paint, int bidiFlags, TypefaceImpl* typeface,
|
ANDROID_API static float measureText(const Paint* paint, int bidiFlags, TypefaceImpl* typeface,
|
||||||
const uint16_t* buf, size_t start, size_t count, size_t bufSize, float *advances);
|
const uint16_t* buf, size_t start, size_t count, size_t bufSize, float *advances);
|
||||||
|
|
||||||
static bool hasVariationSelector(TypefaceImpl* typeface, uint32_t codepoint, uint32_t vs);
|
ANDROID_API static bool hasVariationSelector(TypefaceImpl* typeface, uint32_t codepoint, uint32_t vs);
|
||||||
|
|
||||||
static float xOffsetForTextAlign(Paint* paint, const Layout& layout);
|
ANDROID_API static float xOffsetForTextAlign(Paint* paint, const Layout& layout);
|
||||||
|
|
||||||
static float hOffsetForTextAlign(Paint* paint, const Layout& layout, const SkPath& path);
|
ANDROID_API static float hOffsetForTextAlign(Paint* paint, const Layout& layout, const SkPath& path);
|
||||||
// f is a functor of type void f(size_t start, size_t end);
|
// f is a functor of type void f(size_t start, size_t end);
|
||||||
template <typename F>
|
template <typename F>
|
||||||
static void forFontRun(const Layout& layout, Paint* paint, F& f) {
|
ANDROID_API static void forFontRun(const Layout& layout, Paint* paint, F& f) {
|
||||||
float saveSkewX = paint->getTextSkewX();
|
float saveSkewX = paint->getTextSkewX();
|
||||||
bool savefakeBold = paint->isFakeBoldText();
|
bool savefakeBold = paint->isFakeBoldText();
|
||||||
MinikinFont* curFont = NULL;
|
MinikinFont* curFont = NULL;
|
||||||
@@ -17,6 +17,8 @@
|
|||||||
#ifndef ANDROID_GRAPHICS_PAINT_H_
|
#ifndef ANDROID_GRAPHICS_PAINT_H_
|
||||||
#define ANDROID_GRAPHICS_PAINT_H_
|
#define ANDROID_GRAPHICS_PAINT_H_
|
||||||
|
|
||||||
|
#include <cutils/compiler.h>
|
||||||
|
|
||||||
#include <SkPaint.h>
|
#include <SkPaint.h>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
@@ -24,7 +26,7 @@
|
|||||||
|
|
||||||
namespace android {
|
namespace android {
|
||||||
|
|
||||||
class Paint : public SkPaint {
|
class ANDROID_API Paint : public SkPaint {
|
||||||
public:
|
public:
|
||||||
Paint();
|
Paint();
|
||||||
Paint(const Paint& paint);
|
Paint(const Paint& paint);
|
||||||
@@ -45,7 +47,7 @@ public:
|
|||||||
return mLetterSpacing;
|
return mLetterSpacing;
|
||||||
}
|
}
|
||||||
|
|
||||||
void setFontFeatureSettings(const std::string &fontFeatureSettings) {
|
void setFontFeatureSettings(const std::string& fontFeatureSettings) {
|
||||||
mFontFeatureSettings = fontFeatureSettings;
|
mFontFeatureSettings = fontFeatureSettings;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -15,10 +15,6 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include "Paint.h"
|
#include "Paint.h"
|
||||||
#include <SkPaint.h>
|
|
||||||
|
|
||||||
#define LOG_TAG "Paint"
|
|
||||||
#include <cutils/log.h>
|
|
||||||
|
|
||||||
namespace android {
|
namespace android {
|
||||||
|
|
||||||
@@ -20,21 +20,16 @@
|
|||||||
* being, that choice is hidden under the USE_MINIKIN compile-time flag.
|
* being, that choice is hidden under the USE_MINIKIN compile-time flag.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define LOG_TAG "TypefaceImpl"
|
#include "TypefaceImpl.h"
|
||||||
|
|
||||||
#include "jni.h" // for jlong, remove when being passed proper type
|
|
||||||
|
|
||||||
|
#include "MinikinSkia.h"
|
||||||
#include "SkTypeface.h"
|
#include "SkTypeface.h"
|
||||||
|
#include "SkPaint.h"
|
||||||
|
|
||||||
#include <vector>
|
|
||||||
#include <minikin/FontCollection.h>
|
#include <minikin/FontCollection.h>
|
||||||
#include <minikin/FontFamily.h>
|
#include <minikin/FontFamily.h>
|
||||||
#include <minikin/Layout.h>
|
#include <minikin/Layout.h>
|
||||||
#include "SkPaint.h"
|
#include <utils/Log.h>
|
||||||
#include "MinikinSkia.h"
|
|
||||||
|
|
||||||
#include "TypefaceImpl.h"
|
|
||||||
#include "Utils.h"
|
|
||||||
|
|
||||||
namespace android {
|
namespace android {
|
||||||
|
|
||||||
@@ -133,15 +128,10 @@ TypefaceImpl* TypefaceImpl_createWeightAlias(TypefaceImpl* src, int weight) {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
TypefaceImpl* TypefaceImpl_createFromFamilies(const jlong* families, size_t size) {
|
TypefaceImpl* TypefaceImpl_createFromFamilies(const std::vector<FontFamily*>& families) {
|
||||||
std::vector<FontFamily *>familyVec;
|
|
||||||
for (size_t i = 0; i < size; i++) {
|
|
||||||
FontFamily* family = reinterpret_cast<FontFamily*>(families[i]);
|
|
||||||
familyVec.push_back(family);
|
|
||||||
}
|
|
||||||
TypefaceImpl* result = new TypefaceImpl;
|
TypefaceImpl* result = new TypefaceImpl;
|
||||||
result->fFontCollection = new FontCollection(familyVec);
|
result->fFontCollection = new FontCollection(families);
|
||||||
if (size == 0) {
|
if (families.empty()) {
|
||||||
ALOGW("createFromFamilies creating empty collection");
|
ALOGW("createFromFamilies creating empty collection");
|
||||||
result->fSkiaStyle = SkTypeface::kNormal;
|
result->fSkiaStyle = SkTypeface::kNormal;
|
||||||
} else {
|
} else {
|
||||||
@@ -18,15 +18,15 @@
|
|||||||
#ifndef _ANDROID_GRAPHICS_TYPEFACE_IMPL_H_
|
#ifndef _ANDROID_GRAPHICS_TYPEFACE_IMPL_H_
|
||||||
#define _ANDROID_GRAPHICS_TYPEFACE_IMPL_H_
|
#define _ANDROID_GRAPHICS_TYPEFACE_IMPL_H_
|
||||||
|
|
||||||
#include "jni.h" // for jlong, eventually remove
|
|
||||||
#include "SkTypeface.h"
|
#include "SkTypeface.h"
|
||||||
#include <androidfw/AssetManager.h>
|
|
||||||
|
|
||||||
|
#include <cutils/compiler.h>
|
||||||
#include <minikin/FontCollection.h>
|
#include <minikin/FontCollection.h>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
namespace android {
|
namespace android {
|
||||||
|
|
||||||
struct TypefaceImpl {
|
struct ANDROID_API TypefaceImpl {
|
||||||
FontCollection *fFontCollection;
|
FontCollection *fFontCollection;
|
||||||
|
|
||||||
// style used for constructing and querying Typeface objects
|
// style used for constructing and querying Typeface objects
|
||||||
@@ -44,21 +44,19 @@ struct TypefaceImpl {
|
|||||||
// is just a pointer to SkTypeface, in the non-USE_MINIKIN case.
|
// is just a pointer to SkTypeface, in the non-USE_MINIKIN case.
|
||||||
// TODO: when #ifdef USE_MINIKIN is removed, move to member functions.
|
// TODO: when #ifdef USE_MINIKIN is removed, move to member functions.
|
||||||
|
|
||||||
TypefaceImpl* TypefaceImpl_resolveDefault(TypefaceImpl* src);
|
ANDROID_API TypefaceImpl* TypefaceImpl_resolveDefault(TypefaceImpl* src);
|
||||||
|
|
||||||
TypefaceImpl* TypefaceImpl_createFromTypeface(TypefaceImpl* src, SkTypeface::Style style);
|
ANDROID_API TypefaceImpl* TypefaceImpl_createFromTypeface(TypefaceImpl* src, SkTypeface::Style style);
|
||||||
|
|
||||||
TypefaceImpl* TypefaceImpl_createWeightAlias(TypefaceImpl* src, int baseweight);
|
ANDROID_API TypefaceImpl* TypefaceImpl_createWeightAlias(TypefaceImpl* src, int baseweight);
|
||||||
|
|
||||||
// When we remove the USE_MINIKIN ifdef, probably a good idea to move the casting
|
ANDROID_API TypefaceImpl* TypefaceImpl_createFromFamilies(const std::vector<FontFamily*>& families);
|
||||||
// (from jlong to FontFamily*) to the caller in Typeface.cpp.
|
|
||||||
TypefaceImpl* TypefaceImpl_createFromFamilies(const jlong* families, size_t size);
|
|
||||||
|
|
||||||
void TypefaceImpl_unref(TypefaceImpl* face);
|
ANDROID_API void TypefaceImpl_unref(TypefaceImpl* face);
|
||||||
|
|
||||||
int TypefaceImpl_getStyle(TypefaceImpl* face);
|
ANDROID_API int TypefaceImpl_getStyle(TypefaceImpl* face);
|
||||||
|
|
||||||
void TypefaceImpl_setDefault(TypefaceImpl* face);
|
ANDROID_API void TypefaceImpl_setDefault(TypefaceImpl* face);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -21,8 +21,11 @@ LOCAL_SHARED_LIBRARIES += \
|
|||||||
libskia \
|
libskia \
|
||||||
libui \
|
libui \
|
||||||
libgui \
|
libgui \
|
||||||
libprotobuf-cpp-lite
|
libprotobuf-cpp-lite \
|
||||||
|
libharfbuzz_ng \
|
||||||
|
libft2 \
|
||||||
|
libminikin
|
||||||
|
|
||||||
ifneq (false,$(ANDROID_ENABLE_RENDERSCRIPT))
|
ifneq (false,$(ANDROID_ENABLE_RENDERSCRIPT))
|
||||||
LOCAL_SHARED_LIBRARIES += libRS libRScpp
|
LOCAL_SHARED_LIBRARIES += libRS libRScpp
|
||||||
endif
|
endif
|
||||||
|
|||||||
@@ -19,7 +19,6 @@
|
|||||||
|
|
||||||
#include "AnimationContext.h"
|
#include "AnimationContext.h"
|
||||||
#include "Caches.h"
|
#include "Caches.h"
|
||||||
#include "Canvas.h"
|
|
||||||
#include "DeferredLayerUpdater.h"
|
#include "DeferredLayerUpdater.h"
|
||||||
#include "EglManager.h"
|
#include "EglManager.h"
|
||||||
#include "LayerUpdateQueue.h"
|
#include "LayerUpdateQueue.h"
|
||||||
@@ -27,6 +26,7 @@
|
|||||||
#include "OpenGLRenderer.h"
|
#include "OpenGLRenderer.h"
|
||||||
#include "Properties.h"
|
#include "Properties.h"
|
||||||
#include "RenderThread.h"
|
#include "RenderThread.h"
|
||||||
|
#include "hwui/Canvas.h"
|
||||||
#include "renderstate/RenderState.h"
|
#include "renderstate/RenderState.h"
|
||||||
#include "renderstate/Stencil.h"
|
#include "renderstate/Stencil.h"
|
||||||
#include "protos/hwui.pb.h"
|
#include "protos/hwui.pb.h"
|
||||||
|
|||||||
@@ -87,7 +87,7 @@ void TestUtils::layoutTextUnscaled(const SkPaint& paint, const char* text,
|
|||||||
*outTotalAdvance = totalAdvance;
|
*outTotalAdvance = totalAdvance;
|
||||||
}
|
}
|
||||||
|
|
||||||
void TestUtils::drawTextToCanvas(TestCanvas* canvas, const char* text,
|
void TestUtils::drawUtf8ToCanvas(TestCanvas* canvas, const char* text,
|
||||||
const SkPaint& paint, float x, float y) {
|
const SkPaint& paint, float x, float y) {
|
||||||
// drawing text requires GlyphID TextEncoding (which JNI layer would have done)
|
// drawing text requires GlyphID TextEncoding (which JNI layer would have done)
|
||||||
LOG_ALWAYS_FATAL_IF(paint.getTextEncoding() != SkPaint::kGlyphID_TextEncoding,
|
LOG_ALWAYS_FATAL_IF(paint.getTextEncoding() != SkPaint::kGlyphID_TextEncoding,
|
||||||
@@ -113,11 +113,11 @@ void TestUtils::drawTextToCanvas(TestCanvas* canvas, const char* text,
|
|||||||
// Force left alignment, since alignment offset is already baked in
|
// Force left alignment, since alignment offset is already baked in
|
||||||
SkPaint alignPaintCopy(paint);
|
SkPaint alignPaintCopy(paint);
|
||||||
alignPaintCopy.setTextAlign(SkPaint::kLeft_Align);
|
alignPaintCopy.setTextAlign(SkPaint::kLeft_Align);
|
||||||
canvas->drawText(glyphs.data(), positions.data(), glyphs.size(), alignPaintCopy, x, y,
|
canvas->drawGlyphs(glyphs.data(), positions.data(), glyphs.size(), alignPaintCopy, x, y,
|
||||||
bounds.left, bounds.top, bounds.right, bounds.bottom, totalAdvance);
|
bounds.left, bounds.top, bounds.right, bounds.bottom, totalAdvance);
|
||||||
}
|
}
|
||||||
|
|
||||||
void TestUtils::drawTextToCanvas(TestCanvas* canvas, const char* text,
|
void TestUtils::drawUtf8ToCanvas(TestCanvas* canvas, const char* text,
|
||||||
const SkPaint& paint, const SkPath& path) {
|
const SkPaint& paint, const SkPath& path) {
|
||||||
// drawing text requires GlyphID TextEncoding (which JNI layer would have done)
|
// drawing text requires GlyphID TextEncoding (which JNI layer would have done)
|
||||||
LOG_ALWAYS_FATAL_IF(paint.getTextEncoding() != SkPaint::kGlyphID_TextEncoding,
|
LOG_ALWAYS_FATAL_IF(paint.getTextEncoding() != SkPaint::kGlyphID_TextEncoding,
|
||||||
@@ -130,7 +130,7 @@ void TestUtils::drawTextToCanvas(TestCanvas* canvas, const char* text,
|
|||||||
SkUnichar unichar = SkUTF8_NextUnichar(&text);
|
SkUnichar unichar = SkUTF8_NextUnichar(&text);
|
||||||
glyphs.push_back(autoCache.getCache()->unicharToGlyph(unichar));
|
glyphs.push_back(autoCache.getCache()->unicharToGlyph(unichar));
|
||||||
}
|
}
|
||||||
canvas->drawTextOnPath(glyphs.data(), glyphs.size(), path, 0, 0, paint);
|
canvas->drawGlyphsOnPath(glyphs.data(), glyphs.size(), path, 0, 0, paint);
|
||||||
}
|
}
|
||||||
|
|
||||||
void TestUtils::TestTask::run() {
|
void TestUtils::TestTask::run() {
|
||||||
@@ -143,5 +143,13 @@ void TestUtils::TestTask::run() {
|
|||||||
renderState.onGLContextDestroyed();
|
renderState.onGLContextDestroyed();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::unique_ptr<uint16_t[]> TestUtils::utf8ToUtf16(const char* str) {
|
||||||
|
const size_t strLen = strlen(str);
|
||||||
|
const ssize_t utf16Len = utf8_to_utf16_length((uint8_t*) str, strLen);
|
||||||
|
std::unique_ptr<uint16_t[]> dst(new uint16_t[utf16Len + 1]);
|
||||||
|
utf8_to_utf16((uint8_t*) str, strLen, (char16_t*) dst.get());
|
||||||
|
return dst;
|
||||||
|
}
|
||||||
|
|
||||||
} /* namespace uirenderer */
|
} /* namespace uirenderer */
|
||||||
} /* namespace android */
|
} /* namespace android */
|
||||||
|
|||||||
@@ -207,12 +207,14 @@ public:
|
|||||||
std::vector<glyph_t>* outGlyphs, std::vector<float>* outPositions,
|
std::vector<glyph_t>* outGlyphs, std::vector<float>* outPositions,
|
||||||
float* outTotalAdvance, Rect* outBounds);
|
float* outTotalAdvance, Rect* outBounds);
|
||||||
|
|
||||||
static void drawTextToCanvas(TestCanvas* canvas, const char* text,
|
static void drawUtf8ToCanvas(TestCanvas* canvas, const char* text,
|
||||||
const SkPaint& paint, float x, float y);
|
const SkPaint& paint, float x, float y);
|
||||||
|
|
||||||
static void drawTextToCanvas(TestCanvas* canvas, const char* text,
|
static void drawUtf8ToCanvas(TestCanvas* canvas, const char* text,
|
||||||
const SkPaint& paint, const SkPath& path);
|
const SkPaint& paint, const SkPath& path);
|
||||||
|
|
||||||
|
static std::unique_ptr<uint16_t[]> utf8ToUtf16(const char* str);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static void syncHierarchyPropertiesAndDisplayListImpl(RenderNode* node) {
|
static void syncHierarchyPropertiesAndDisplayListImpl(RenderNode* node) {
|
||||||
node->syncProperties();
|
node->syncProperties();
|
||||||
|
|||||||
@@ -136,9 +136,9 @@ private:
|
|||||||
textPaint.setAntiAlias(true);
|
textPaint.setAntiAlias(true);
|
||||||
char buf[256];
|
char buf[256];
|
||||||
snprintf(buf, sizeof(buf), "This card is #%d", cardId);
|
snprintf(buf, sizeof(buf), "This card is #%d", cardId);
|
||||||
TestUtils::drawTextToCanvas(&canvas, buf, textPaint, cardHeight, dp(25));
|
TestUtils::drawUtf8ToCanvas(&canvas, buf, textPaint, cardHeight, dp(25));
|
||||||
textPaint.setTextSize(dp(15));
|
textPaint.setTextSize(dp(15));
|
||||||
TestUtils::drawTextToCanvas(&canvas, "This is some more text on the card", textPaint,
|
TestUtils::drawUtf8ToCanvas(&canvas, "This is some more text on the card", textPaint,
|
||||||
cardHeight, dp(45));
|
cardHeight, dp(45));
|
||||||
|
|
||||||
canvas.drawBitmap(createRandomCharIcon(), dp(10), dp(10), nullptr);
|
canvas.drawBitmap(createRandomCharIcon(), dp(10), dp(10), nullptr);
|
||||||
|
|||||||
@@ -39,14 +39,14 @@ public:
|
|||||||
|
|
||||||
paint.setColor(Color::Black);
|
paint.setColor(Color::Black);
|
||||||
for (int i = 0; i < 10; i++) {
|
for (int i = 0; i < 10; i++) {
|
||||||
TestUtils::drawTextToCanvas(&canvas, "Test string", paint, 400, i * 100);
|
TestUtils::drawUtf8ToCanvas(&canvas, "Test string", paint, 400, i * 100);
|
||||||
}
|
}
|
||||||
|
|
||||||
SkPath path;
|
SkPath path;
|
||||||
path.addOval(SkRect::MakeLTRB(100, 100, 300, 300));
|
path.addOval(SkRect::MakeLTRB(100, 100, 300, 300));
|
||||||
|
|
||||||
paint.setColor(Color::Blue_500);
|
paint.setColor(Color::Blue_500);
|
||||||
TestUtils::drawTextToCanvas(&canvas, "This is a neat circle of text!", paint, path);
|
TestUtils::drawUtf8ToCanvas(&canvas, "This is a neat circle of text!", paint, path);
|
||||||
});
|
});
|
||||||
canvas.drawRenderNode(card.get());
|
canvas.drawRenderNode(card.get());
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,9 +16,9 @@
|
|||||||
|
|
||||||
#include "CanvasState.h"
|
#include "CanvasState.h"
|
||||||
|
|
||||||
#include "Canvas.h"
|
|
||||||
#include "Matrix.h"
|
#include "Matrix.h"
|
||||||
#include "Rect.h"
|
#include "Rect.h"
|
||||||
|
#include "hwui/Canvas.h"
|
||||||
#include "utils/LinearAllocator.h"
|
#include "utils/LinearAllocator.h"
|
||||||
|
|
||||||
#include <gtest/gtest.h>
|
#include <gtest/gtest.h>
|
||||||
|
|||||||
@@ -274,8 +274,8 @@ TEST(FrameBuilder, textMerging) {
|
|||||||
paint.setTextEncoding(SkPaint::kGlyphID_TextEncoding);
|
paint.setTextEncoding(SkPaint::kGlyphID_TextEncoding);
|
||||||
paint.setAntiAlias(true);
|
paint.setAntiAlias(true);
|
||||||
paint.setTextSize(50);
|
paint.setTextSize(50);
|
||||||
TestUtils::drawTextToCanvas(&canvas, "Test string1", paint, 100, 0); // will be top clipped
|
TestUtils::drawUtf8ToCanvas(&canvas, "Test string1", paint, 100, 0); // will be top clipped
|
||||||
TestUtils::drawTextToCanvas(&canvas, "Test string1", paint, 100, 100); // not clipped
|
TestUtils::drawUtf8ToCanvas(&canvas, "Test string1", paint, 100, 100); // not clipped
|
||||||
});
|
});
|
||||||
FrameBuilder frameBuilder(sEmptyLayerUpdateQueue, SkRect::MakeWH(400, 400), 400, 400,
|
FrameBuilder frameBuilder(sEmptyLayerUpdateQueue, SkRect::MakeWH(400, 400), 400, 400,
|
||||||
TestUtils::createSyncedNodeList(node), sLightGeometry, nullptr);
|
TestUtils::createSyncedNodeList(node), sLightGeometry, nullptr);
|
||||||
@@ -305,7 +305,7 @@ TEST(FrameBuilder, textStrikethrough) {
|
|||||||
textPaint.setStrikeThruText(true);
|
textPaint.setStrikeThruText(true);
|
||||||
textPaint.setTextEncoding(SkPaint::kGlyphID_TextEncoding);
|
textPaint.setTextEncoding(SkPaint::kGlyphID_TextEncoding);
|
||||||
for (int i = 0; i < LOOPS; i++) {
|
for (int i = 0; i < LOOPS; i++) {
|
||||||
TestUtils::drawTextToCanvas(&canvas, "test text", textPaint, 10, 100 * (i + 1));
|
TestUtils::drawUtf8ToCanvas(&canvas, "test text", textPaint, 10, 100 * (i + 1));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
FrameBuilder frameBuilder(sEmptyLayerUpdateQueue, SkRect::MakeWH(200, 2000), 200, 2000,
|
FrameBuilder frameBuilder(sEmptyLayerUpdateQueue, SkRect::MakeWH(200, 2000), 200, 2000,
|
||||||
@@ -361,7 +361,7 @@ TEST(FrameBuilder, textStyle) {
|
|||||||
// They'll get merged, but with
|
// They'll get merged, but with
|
||||||
for (auto style : styles) {
|
for (auto style : styles) {
|
||||||
paint.setStyle(style);
|
paint.setStyle(style);
|
||||||
TestUtils::drawTextToCanvas(&canvas, "Test string1", paint, 100, 100);
|
TestUtils::drawUtf8ToCanvas(&canvas, "Test string1", paint, 100, 100);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
FrameBuilder frameBuilder(sEmptyLayerUpdateQueue, SkRect::MakeWH(400, 400), 400, 400,
|
FrameBuilder frameBuilder(sEmptyLayerUpdateQueue, SkRect::MakeWH(400, 400), 400, 400,
|
||||||
|
|||||||
@@ -18,6 +18,8 @@
|
|||||||
|
|
||||||
#include <RecordedOp.h>
|
#include <RecordedOp.h>
|
||||||
#include <RecordingCanvas.h>
|
#include <RecordingCanvas.h>
|
||||||
|
#include <hwui/Paint.h>
|
||||||
|
#include <minikin/Layout.h>
|
||||||
#include <tests/common/TestUtils.h>
|
#include <tests/common/TestUtils.h>
|
||||||
#include <utils/Color.h>
|
#include <utils/Color.h>
|
||||||
|
|
||||||
@@ -131,13 +133,13 @@ TEST(RecordingCanvas, drawRoundRect) {
|
|||||||
<< "Non-rounded rects should be converted";
|
<< "Non-rounded rects should be converted";
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(RecordingCanvas, drawText) {
|
TEST(RecordingCanvas, drawGlyphs) {
|
||||||
auto dl = TestUtils::createDisplayList<RecordingCanvas>(200, 200, [](RecordingCanvas& canvas) {
|
auto dl = TestUtils::createDisplayList<RecordingCanvas>(200, 200, [](RecordingCanvas& canvas) {
|
||||||
SkPaint paint;
|
SkPaint paint;
|
||||||
paint.setAntiAlias(true);
|
paint.setAntiAlias(true);
|
||||||
paint.setTextSize(20);
|
paint.setTextSize(20);
|
||||||
paint.setTextEncoding(SkPaint::kGlyphID_TextEncoding);
|
paint.setTextEncoding(SkPaint::kGlyphID_TextEncoding);
|
||||||
TestUtils::drawTextToCanvas(&canvas, "test text", paint, 25, 25);
|
TestUtils::drawUtf8ToCanvas(&canvas, "test text", paint, 25, 25);
|
||||||
});
|
});
|
||||||
|
|
||||||
int count = 0;
|
int count = 0;
|
||||||
@@ -152,7 +154,7 @@ TEST(RecordingCanvas, drawText) {
|
|||||||
ASSERT_EQ(1, count);
|
ASSERT_EQ(1, count);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(RecordingCanvas, drawText_strikeThruAndUnderline) {
|
TEST(RecordingCanvas, drawGlyphs_strikeThruAndUnderline) {
|
||||||
auto dl = TestUtils::createDisplayList<RecordingCanvas>(200, 200, [](RecordingCanvas& canvas) {
|
auto dl = TestUtils::createDisplayList<RecordingCanvas>(200, 200, [](RecordingCanvas& canvas) {
|
||||||
SkPaint paint;
|
SkPaint paint;
|
||||||
paint.setAntiAlias(true);
|
paint.setAntiAlias(true);
|
||||||
@@ -162,7 +164,7 @@ TEST(RecordingCanvas, drawText_strikeThruAndUnderline) {
|
|||||||
for (int j = 0; j < 2; j++) {
|
for (int j = 0; j < 2; j++) {
|
||||||
paint.setUnderlineText(i != 0);
|
paint.setUnderlineText(i != 0);
|
||||||
paint.setStrikeThruText(j != 0);
|
paint.setStrikeThruText(j != 0);
|
||||||
TestUtils::drawTextToCanvas(&canvas, "test text", paint, 25, 25);
|
TestUtils::drawUtf8ToCanvas(&canvas, "test text", paint, 25, 25);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -184,18 +186,18 @@ TEST(RecordingCanvas, drawText_strikeThruAndUnderline) {
|
|||||||
EXPECT_EQ(RecordedOpId::RectOp, ops[index++]->opId); // strikethrough
|
EXPECT_EQ(RecordedOpId::RectOp, ops[index++]->opId); // strikethrough
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(RecordingCanvas, drawText_forceAlignLeft) {
|
TEST(RecordingCanvas, drawGlyphs_forceAlignLeft) {
|
||||||
auto dl = TestUtils::createDisplayList<RecordingCanvas>(200, 200, [](RecordingCanvas& canvas) {
|
auto dl = TestUtils::createDisplayList<RecordingCanvas>(200, 200, [](RecordingCanvas& canvas) {
|
||||||
SkPaint paint;
|
SkPaint paint;
|
||||||
paint.setAntiAlias(true);
|
paint.setAntiAlias(true);
|
||||||
paint.setTextSize(20);
|
paint.setTextSize(20);
|
||||||
paint.setTextEncoding(SkPaint::kGlyphID_TextEncoding);
|
paint.setTextEncoding(SkPaint::kGlyphID_TextEncoding);
|
||||||
paint.setTextAlign(SkPaint::kLeft_Align);
|
paint.setTextAlign(SkPaint::kLeft_Align);
|
||||||
TestUtils::drawTextToCanvas(&canvas, "test text", paint, 25, 25);
|
TestUtils::drawUtf8ToCanvas(&canvas, "test text", paint, 25, 25);
|
||||||
paint.setTextAlign(SkPaint::kCenter_Align);
|
paint.setTextAlign(SkPaint::kCenter_Align);
|
||||||
TestUtils::drawTextToCanvas(&canvas, "test text", paint, 25, 25);
|
TestUtils::drawUtf8ToCanvas(&canvas, "test text", paint, 25, 25);
|
||||||
paint.setTextAlign(SkPaint::kRight_Align);
|
paint.setTextAlign(SkPaint::kRight_Align);
|
||||||
TestUtils::drawTextToCanvas(&canvas, "test text", paint, 25, 25);
|
TestUtils::drawUtf8ToCanvas(&canvas, "test text", paint, 25, 25);
|
||||||
});
|
});
|
||||||
|
|
||||||
int count = 0;
|
int count = 0;
|
||||||
@@ -576,7 +578,7 @@ TEST(RecordingCanvas, refPaint) {
|
|||||||
canvas.drawRect(0, 0, 200, 10, paint);
|
canvas.drawRect(0, 0, 200, 10, paint);
|
||||||
SkPaint paintCopy(paint);
|
SkPaint paintCopy(paint);
|
||||||
canvas.drawRect(0, 10, 200, 20, paintCopy);
|
canvas.drawRect(0, 10, 200, 20, paintCopy);
|
||||||
TestUtils::drawTextToCanvas(&canvas, "helloworld", paint, 50, 25);
|
TestUtils::drawUtf8ToCanvas(&canvas, "helloworld", paint, 50, 25);
|
||||||
|
|
||||||
// only here do we use different paint ptr
|
// only here do we use different paint ptr
|
||||||
paint.setColor(SK_ColorRED);
|
paint.setColor(SK_ColorRED);
|
||||||
@@ -597,5 +599,54 @@ TEST(RecordingCanvas, refPaint) {
|
|||||||
EXPECT_NE(&paint, ops[3]->paint);
|
EXPECT_NE(&paint, ops[3]->paint);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST(RecordingCanvas, drawText) {
|
||||||
|
auto dl = TestUtils::createDisplayList<RecordingCanvas>(200, 200, [](RecordingCanvas& canvas) {
|
||||||
|
Paint paint;
|
||||||
|
paint.setAntiAlias(true);
|
||||||
|
paint.setTextSize(20);
|
||||||
|
paint.setTextEncoding(SkPaint::kGlyphID_TextEncoding);
|
||||||
|
std::unique_ptr<uint16_t[]> dst = TestUtils::utf8ToUtf16("HELLO");
|
||||||
|
canvas.drawText(dst.get(), 0, 5, 5, 25, 25, kBidi_Force_LTR, paint, NULL);
|
||||||
|
});
|
||||||
|
|
||||||
|
int count = 0;
|
||||||
|
playbackOps(*dl, [&count](const RecordedOp& op) {
|
||||||
|
count++;
|
||||||
|
ASSERT_EQ(RecordedOpId::TextOp, op.opId);
|
||||||
|
EXPECT_EQ(nullptr, op.localClip);
|
||||||
|
EXPECT_TRUE(op.localMatrix.isIdentity());
|
||||||
|
EXPECT_TRUE(op.unmappedBounds.getHeight() >= 10);
|
||||||
|
EXPECT_TRUE(op.unmappedBounds.getWidth() >= 25);
|
||||||
|
});
|
||||||
|
ASSERT_EQ(1, count);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(RecordingCanvas, drawTextInHighContrast) {
|
||||||
|
auto dl = TestUtils::createDisplayList<RecordingCanvas>(200, 200, [](RecordingCanvas& canvas) {
|
||||||
|
canvas.setHighContrastText(true);
|
||||||
|
Paint paint;
|
||||||
|
paint.setColor(SK_ColorWHITE);
|
||||||
|
paint.setAntiAlias(true);
|
||||||
|
paint.setTextSize(20);
|
||||||
|
paint.setTextEncoding(SkPaint::kGlyphID_TextEncoding);
|
||||||
|
std::unique_ptr<uint16_t[]> dst = TestUtils::utf8ToUtf16("HELLO");
|
||||||
|
canvas.drawText(dst.get(), 0, 5, 5, 25, 25, kBidi_Force_LTR, paint, NULL);
|
||||||
|
});
|
||||||
|
|
||||||
|
int count = 0;
|
||||||
|
playbackOps(*dl, [&count](const RecordedOp& op) {
|
||||||
|
ASSERT_EQ(RecordedOpId::TextOp, op.opId);
|
||||||
|
if (count++ == 0) {
|
||||||
|
EXPECT_EQ(SK_ColorBLACK, op.paint->getColor());
|
||||||
|
EXPECT_EQ(SkPaint::kStrokeAndFill_Style, op.paint->getStyle());
|
||||||
|
} else {
|
||||||
|
EXPECT_EQ(SK_ColorWHITE, op.paint->getColor());
|
||||||
|
EXPECT_EQ(SkPaint::kFill_Style, op.paint->getStyle());
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
|
ASSERT_EQ(2, count);
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace uirenderer
|
} // namespace uirenderer
|
||||||
} // namespace android
|
} // namespace android
|
||||||
|
|||||||
Reference in New Issue
Block a user