Start of Minikin integration
This is the current state of the Minikin integration. All changes are hidden behind USE_MINIKIN #ifdef, so it should be safe to apply. To play with the Minikin branch, set this in your BoardConfig.mk . This change also merges in 64-bit changes that were happenening in parallel. Change-Id: Idd94553bcbe324c5875d0ff06495c966c3e95b7f
This commit is contained in:
@ -1138,14 +1138,15 @@ class GLES20Canvas extends HardwareCanvas {
|
||||
|
||||
int modifiers = setupModifiers(paint);
|
||||
try {
|
||||
nDrawText(mRenderer, text, index, count, x, y, paint.mBidiFlags, paint.mNativePaint);
|
||||
nDrawText(mRenderer, text, index, count, x, y, paint.mBidiFlags, paint.mNativePaint,
|
||||
paint.mNativeTypeface);
|
||||
} finally {
|
||||
if (modifiers != MODIFIER_NONE) nResetModifiers(mRenderer, modifiers);
|
||||
}
|
||||
}
|
||||
|
||||
private static native void nDrawText(long renderer, char[] text, int index, int count,
|
||||
float x, float y, int bidiFlags, long paint);
|
||||
float x, float y, int bidiFlags, long paint, long typeface);
|
||||
|
||||
@Override
|
||||
public void drawText(CharSequence text, int start, int end, float x, float y, Paint paint) {
|
||||
@ -1154,7 +1155,7 @@ class GLES20Canvas extends HardwareCanvas {
|
||||
if (text instanceof String || text instanceof SpannedString ||
|
||||
text instanceof SpannableString) {
|
||||
nDrawText(mRenderer, text.toString(), start, end, x, y, paint.mBidiFlags,
|
||||
paint.mNativePaint);
|
||||
paint.mNativePaint, paint.mNativeTypeface);
|
||||
} else if (text instanceof GraphicsOperations) {
|
||||
((GraphicsOperations) text).drawText(this, start, end, x, y,
|
||||
paint);
|
||||
@ -1162,7 +1163,7 @@ class GLES20Canvas extends HardwareCanvas {
|
||||
char[] buf = TemporaryBuffer.obtain(end - start);
|
||||
TextUtils.getChars(text, start, end, buf, 0);
|
||||
nDrawText(mRenderer, buf, 0, end - start, x, y,
|
||||
paint.mBidiFlags, paint.mNativePaint);
|
||||
paint.mBidiFlags, paint.mNativePaint, paint.mNativeTypeface);
|
||||
TemporaryBuffer.recycle(buf);
|
||||
}
|
||||
} finally {
|
||||
@ -1178,21 +1179,22 @@ class GLES20Canvas extends HardwareCanvas {
|
||||
|
||||
int modifiers = setupModifiers(paint);
|
||||
try {
|
||||
nDrawText(mRenderer, text, start, end, x, y, paint.mBidiFlags, paint.mNativePaint);
|
||||
nDrawText(mRenderer, text, start, end, x, y, paint.mBidiFlags, paint.mNativePaint,
|
||||
paint.mNativeTypeface);
|
||||
} finally {
|
||||
if (modifiers != MODIFIER_NONE) nResetModifiers(mRenderer, modifiers);
|
||||
}
|
||||
}
|
||||
|
||||
private static native void nDrawText(long renderer, String text, int start, int end,
|
||||
float x, float y, int bidiFlags, long paint);
|
||||
float x, float y, int bidiFlags, long paint, long typeface);
|
||||
|
||||
@Override
|
||||
public void drawText(String text, float x, float y, Paint paint) {
|
||||
int modifiers = setupModifiers(paint);
|
||||
try {
|
||||
nDrawText(mRenderer, text, 0, text.length(), x, y, paint.mBidiFlags,
|
||||
paint.mNativePaint);
|
||||
paint.mNativePaint, paint.mNativeTypeface);
|
||||
} finally {
|
||||
if (modifiers != MODIFIER_NONE) nResetModifiers(mRenderer, modifiers);
|
||||
}
|
||||
@ -1246,14 +1248,14 @@ class GLES20Canvas extends HardwareCanvas {
|
||||
int modifiers = setupModifiers(paint);
|
||||
try {
|
||||
nDrawTextRun(mRenderer, text, index, count, contextIndex, contextCount, x, y, dir,
|
||||
paint.mNativePaint);
|
||||
paint.mNativePaint, paint.mNativeTypeface);
|
||||
} finally {
|
||||
if (modifiers != MODIFIER_NONE) nResetModifiers(mRenderer, modifiers);
|
||||
}
|
||||
}
|
||||
|
||||
private static native void nDrawTextRun(long renderer, char[] text, int index, int count,
|
||||
int contextIndex, int contextCount, float x, float y, int dir, long nativePaint);
|
||||
int contextIndex, int contextCount, float x, float y, int dir, long nativePaint, long nativeTypeface);
|
||||
|
||||
@Override
|
||||
public void drawTextRun(CharSequence text, int start, int end, int contextStart, int contextEnd,
|
||||
@ -1268,7 +1270,7 @@ class GLES20Canvas extends HardwareCanvas {
|
||||
if (text instanceof String || text instanceof SpannedString ||
|
||||
text instanceof SpannableString) {
|
||||
nDrawTextRun(mRenderer, text.toString(), start, end, contextStart,
|
||||
contextEnd, x, y, flags, paint.mNativePaint);
|
||||
contextEnd, x, y, flags, paint.mNativePaint, paint.mNativeTypeface);
|
||||
} else if (text instanceof GraphicsOperations) {
|
||||
((GraphicsOperations) text).drawTextRun(this, start, end,
|
||||
contextStart, contextEnd, x, y, flags, paint);
|
||||
@ -1278,7 +1280,7 @@ class GLES20Canvas extends HardwareCanvas {
|
||||
char[] buf = TemporaryBuffer.obtain(contextLen);
|
||||
TextUtils.getChars(text, contextStart, contextEnd, buf, 0);
|
||||
nDrawTextRun(mRenderer, buf, start - contextStart, len, 0, contextLen,
|
||||
x, y, flags, paint.mNativePaint);
|
||||
x, y, flags, paint.mNativePaint, paint.mNativeTypeface);
|
||||
TemporaryBuffer.recycle(buf);
|
||||
}
|
||||
} finally {
|
||||
@ -1287,7 +1289,7 @@ class GLES20Canvas extends HardwareCanvas {
|
||||
}
|
||||
|
||||
private static native void nDrawTextRun(long renderer, String text, int start, int end,
|
||||
int contextStart, int contextEnd, float x, float y, int flags, long nativePaint);
|
||||
int contextStart, int contextEnd, float x, float y, int flags, long nativePaint, long nativeTypeface);
|
||||
|
||||
@Override
|
||||
public void drawVertices(VertexMode mode, int vertexCount, float[] verts, int vertOffset,
|
||||
|
@ -94,6 +94,7 @@ LOCAL_SRC_FILES:= \
|
||||
android/graphics/Canvas.cpp \
|
||||
android/graphics/ColorFilter.cpp \
|
||||
android/graphics/DrawFilter.cpp \
|
||||
android/graphics/FontFamily.cpp \
|
||||
android/graphics/CreateJavaOutputStreamAdaptor.cpp \
|
||||
android/graphics/Graphics.cpp \
|
||||
android/graphics/HarfBuzzNGFaceSkia.cpp \
|
||||
@ -227,7 +228,8 @@ ifeq ($(USE_MINIKIN), true)
|
||||
LOCAL_CFLAGS += -DUSE_MINIKIN
|
||||
LOCAL_C_INCLUDES += frameworks/minikin/include \
|
||||
external/freetype/include
|
||||
LOCAL_SRC_FILES += android/graphics/MinikinSkia.cpp
|
||||
LOCAL_SRC_FILES += android/graphics/MinikinSkia.cpp \
|
||||
android/graphics/MinikinUtils.cpp
|
||||
# note: the freetype include is spurious; minikin itself probably
|
||||
# shouldn't depend on it
|
||||
LOCAL_SHARED_LIBRARIES += libminikin libstlport
|
||||
|
@ -107,6 +107,7 @@ extern int register_android_emoji_EmojiFactory(JNIEnv* env);
|
||||
extern int register_android_graphics_Canvas(JNIEnv* env);
|
||||
extern int register_android_graphics_ColorFilter(JNIEnv* env);
|
||||
extern int register_android_graphics_DrawFilter(JNIEnv* env);
|
||||
extern int register_android_graphics_FontFamily(JNIEnv* env);
|
||||
extern int register_android_graphics_Matrix(JNIEnv* env);
|
||||
extern int register_android_graphics_Paint(JNIEnv* env);
|
||||
extern int register_android_graphics_Path(JNIEnv* env);
|
||||
@ -1223,6 +1224,7 @@ static const RegJNIRec gRegJNI[] = {
|
||||
REG_JNI(register_android_graphics_Canvas),
|
||||
REG_JNI(register_android_graphics_ColorFilter),
|
||||
REG_JNI(register_android_graphics_DrawFilter),
|
||||
REG_JNI(register_android_graphics_FontFamily),
|
||||
REG_JNI(register_android_graphics_Interpolator),
|
||||
REG_JNI(register_android_graphics_LayerRasterizer),
|
||||
REG_JNI(register_android_graphics_MaskFilter),
|
||||
|
@ -30,6 +30,7 @@
|
||||
#ifdef USE_MINIKIN
|
||||
#include <minikin/Layout.h>
|
||||
#include "MinikinSkia.h"
|
||||
#include "MinikinUtils.h"
|
||||
#endif
|
||||
|
||||
#include "TextLayout.h"
|
||||
@ -820,7 +821,7 @@ public:
|
||||
}
|
||||
|
||||
#ifdef USE_MINIKIN
|
||||
static void drawGlyphsToSkia(SkCanvas *canvas, SkPaint *paint, Layout *layout, float x, float y) {
|
||||
static void drawGlyphsToSkia(SkCanvas* canvas, SkPaint* paint, Layout* layout, float x, float y) {
|
||||
size_t nGlyphs = layout->nGlyphs();
|
||||
uint16_t *glyphs = new uint16_t[nGlyphs];
|
||||
SkPoint *pos = new SkPoint[nGlyphs];
|
||||
@ -865,15 +866,7 @@ public:
|
||||
|
||||
#ifdef USE_MINIKIN
|
||||
Layout layout;
|
||||
TypefaceImpl* resolvedFace = TypefaceImpl_resolveDefault(typeface);
|
||||
layout.setFontCollection(resolvedFace->fFontCollection);
|
||||
FontStyle style = resolvedFace->fStyle;
|
||||
char css[256];
|
||||
sprintf(css, "font-size: %d; font-weight: %d; font-style: %s",
|
||||
(int)paint->getTextSize(),
|
||||
style.getWeight() * 100,
|
||||
style.getItalic() ? "italic" : "normal");
|
||||
layout.setProperties(css);
|
||||
MinikinUtils::SetLayoutProperties(&layout, paint, typeface);
|
||||
layout.doLayout(textArray + start, count);
|
||||
drawGlyphsToSkia(canvas, paint, &layout, x, y);
|
||||
#else
|
||||
|
75
core/jni/android/graphics/FontFamily.cpp
Normal file
75
core/jni/android/graphics/FontFamily.cpp
Normal file
@ -0,0 +1,75 @@
|
||||
/*
|
||||
* Copyright (C) 2014 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.
|
||||
*/
|
||||
|
||||
#define LOG_TAG "Minikin"
|
||||
|
||||
#include "JNIHelp.h"
|
||||
#include <android_runtime/AndroidRuntime.h>
|
||||
|
||||
#include "SkTypeface.h"
|
||||
#include "GraphicsJNI.h"
|
||||
#include <ScopedPrimitiveArray.h>
|
||||
#include <ScopedUtfChars.h>
|
||||
|
||||
#ifdef USE_MINIKIN
|
||||
#include <minikin/FontFamily.h>
|
||||
#include "MinikinSkia.h"
|
||||
#endif
|
||||
|
||||
namespace android {
|
||||
|
||||
static jlong FontFamily_create(JNIEnv* env, jobject clazz) {
|
||||
#ifdef USE_MINIKIN
|
||||
return (jlong)new FontFamily();
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
static void FontFamily_destroy(JNIEnv* env, jobject clazz, jlong ptr) {
|
||||
// TODO: work out lifetime issues
|
||||
}
|
||||
|
||||
static jboolean FontFamily_addFont(JNIEnv* env, jobject clazz, jlong familyPtr, jstring path) {
|
||||
#ifdef USE_MINIKIN
|
||||
NPE_CHECK_RETURN_ZERO(env, path);
|
||||
ScopedUtfChars str(env, path);
|
||||
ALOGD("addFont %s", str.c_str());
|
||||
SkTypeface* face = SkTypeface::CreateFromFile(str.c_str());
|
||||
MinikinFont* minikinFont = new MinikinFontSkia(face);
|
||||
FontFamily* fontFamily = (FontFamily*)familyPtr;
|
||||
return fontFamily->addFont(minikinFont);
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static JNINativeMethod gFontFamilyMethods[] = {
|
||||
{ "nCreateFamily", "()J", (void*)FontFamily_create },
|
||||
{ "nDestroyFamily", "(J)V", (void*)FontFamily_destroy },
|
||||
{ "nAddFont", "(JLjava/lang/String;)Z", (void*)FontFamily_addFont },
|
||||
};
|
||||
|
||||
int register_android_graphics_FontFamily(JNIEnv* env)
|
||||
{
|
||||
return android::AndroidRuntime::registerNativeMethods(env,
|
||||
"android/graphics/FontFamily",
|
||||
gFontFamilyMethods, NELEM(gFontFamilyMethods));
|
||||
}
|
||||
|
||||
}
|
@ -167,6 +167,7 @@ static jfieldID gCanvas_nativeInstanceID;
|
||||
|
||||
static jclass gPaint_class;
|
||||
static jfieldID gPaint_nativeInstanceID;
|
||||
static jfieldID gPaint_nativeTypefaceID;
|
||||
|
||||
static jclass gPicture_class;
|
||||
static jfieldID gPicture_nativeInstanceID;
|
||||
@ -334,6 +335,16 @@ SkPaint* GraphicsJNI::getNativePaint(JNIEnv* env, jobject paint) {
|
||||
return p;
|
||||
}
|
||||
|
||||
android::TypefaceImpl* GraphicsJNI::getNativeTypeface(JNIEnv* env, jobject paint) {
|
||||
SkASSERT(env);
|
||||
SkASSERT(paint);
|
||||
SkASSERT(env->IsInstanceOf(paint, gPaint_class));
|
||||
jlong typefaceHandle = env->GetLongField(paint, gPaint_nativeTypefaceID);
|
||||
android::TypefaceImpl* p = reinterpret_cast<android::TypefaceImpl*>(typefaceHandle);
|
||||
SkASSERT(p);
|
||||
return p;
|
||||
}
|
||||
|
||||
SkPicture* GraphicsJNI::getNativePicture(JNIEnv* env, jobject picture)
|
||||
{
|
||||
SkASSERT(env);
|
||||
@ -698,6 +709,7 @@ int register_android_graphics_Graphics(JNIEnv* env)
|
||||
|
||||
gPaint_class = make_globalref(env, "android/graphics/Paint");
|
||||
gPaint_nativeInstanceID = getFieldIDCheck(env, gPaint_class, "mNativePaint", "J");
|
||||
gPaint_nativeTypefaceID = getFieldIDCheck(env, gPaint_class, "mNativeTypeface", "J");
|
||||
|
||||
gPicture_class = make_globalref(env, "android/graphics/Picture");
|
||||
gPicture_nativeInstanceID = getFieldIDCheck(env, gPicture_class, "mNativePicture", "J");
|
||||
|
@ -8,6 +8,7 @@
|
||||
#include "SkPoint.h"
|
||||
#include "SkRect.h"
|
||||
#include "SkImageDecoder.h"
|
||||
#include "TypefaceImpl.h"
|
||||
#include <jni.h>
|
||||
|
||||
class SkBitmapRegionDecoder;
|
||||
@ -46,6 +47,7 @@ public:
|
||||
|
||||
static SkCanvas* getNativeCanvas(JNIEnv*, jobject canvas);
|
||||
static SkPaint* getNativePaint(JNIEnv*, jobject paint);
|
||||
static android::TypefaceImpl* getNativeTypeface(JNIEnv*, jobject paint);
|
||||
static SkBitmap* getNativeBitmap(JNIEnv*, jobject bitmap);
|
||||
static SkPicture* getNativePicture(JNIEnv*, jobject picture);
|
||||
static SkRegion* getNativeRegion(JNIEnv*, jobject region);
|
||||
|
@ -16,7 +16,6 @@
|
||||
|
||||
#include <SkTypeface.h>
|
||||
#include <SkPaint.h>
|
||||
#include <SkFP.h>
|
||||
|
||||
#define LOG_TAG "Minikin"
|
||||
#include <cutils/log.h>
|
||||
@ -44,19 +43,35 @@ bool MinikinFontSkia::GetGlyph(uint32_t codepoint, uint32_t *glyph) const {
|
||||
return !!glyph;
|
||||
}
|
||||
|
||||
static void MinikinFontSkia_SetSkiaPaint(SkTypeface* typeface, SkPaint* skPaint, const MinikinPaint& paint) {
|
||||
skPaint->setTypeface(typeface);
|
||||
skPaint->setTextEncoding(SkPaint::kGlyphID_TextEncoding);
|
||||
// TODO: set more paint parameters from Minikin
|
||||
skPaint->setTextSize(paint.size);
|
||||
}
|
||||
|
||||
float MinikinFontSkia::GetHorizontalAdvance(uint32_t glyph_id,
|
||||
const MinikinPaint &paint) const {
|
||||
SkPaint skpaint;
|
||||
skpaint.setTypeface(mTypeface);
|
||||
skpaint.setTextEncoding(SkPaint::kGlyphID_TextEncoding);
|
||||
// TODO: set more paint parameters from Minikin
|
||||
skpaint.setTextSize(paint.size);
|
||||
SkPaint skPaint;
|
||||
uint16_t glyph16 = glyph_id;
|
||||
SkScalar skWidth;
|
||||
MinikinFontSkia_SetSkiaPaint(mTypeface, &skPaint, paint);
|
||||
skPaint.getTextWidths(&glyph16, sizeof(glyph16), &skWidth, NULL);
|
||||
ALOGD("width for typeface %d glyph %d = %f", mTypeface->uniqueID(), glyph_id, skWidth);
|
||||
return skWidth;
|
||||
}
|
||||
|
||||
void MinikinFontSkia::GetBounds(MinikinRect* bounds, uint32_t glyph_id,
|
||||
const MinikinPaint& paint) const {
|
||||
SkPaint skPaint;
|
||||
uint16_t glyph16 = glyph_id;
|
||||
SkRect skBounds;
|
||||
skpaint.getTextWidths(&glyph16, sizeof(glyph16), &skWidth, &skBounds);
|
||||
// TODO: get bounds information
|
||||
return SkScalarToFP(skWidth);
|
||||
MinikinFontSkia_SetSkiaPaint(mTypeface, &skPaint, paint);
|
||||
skPaint.getTextWidths(&glyph16, sizeof(glyph16), NULL, &skBounds);
|
||||
bounds->mLeft = skBounds.fLeft;
|
||||
bounds->mTop = skBounds.fTop;
|
||||
bounds->mRight = skBounds.fRight;
|
||||
bounds->mBottom = skBounds.fBottom;
|
||||
}
|
||||
|
||||
bool MinikinFontSkia::GetTable(uint32_t tag, uint8_t *buf, size_t *size) {
|
||||
|
@ -27,6 +27,9 @@ public:
|
||||
float GetHorizontalAdvance(uint32_t glyph_id,
|
||||
const MinikinPaint &paint) const;
|
||||
|
||||
void GetBounds(MinikinRect* bounds, uint32_t glyph_id,
|
||||
const MinikinPaint &paint) const;
|
||||
|
||||
// If buf is NULL, just update size
|
||||
bool GetTable(uint32_t tag, uint8_t *buf, size_t *size);
|
||||
|
||||
@ -36,7 +39,6 @@ public:
|
||||
|
||||
private:
|
||||
SkTypeface *mTypeface;
|
||||
|
||||
};
|
||||
|
||||
} // namespace android
|
38
core/jni/android/graphics/MinikinUtils.cpp
Normal file
38
core/jni/android/graphics/MinikinUtils.cpp
Normal file
@ -0,0 +1,38 @@
|
||||
/*
|
||||
* Copyright (C) 2014 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 "SkPaint.h"
|
||||
#include "minikin/Layout.h"
|
||||
#include "TypefaceImpl.h"
|
||||
|
||||
#include "MinikinUtils.h"
|
||||
|
||||
namespace android {
|
||||
|
||||
void MinikinUtils::SetLayoutProperties(Layout* layout, SkPaint* paint,
|
||||
TypefaceImpl* typeface) {
|
||||
TypefaceImpl* resolvedFace = TypefaceImpl_resolveDefault(typeface);
|
||||
layout->setFontCollection(resolvedFace->fFontCollection);
|
||||
FontStyle style = resolvedFace->fStyle;
|
||||
char css[256];
|
||||
sprintf(css, "font-size: %d; font-weight: %d; font-style: %s",
|
||||
(int)paint->getTextSize(),
|
||||
style.getWeight() * 100,
|
||||
style.getItalic() ? "italic" : "normal");
|
||||
layout->setProperties(css);
|
||||
}
|
||||
|
||||
}
|
37
core/jni/android/graphics/MinikinUtils.h
Normal file
37
core/jni/android/graphics/MinikinUtils.h
Normal file
@ -0,0 +1,37 @@
|
||||
/*
|
||||
* Copyright (C) 2014 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Utilities for making Minikin work, especially from existing objects like
|
||||
* SkPaint and so on.
|
||||
**/
|
||||
|
||||
// TODO: does this really need to be separate from MinikinSkia?
|
||||
|
||||
#ifndef ANDROID_MINIKIN_UTILS_H
|
||||
#define ANDROID_MINIKIN_UTILS_H
|
||||
|
||||
namespace android {
|
||||
|
||||
class MinikinUtils {
|
||||
public:
|
||||
static void SetLayoutProperties(Layout* layout, SkPaint* paint,
|
||||
TypefaceImpl* face);
|
||||
};
|
||||
|
||||
} // namespace android
|
||||
|
||||
#endif // ANDROID_MINIKIN_UTILS_H
|
@ -35,6 +35,12 @@
|
||||
#include "unicode/ushape.h"
|
||||
#include "TextLayout.h"
|
||||
|
||||
#ifdef USE_MINIKIN
|
||||
#include <minikin/Layout.h>
|
||||
#include "MinikinSkia.h"
|
||||
#include "MinikinUtils.h"
|
||||
#endif
|
||||
|
||||
// temporary for debugging
|
||||
#include <Caches.h>
|
||||
#include <utils/Log.h>
|
||||
@ -493,8 +499,16 @@ public:
|
||||
const jchar* textArray = env->GetCharArrayElements(text, NULL);
|
||||
jfloat result = 0;
|
||||
|
||||
#ifdef USE_MINIKIN
|
||||
Layout layout;
|
||||
TypefaceImpl* typeface = GraphicsJNI::getNativeTypeface(env, jpaint);
|
||||
MinikinUtils::SetLayoutProperties(&layout, paint, typeface);
|
||||
layout.doLayout(textArray + index, count);
|
||||
result = layout.getAdvance();
|
||||
#else
|
||||
TextLayout::getTextRunAdvances(paint, textArray, index, count, textLength,
|
||||
bidiFlags, NULL /* dont need all advances */, &result);
|
||||
#endif
|
||||
|
||||
env->ReleaseCharArrayElements(text, const_cast<jchar*>(textArray), JNI_ABORT);
|
||||
return result;
|
||||
@ -519,8 +533,16 @@ public:
|
||||
SkPaint* paint = GraphicsJNI::getNativePaint(env, jpaint);
|
||||
jfloat width = 0;
|
||||
|
||||
#ifdef USE_MINIKIN
|
||||
Layout layout;
|
||||
TypefaceImpl* typeface = GraphicsJNI::getNativeTypeface(env, jpaint);
|
||||
MinikinUtils::SetLayoutProperties(&layout, paint, typeface);
|
||||
layout.doLayout(textArray + start, count);
|
||||
width = layout.getAdvance();
|
||||
#else
|
||||
TextLayout::getTextRunAdvances(paint, textArray, start, count, textLength,
|
||||
bidiFlags, NULL /* dont need all advances */, &width);
|
||||
#endif
|
||||
|
||||
env->ReleaseStringChars(text, textArray);
|
||||
return width;
|
||||
@ -539,15 +561,23 @@ public:
|
||||
SkPaint* paint = GraphicsJNI::getNativePaint(env, jpaint);
|
||||
jfloat width = 0;
|
||||
|
||||
#ifdef USE_MINIKIN
|
||||
Layout layout;
|
||||
TypefaceImpl* typeface = GraphicsJNI::getNativeTypeface(env, jpaint);
|
||||
MinikinUtils::SetLayoutProperties(&layout, paint, typeface);
|
||||
layout.doLayout(textArray, textLength);
|
||||
width = layout.getAdvance();
|
||||
#else
|
||||
TextLayout::getTextRunAdvances(paint, textArray, 0, textLength, textLength,
|
||||
bidiFlags, NULL /* dont need all advances */, &width);
|
||||
#endif
|
||||
|
||||
env->ReleaseStringChars(text, textArray);
|
||||
return width;
|
||||
}
|
||||
|
||||
static int dotextwidths(JNIEnv* env, SkPaint* paint, const jchar text[], int count, jfloatArray widths,
|
||||
jint bidiFlags) {
|
||||
static int dotextwidths(JNIEnv* env, SkPaint* paint, TypefaceImpl* typeface, const jchar text[], int count,
|
||||
jfloatArray widths, jint bidiFlags) {
|
||||
NPE_CHECK_RETURN_ZERO(env, paint);
|
||||
NPE_CHECK_RETURN_ZERO(env, text);
|
||||
|
||||
@ -567,27 +597,36 @@ public:
|
||||
AutoJavaFloatArray autoWidths(env, widths, count);
|
||||
jfloat* widthsArray = autoWidths.ptr();
|
||||
|
||||
#ifdef USE_MINIKIN
|
||||
Layout layout;
|
||||
MinikinUtils::SetLayoutProperties(&layout, paint, typeface);
|
||||
layout.doLayout(text, count);
|
||||
layout.getAdvances(widthsArray);
|
||||
#else
|
||||
TextLayout::getTextRunAdvances(paint, text, 0, count, count,
|
||||
bidiFlags, widthsArray, NULL /* dont need totalAdvance */);
|
||||
#endif
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
static jint getTextWidths___CIII_F(JNIEnv* env, jobject clazz, jlong paintHandle, jcharArray text,
|
||||
static jint getTextWidths___CIII_F(JNIEnv* env, jobject clazz, jlong paintHandle, jlong typefaceHandle, jcharArray text,
|
||||
jint index, jint count, jint bidiFlags, jfloatArray widths) {
|
||||
SkPaint* paint = reinterpret_cast<SkPaint*>(paintHandle);
|
||||
TypefaceImpl* typeface = reinterpret_cast<TypefaceImpl*>(typefaceHandle);
|
||||
const jchar* textArray = env->GetCharArrayElements(text, NULL);
|
||||
count = dotextwidths(env, paint, textArray + index, count, widths, bidiFlags);
|
||||
count = dotextwidths(env, paint, typeface, textArray + index, count, widths, bidiFlags);
|
||||
env->ReleaseCharArrayElements(text, const_cast<jchar*>(textArray),
|
||||
JNI_ABORT);
|
||||
return count;
|
||||
}
|
||||
|
||||
static jint getTextWidths__StringIII_F(JNIEnv* env, jobject clazz, jlong paintHandle, jstring text,
|
||||
static jint getTextWidths__StringIII_F(JNIEnv* env, jobject clazz, jlong paintHandle, jlong typefaceHandle, jstring text,
|
||||
jint start, jint end, jint bidiFlags, jfloatArray widths) {
|
||||
SkPaint* paint = reinterpret_cast<SkPaint*>(paintHandle);
|
||||
TypefaceImpl* typeface = reinterpret_cast<TypefaceImpl*>(typefaceHandle);
|
||||
const jchar* textArray = env->GetStringChars(text, NULL);
|
||||
int count = dotextwidths(env, paint, textArray + start, end - start, widths, bidiFlags);
|
||||
int count = dotextwidths(env, paint, typeface, textArray + start, end - start, widths, bidiFlags);
|
||||
env->ReleaseStringChars(text, textArray);
|
||||
return count;
|
||||
}
|
||||
@ -633,7 +672,7 @@ public:
|
||||
return count;
|
||||
}
|
||||
|
||||
static jfloat doTextRunAdvances(JNIEnv *env, SkPaint *paint, const jchar *text,
|
||||
static jfloat doTextRunAdvances(JNIEnv *env, SkPaint *paint, TypefaceImpl* typeface, const jchar *text,
|
||||
jint start, jint count, jint contextCount, jint flags,
|
||||
jfloatArray advances, jint advancesIndex) {
|
||||
NPE_CHECK_RETURN_ZERO(env, paint);
|
||||
@ -656,8 +695,16 @@ public:
|
||||
jfloat* advancesArray = new jfloat[count];
|
||||
jfloat totalAdvance = 0;
|
||||
|
||||
#ifdef USE_MINIKIN
|
||||
Layout layout;
|
||||
MinikinUtils::SetLayoutProperties(&layout, paint, typeface);
|
||||
layout.doLayout(text + start, count);
|
||||
layout.getAdvances(advancesArray);
|
||||
totalAdvance = layout.getAdvance();
|
||||
#else
|
||||
TextLayout::getTextRunAdvances(paint, text, start, count, contextCount, flags,
|
||||
advancesArray, &totalAdvance);
|
||||
#endif
|
||||
|
||||
if (advances != NULL) {
|
||||
env->SetFloatArrayRegion(advances, advancesIndex, count, advancesArray);
|
||||
@ -667,22 +714,26 @@ public:
|
||||
}
|
||||
|
||||
static jfloat getTextRunAdvances___CIIIII_FI(JNIEnv* env, jobject clazz, jlong paintHandle,
|
||||
jlong typefaceHandle,
|
||||
jcharArray text, jint index, jint count, jint contextIndex, jint contextCount,
|
||||
jint flags, jfloatArray advances, jint advancesIndex) {
|
||||
SkPaint* paint = reinterpret_cast<SkPaint*>(paintHandle);
|
||||
TypefaceImpl* typeface = reinterpret_cast<TypefaceImpl*>(typefaceHandle);
|
||||
jchar* textArray = env->GetCharArrayElements(text, NULL);
|
||||
jfloat result = doTextRunAdvances(env, paint, textArray + contextIndex,
|
||||
jfloat result = doTextRunAdvances(env, paint, typeface, textArray + contextIndex,
|
||||
index - contextIndex, count, contextCount, flags, advances, advancesIndex);
|
||||
env->ReleaseCharArrayElements(text, textArray, JNI_ABORT);
|
||||
return result;
|
||||
}
|
||||
|
||||
static jfloat getTextRunAdvances__StringIIIII_FI(JNIEnv* env, jobject clazz, jlong paintHandle,
|
||||
jlong typefaceHandle,
|
||||
jstring text, jint start, jint end, jint contextStart, jint contextEnd, jint flags,
|
||||
jfloatArray advances, jint advancesIndex) {
|
||||
SkPaint* paint = reinterpret_cast<SkPaint*>(paintHandle);
|
||||
TypefaceImpl* typeface = reinterpret_cast<TypefaceImpl*>(typefaceHandle);
|
||||
const jchar* textArray = env->GetStringChars(text, NULL);
|
||||
jfloat result = doTextRunAdvances(env, paint, textArray + contextStart,
|
||||
jfloat result = doTextRunAdvances(env, paint, typeface, textArray + contextStart,
|
||||
start - contextStart, end - start, contextEnd - contextStart, flags,
|
||||
advances, advancesIndex);
|
||||
env->ReleaseStringChars(text, textArray);
|
||||
@ -949,11 +1000,11 @@ static JNINativeMethod methods[] = {
|
||||
{"native_measureText","(Ljava/lang/String;III)F", (void*) SkPaintGlue::measureText_StringIII},
|
||||
{"native_breakText","([CIIFI[F)I", (void*) SkPaintGlue::breakTextC},
|
||||
{"native_breakText","(Ljava/lang/String;ZFI[F)I", (void*) SkPaintGlue::breakTextS},
|
||||
{"native_getTextWidths","(J[CIII[F)I", (void*) SkPaintGlue::getTextWidths___CIII_F},
|
||||
{"native_getTextWidths","(JLjava/lang/String;III[F)I", (void*) SkPaintGlue::getTextWidths__StringIII_F},
|
||||
{"native_getTextRunAdvances","(J[CIIIII[FI)F",
|
||||
{"native_getTextWidths","(JJ[CIII[F)I", (void*) SkPaintGlue::getTextWidths___CIII_F},
|
||||
{"native_getTextWidths","(JJLjava/lang/String;III[F)I", (void*) SkPaintGlue::getTextWidths__StringIII_F},
|
||||
{"native_getTextRunAdvances","(JJ[CIIIII[FI)F",
|
||||
(void*) SkPaintGlue::getTextRunAdvances___CIIIII_FI},
|
||||
{"native_getTextRunAdvances","(JLjava/lang/String;IIIII[FI)F",
|
||||
{"native_getTextRunAdvances","(JJLjava/lang/String;IIIII[FI)F",
|
||||
(void*) SkPaintGlue::getTextRunAdvances__StringIIIII_FI},
|
||||
|
||||
|
||||
|
@ -18,6 +18,7 @@
|
||||
#include <android_runtime/AndroidRuntime.h>
|
||||
|
||||
#include "GraphicsJNI.h"
|
||||
#include <ScopedPrimitiveArray.h>
|
||||
#include "SkStream.h"
|
||||
#include "SkTypeface.h"
|
||||
#include "TypefaceImpl.h"
|
||||
@ -62,7 +63,7 @@ static jlong Typeface_create(JNIEnv* env, jobject, jstring name,
|
||||
}
|
||||
|
||||
static jlong Typeface_createFromTypeface(JNIEnv* env, jobject, jlong familyHandle, jint style) {
|
||||
SkTypeface* family = reinterpret_cast<SkTypeface*>(familyHandle);
|
||||
TypefaceImpl* family = reinterpret_cast<TypefaceImpl*>(familyHandle);
|
||||
TypefaceImpl* face = TypefaceImpl_createFromTypeface(family, (SkTypeface::Style)style);
|
||||
// Try to find the closest matching font, using the standard heuristic
|
||||
if (NULL == face) {
|
||||
@ -114,6 +115,11 @@ static jlong Typeface_createFromFile(JNIEnv* env, jobject, jstring jpath) {
|
||||
return reinterpret_cast<jlong>(TypefaceImpl_createFromFile(str.c_str()));
|
||||
}
|
||||
|
||||
static jlong Typeface_createFromArray(JNIEnv *env, jobject, jlongArray familyArray) {
|
||||
ScopedLongArrayRO families(env, familyArray);
|
||||
return reinterpret_cast<jlong>(TypefaceImpl_createFromFamilies(families.get(), families.size()));
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static JNINativeMethod gTypefaceMethods[] = {
|
||||
@ -125,6 +131,8 @@ static JNINativeMethod gTypefaceMethods[] = {
|
||||
(void*)Typeface_createFromAsset },
|
||||
{ "nativeCreateFromFile", "(Ljava/lang/String;)J",
|
||||
(void*)Typeface_createFromFile },
|
||||
{ "nativeCreateFromArray", "([J)J",
|
||||
(void*)Typeface_createFromArray },
|
||||
};
|
||||
|
||||
int register_android_graphics_Typeface(JNIEnv* env)
|
||||
|
@ -20,6 +20,10 @@
|
||||
* being, that choice is hidden under the USE_MINIKIN compile-time flag.
|
||||
*/
|
||||
|
||||
#define LOG_TAG "TypefaceImpl"
|
||||
|
||||
#include "jni.h" // for jlong, remove when being passed proper type
|
||||
|
||||
#include "SkStream.h"
|
||||
#include "SkTypeface.h"
|
||||
|
||||
@ -146,6 +150,19 @@ TypefaceImpl* TypefaceImpl_createFromAsset(Asset* asset) {
|
||||
return createFromSkTypeface(face);
|
||||
}
|
||||
|
||||
TypefaceImpl* TypefaceImpl_createFromFamilies(const jlong* families, size_t size) {
|
||||
ALOGD("createFromFamilies size=%d", size);
|
||||
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;
|
||||
result->fFontCollection = new FontCollection(familyVec);
|
||||
result->fStyle = FontStyle(); // TODO: improve
|
||||
return result;
|
||||
}
|
||||
|
||||
void TypefaceImpl_unref(TypefaceImpl* face) {
|
||||
delete face;
|
||||
}
|
||||
@ -189,6 +206,11 @@ TypefaceImpl* TypefaceImpl_createFromAsset(Asset* asset) {
|
||||
return face;
|
||||
}
|
||||
|
||||
TypefaceImpl* TypefaceImpl_createFromFamilies(const jlong* families, size_t size) {
|
||||
// Should never be called in non-Minikin builds
|
||||
return 0;
|
||||
}
|
||||
|
||||
void TypefaceImpl_unref(TypefaceImpl* face) {
|
||||
SkSafeUnref(face);
|
||||
}
|
||||
|
@ -18,6 +18,8 @@
|
||||
#ifndef ANDROID_TYPEFACE_IMPL_H
|
||||
#define ANDROID_TYPEFACE_IMPL_H
|
||||
|
||||
#include "jni.h" // for jlong, eventually remove
|
||||
#include "SkTypeface.h"
|
||||
#include <androidfw/AssetManager.h>
|
||||
|
||||
#ifdef USE_MINIKIN
|
||||
@ -51,6 +53,10 @@ TypefaceImpl* TypefaceImpl_createFromFile(const char* filename);
|
||||
|
||||
TypefaceImpl* TypefaceImpl_createFromAsset(Asset* asset);
|
||||
|
||||
// When we remove the USE_MINIKIN ifdef, probably a good idea to move the casting
|
||||
// (from jlong to FontFamily*) to the caller in Typeface.cpp.
|
||||
TypefaceImpl* TypefaceImpl_createFromFamilies(const jlong* families, size_t size);
|
||||
|
||||
void TypefaceImpl_unref(TypefaceImpl* face);
|
||||
|
||||
int TypefaceImpl_getStyle(TypefaceImpl* face);
|
||||
|
@ -50,6 +50,12 @@
|
||||
#include <Rect.h>
|
||||
#include <RenderNode.h>
|
||||
|
||||
#ifdef USE_MINIKIN
|
||||
#include <minikin/Layout.h>
|
||||
#include "MinikinSkia.h"
|
||||
#include "MinikinUtils.h"
|
||||
#endif
|
||||
|
||||
#include <TextLayout.h>
|
||||
#include <TextLayoutCache.h>
|
||||
|
||||
@ -684,8 +690,58 @@ static float xOffsetForTextAlign(SkPaint* paint, float totalAdvance) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef USE_MINIKIN
|
||||
static void renderTextLayout(OpenGLRenderer* renderer, Layout* layout,
|
||||
jfloat x, jfloat y, SkPaint* paint) {
|
||||
size_t nGlyphs = layout->nGlyphs();
|
||||
float* pos = new float[nGlyphs * 2];
|
||||
uint16_t* glyphs = new uint16_t[nGlyphs];
|
||||
SkTypeface* lastFace = 0;
|
||||
SkTypeface* skFace = 0;
|
||||
size_t start = 0;
|
||||
MinikinRect b;
|
||||
layout->getBounds(&b);
|
||||
android::uirenderer::Rect bounds(b.mLeft, b.mTop, b.mRight, b.mBottom);
|
||||
bounds.translate(x, y);
|
||||
float totalAdvance = layout->getAdvance();
|
||||
|
||||
for (size_t i = 0; i < nGlyphs; i++) {
|
||||
MinikinFontSkia* mfs = static_cast<MinikinFontSkia *>(layout->getFont(i));
|
||||
skFace = mfs->GetSkTypeface();
|
||||
glyphs[i] = layout->getGlyphId(i);
|
||||
pos[2 * i] = SkFloatToScalar(layout->getX(i));
|
||||
pos[2 * i + 1] = SkFloatToScalar(layout->getY(i));
|
||||
if (i > 0 && skFace != lastFace) {
|
||||
paint->setTypeface(lastFace);
|
||||
size_t glyphsCount = i - start;
|
||||
int bytesCount = glyphsCount * sizeof(jchar);
|
||||
renderer->drawText((const char*) (glyphs + start), bytesCount, glyphsCount,
|
||||
x, y, pos + 2 * start, paint, totalAdvance, bounds);
|
||||
start = i;
|
||||
}
|
||||
lastFace = skFace;
|
||||
}
|
||||
if (skFace != NULL) {
|
||||
paint->setTypeface(skFace);
|
||||
size_t glyphsCount = nGlyphs - start;
|
||||
int bytesCount = glyphsCount * sizeof(jchar);
|
||||
renderer->drawText((const char*) (glyphs + start), bytesCount, glyphsCount,
|
||||
x, y, pos + 2 * start, paint, totalAdvance, bounds);
|
||||
}
|
||||
delete[] glyphs;
|
||||
delete[] pos;
|
||||
}
|
||||
#endif
|
||||
|
||||
static void renderText(OpenGLRenderer* renderer, const jchar* text, int count,
|
||||
jfloat x, jfloat y, int flags, SkPaint* paint) {
|
||||
jfloat x, jfloat y, int flags, SkPaint* paint, TypefaceImpl* typeface) {
|
||||
#ifdef USE_MINIKIN
|
||||
Layout layout;
|
||||
MinikinUtils::SetLayoutProperties(&layout, paint, typeface);
|
||||
layout.doLayout(text, count);
|
||||
x += xOffsetForTextAlign(paint, layout.getAdvance());
|
||||
renderTextLayout(renderer, &layout, x, y, paint);
|
||||
#else
|
||||
sp<TextLayoutValue> value = TextLayoutEngine::getInstance().getValue(paint,
|
||||
text, 0, count, count, flags);
|
||||
if (value == NULL) {
|
||||
@ -703,6 +759,7 @@ static void renderText(OpenGLRenderer* renderer, const jchar* text, int count,
|
||||
|
||||
renderer->drawText((const char*) glyphs, bytesCount, glyphsCount,
|
||||
x, y, positions, paint, totalAdvance, bounds);
|
||||
#endif
|
||||
}
|
||||
|
||||
static void renderTextOnPath(OpenGLRenderer* renderer, const jchar* text, int count,
|
||||
@ -721,7 +778,14 @@ static void renderTextOnPath(OpenGLRenderer* renderer, const jchar* text, int co
|
||||
|
||||
static void renderTextRun(OpenGLRenderer* renderer, const jchar* text,
|
||||
jint start, jint count, jint contextCount, jfloat x, jfloat y,
|
||||
int flags, SkPaint* paint) {
|
||||
int flags, SkPaint* paint, TypefaceImpl* typeface) {
|
||||
#ifdef USE_MINIKIN
|
||||
Layout layout;
|
||||
MinikinUtils::SetLayoutProperties(&layout, paint, typeface);
|
||||
layout.doLayout(text + start, count);
|
||||
x += xOffsetForTextAlign(paint, layout.getAdvance());
|
||||
renderTextLayout(renderer, &layout, x, y, paint);
|
||||
#else
|
||||
sp<TextLayoutValue> value = TextLayoutEngine::getInstance().getValue(paint,
|
||||
text, start, count, contextCount, flags);
|
||||
if (value == NULL) {
|
||||
@ -739,27 +803,30 @@ static void renderTextRun(OpenGLRenderer* renderer, const jchar* text,
|
||||
|
||||
renderer->drawText((const char*) glyphs, bytesCount, glyphsCount,
|
||||
x, y, positions, paint, totalAdvance, bounds);
|
||||
#endif
|
||||
}
|
||||
|
||||
static void android_view_GLES20Canvas_drawTextArray(JNIEnv* env, jobject clazz,
|
||||
jlong rendererPtr, jcharArray text, jint index, jint count,
|
||||
jfloat x, jfloat y, jint flags, jlong paintPtr) {
|
||||
jfloat x, jfloat y, jint flags, jlong paintPtr, jlong typefacePtr) {
|
||||
OpenGLRenderer* renderer = reinterpret_cast<OpenGLRenderer*>(rendererPtr);
|
||||
jchar* textArray = env->GetCharArrayElements(text, NULL);
|
||||
SkPaint* paint = reinterpret_cast<SkPaint*>(paintPtr);
|
||||
TypefaceImpl* typeface = reinterpret_cast<TypefaceImpl*>(typefacePtr);
|
||||
|
||||
renderText(renderer, textArray + index, count, x, y, flags, paint);
|
||||
renderText(renderer, textArray + index, count, x, y, flags, paint, typeface);
|
||||
env->ReleaseCharArrayElements(text, textArray, JNI_ABORT);
|
||||
}
|
||||
|
||||
static void android_view_GLES20Canvas_drawText(JNIEnv* env, jobject clazz,
|
||||
jlong rendererPtr, jstring text, jint start, jint end,
|
||||
jfloat x, jfloat y, jint flags, jlong paintPtr) {
|
||||
jfloat x, jfloat y, jint flags, jlong paintPtr, jlong typefacePtr) {
|
||||
OpenGLRenderer* renderer = reinterpret_cast<OpenGLRenderer*>(rendererPtr);
|
||||
const jchar* textArray = env->GetStringChars(text, NULL);
|
||||
SkPaint* paint = reinterpret_cast<SkPaint*>(paintPtr);
|
||||
TypefaceImpl* typeface = reinterpret_cast<TypefaceImpl*>(typefacePtr);
|
||||
|
||||
renderText(renderer, textArray + start, end - start, x, y, flags, paint);
|
||||
renderText(renderer, textArray + start, end - start, x, y, flags, paint, typeface);
|
||||
env->ReleaseStringChars(text, textArray);
|
||||
}
|
||||
|
||||
@ -792,28 +859,30 @@ static void android_view_GLES20Canvas_drawTextOnPath(JNIEnv* env, jobject clazz,
|
||||
static void android_view_GLES20Canvas_drawTextRunArray(JNIEnv* env, jobject clazz,
|
||||
jlong rendererPtr, jcharArray text, jint index, jint count,
|
||||
jint contextIndex, jint contextCount, jfloat x, jfloat y, jint dirFlags,
|
||||
jlong paintPtr) {
|
||||
jlong paintPtr, jlong typefacePtr) {
|
||||
OpenGLRenderer* renderer = reinterpret_cast<OpenGLRenderer*>(rendererPtr);
|
||||
jchar* textArray = env->GetCharArrayElements(text, NULL);
|
||||
SkPaint* paint = reinterpret_cast<SkPaint*>(paintPtr);
|
||||
TypefaceImpl* typeface = reinterpret_cast<TypefaceImpl*>(typefacePtr);
|
||||
|
||||
renderTextRun(renderer, textArray + contextIndex, index - contextIndex,
|
||||
count, contextCount, x, y, dirFlags, paint);
|
||||
count, contextCount, x, y, dirFlags, paint, typeface);
|
||||
env->ReleaseCharArrayElements(text, textArray, JNI_ABORT);
|
||||
}
|
||||
|
||||
static void android_view_GLES20Canvas_drawTextRun(JNIEnv* env, jobject clazz,
|
||||
jlong rendererPtr, jstring text, jint start, jint end,
|
||||
jint contextStart, int contextEnd, jfloat x, jfloat y, jint dirFlags,
|
||||
jlong paintPtr) {
|
||||
jlong paintPtr, jlong typefacePtr) {
|
||||
OpenGLRenderer* renderer = reinterpret_cast<OpenGLRenderer*>(rendererPtr);
|
||||
const jchar* textArray = env->GetStringChars(text, NULL);
|
||||
jint count = end - start;
|
||||
jint contextCount = contextEnd - contextStart;
|
||||
SkPaint* paint = reinterpret_cast<SkPaint*>(paintPtr);
|
||||
TypefaceImpl* typeface = reinterpret_cast<TypefaceImpl*>(typefacePtr);
|
||||
|
||||
renderTextRun(renderer, textArray + contextStart, start - contextStart,
|
||||
count, contextCount, x, y, dirFlags, paint);
|
||||
count, contextCount, x, y, dirFlags, paint, typeface);
|
||||
env->ReleaseStringChars(text, textArray);
|
||||
}
|
||||
|
||||
@ -1055,16 +1124,16 @@ static JNINativeMethod gMethods[] = {
|
||||
{ "nSetupPaintFilter", "(JII)V", (void*) android_view_GLES20Canvas_setupPaintFilter },
|
||||
{ "nResetPaintFilter", "(J)V", (void*) android_view_GLES20Canvas_resetPaintFilter },
|
||||
|
||||
{ "nDrawText", "(J[CIIFFIJ)V", (void*) android_view_GLES20Canvas_drawTextArray },
|
||||
{ "nDrawText", "(JLjava/lang/String;IIFFIJ)V",
|
||||
{ "nDrawText", "(J[CIIFFIJJ)V", (void*) android_view_GLES20Canvas_drawTextArray },
|
||||
{ "nDrawText", "(JLjava/lang/String;IIFFIJJ)V",
|
||||
(void*) android_view_GLES20Canvas_drawText },
|
||||
|
||||
{ "nDrawTextOnPath", "(J[CIIJFFIJ)V", (void*) android_view_GLES20Canvas_drawTextArrayOnPath },
|
||||
{ "nDrawTextOnPath", "(JLjava/lang/String;IIJFFIJ)V",
|
||||
(void*) android_view_GLES20Canvas_drawTextOnPath },
|
||||
|
||||
{ "nDrawTextRun", "(J[CIIIIFFIJ)V", (void*) android_view_GLES20Canvas_drawTextRunArray },
|
||||
{ "nDrawTextRun", "(JLjava/lang/String;IIIIFFIJ)V",
|
||||
{ "nDrawTextRun", "(J[CIIIIFFIJJ)V", (void*) android_view_GLES20Canvas_drawTextRunArray },
|
||||
{ "nDrawTextRun", "(JLjava/lang/String;IIIIFFIJJ)V",
|
||||
(void*) android_view_GLES20Canvas_drawTextRun },
|
||||
|
||||
{ "nDrawPosText", "(J[CII[FJ)V", (void*) android_view_GLES20Canvas_drawPosTextArray },
|
||||
|
40
graphics/java/android/graphics/FontFamily.java
Normal file
40
graphics/java/android/graphics/FontFamily.java
Normal file
@ -0,0 +1,40 @@
|
||||
/*
|
||||
* Copyright (C) 2014 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.
|
||||
*/
|
||||
|
||||
package android.graphics;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
/**
|
||||
* A family of typefaces with different styles.
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
public class FontFamily {
|
||||
public long mNativePtr;
|
||||
public FontFamily() {
|
||||
mNativePtr = nCreateFamily();
|
||||
}
|
||||
// TODO: finalization
|
||||
|
||||
public boolean addFont(File path) {
|
||||
return nAddFont(mNativePtr, path.getAbsolutePath());
|
||||
}
|
||||
|
||||
static native long nCreateFamily();
|
||||
static native void nDestroyFamily(long nativePtr);
|
||||
static native boolean nAddFont(long nativeFamily, String path);
|
||||
}
|
@ -1686,12 +1686,12 @@ public class Paint {
|
||||
return 0;
|
||||
}
|
||||
if (!mHasCompatScaling) {
|
||||
return native_getTextWidths(mNativePaint, text, index, count, mBidiFlags, widths);
|
||||
return native_getTextWidths(mNativePaint, mNativeTypeface, text, index, count, mBidiFlags, widths);
|
||||
}
|
||||
|
||||
final float oldSize = getTextSize();
|
||||
setTextSize(oldSize*mCompatScaling);
|
||||
int res = native_getTextWidths(mNativePaint, text, index, count, mBidiFlags, widths);
|
||||
int res = native_getTextWidths(mNativePaint, mNativeTypeface, text, index, count, mBidiFlags, widths);
|
||||
setTextSize(oldSize);
|
||||
for (int i=0; i<res; i++) {
|
||||
widths[i] *= mInvCompatScaling;
|
||||
@ -1768,12 +1768,12 @@ public class Paint {
|
||||
return 0;
|
||||
}
|
||||
if (!mHasCompatScaling) {
|
||||
return native_getTextWidths(mNativePaint, text, start, end, mBidiFlags, widths);
|
||||
return native_getTextWidths(mNativePaint, mNativeTypeface, text, start, end, mBidiFlags, widths);
|
||||
}
|
||||
|
||||
final float oldSize = getTextSize();
|
||||
setTextSize(oldSize*mCompatScaling);
|
||||
int res = native_getTextWidths(mNativePaint, text, start, end, mBidiFlags, widths);
|
||||
int res = native_getTextWidths(mNativePaint, mNativeTypeface, text, start, end, mBidiFlags, widths);
|
||||
setTextSize(oldSize);
|
||||
for (int i=0; i<res; i++) {
|
||||
widths[i] *= mInvCompatScaling;
|
||||
@ -1863,13 +1863,13 @@ public class Paint {
|
||||
return 0f;
|
||||
}
|
||||
if (!mHasCompatScaling) {
|
||||
return native_getTextRunAdvances(mNativePaint, chars, index, count,
|
||||
return native_getTextRunAdvances(mNativePaint, mNativeTypeface, chars, index, count,
|
||||
contextIndex, contextCount, flags, advances, advancesIndex);
|
||||
}
|
||||
|
||||
final float oldSize = getTextSize();
|
||||
setTextSize(oldSize * mCompatScaling);
|
||||
float res = native_getTextRunAdvances(mNativePaint, chars, index, count,
|
||||
float res = native_getTextRunAdvances(mNativePaint, mNativeTypeface, chars, index, count,
|
||||
contextIndex, contextCount, flags, advances, advancesIndex);
|
||||
setTextSize(oldSize);
|
||||
|
||||
@ -1994,13 +1994,13 @@ public class Paint {
|
||||
}
|
||||
|
||||
if (!mHasCompatScaling) {
|
||||
return native_getTextRunAdvances(mNativePaint, text, start, end,
|
||||
return native_getTextRunAdvances(mNativePaint, mNativeTypeface, text, start, end,
|
||||
contextStart, contextEnd, flags, advances, advancesIndex);
|
||||
}
|
||||
|
||||
final float oldSize = getTextSize();
|
||||
setTextSize(oldSize * mCompatScaling);
|
||||
float totalAdvance = native_getTextRunAdvances(mNativePaint, text, start, end,
|
||||
float totalAdvance = native_getTextRunAdvances(mNativePaint, mNativeTypeface, text, start, end,
|
||||
contextStart, contextEnd, flags, advances, advancesIndex);
|
||||
setTextSize(oldSize);
|
||||
|
||||
@ -2265,19 +2265,19 @@ public class Paint {
|
||||
private static native void native_setTextLocale(long native_object,
|
||||
String locale);
|
||||
|
||||
private static native int native_getTextWidths(long native_object,
|
||||
private static native int native_getTextWidths(long native_object, long native_typeface,
|
||||
char[] text, int index, int count, int bidiFlags, float[] widths);
|
||||
private static native int native_getTextWidths(long native_object,
|
||||
private static native int native_getTextWidths(long native_object, long native_typeface,
|
||||
String text, int start, int end, int bidiFlags, float[] widths);
|
||||
|
||||
private static native int native_getTextGlyphs(long native_object,
|
||||
String text, int start, int end, int contextStart, int contextEnd,
|
||||
int flags, char[] glyphs);
|
||||
|
||||
private static native float native_getTextRunAdvances(long native_object,
|
||||
private static native float native_getTextRunAdvances(long native_object, long native_typeface,
|
||||
char[] text, int index, int count, int contextIndex, int contextCount,
|
||||
int flags, float[] advances, int advancesIndex);
|
||||
private static native float native_getTextRunAdvances(long native_object,
|
||||
private static native float native_getTextRunAdvances(long native_object, long native_typeface,
|
||||
String text, int start, int end, int contextStart, int contextEnd,
|
||||
int flags, float[] advances, int advancesIndex);
|
||||
|
||||
|
@ -17,6 +17,7 @@
|
||||
package android.graphics;
|
||||
|
||||
import android.content.res.AssetManager;
|
||||
import android.util.Log;
|
||||
import android.util.SparseArray;
|
||||
import android.util.LongSparseArray;
|
||||
|
||||
@ -173,6 +174,22 @@ public class Typeface {
|
||||
return new Typeface(nativeCreateFromFile(path));
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new typeface from an array of font families.
|
||||
*
|
||||
* @param families array of font families
|
||||
* @hide
|
||||
*/
|
||||
public static Typeface createFromFamilies(FontFamily[] families) {
|
||||
long[] ptrArray = new long[families.length];
|
||||
Log.d("Minikin", "# of families: " + families.length);
|
||||
for (int i = 0; i < families.length; i++) {
|
||||
Log.d("Minikin", "family ptr: " + families[i].mNativePtr);
|
||||
ptrArray[i] = families[i].mNativePtr;
|
||||
}
|
||||
return new Typeface(nativeCreateFromArray(ptrArray));
|
||||
}
|
||||
|
||||
// don't allow clients to call this directly
|
||||
private Typeface(long ni) {
|
||||
if (ni == 0) {
|
||||
@ -234,4 +251,5 @@ public class Typeface {
|
||||
private static native int nativeGetStyle(long native_instance);
|
||||
private static native long nativeCreateFromAsset(AssetManager mgr, String path);
|
||||
private static native long nativeCreateFromFile(String path);
|
||||
private static native long nativeCreateFromArray(long[] familyArray);
|
||||
}
|
||||
|
Reference in New Issue
Block a user