Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 0d221012 authored by Dianne Hackborn's avatar Dianne Hackborn
Browse files

Fix #2018814: System cannot correctly render assets with "wrap_content" attribute in QVGA

It turns out we were not returning the density for anything retrieved from a
TypedArray...  which basically means any bitmap references from a layout or style...!!!

This is now fixed.

Also fiddle with the density compatibility mode to turn on smoothing in certain situations,
helping the look of things when they need to scale and we couldn't do the scaling at
load time.
parent c6eb5ac9
Loading
Loading
Loading
Loading
+2 −1
Original line number Diff line number Diff line
@@ -637,12 +637,13 @@ public final class AssetManager {
     *  mRetData. */
    private native final int loadResourceBagValue(int ident, int bagEntryId, TypedValue outValue,
                                               boolean resolve);
    /*package*/ static final int STYLE_NUM_ENTRIES = 5;
    /*package*/ static final int STYLE_NUM_ENTRIES = 6;
    /*package*/ static final int STYLE_TYPE = 0;
    /*package*/ static final int STYLE_DATA = 1;
    /*package*/ static final int STYLE_ASSET_COOKIE = 2;
    /*package*/ static final int STYLE_RESOURCE_ID = 3;
    /*package*/ static final int STYLE_CHANGING_CONFIGURATIONS = 4;
    /*package*/ static final int STYLE_DENSITY = 5;
    /*package*/ native static final boolean applyStyle(int theme,
            int defStyleAttr, int defStyleRes, int xmlParser,
            int[] inAttrs, int[] outValues, int[] outIndices);
+1 −0
Original line number Diff line number Diff line
@@ -654,6 +654,7 @@ public class TypedArray {
        outValue.assetCookie = data[index+AssetManager.STYLE_ASSET_COOKIE];
        outValue.resourceId = data[index+AssetManager.STYLE_RESOURCE_ID];
        outValue.changingConfigurations = data[index+AssetManager.STYLE_CHANGING_CONFIGURATIONS];
        outValue.density = data[index+AssetManager.STYLE_DENSITY];
        if (type == TypedValue.TYPE_STRING) {
            outValue.string = loadStringValueAt(index);
        }
+4 −1
Original line number Diff line number Diff line
@@ -21,7 +21,6 @@ import com.android.internal.view.IInputMethodSession;

import android.graphics.Canvas;
import android.graphics.PixelFormat;
import android.graphics.Point;
import android.graphics.PorterDuff;
import android.graphics.Rect;
import android.graphics.Region;
@@ -1213,6 +1212,8 @@ public final class ViewRoot extends Handler implements ViewParent,
                        if (mTranslator != null) {
                            mTranslator.translateCanvas(canvas);
                        }
                        canvas.setScreenDensity(scalingRequired
                                ? DisplayMetrics.DENSITY_DEVICE : 0);
                        mView.draw(canvas);
                        if (Config.DEBUG && ViewDebug.consistencyCheckEnabled) {
                            mView.dispatchConsistencyCheck(ViewDebug.CONSISTENCY_DRAWING);
@@ -1321,6 +1322,8 @@ public final class ViewRoot extends Handler implements ViewParent,
                    if (mTranslator != null) {
                        mTranslator.translateCanvas(canvas);
                    }
                    canvas.setScreenDensity(scalingRequired
                            ? DisplayMetrics.DENSITY_DEVICE : 0);
                    mView.draw(canvas);
                } finally {
                    mAttachInfo.mIgnoreDirtyState = false;
+35 −11
Original line number Diff line number Diff line
@@ -463,13 +463,22 @@ public:
                                          SkCanvas* canvas, SkBitmap* bitmap,
                                          jfloat left, jfloat top,
                                          SkPaint* paint, jint canvasDensity,
                                          jint bitmapDensity) {
                                          jint screenDensity, jint bitmapDensity) {
        SkScalar left_ = SkFloatToScalar(left);
        SkScalar top_ = SkFloatToScalar(top);

        if (canvasDensity == bitmapDensity || canvasDensity == 0
                || bitmapDensity == 0) {
            if (screenDensity != 0 && screenDensity != bitmapDensity) {
                SkPaint filteredPaint;
                if (paint) {
                    filteredPaint = *paint;
                }
                filteredPaint.setFilterBitmap(true);
                canvas->drawBitmap(*bitmap, left_, top_, &filteredPaint);
            } else {
                canvas->drawBitmap(*bitmap, left_, top_, paint);
            }
        } else {
            canvas->save();
            SkScalar scale = SkFloatToScalar(canvasDensity / (float)bitmapDensity);
@@ -489,30 +498,45 @@ public:
    }

    static void doDrawBitmap(JNIEnv* env, SkCanvas* canvas, SkBitmap* bitmap,
                        jobject srcIRect, const SkRect& dst, SkPaint* paint) {
                        jobject srcIRect, const SkRect& dst, SkPaint* paint,
                        jint screenDensity, jint bitmapDensity) {
        SkIRect    src, *srcPtr = NULL;

        if (NULL != srcIRect) {
            GraphicsJNI::jrect_to_irect(env, srcIRect, &src);
            srcPtr = &src;
        }
        
        if (screenDensity != 0 && screenDensity != bitmapDensity) {
            SkPaint filteredPaint;
            if (paint) {
                filteredPaint = *paint;
            }
            filteredPaint.setFilterBitmap(true);
            canvas->drawBitmapRect(*bitmap, srcPtr, dst, &filteredPaint);
        } else {
            canvas->drawBitmapRect(*bitmap, srcPtr, dst, paint);
        }
    }

    static void drawBitmapRF(JNIEnv* env, jobject, SkCanvas* canvas,
                             SkBitmap* bitmap, jobject srcIRect,
                             jobject dstRectF, SkPaint* paint) {
                             jobject dstRectF, SkPaint* paint,
                             jint screenDensity, jint bitmapDensity) {
        SkRect      dst;
        GraphicsJNI::jrectf_to_rect(env, dstRectF, &dst);
        doDrawBitmap(env, canvas, bitmap, srcIRect, dst, paint);
        doDrawBitmap(env, canvas, bitmap, srcIRect, dst, paint,
                screenDensity, bitmapDensity);
    }
    
    static void drawBitmapRR(JNIEnv* env, jobject, SkCanvas* canvas,
                             SkBitmap* bitmap, jobject srcIRect,
                             jobject dstRect, SkPaint* paint) {
                             jobject dstRect, SkPaint* paint,
                             jint screenDensity, jint bitmapDensity) {
        SkRect      dst;
        GraphicsJNI::jrect_to_rect(env, dstRect, &dst);
        doDrawBitmap(env, canvas, bitmap, srcIRect, dst, paint);
        doDrawBitmap(env, canvas, bitmap, srcIRect, dst, paint,
                screenDensity, bitmapDensity);
    }
    
    static void drawBitmapArray(JNIEnv* env, jobject, SkCanvas* canvas,
@@ -906,11 +930,11 @@ static JNINativeMethod gCanvasMethods[] = {
    {"native_drawRoundRect","(ILandroid/graphics/RectF;FFI)V",
        (void*) SkCanvasGlue::drawRoundRect},
    {"native_drawPath","(III)V", (void*) SkCanvasGlue::drawPath},
    {"native_drawBitmap","(IIFFIII)V",
    {"native_drawBitmap","(IIFFIIII)V",
        (void*) SkCanvasGlue::drawBitmap__BitmapFFPaint},
    {"native_drawBitmap","(IILandroid/graphics/Rect;Landroid/graphics/RectF;I)V",
    {"native_drawBitmap","(IILandroid/graphics/Rect;Landroid/graphics/RectF;III)V",
        (void*) SkCanvasGlue::drawBitmapRF},
    {"native_drawBitmap","(IILandroid/graphics/Rect;Landroid/graphics/Rect;I)V",
    {"native_drawBitmap","(IILandroid/graphics/Rect;Landroid/graphics/Rect;III)V",
        (void*) SkCanvasGlue::drawBitmapRR},
    {"native_drawBitmap", "(I[IIIFFIIZI)V",
    (void*)SkCanvasGlue::drawBitmapArray},
+20 −6
Original line number Diff line number Diff line
@@ -74,12 +74,13 @@ static void doThrow(JNIEnv* env, const char* exc, const char* msg = NULL)
}

enum {
    STYLE_NUM_ENTRIES = 5,
    STYLE_NUM_ENTRIES = 6,
    STYLE_TYPE = 0,
    STYLE_DATA = 1,
    STYLE_ASSET_COOKIE = 2,
    STYLE_RESOURCE_ID = 3,
    STYLE_CHANGING_CONFIGURATIONS = 4
    STYLE_CHANGING_CONFIGURATIONS = 4,
    STYLE_DENSITY = 5
};

static jint copyValue(JNIEnv* env, jobject outValue, const ResTable* table,
@@ -896,6 +897,7 @@ static jboolean android_content_AssetManager_applyStyle(JNIEnv* env, jobject cla
    ResTable::Theme* theme = (ResTable::Theme*)themeToken;
    const ResTable& res = theme->getResTable();
    ResXMLParser* xmlParser = (ResXMLParser*)xmlParserToken;
    ResTable_config config;
    Res_value value;

    const jsize NI = env->GetArrayLength(attrs);
@@ -995,6 +997,7 @@ static jboolean android_content_AssetManager_applyStyle(JNIEnv* env, jobject cla
        value.dataType = Res_value::TYPE_NULL;
        value.data = 0;
        typeSetFlags = 0;
        config.density = 0;

        // Skip through XML attributes until the end or the next possible match.
        while (ix < NX && curIdent > curXmlAttr) {
@@ -1042,7 +1045,8 @@ static jboolean android_content_AssetManager_applyStyle(JNIEnv* env, jobject cla
        if (value.dataType != Res_value::TYPE_NULL) {
            // Take care of resolving the found resource to its final value.
            //printf("Resolving attribute reference\n");
            ssize_t newBlock = theme->resolveAttributeReference(&value, block, &resid, &typeSetFlags);
            ssize_t newBlock = theme->resolveAttributeReference(&value, block,
                    &resid, &typeSetFlags, &config);
            if (newBlock >= 0) block = newBlock;
        } else {
            // If we still don't have a value for this attribute, try to find
@@ -1051,7 +1055,8 @@ static jboolean android_content_AssetManager_applyStyle(JNIEnv* env, jobject cla
            ssize_t newBlock = theme->getAttribute(curIdent, &value, &typeSetFlags);
            if (newBlock >= 0) {
                //printf("Resolving resource reference\n");
                newBlock = res.resolveReference(&value, block, &resid, &typeSetFlags);
                newBlock = res.resolveReference(&value, block, &resid,
                        &typeSetFlags, &config);
                if (newBlock >= 0) block = newBlock;
            }
        }
@@ -1070,6 +1075,7 @@ static jboolean android_content_AssetManager_applyStyle(JNIEnv* env, jobject cla
            block != kXmlBlock ? (jint)res.getTableCookie(block) : (jint)-1;
        dest[STYLE_RESOURCE_ID] = resid;
        dest[STYLE_CHANGING_CONFIGURATIONS] = typeSetFlags;
        dest[STYLE_DENSITY] = config.density;
        
        if (indices != NULL && value.dataType != Res_value::TYPE_NULL) {
            indicesIdx++;
@@ -1108,6 +1114,7 @@ static jboolean android_content_AssetManager_retrieveAttributes(JNIEnv* env, job
    }
    const ResTable& res(am->getResources());
    ResXMLParser* xmlParser = (ResXMLParser*)xmlParserToken;
    ResTable_config config;
    Res_value value;
    
    const jsize NI = env->GetArrayLength(attrs);
@@ -1160,6 +1167,7 @@ static jboolean android_content_AssetManager_retrieveAttributes(JNIEnv* env, job
        value.dataType = Res_value::TYPE_NULL;
        value.data = 0;
        typeSetFlags = 0;
        config.density = 0;
        
        // Skip through XML attributes until the end or the next possible match.
        while (ix < NX && curIdent > curXmlAttr) {
@@ -1179,7 +1187,8 @@ static jboolean android_content_AssetManager_retrieveAttributes(JNIEnv* env, job
        if (value.dataType != Res_value::TYPE_NULL) {
            // Take care of resolving the found resource to its final value.
            //printf("Resolving attribute reference\n");
            ssize_t newBlock = res.resolveReference(&value, block, &resid, &typeSetFlags);
            ssize_t newBlock = res.resolveReference(&value, block, &resid,
                    &typeSetFlags, &config);
            if (newBlock >= 0) block = newBlock;
        }
        
@@ -1197,6 +1206,7 @@ static jboolean android_content_AssetManager_retrieveAttributes(JNIEnv* env, job
            block != kXmlBlock ? (jint)res.getTableCookie(block) : (jint)-1;
        dest[STYLE_RESOURCE_ID] = resid;
        dest[STYLE_CHANGING_CONFIGURATIONS] = typeSetFlags;
        dest[STYLE_DENSITY] = config.density;
        
        if (indices != NULL && value.dataType != Res_value::TYPE_NULL) {
            indicesIdx++;
@@ -1250,6 +1260,7 @@ static jint android_content_AssetManager_retrieveArray(JNIEnv* env, jobject claz
        return JNI_FALSE;
    }
    const ResTable& res(am->getResources());
    ResTable_config config;
    Res_value value;
    ssize_t block;
    
@@ -1276,13 +1287,15 @@ static jint android_content_AssetManager_retrieveArray(JNIEnv* env, jobject claz
    while (i < NV && arrayEnt < endArrayEnt) {
        block = arrayEnt->stringBlock;
        typeSetFlags = arrayTypeSetFlags;
        config.density = 0;
        value = arrayEnt->map.value;
                
        uint32_t resid = 0;
        if (value.dataType != Res_value::TYPE_NULL) {
            // Take care of resolving the found resource to its final value.
            //printf("Resolving attribute reference\n");
            ssize_t newBlock = res.resolveReference(&value, block, &resid, &typeSetFlags);
            ssize_t newBlock = res.resolveReference(&value, block, &resid,
                    &typeSetFlags, &config);
            if (newBlock >= 0) block = newBlock;
        }

@@ -1299,6 +1312,7 @@ static jint android_content_AssetManager_retrieveArray(JNIEnv* env, jobject claz
        dest[STYLE_ASSET_COOKIE] = (jint)res.getTableCookie(block);
        dest[STYLE_RESOURCE_ID] = resid;
        dest[STYLE_CHANGING_CONFIGURATIONS] = typeSetFlags;
        dest[STYLE_DENSITY] = config.density;
        dest += STYLE_NUM_ENTRIES;
        i+= STYLE_NUM_ENTRIES;
        arrayEnt++;
Loading