diff options
-rw-r--r-- | core/java/android/view/GLES20Canvas.java | 26 | ||||
-rw-r--r-- | core/jni/Android.mk | 4 | ||||
-rw-r--r-- | core/jni/AndroidRuntime.cpp | 2 | ||||
-rw-r--r-- | core/jni/android/graphics/Canvas.cpp | 13 | ||||
-rw-r--r-- | core/jni/android/graphics/FontFamily.cpp | 75 | ||||
-rw-r--r-- | core/jni/android/graphics/Graphics.cpp | 12 | ||||
-rw-r--r-- | core/jni/android/graphics/GraphicsJNI.h | 2 | ||||
-rw-r--r-- | core/jni/android/graphics/MinikinSkia.cpp | 33 | ||||
-rw-r--r-- | core/jni/android/graphics/MinikinSkia.h | 4 | ||||
-rw-r--r-- | core/jni/android/graphics/MinikinUtils.cpp | 38 | ||||
-rw-r--r-- | core/jni/android/graphics/MinikinUtils.h | 37 | ||||
-rw-r--r-- | core/jni/android/graphics/Paint.cpp | 77 | ||||
-rw-r--r-- | core/jni/android/graphics/Typeface.cpp | 10 | ||||
-rw-r--r-- | core/jni/android/graphics/TypefaceImpl.cpp | 22 | ||||
-rw-r--r-- | core/jni/android/graphics/TypefaceImpl.h | 6 | ||||
-rw-r--r-- | core/jni/android_view_GLES20Canvas.cpp | 97 | ||||
-rw-r--r-- | graphics/java/android/graphics/FontFamily.java | 40 | ||||
-rw-r--r-- | graphics/java/android/graphics/Paint.java | 24 | ||||
-rw-r--r-- | graphics/java/android/graphics/Typeface.java | 18 |
19 files changed, 467 insertions, 73 deletions
diff --git a/core/java/android/view/GLES20Canvas.java b/core/java/android/view/GLES20Canvas.java index 6c451eb..a272296 100644 --- a/core/java/android/view/GLES20Canvas.java +++ b/core/java/android/view/GLES20Canvas.java @@ -1127,14 +1127,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) { @@ -1143,7 +1144,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); @@ -1151,7 +1152,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 { @@ -1167,21 +1168,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); } @@ -1235,14 +1237,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, @@ -1257,7 +1259,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); @@ -1267,7 +1269,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 { @@ -1276,7 +1278,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, diff --git a/core/jni/Android.mk b/core/jni/Android.mk index 7dc639d..07597a0 100644 --- a/core/jni/Android.mk +++ b/core/jni/Android.mk @@ -95,6 +95,7 @@ LOCAL_SRC_FILES:= \ android/graphics/CanvasProperty.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 \ @@ -231,7 +232,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 diff --git a/core/jni/AndroidRuntime.cpp b/core/jni/AndroidRuntime.cpp index 1038fa0..767439a 100644 --- a/core/jni/AndroidRuntime.cpp +++ b/core/jni/AndroidRuntime.cpp @@ -108,6 +108,7 @@ extern int register_android_graphics_Canvas(JNIEnv* env); extern int register_android_graphics_CanvasProperty(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); @@ -1236,6 +1237,7 @@ static const RegJNIRec gRegJNI[] = { REG_JNI(register_android_graphics_CanvasProperty), 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), diff --git a/core/jni/android/graphics/Canvas.cpp b/core/jni/android/graphics/Canvas.cpp index 2adbf3a..9e0996a 100644 --- a/core/jni/android/graphics/Canvas.cpp +++ b/core/jni/android/graphics/Canvas.cpp @@ -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 diff --git a/core/jni/android/graphics/FontFamily.cpp b/core/jni/android/graphics/FontFamily.cpp new file mode 100644 index 0000000..5782312 --- /dev/null +++ b/core/jni/android/graphics/FontFamily.cpp @@ -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)); +} + +} diff --git a/core/jni/android/graphics/Graphics.cpp b/core/jni/android/graphics/Graphics.cpp index e4c74b2..ed28c24 100644 --- a/core/jni/android/graphics/Graphics.cpp +++ b/core/jni/android/graphics/Graphics.cpp @@ -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"); diff --git a/core/jni/android/graphics/GraphicsJNI.h b/core/jni/android/graphics/GraphicsJNI.h index cb154aa..4c42341 100644 --- a/core/jni/android/graphics/GraphicsJNI.h +++ b/core/jni/android/graphics/GraphicsJNI.h @@ -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); diff --git a/core/jni/android/graphics/MinikinSkia.cpp b/core/jni/android/graphics/MinikinSkia.cpp index 622c935..60d1fd8 100644 --- a/core/jni/android/graphics/MinikinSkia.cpp +++ b/core/jni/android/graphics/MinikinSkia.cpp @@ -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) { diff --git a/core/jni/android/graphics/MinikinSkia.h b/core/jni/android/graphics/MinikinSkia.h index 0edb557..7a8954d 100644 --- a/core/jni/android/graphics/MinikinSkia.h +++ b/core/jni/android/graphics/MinikinSkia.h @@ -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
\ No newline at end of file diff --git a/core/jni/android/graphics/MinikinUtils.cpp b/core/jni/android/graphics/MinikinUtils.cpp new file mode 100644 index 0000000..0f13271 --- /dev/null +++ b/core/jni/android/graphics/MinikinUtils.cpp @@ -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); +} + +} diff --git a/core/jni/android/graphics/MinikinUtils.h b/core/jni/android/graphics/MinikinUtils.h new file mode 100644 index 0000000..5668ad7 --- /dev/null +++ b/core/jni/android/graphics/MinikinUtils.h @@ -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 diff --git a/core/jni/android/graphics/Paint.cpp b/core/jni/android/graphics/Paint.cpp index 22c17dd..acfab56 100644 --- a/core/jni/android/graphics/Paint.cpp +++ b/core/jni/android/graphics/Paint.cpp @@ -36,6 +36,12 @@ #include "utils/Blur.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> @@ -494,8 +500,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; @@ -520,8 +534,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; @@ -540,15 +562,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); @@ -568,27 +598,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; } @@ -634,7 +673,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); @@ -657,8 +696,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); @@ -668,22 +715,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); @@ -954,11 +1005,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}, diff --git a/core/jni/android/graphics/Typeface.cpp b/core/jni/android/graphics/Typeface.cpp index a349a7f..02b04de 100644 --- a/core/jni/android/graphics/Typeface.cpp +++ b/core/jni/android/graphics/Typeface.cpp @@ -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) diff --git a/core/jni/android/graphics/TypefaceImpl.cpp b/core/jni/android/graphics/TypefaceImpl.cpp index f6d3a6e..a60dd7e 100644 --- a/core/jni/android/graphics/TypefaceImpl.cpp +++ b/core/jni/android/graphics/TypefaceImpl.cpp @@ -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); } diff --git a/core/jni/android/graphics/TypefaceImpl.h b/core/jni/android/graphics/TypefaceImpl.h index 4c51bec..4e021cd 100644 --- a/core/jni/android/graphics/TypefaceImpl.h +++ b/core/jni/android/graphics/TypefaceImpl.h @@ -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); diff --git a/core/jni/android_view_GLES20Canvas.cpp b/core/jni/android_view_GLES20Canvas.cpp index fae6698..c3fe4a3 100644 --- a/core/jni/android_view_GLES20Canvas.cpp +++ b/core/jni/android_view_GLES20Canvas.cpp @@ -51,6 +51,12 @@ #include <RenderNode.h> #include <CanvasProperty.h> +#ifdef USE_MINIKIN +#include <minikin/Layout.h> +#include "MinikinSkia.h" +#include "MinikinUtils.h" +#endif + #include <TextLayout.h> #include <TextLayoutCache.h> @@ -661,8 +667,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) { @@ -680,6 +736,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, @@ -698,7 +755,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) { @@ -716,27 +780,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); } @@ -769,28 +836,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); } @@ -1028,16 +1097,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 }, diff --git a/graphics/java/android/graphics/FontFamily.java b/graphics/java/android/graphics/FontFamily.java new file mode 100644 index 0000000..afa8706 --- /dev/null +++ b/graphics/java/android/graphics/FontFamily.java @@ -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); +} diff --git a/graphics/java/android/graphics/Paint.java b/graphics/java/android/graphics/Paint.java index 457b3ea..bdef404 100644 --- a/graphics/java/android/graphics/Paint.java +++ b/graphics/java/android/graphics/Paint.java @@ -1655,12 +1655,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; @@ -1737,12 +1737,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; @@ -1832,13 +1832,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); @@ -1963,13 +1963,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); @@ -2234,19 +2234,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); diff --git a/graphics/java/android/graphics/Typeface.java b/graphics/java/android/graphics/Typeface.java index 73e0e8d..4b95fcd 100644 --- a/graphics/java/android/graphics/Typeface.java +++ b/graphics/java/android/graphics/Typeface.java @@ -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); } |