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

Commit 2784ff0a authored by Dianne Hackborn's avatar Dianne Hackborn
Browse files

Fix issue where scaled bitmap sizes could be wrong.

The Bitmap functions to get the scaled width/height couldn't actually
do the right thing because they didn't know the destination they would
be drawing to.  Now there are two forms of them, taking an explicit
parameter specifying the destination.
parent a53b8286
Loading
Loading
Loading
Loading
+30 −0
Original line number Diff line number Diff line
@@ -49036,6 +49036,21 @@
 deprecated="not deprecated"
 visibility="public"
>
<parameter name="canvas" type="android.graphics.Canvas">
</parameter>
</method>
<method name="getScaledHeight"
 return="int"
 abstract="false"
 native="false"
 synchronized="false"
 static="false"
 final="false"
 deprecated="not deprecated"
 visibility="public"
>
<parameter name="metrics" type="android.util.DisplayMetrics">
</parameter>
</method>
<method name="getScaledWidth"
 return="int"
@@ -49047,6 +49062,21 @@
 deprecated="not deprecated"
 visibility="public"
>
<parameter name="canvas" type="android.graphics.Canvas">
</parameter>
</method>
<method name="getScaledWidth"
 return="int"
 abstract="false"
 native="false"
 synchronized="false"
 static="false"
 final="false"
 deprecated="not deprecated"
 visibility="public"
>
<parameter name="metrics" type="android.util.DisplayMetrics">
</parameter>
</method>
<method name="getWidth"
 return="int"
+17 −3
Original line number Diff line number Diff line
@@ -84,6 +84,11 @@ public class CompatibilityInfo {

    private static final int SCALING_EXPANDABLE_MASK = SCALING_REQUIRED | EXPANDABLE;

    /**
     * The effective screen density we have selected for this application.
     */
    public final int applicationDensity;
    
    /**
     * Application's scale.
     */
@@ -107,28 +112,34 @@ public class CompatibilityInfo {
        }
        
        float packageDensityScale = -1.0f;
        int packageDensity = 0;
        if (appInfo.supportsDensities != null) {
            int minDiff = Integer.MAX_VALUE;
            for (int density : appInfo.supportsDensities) {
                if (density == ApplicationInfo.ANY_DENSITY) {
                    packageDensity = DisplayMetrics.DENSITY_DEVICE;
                    packageDensityScale = 1.0f;
                    break;
                }
                int tmpDiff = Math.abs(DisplayMetrics.DENSITY_DEVICE - density);
                if (tmpDiff == 0) {
                    packageDensity = DisplayMetrics.DENSITY_DEVICE;
                    packageDensityScale = 1.0f;
                    break;
                }
                // prefer higher density (appScale>1.0), unless that's only option.
                if (tmpDiff < minDiff && packageDensityScale < 1.0f) {
                    packageDensity = density;
                    packageDensityScale = DisplayMetrics.DENSITY_DEVICE / (float) density;
                    minDiff = tmpDiff;
                }
            }
        }
        if (packageDensityScale > 0.0f) {
            applicationDensity = packageDensity;
            applicationScale = packageDensityScale;
        } else {
            applicationDensity = DisplayMetrics.DENSITY_DEFAULT;
            applicationScale =
                    DisplayMetrics.DENSITY_DEVICE / (float) DisplayMetrics.DENSITY_DEFAULT;
        }
@@ -139,9 +150,11 @@ public class CompatibilityInfo {
        }
    }

    private CompatibilityInfo(int appFlags, int compFlags, float scale, float invertedScale) {
    private CompatibilityInfo(int appFlags, int compFlags,
            int dens, float scale, float invertedScale) {
        this.appFlags = appFlags;
        mCompatibilityFlags = compFlags;
        applicationDensity = dens;
        applicationScale = scale;
        applicationInvertedScale = invertedScale;
    }
@@ -151,6 +164,7 @@ public class CompatibilityInfo {
                | ApplicationInfo.FLAG_SUPPORTS_NORMAL_SCREENS
                | ApplicationInfo.FLAG_SUPPORTS_LARGE_SCREENS,
                EXPANDABLE | CONFIGURED_EXPANDABLE,
                DisplayMetrics.DENSITY_DEVICE,
                1.0f,
                1.0f);
    }
@@ -160,7 +174,7 @@ public class CompatibilityInfo {
     */
    public CompatibilityInfo copy() {
        CompatibilityInfo info = new CompatibilityInfo(appFlags, mCompatibilityFlags,
                applicationScale, applicationInvertedScale);
                applicationDensity, applicationScale, applicationInvertedScale);
        return info;
    }
 
+43 −4
Original line number Diff line number Diff line
@@ -18,6 +18,7 @@ package android.graphics;

import android.os.Parcel;
import android.os.Parcelable;
import android.util.DisplayMetrics;

import java.io.OutputStream;
import java.nio.Buffer;
@@ -605,22 +606,60 @@ public final class Bitmap implements Parcelable {
     * Convenience method that returns the width of this bitmap divided
     * by the density scale factor.
     *
     * @param canvas The Canvas the bitmap will be drawn to.
     * @return The scaled width of this bitmap, according to the density scale factor.
     */
    public int getScaledWidth() {
    public int getScaledWidth(Canvas canvas) {
        final float scale = mDensityScale;
        return scale == DENSITY_SCALE_UNKNOWN ? getWidth() : (int) (getWidth() / scale);
        if (!mAutoScaling || scale < 0) {
            return getWidth();
        }
        return (int)(getWidth() * canvas.getDensityScale() / scale);
    }

    /**
     * Convenience method that returns the height of this bitmap divided
     * by the density scale factor.
     *
     * @param canvas The Canvas the bitmap will be drawn to.
     * @return The scaled height of this bitmap, according to the density scale factor.
     */
    public int getScaledHeight(Canvas canvas) {
        final float scale = mDensityScale;
        if (!mAutoScaling || scale < 0) {
            return getHeight();
        }
        return (int)(getHeight() * canvas.getDensityScale() / scale);
    }

    /**
     * Convenience method that returns the width of this bitmap divided
     * by the density scale factor.
     *
     * @param metrics The target display metrics.
     * @return The scaled width of this bitmap, according to the density scale factor.
     */
    public int getScaledWidth(DisplayMetrics metrics) {
        final float scale = mDensityScale;
        if (!mAutoScaling || scale < 0) {
            return getWidth();
        }
        return (int)(getWidth() * metrics.density / scale);
    }

    /**
     * Convenience method that returns the height of this bitmap divided
     * by the density scale factor.
     *
     * @param metrics The target display metrics.
     * @return The scaled height of this bitmap, according to the density scale factor.
     */
    public int getScaledHeight() {
    public int getScaledHeight(DisplayMetrics metrics) {
        final float scale = mDensityScale;
        return scale == DENSITY_SCALE_UNKNOWN ? getWidth() : (int) (getHeight() / scale);
        if (!mAutoScaling || scale < 0) {
            return getHeight();
        }
        return (int)(getHeight() * metrics.density / scale);
    }

    /**
+1 −1
Original line number Diff line number Diff line
@@ -25,7 +25,7 @@
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        <activity android:name="DpiTestActivityNoCompat" android:label="DpiTestCompat">
        <activity android:name="DpiTestNoCompatActivity" android:label="DpiTestNoCompat">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
+12 −3
Original line number Diff line number Diff line
@@ -17,6 +17,8 @@
package com.google.android.test.dpi;

import android.app.Activity;
import android.app.ActivityThread;
import android.app.Application;
import android.os.Bundle;
import android.graphics.BitmapFactory;
import android.graphics.Bitmap;
@@ -31,6 +33,7 @@ import android.content.Context;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.content.res.CompatibilityInfo;
import android.util.DisplayMetrics;

public class DpiTestActivity extends Activity {
    public DpiTestActivity() {
@@ -45,7 +48,10 @@ public class DpiTestActivity extends Activity {
    
    public void init(boolean noCompat) {
        try {
            ApplicationInfo ai = getPackageManager().getApplicationInfo(
            // This is all a dirty hack.  Don't think a real application should
            // be doing it.
            Application app = ActivityThread.currentActivityThread().getApplication();
            ApplicationInfo ai = app.getPackageManager().getApplicationInfo(
                    "com.google.android.test.dpi",
                    PackageManager.GET_SUPPORTS_DENSITIES);
            if (noCompat) {
@@ -53,8 +59,8 @@ public class DpiTestActivity extends Activity {
                    | ApplicationInfo.FLAG_SUPPORTS_NORMAL_SCREENS
                    | ApplicationInfo.FLAG_SUPPORTS_SMALL_SCREENS;
                ai.supportsDensities = new int[] { ApplicationInfo.ANY_DENSITY };
                app.getResources().setCompatibilityInfo(new CompatibilityInfo(ai));
            }
            getResources().setCompatibilityInfo(new CompatibilityInfo(ai));
        } catch (PackageManager.NameNotFoundException e) {
            throw new RuntimeException("ouch", e);
        }
@@ -192,7 +198,10 @@ public class DpiTestActivity extends Activity {
        @Override
        protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
            super.onMeasure(widthMeasureSpec, heightMeasureSpec);
            setMeasuredDimension(mBitmap.getScaledWidth(), mBitmap.getScaledHeight());
            final DisplayMetrics metrics = getResources().getDisplayMetrics();
            setMeasuredDimension(
                    mBitmap.getScaledWidth(metrics),
                    mBitmap.getScaledHeight(metrics));
        }

        @Override