summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--core/java/android/view/GLES20Canvas.java26
-rw-r--r--core/jni/Android.mk4
-rw-r--r--core/jni/AndroidRuntime.cpp2
-rw-r--r--core/jni/android/graphics/Canvas.cpp13
-rw-r--r--core/jni/android/graphics/FontFamily.cpp75
-rw-r--r--core/jni/android/graphics/Graphics.cpp12
-rw-r--r--core/jni/android/graphics/GraphicsJNI.h2
-rw-r--r--core/jni/android/graphics/MinikinSkia.cpp33
-rw-r--r--core/jni/android/graphics/MinikinSkia.h4
-rw-r--r--core/jni/android/graphics/MinikinUtils.cpp38
-rw-r--r--core/jni/android/graphics/MinikinUtils.h37
-rw-r--r--core/jni/android/graphics/Paint.cpp77
-rw-r--r--core/jni/android/graphics/Typeface.cpp10
-rw-r--r--core/jni/android/graphics/TypefaceImpl.cpp22
-rw-r--r--core/jni/android/graphics/TypefaceImpl.h6
-rw-r--r--core/jni/android_view_GLES20Canvas.cpp97
-rw-r--r--graphics/java/android/graphics/FontFamily.java40
-rw-r--r--graphics/java/android/graphics/Paint.java24
-rw-r--r--graphics/java/android/graphics/Typeface.java18
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);
}