Loading api/current.txt +1 −0 Original line number Original line Diff line number Diff line Loading @@ -11388,6 +11388,7 @@ package android.graphics { method public int getTextWidths(java.lang.String, float[]); method public int getTextWidths(java.lang.String, float[]); method public android.graphics.Typeface getTypeface(); method public android.graphics.Typeface getTypeface(); method public android.graphics.Xfermode getXfermode(); method public android.graphics.Xfermode getXfermode(); method public boolean hasGlyph(java.lang.String); method public final boolean isAntiAlias(); method public final boolean isAntiAlias(); method public final boolean isDither(); method public final boolean isDither(); method public boolean isElegantTextHeight(); method public boolean isElegantTextHeight(); api/system-current.txt +1 −0 Original line number Original line Diff line number Diff line Loading @@ -11677,6 +11677,7 @@ package android.graphics { method public int getTextWidths(java.lang.String, float[]); method public int getTextWidths(java.lang.String, float[]); method public android.graphics.Typeface getTypeface(); method public android.graphics.Typeface getTypeface(); method public android.graphics.Xfermode getXfermode(); method public android.graphics.Xfermode getXfermode(); method public boolean hasGlyph(java.lang.String); method public final boolean isAntiAlias(); method public final boolean isAntiAlias(); method public final boolean isDither(); method public final boolean isDither(); method public boolean isElegantTextHeight(); method public boolean isElegantTextHeight(); core/jni/android/graphics/Paint.cpp +66 −0 Original line number Original line Diff line number Diff line Loading @@ -23,6 +23,7 @@ #include "GraphicsJNI.h" #include "GraphicsJNI.h" #include "core_jni_helpers.h" #include "core_jni_helpers.h" #include <ScopedUtfChars.h> #include <ScopedUtfChars.h> #include <ScopedStringChars.h> #include "SkBlurDrawLooper.h" #include "SkBlurDrawLooper.h" #include "SkColorFilter.h" #include "SkColorFilter.h" Loading @@ -41,6 +42,8 @@ #include "Paint.h" #include "Paint.h" #include "TypefaceImpl.h" #include "TypefaceImpl.h" #include <vector> // temporary for debugging // temporary for debugging #include <Caches.h> #include <Caches.h> #include <utils/Log.h> #include <utils/Log.h> Loading Loading @@ -972,6 +975,68 @@ public: JNI_ABORT); JNI_ABORT); } } static jboolean layoutContainsNotdef(const Layout& layout) { for (size_t i = 0; i < layout.nGlyphs(); i++) { if (layout.getGlyphId(i) == 0) { return true; } } return false; } static jboolean hasGlyphVariation(const Paint* paint, TypefaceImpl* typeface, jint bidiFlags, const jchar* chars, size_t size) { // TODO: query font for whether character has variation selector; requires a corresponding // function in Minikin. return false; } static jboolean hasGlyph(JNIEnv *env, jclass, jlong paintHandle, jlong typefaceHandle, jint bidiFlags, jstring string) { const Paint* paint = reinterpret_cast<Paint*>(paintHandle); TypefaceImpl* typeface = reinterpret_cast<TypefaceImpl*>(typefaceHandle); ScopedStringChars str(env, string); /* start by rejecting variation selectors (not supported yet) */ size_t nChars = 0; for (size_t i = 0; i < str.size(); i++) { jchar c = str[i]; if (0xDC00 <= c && c <= 0xDFFF) { // invalid UTF-16, unpaired trailing surrogate return false; } else if (0xD800 <= c && c <= 0xDBFF) { if (i + 1 == str.size()) { // invalid UTF-16, unpaired leading surrogate at end of string return false; } i++; jchar c2 = str[i]; if (!(0xDC00 <= c2 && c2 <= 0xDFFF)) { // invalid UTF-16, unpaired leading surrogate return false; } // UTF-16 encoding of range U+E0100..U+E01EF is DB40 DD00 .. DB40 DDEF if (c == 0xDB40 && 0xDD00 <= c2 && c2 <= 0xDDEF) { return hasGlyphVariation(paint, typeface, bidiFlags, str.get(), str.size()); } } else if (0xFE00 <= c && c <= 0xFE0F) { return hasGlyphVariation(paint, typeface, bidiFlags, str.get(), str.size()); } nChars++; } Layout layout; MinikinUtils::doLayout(&layout, paint, bidiFlags, typeface, str.get(), 0, str.size(), str.size()); size_t nGlyphs = layout.nGlyphs(); if (nGlyphs != 1 && nChars > 1) { // multiple-character input, and was not a ligature // TODO: handle ZWJ/ZWNJ characters specially so we can detect certain ligatures // in joining scripts, such as Arabic and Mongolian. return false; } return nGlyphs > 0 && !layoutContainsNotdef(layout); } }; }; static JNINativeMethod methods[] = { static JNINativeMethod methods[] = { Loading Loading @@ -1057,6 +1122,7 @@ static JNINativeMethod methods[] = { (void*) PaintGlue::getStringBounds }, (void*) PaintGlue::getStringBounds }, {"nativeGetCharArrayBounds", "(JJ[CIIILandroid/graphics/Rect;)V", {"nativeGetCharArrayBounds", "(JJ[CIIILandroid/graphics/Rect;)V", (void*) PaintGlue::getCharArrayBounds }, (void*) PaintGlue::getCharArrayBounds }, {"native_hasGlyph", "(JJILjava/lang/String;)Z", (void*) PaintGlue::hasGlyph }, {"native_setShadowLayer", "!(JFFFI)V", (void*)PaintGlue::setShadowLayer}, {"native_setShadowLayer", "!(JFFFI)V", (void*)PaintGlue::setShadowLayer}, {"native_hasShadowLayer", "!(J)Z", (void*)PaintGlue::hasShadowLayer} {"native_hasShadowLayer", "!(J)Z", (void*)PaintGlue::hasShadowLayer} Loading core/jni/android/graphics/Typeface.cpp +1 −1 Original line number Original line Diff line number Diff line Loading @@ -18,7 +18,7 @@ #include "core_jni_helpers.h" #include "core_jni_helpers.h" #include "GraphicsJNI.h" #include "GraphicsJNI.h" #include <ScopedPrimitiveArray.h> #include "ScopedPrimitiveArray.h" #include "SkTypeface.h" #include "SkTypeface.h" #include "TypefaceImpl.h" #include "TypefaceImpl.h" #include <android_runtime/android_util_AssetManager.h> #include <android_runtime/android_util_AssetManager.h> Loading graphics/java/android/graphics/Paint.java +22 −0 Original line number Original line Diff line number Diff line Loading @@ -2249,6 +2249,26 @@ public class Paint { bounds); bounds); } } /** * Determine whether the typeface set on the paint has a glyph supporting the string. The * simplest case is when the string contains a single character, in which this method * determines whether the font has the character. In the case of multiple characters, the * method returns true if there is a single glyph representing the ligature. For example, if * the input is a pair of regional indicator symbols, determine whether there is an emoji flag * for the pair. * * Finally, if the string contains a variation selector, the method only returns true if * the fonts contains a glyph specific to that variation. * * Checking is done on the entire fallback chain, not just the immediate font referenced. * * @param string the string to test whether there is glyph support * @return true if the typeface has a glyph for the string */ public boolean hasGlyph(String string) { return native_hasGlyph(mNativePaint, mNativeTypeface, mBidiFlags, string); } @Override @Override protected void finalize() throws Throwable { protected void finalize() throws Throwable { try { try { Loading Loading @@ -2334,4 +2354,6 @@ public class Paint { String settings); String settings); private static native int native_getHyphenEdit(long native_object); private static native int native_getHyphenEdit(long native_object); private static native void native_setHyphenEdit(long native_object, int hyphen); private static native void native_setHyphenEdit(long native_object, int hyphen); private static native boolean native_hasGlyph(long native_object, long native_typeface, int bidiFlags, String string); } } Loading
api/current.txt +1 −0 Original line number Original line Diff line number Diff line Loading @@ -11388,6 +11388,7 @@ package android.graphics { method public int getTextWidths(java.lang.String, float[]); method public int getTextWidths(java.lang.String, float[]); method public android.graphics.Typeface getTypeface(); method public android.graphics.Typeface getTypeface(); method public android.graphics.Xfermode getXfermode(); method public android.graphics.Xfermode getXfermode(); method public boolean hasGlyph(java.lang.String); method public final boolean isAntiAlias(); method public final boolean isAntiAlias(); method public final boolean isDither(); method public final boolean isDither(); method public boolean isElegantTextHeight(); method public boolean isElegantTextHeight();
api/system-current.txt +1 −0 Original line number Original line Diff line number Diff line Loading @@ -11677,6 +11677,7 @@ package android.graphics { method public int getTextWidths(java.lang.String, float[]); method public int getTextWidths(java.lang.String, float[]); method public android.graphics.Typeface getTypeface(); method public android.graphics.Typeface getTypeface(); method public android.graphics.Xfermode getXfermode(); method public android.graphics.Xfermode getXfermode(); method public boolean hasGlyph(java.lang.String); method public final boolean isAntiAlias(); method public final boolean isAntiAlias(); method public final boolean isDither(); method public final boolean isDither(); method public boolean isElegantTextHeight(); method public boolean isElegantTextHeight();
core/jni/android/graphics/Paint.cpp +66 −0 Original line number Original line Diff line number Diff line Loading @@ -23,6 +23,7 @@ #include "GraphicsJNI.h" #include "GraphicsJNI.h" #include "core_jni_helpers.h" #include "core_jni_helpers.h" #include <ScopedUtfChars.h> #include <ScopedUtfChars.h> #include <ScopedStringChars.h> #include "SkBlurDrawLooper.h" #include "SkBlurDrawLooper.h" #include "SkColorFilter.h" #include "SkColorFilter.h" Loading @@ -41,6 +42,8 @@ #include "Paint.h" #include "Paint.h" #include "TypefaceImpl.h" #include "TypefaceImpl.h" #include <vector> // temporary for debugging // temporary for debugging #include <Caches.h> #include <Caches.h> #include <utils/Log.h> #include <utils/Log.h> Loading Loading @@ -972,6 +975,68 @@ public: JNI_ABORT); JNI_ABORT); } } static jboolean layoutContainsNotdef(const Layout& layout) { for (size_t i = 0; i < layout.nGlyphs(); i++) { if (layout.getGlyphId(i) == 0) { return true; } } return false; } static jboolean hasGlyphVariation(const Paint* paint, TypefaceImpl* typeface, jint bidiFlags, const jchar* chars, size_t size) { // TODO: query font for whether character has variation selector; requires a corresponding // function in Minikin. return false; } static jboolean hasGlyph(JNIEnv *env, jclass, jlong paintHandle, jlong typefaceHandle, jint bidiFlags, jstring string) { const Paint* paint = reinterpret_cast<Paint*>(paintHandle); TypefaceImpl* typeface = reinterpret_cast<TypefaceImpl*>(typefaceHandle); ScopedStringChars str(env, string); /* start by rejecting variation selectors (not supported yet) */ size_t nChars = 0; for (size_t i = 0; i < str.size(); i++) { jchar c = str[i]; if (0xDC00 <= c && c <= 0xDFFF) { // invalid UTF-16, unpaired trailing surrogate return false; } else if (0xD800 <= c && c <= 0xDBFF) { if (i + 1 == str.size()) { // invalid UTF-16, unpaired leading surrogate at end of string return false; } i++; jchar c2 = str[i]; if (!(0xDC00 <= c2 && c2 <= 0xDFFF)) { // invalid UTF-16, unpaired leading surrogate return false; } // UTF-16 encoding of range U+E0100..U+E01EF is DB40 DD00 .. DB40 DDEF if (c == 0xDB40 && 0xDD00 <= c2 && c2 <= 0xDDEF) { return hasGlyphVariation(paint, typeface, bidiFlags, str.get(), str.size()); } } else if (0xFE00 <= c && c <= 0xFE0F) { return hasGlyphVariation(paint, typeface, bidiFlags, str.get(), str.size()); } nChars++; } Layout layout; MinikinUtils::doLayout(&layout, paint, bidiFlags, typeface, str.get(), 0, str.size(), str.size()); size_t nGlyphs = layout.nGlyphs(); if (nGlyphs != 1 && nChars > 1) { // multiple-character input, and was not a ligature // TODO: handle ZWJ/ZWNJ characters specially so we can detect certain ligatures // in joining scripts, such as Arabic and Mongolian. return false; } return nGlyphs > 0 && !layoutContainsNotdef(layout); } }; }; static JNINativeMethod methods[] = { static JNINativeMethod methods[] = { Loading Loading @@ -1057,6 +1122,7 @@ static JNINativeMethod methods[] = { (void*) PaintGlue::getStringBounds }, (void*) PaintGlue::getStringBounds }, {"nativeGetCharArrayBounds", "(JJ[CIIILandroid/graphics/Rect;)V", {"nativeGetCharArrayBounds", "(JJ[CIIILandroid/graphics/Rect;)V", (void*) PaintGlue::getCharArrayBounds }, (void*) PaintGlue::getCharArrayBounds }, {"native_hasGlyph", "(JJILjava/lang/String;)Z", (void*) PaintGlue::hasGlyph }, {"native_setShadowLayer", "!(JFFFI)V", (void*)PaintGlue::setShadowLayer}, {"native_setShadowLayer", "!(JFFFI)V", (void*)PaintGlue::setShadowLayer}, {"native_hasShadowLayer", "!(J)Z", (void*)PaintGlue::hasShadowLayer} {"native_hasShadowLayer", "!(J)Z", (void*)PaintGlue::hasShadowLayer} Loading
core/jni/android/graphics/Typeface.cpp +1 −1 Original line number Original line Diff line number Diff line Loading @@ -18,7 +18,7 @@ #include "core_jni_helpers.h" #include "core_jni_helpers.h" #include "GraphicsJNI.h" #include "GraphicsJNI.h" #include <ScopedPrimitiveArray.h> #include "ScopedPrimitiveArray.h" #include "SkTypeface.h" #include "SkTypeface.h" #include "TypefaceImpl.h" #include "TypefaceImpl.h" #include <android_runtime/android_util_AssetManager.h> #include <android_runtime/android_util_AssetManager.h> Loading
graphics/java/android/graphics/Paint.java +22 −0 Original line number Original line Diff line number Diff line Loading @@ -2249,6 +2249,26 @@ public class Paint { bounds); bounds); } } /** * Determine whether the typeface set on the paint has a glyph supporting the string. The * simplest case is when the string contains a single character, in which this method * determines whether the font has the character. In the case of multiple characters, the * method returns true if there is a single glyph representing the ligature. For example, if * the input is a pair of regional indicator symbols, determine whether there is an emoji flag * for the pair. * * Finally, if the string contains a variation selector, the method only returns true if * the fonts contains a glyph specific to that variation. * * Checking is done on the entire fallback chain, not just the immediate font referenced. * * @param string the string to test whether there is glyph support * @return true if the typeface has a glyph for the string */ public boolean hasGlyph(String string) { return native_hasGlyph(mNativePaint, mNativeTypeface, mBidiFlags, string); } @Override @Override protected void finalize() throws Throwable { protected void finalize() throws Throwable { try { try { Loading Loading @@ -2334,4 +2354,6 @@ public class Paint { String settings); String settings); private static native int native_getHyphenEdit(long native_object); private static native int native_getHyphenEdit(long native_object); private static native void native_setHyphenEdit(long native_object, int hyphen); private static native void native_setHyphenEdit(long native_object, int hyphen); private static native boolean native_hasGlyph(long native_object, long native_typeface, int bidiFlags, String string); } }