Android: Fix exceptions in ExtractStyle.java on Android L
Android L adds support for 64 bit (arm and x86) and they did lots of changes that are incompatible with old implementation. Task-number: QTBUG-40120 Change-Id: I69b78a9eed896d2ddabc1bf2a55886faeae47974 Reviewed-by: J-P Nurmi <jpnurmi@digia.com>
This commit is contained in:
parent
61179c1447
commit
c0c80f14af
53
src/3rdparty/android/extract.h
vendored
53
src/3rdparty/android/extract.h
vendored
@ -114,4 +114,57 @@ struct Res_png_9patch
|
||||
static Res_png_9patch* deserialize(const void* data);
|
||||
};
|
||||
|
||||
struct Res_png_9patch20
|
||||
{
|
||||
Res_png_9patch20() : wasDeserialized(false), numXDivs(0), numYDivs(0), numColors(0), xDivsOffset(0),
|
||||
yDivsOffset(0),paddingLeft(0), paddingRight(0), paddingTop(0), paddingBottom(0),
|
||||
colorsOffset(0) { }
|
||||
|
||||
int8_t wasDeserialized;
|
||||
int8_t numXDivs;
|
||||
int8_t numYDivs;
|
||||
int8_t numColors;
|
||||
|
||||
// The offset (from the start of this structure) to the xDivs & yDivs
|
||||
// array for this 9patch. To get a pointer to this array, call
|
||||
// getXDivs or getYDivs. Note that the serialized form for 9patches places
|
||||
// the xDivs, yDivs and colors arrays immediately after the location
|
||||
// of the Res_png_9patch struct.
|
||||
uint32_t xDivsOffset;
|
||||
uint32_t yDivsOffset;
|
||||
|
||||
int32_t paddingLeft, paddingRight;
|
||||
int32_t paddingTop, paddingBottom;
|
||||
|
||||
enum {
|
||||
// The 9 patch segment is not a solid color.
|
||||
NO_COLOR = 0x00000001,
|
||||
|
||||
// The 9 patch segment is completely transparent.
|
||||
TRANSPARENT_COLOR = 0x00000000
|
||||
};
|
||||
|
||||
// The offset (from the start of this structure) to the colors array
|
||||
// for this 9patch.
|
||||
uint32_t colorsOffset;
|
||||
|
||||
// Deserialize/Unmarshall the patch data
|
||||
static Res_png_9patch20* deserialize(void* data);
|
||||
|
||||
// These tell where the next section of a patch starts.
|
||||
// For example, the first patch includes the pixels from
|
||||
// 0 to xDivs[0]-1 and the second patch includes the pixels
|
||||
// from xDivs[0] to xDivs[1]-1.
|
||||
inline int32_t* getXDivs() const {
|
||||
return reinterpret_cast<int32_t*>(reinterpret_cast<uintptr_t>(this) + xDivsOffset);
|
||||
}
|
||||
inline int32_t* getYDivs() const {
|
||||
return reinterpret_cast<int32_t*>(reinterpret_cast<uintptr_t>(this) + yDivsOffset);
|
||||
}
|
||||
inline uint32_t* getColors() const {
|
||||
return reinterpret_cast<uint32_t*>(reinterpret_cast<uintptr_t>(this) + colorsOffset);
|
||||
}
|
||||
|
||||
} __attribute__((packed));
|
||||
|
||||
#endif
|
||||
|
@ -90,6 +90,9 @@ public class ExtractStyle {
|
||||
|
||||
native static int[] extractChunkInfo(byte[] chunkData);
|
||||
native static int[] extractNativeChunkInfo(int nativeChunk);
|
||||
native static int[] extractChunkInfo20(byte[] chunkData);
|
||||
native static int[] extractNativeChunkInfo20(long nativeChunk);
|
||||
|
||||
|
||||
Class<?> styleableClass = getStylableClass();
|
||||
final int[] EMPTY_STATE_SET = {};
|
||||
@ -337,6 +340,9 @@ public class ExtractStyle {
|
||||
}
|
||||
|
||||
public void drawPatch(Bitmap bmp, byte[] chunks, RectF dst, Paint paint) {
|
||||
if (Build.VERSION.SDK_INT > 19)
|
||||
chunkData = extractChunkInfo20(chunks);
|
||||
else
|
||||
chunkData = extractChunkInfo(chunks);
|
||||
}
|
||||
}
|
||||
@ -630,6 +636,8 @@ public class ExtractStyle {
|
||||
JSONObject stateJson = new JSONObject();
|
||||
final Drawable d = (Drawable) StateListDrawable.class.getMethod("getStateDrawable", Integer.TYPE).invoke(stateList, i);
|
||||
final int [] states = (int[]) StateListDrawable.class.getMethod("getStateSet", Integer.TYPE).invoke(stateList, i);
|
||||
if (states == null)
|
||||
continue;
|
||||
stateJson.put("states", getStatesList(states));
|
||||
stateJson.put("drawable", getDrawable(d, filename+"__"+getStatesName(states)));
|
||||
array.put(stateJson);
|
||||
@ -658,9 +666,7 @@ public class ExtractStyle {
|
||||
int [] intArray=(int[]) gradientStateClass.getField("mColors").get(obj);
|
||||
json.put("colors",getJsonArray(intArray, 0, intArray.length));
|
||||
json.put("positions",getJsonArray((float[]) gradientStateClass.getField("mPositions").get(obj)));
|
||||
json.put("solidColor",gradientStateClass.getField("mSolidColor").getInt(obj));
|
||||
json.put("strokeWidth",gradientStateClass.getField("mStrokeWidth").getInt(obj));
|
||||
json.put("strokeColor",gradientStateClass.getField("mStrokeColor").getInt(obj));
|
||||
json.put("strokeDashWidth",gradientStateClass.getField("mStrokeDashWidth").getFloat(obj));
|
||||
json.put("strokeDashGap",gradientStateClass.getField("mStrokeDashGap").getFloat(obj));
|
||||
json.put("radius",gradientStateClass.getField("mRadius").getFloat(obj));
|
||||
@ -676,6 +682,10 @@ public class ExtractStyle {
|
||||
json.put("thicknessRatio",gradientStateClass.getField("mThicknessRatio").getFloat(obj));
|
||||
json.put("innerRadius",gradientStateClass.getField("mInnerRadius").getInt(obj));
|
||||
json.put("thickness",gradientStateClass.getField("mThickness").getInt(obj));
|
||||
if (Build.VERSION.SDK_INT < 20) {
|
||||
json.put("solidColor",gradientStateClass.getField("mSolidColor").getInt(obj));
|
||||
json.put("strokeColor",gradientStateClass.getField("mStrokeColor").getInt(obj));
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
@ -789,6 +799,8 @@ public class ExtractStyle {
|
||||
{
|
||||
Field mNativeChunk = np.getClass().getDeclaredField("mNativeChunk");
|
||||
mNativeChunk.setAccessible(true);
|
||||
if (Build.VERSION.SDK_INT > 19)
|
||||
return getJsonChunkInfo(extractNativeChunkInfo20(mNativeChunk.getLong(np)));
|
||||
return getJsonChunkInfo(extractNativeChunkInfo(mNativeChunk.getInt(np)));
|
||||
}
|
||||
}
|
||||
|
@ -47,9 +47,7 @@
|
||||
#include <alloca.h>
|
||||
|
||||
#define LOG_TAG "extractSyleInfo"
|
||||
#define LOGI(...) __android_log_print(ANDROID_LOG_INFO,LOG_TAG,__VA_ARGS__)
|
||||
#define LOGE(...) __android_log_print(ANDROID_LOG_ERROR,LOG_TAG,__VA_ARGS__)
|
||||
#define LOGF(...) __android_log_print(ANDROID_LOG_FATAL,LOG_TAG,__VA_ARGS__)
|
||||
|
||||
extern "C" JNIEXPORT jintArray JNICALL Java_org_qtproject_qt5_android_ExtractStyle_extractNativeChunkInfo(JNIEnv * env, jobject, Res_png_9patch* chunk)
|
||||
{
|
||||
@ -133,3 +131,63 @@ Res_png_9patch* Res_png_9patch::deserialize(const void* inData)
|
||||
deserializeInternal(inData, (Res_png_9patch*) inData);
|
||||
return (Res_png_9patch*) inData;
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT jintArray JNICALL Java_org_qtproject_qt5_android_ExtractStyle_extractNativeChunkInfo20(JNIEnv * env, jobject, long addr)
|
||||
{
|
||||
Res_png_9patch20* chunk = reinterpret_cast<Res_png_9patch20*>(addr);
|
||||
Res_png_9patch20::deserialize(chunk);
|
||||
//printChunkInformation(chunk);
|
||||
jintArray result;
|
||||
size_t size = 3+chunk->numXDivs+chunk->numYDivs+chunk->numColors;
|
||||
result = env->NewIntArray(size);
|
||||
if (!result)
|
||||
return 0;
|
||||
|
||||
jint *data = (jint*)malloc(sizeof(jint)*size);
|
||||
size_t pos = 0;
|
||||
data[pos++] = chunk->numXDivs;
|
||||
data[pos++] = chunk->numYDivs;
|
||||
data[pos++] = chunk->numColors;
|
||||
|
||||
int32_t* xDivs = chunk->getXDivs();
|
||||
int32_t* yDivs = chunk->getYDivs();
|
||||
uint32_t* colors = chunk->getColors();
|
||||
|
||||
for (int x = 0; x <chunk->numXDivs; x ++)
|
||||
data[pos++]=xDivs[x];
|
||||
for (int y = 0; y <chunk->numYDivs; y ++)
|
||||
data[pos++] = yDivs[y];
|
||||
for (int c = 0; c <chunk->numColors; c ++)
|
||||
data[pos++] = colors[c];
|
||||
env->SetIntArrayRegion(result, 0, size, data);
|
||||
free(data);
|
||||
return result;
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT jintArray JNICALL Java_org_qtproject_qt5_android_ExtractStyle_extractChunkInfo20(JNIEnv * env, jobject obj, jbyteArray chunkObj)
|
||||
{
|
||||
size_t chunkSize = env->GetArrayLength(chunkObj);
|
||||
void* storage = alloca(chunkSize);
|
||||
env->GetByteArrayRegion(chunkObj, 0, chunkSize,
|
||||
reinterpret_cast<jbyte*>(storage));
|
||||
|
||||
if (!env->ExceptionCheck())
|
||||
return Java_org_qtproject_qt5_android_ExtractStyle_extractNativeChunkInfo20(env, obj, long(storage));
|
||||
else
|
||||
env->ExceptionClear();
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline void fill9patchOffsets(Res_png_9patch20* patch) {
|
||||
patch->xDivsOffset = sizeof(Res_png_9patch20);
|
||||
patch->yDivsOffset = patch->xDivsOffset + (patch->numXDivs * sizeof(int32_t));
|
||||
patch->colorsOffset = patch->yDivsOffset + (patch->numYDivs * sizeof(int32_t));
|
||||
}
|
||||
|
||||
Res_png_9patch20* Res_png_9patch20::deserialize(void* inData)
|
||||
{
|
||||
Res_png_9patch20* patch = reinterpret_cast<Res_png_9patch20*>(inData);
|
||||
patch->wasDeserialized = true;
|
||||
fill9patchOffsets(patch);
|
||||
return patch;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user