Merge change 9039 into donut

* changes:
  Fix #2018814: System cannot correctly render assets with "wrap_content" attribute in QVGA
This commit is contained in:
Android (Google) Code Review
2009-07-29 19:44:48 -07:00
18 changed files with 206 additions and 31 deletions

View File

@ -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);

View File

@ -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);
}

View File

@ -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;

View File

@ -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},

View File

@ -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++;

View File

@ -51,6 +51,9 @@ public class Canvas {
// Package-scoped for quick access.
/*package*/ int mDensity = Bitmap.DENSITY_NONE;
// Used to determine when compatibility scaling is in effect.
private int mScreenDensity = Bitmap.DENSITY_NONE;
// Used by native code
@SuppressWarnings({"UnusedDeclaration"})
private int mSurfaceFormat;
@ -219,6 +222,11 @@ public class Canvas {
mDensity = density;
}
/** @hide */
public void setScreenDensity(int density) {
mScreenDensity = density;
}
// the SAVE_FLAG constants must match their native equivalents
/** restore the current matrix when restore() is called */
@ -971,7 +979,8 @@ public class Canvas {
public void drawBitmap(Bitmap bitmap, float left, float top, Paint paint) {
throwIfRecycled(bitmap);
native_drawBitmap(mNativeCanvas, bitmap.ni(), left, top,
paint != null ? paint.mNativePaint : 0, mDensity, bitmap.mDensity);
paint != null ? paint.mNativePaint : 0, mDensity, mScreenDensity,
bitmap.mDensity);
}
/**
@ -1002,7 +1011,8 @@ public class Canvas {
}
throwIfRecycled(bitmap);
native_drawBitmap(mNativeCanvas, bitmap.ni(), src, dst,
paint != null ? paint.mNativePaint : 0);
paint != null ? paint.mNativePaint : 0,
mScreenDensity, bitmap.mDensity);
}
/**
@ -1033,7 +1043,8 @@ public class Canvas {
}
throwIfRecycled(bitmap);
native_drawBitmap(mNativeCanvas, bitmap.ni(), src, dst,
paint != null ? paint.mNativePaint : 0);
paint != null ? paint.mNativePaint : 0,
mScreenDensity, bitmap.mDensity);
}
/**
@ -1513,13 +1524,19 @@ public class Canvas {
private native void native_drawBitmap(int nativeCanvas, int bitmap,
float left, float top,
int nativePaintOrZero,
int canvasDensity, int bitmapDensity);
int canvasDensity,
int screenDensity,
int bitmapDensity);
private native void native_drawBitmap(int nativeCanvas, int bitmap,
Rect src, RectF dst,
int nativePaintOrZero);
int nativePaintOrZero,
int screenDensity,
int bitmapDensity);
private static native void native_drawBitmap(int nativeCanvas, int bitmap,
Rect src, Rect dst,
int nativePaintOrZero);
int nativePaintOrZero,
int screenDensity,
int bitmapDensity);
private static native void native_drawBitmap(int nativeCanvas, int[] colors,
int offset, int stride, float x,
float y, int width, int height,

View File

@ -1655,7 +1655,8 @@ public:
ssize_t resolveReference(Res_value* inOutValue,
ssize_t blockIndex,
uint32_t* outLastRef = NULL,
uint32_t* inoutTypeSpecFlags = NULL) const;
uint32_t* inoutTypeSpecFlags = NULL,
ResTable_config* outConfig = NULL) const;
enum {
TMP_BUFFER_SIZE = 16
@ -1729,7 +1730,8 @@ public:
*/
ssize_t resolveAttributeReference(Res_value* inOutValue,
ssize_t blockIndex, uint32_t* outLastRef = NULL,
uint32_t* inoutTypeSpecFlags = NULL) const;
uint32_t* inoutTypeSpecFlags = NULL,
ResTable_config* inoutConfig = NULL) const;
void dumpToLog() const;

View File

@ -1486,7 +1486,7 @@ ssize_t ResTable::Theme::getAttribute(uint32_t resID, Res_value* outValue,
ssize_t ResTable::Theme::resolveAttributeReference(Res_value* inOutValue,
ssize_t blockIndex, uint32_t* outLastRef,
uint32_t* inoutTypeSpecFlags) const
uint32_t* inoutTypeSpecFlags, ResTable_config* inoutConfig) const
{
//printf("Resolving type=0x%x\n", inOutValue->dataType);
if (inOutValue->dataType == Res_value::TYPE_ATTRIBUTE) {
@ -1498,7 +1498,8 @@ ssize_t ResTable::Theme::resolveAttributeReference(Res_value* inOutValue,
return blockIndex;
}
}
return mTable.resolveReference(inOutValue, blockIndex, outLastRef);
return mTable.resolveReference(inOutValue, blockIndex, outLastRef,
inoutTypeSpecFlags, inoutConfig);
}
void ResTable::Theme::dumpToLog() const
@ -1891,7 +1892,8 @@ ssize_t ResTable::getResource(uint32_t resID, Res_value* outValue, bool mayBeBag
}
ssize_t ResTable::resolveReference(Res_value* value, ssize_t blockIndex,
uint32_t* outLastRef, uint32_t* inoutTypeSpecFlags) const
uint32_t* outLastRef, uint32_t* inoutTypeSpecFlags,
ResTable_config* outConfig) const
{
int count=0;
while (blockIndex >= 0 && value->dataType == value->TYPE_REFERENCE
@ -1899,7 +1901,8 @@ ssize_t ResTable::resolveReference(Res_value* value, ssize_t blockIndex,
if (outLastRef) *outLastRef = value->data;
uint32_t lastRef = value->data;
uint32_t newFlags = 0;
const ssize_t newIndex = getResource(value->data, value, true, &newFlags);
const ssize_t newIndex = getResource(value->data, value, true, &newFlags,
outConfig);
//LOGI("Resolving reference d=%p: newIndex=%d, t=0x%02x, d=%p\n",
// (void*)lastRef, (int)newIndex, (int)value->dataType, (void*)value->data);
//printf("Getting reference 0x%08x: newIndex=%d\n", value->data, newIndex);

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.9 KiB

View File

@ -0,0 +1,37 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (C) 2009 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.
-->
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/reslogo120dpi" />
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/reslogo160dpi" />
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/reslogo240dpi" />
</LinearLayout>

View File

@ -0,0 +1,26 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (C) 2009 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.
-->
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<ImageView style="@style/ImageView120dpi" />
<ImageView style="@style/ImageView160dpi" />
<ImageView style="@style/ImageView240dpi" />
</LinearLayout>

View File

@ -0,0 +1,35 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (C) 2009 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.
-->
<resources>
<style name="ImageView120dpi">
<item name="android:src">@drawable/stylogo120dpi</item>
<item name="android:layout_width">wrap_content</item>
<item name="android:layout_height">wrap_content</item>
</style>
<style name="ImageView160dpi">
<item name="android:src">@drawable/stylogo160dpi</item>
<item name="android:layout_width">wrap_content</item>
<item name="android:layout_height">wrap_content</item>
</style>
<style name="ImageView240dpi">
<item name="android:src">@drawable/stylogo240dpi</item>
<item name="android:layout_width">wrap_content</item>
<item name="android:layout_height">wrap_content</item>
</style>
</resources>

View File

@ -28,6 +28,7 @@ import android.graphics.drawable.Drawable;
import android.widget.LinearLayout;
import android.widget.TextView;
import android.widget.ScrollView;
import android.view.LayoutInflater;
import android.view.View;
import android.content.Context;
import android.content.pm.ApplicationInfo;
@ -71,6 +72,9 @@ public class DpiTestActivity extends Activity {
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
final LayoutInflater li = (LayoutInflater)getSystemService(
LAYOUT_INFLATER_SERVICE);
this.setTitle(R.string.act_title);
LinearLayout root = new LinearLayout(this);
root.setOrientation(LinearLayout.VERTICAL);
@ -96,6 +100,14 @@ public class DpiTestActivity extends Activity {
addLabelToRoot(root, "Prescaled resource drawable");
addChildToRoot(root, layout);
layout = (LinearLayout)li.inflate(R.layout.image_views, null);
addLabelToRoot(root, "Inflated layout");
addChildToRoot(root, layout);
layout = (LinearLayout)li.inflate(R.layout.styled_image_views, null);
addLabelToRoot(root, "Inflated styled layout");
addChildToRoot(root, layout);
layout = new LinearLayout(this);
addCanvasBitmap(layout, R.drawable.logo120dpi, true);
addCanvasBitmap(layout, R.drawable.logo160dpi, true);