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

Commit a9f1dd02 authored by Eric Fischer's avatar Eric Fischer
Browse files

Make <font size> and <font height> in string resources respect density.

This unfortunately requires API changes because the existing text markup
classes had no access to the screen density.

TextPaint gains a "density" field so that TextView can pass the density
along.  AbsoluteSizeSpan gains a new flag to indicate that its argument
is in dip instead of in physical pixels.  LineHeightSpan gains an inner
interface whose chooseHeight() method includes a TextPaint argument so
it can get at the density.  And when StringBlock creates the markup
objects, it now uses the density-aware versions.

Bug 1976971, Bug 2031746
parent c71c35d6
Loading
Loading
Loading
Loading
+68 −0
Original line number Diff line number Diff line
@@ -130128,6 +130128,16 @@
 visibility="public"
>
</field>
<field name="density"
 type="float"
 transient="false"
 volatile="false"
 static="false"
 final="false"
 deprecated="not deprecated"
 visibility="public"
>
</field>
<field name="drawableState"
 type="int[]"
 transient="false"
@@ -135126,6 +135136,18 @@
 deprecated="not deprecated"
 visibility="public"
>
<parameter name="size" type="int">
</parameter>
<parameter name="dip" type="boolean">
</parameter>
</constructor>
<constructor name="AbsoluteSizeSpan"
 type="android.text.style.AbsoluteSizeSpan"
 static="false"
 final="false"
 deprecated="not deprecated"
 visibility="public"
>
<parameter name="src" type="android.os.Parcel">
</parameter>
</constructor>
@@ -135140,6 +135162,17 @@
 visibility="public"
>
</method>
<method name="getDip"
 return="boolean"
 abstract="false"
 native="false"
 synchronized="false"
 static="false"
 final="false"
 deprecated="not deprecated"
 visibility="public"
>
</method>
<method name="getSize"
 return="int"
 abstract="false"
@@ -136530,6 +136563,41 @@
</parameter>
</method>
</interface>
<interface name="LineHeightSpan.WithDensity"
 abstract="true"
 static="true"
 final="false"
 deprecated="not deprecated"
 visibility="public"
>
<implements name="android.text.style.LineHeightSpan">
</implements>
<method name="chooseHeight"
 return="void"
 abstract="true"
 native="false"
 synchronized="false"
 static="false"
 final="false"
 deprecated="not deprecated"
 visibility="public"
>
<parameter name="text" type="java.lang.CharSequence">
</parameter>
<parameter name="start" type="int">
</parameter>
<parameter name="end" type="int">
</parameter>
<parameter name="spanstartv" type="int">
</parameter>
<parameter name="v" type="int">
</parameter>
<parameter name="fm" type="android.graphics.Paint.FontMetricsInt">
</parameter>
<parameter name="paint" type="android.text.TextPaint">
</parameter>
</method>
</interface>
<class name="MaskFilterSpan"
 extends="android.text.style.CharacterStyle"
 abstract="false"
+23 −11
Original line number Diff line number Diff line
@@ -202,7 +202,7 @@ final class StringBlock {
                    sub = subtag(tag, ";size=");
                    if (sub != null) {
                        int size = Integer.parseInt(sub);
                        buffer.setSpan(new AbsoluteSizeSpan(size),
                        buffer.setSpan(new AbsoluteSizeSpan(size, true),
                                       style[i+1], style[i+2]+1,
                                       Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
                    }
@@ -310,7 +310,7 @@ final class StringBlock {
     * the ascent if possible, or the descent if shrinking the ascent further
     * will make the text unreadable.
     */
    private static class Height implements LineHeightSpan {
    private static class Height implements LineHeightSpan.WithDensity {
        private int mSize;
        private static float sProportion = 0;

@@ -321,9 +321,21 @@ final class StringBlock {
        public void chooseHeight(CharSequence text, int start, int end,
                                 int spanstartv, int v,
                                 Paint.FontMetricsInt fm) {
            if (fm.bottom - fm.top < mSize) {
                fm.top = fm.bottom - mSize;
                fm.ascent = fm.ascent - mSize;
            // Should not get called, at least not by StaticLayout.
            chooseHeight(text, start, end, spanstartv, v, fm, null);
        }

        public void chooseHeight(CharSequence text, int start, int end,
                                 int spanstartv, int v,
                                 Paint.FontMetricsInt fm, TextPaint paint) {
            int size = mSize;
            if (paint != null) {
                size *= paint.density;
            }

            if (fm.bottom - fm.top < size) {
                fm.top = fm.bottom - size;
                fm.ascent = fm.ascent - size;
            } else {
                if (sProportion == 0) {
                    /*
@@ -343,27 +355,27 @@ final class StringBlock {

                int need = (int) Math.ceil(-fm.top * sProportion);

                if (mSize - fm.descent >= need) {
                if (size - fm.descent >= need) {
                    /*
                     * It is safe to shrink the ascent this much.
                     */

                    fm.top = fm.bottom - mSize;
                    fm.ascent = fm.descent - mSize;
                } else if (mSize >= need) {
                    fm.top = fm.bottom - size;
                    fm.ascent = fm.descent - size;
                } else if (size >= need) {
                    /*
                     * We can't show all the descent, but we can at least
                     * show all the ascent.
                     */

                    fm.top = fm.ascent = -need;
                    fm.bottom = fm.descent = fm.top + mSize;
                    fm.bottom = fm.descent = fm.top + size;
                } else {
                    /*
                     * Show as much of the ascent as we can, and no descent.
                     */

                    fm.top = fm.ascent = -mSize;
                    fm.top = fm.ascent = -size;
                    fm.bottom = fm.descent = 0;
                }
            }
+7 −1
Original line number Diff line number Diff line
@@ -968,8 +968,14 @@ extends Layout
            fm.bottom = bottom;

            for (int i = 0; i < chooseht.length; i++) {
                if (chooseht[i] instanceof LineHeightSpan.WithDensity) {
                    ((LineHeightSpan.WithDensity) chooseht[i]).
                        chooseHeight(text, start, end, choosehtv[i], v, fm, paint);

                } else {
                    chooseht[i].chooseHeight(text, start, end, choosehtv[i], v, fm);
                }
            }

            above = fm.ascent;
            below = fm.descent;
+2 −0
Original line number Diff line number Diff line
@@ -27,6 +27,7 @@ public class TextPaint extends Paint {
    public int baselineShift;
    public int linkColor;
    public int[] drawableState;
    public float density = 1.0f;

    public TextPaint() {
        super();
@@ -51,5 +52,6 @@ public class TextPaint extends Paint {
        baselineShift = tp.baselineShift;
        linkColor = tp.linkColor;
        drawableState = tp.drawableState;
        density = tp.density;
    }
}
+30 −2
Original line number Diff line number Diff line
@@ -24,13 +24,28 @@ import android.text.TextUtils;
public class AbsoluteSizeSpan extends MetricAffectingSpan implements ParcelableSpan {

    private final int mSize;
    private boolean mDip;

    /**
     * Set the text size to <code>size</code> physical pixels.
     */
    public AbsoluteSizeSpan(int size) {
        mSize = size;
    }

    /**
     * Set the text size to <code>size</code> physical pixels,
     * or to <code>size</code> device-independent pixels if
     * <code>dip</code> is true.
     */
    public AbsoluteSizeSpan(int size, boolean dip) {
        mSize = size;
        mDip = dip;
    }

    public AbsoluteSizeSpan(Parcel src) {
        mSize = src.readInt();
        mDip = src.readInt() != 0;
    }
    
    public int getSpanTypeId() {
@@ -43,19 +58,32 @@ public class AbsoluteSizeSpan extends MetricAffectingSpan implements ParcelableS

    public void writeToParcel(Parcel dest, int flags) {
        dest.writeInt(mSize);
        dest.writeInt(mDip ? 1 : 0);
    }

    public int getSize() {
        return mSize;
    }

    public boolean getDip() {
        return mDip;
    }

    @Override
    public void updateDrawState(TextPaint ds) {
        if (mDip) {
            ds.setTextSize(mSize * ds.density);
        } else {
            ds.setTextSize(mSize);
        }
    }

    @Override
    public void updateMeasureState(TextPaint ds) {
        if (mDip) {
            ds.setTextSize(mSize * ds.density);
        } else {
            ds.setTextSize(mSize);
        }
    }
}
Loading