Merge "Add Paint.hasGlyph method"
This commit is contained in:
@@ -11388,6 +11388,7 @@ package android.graphics {
|
||||
method public int getTextWidths(java.lang.String, float[]);
|
||||
method public android.graphics.Typeface getTypeface();
|
||||
method public android.graphics.Xfermode getXfermode();
|
||||
method public boolean hasGlyph(java.lang.String);
|
||||
method public final boolean isAntiAlias();
|
||||
method public final boolean isDither();
|
||||
method public boolean isElegantTextHeight();
|
||||
|
||||
@@ -11677,6 +11677,7 @@ package android.graphics {
|
||||
method public int getTextWidths(java.lang.String, float[]);
|
||||
method public android.graphics.Typeface getTypeface();
|
||||
method public android.graphics.Xfermode getXfermode();
|
||||
method public boolean hasGlyph(java.lang.String);
|
||||
method public final boolean isAntiAlias();
|
||||
method public final boolean isDither();
|
||||
method public boolean isElegantTextHeight();
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
#include "GraphicsJNI.h"
|
||||
#include "core_jni_helpers.h"
|
||||
#include <ScopedUtfChars.h>
|
||||
#include <ScopedStringChars.h>
|
||||
|
||||
#include "SkBlurDrawLooper.h"
|
||||
#include "SkColorFilter.h"
|
||||
@@ -41,6 +42,8 @@
|
||||
#include "Paint.h"
|
||||
#include "TypefaceImpl.h"
|
||||
|
||||
#include <vector>
|
||||
|
||||
// temporary for debugging
|
||||
#include <Caches.h>
|
||||
#include <utils/Log.h>
|
||||
@@ -972,6 +975,68 @@ public:
|
||||
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[] = {
|
||||
@@ -1057,6 +1122,7 @@ static JNINativeMethod methods[] = {
|
||||
(void*) PaintGlue::getStringBounds },
|
||||
{"nativeGetCharArrayBounds", "(JJ[CIIILandroid/graphics/Rect;)V",
|
||||
(void*) PaintGlue::getCharArrayBounds },
|
||||
{"native_hasGlyph", "(JJILjava/lang/String;)Z", (void*) PaintGlue::hasGlyph },
|
||||
|
||||
{"native_setShadowLayer", "!(JFFFI)V", (void*)PaintGlue::setShadowLayer},
|
||||
{"native_hasShadowLayer", "!(J)Z", (void*)PaintGlue::hasShadowLayer}
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
#include "core_jni_helpers.h"
|
||||
|
||||
#include "GraphicsJNI.h"
|
||||
#include <ScopedPrimitiveArray.h>
|
||||
#include "ScopedPrimitiveArray.h"
|
||||
#include "SkTypeface.h"
|
||||
#include "TypefaceImpl.h"
|
||||
#include <android_runtime/android_util_AssetManager.h>
|
||||
|
||||
@@ -2249,6 +2249,26 @@ public class Paint {
|
||||
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
|
||||
protected void finalize() throws Throwable {
|
||||
try {
|
||||
@@ -2334,4 +2354,6 @@ public class Paint {
|
||||
String settings);
|
||||
private static native int native_getHyphenEdit(long native_object);
|
||||
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);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user