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

Commit 7d97b913 authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Support font resource in TextAppearanceSpan"

parents eba529b1 c49ee3bd
Loading
Loading
Loading
Loading
+53 −34
Original line number Diff line number Diff line
@@ -19,6 +19,7 @@ package android.text.style;
import android.content.Context;
import android.content.res.ColorStateList;
import android.content.res.TypedArray;
import android.graphics.LeakyTypefaceStorage;
import android.graphics.Typeface;
import android.os.Parcel;
import android.text.ParcelableSpan;
@@ -30,11 +31,12 @@ import android.text.TextUtils;
 * resource.
 */
public class TextAppearanceSpan extends MetricAffectingSpan implements ParcelableSpan {
    private final String mTypeface;
    private final String mFamilyName;
    private final int mStyle;
    private final int mTextSize;
    private final ColorStateList mTextColor;
    private final ColorStateList mTextColorLink;
    private final Typeface mTypeface;

    /**
     * Uses the specified TextAppearance resource to determine the
@@ -68,30 +70,35 @@ public class TextAppearanceSpan extends MetricAffectingSpan implements Parcelabl
                                        TextAppearance_textSize, -1);

        mStyle = a.getInt(com.android.internal.R.styleable.TextAppearance_textStyle, 0);
        mTypeface = a.getFont(com.android.internal.R.styleable.TextAppearance_fontFamily);
        if (mTypeface != null) {
            mFamilyName = null;
        } else {
            String family = a.getString(com.android.internal.R.styleable.TextAppearance_fontFamily);
            if (family != null) {
            mTypeface = family;
                mFamilyName = family;
            } else {
                int tf = a.getInt(com.android.internal.R.styleable.TextAppearance_typeface, 0);

                switch (tf) {
                    case 1:
                    mTypeface = "sans";
                        mFamilyName = "sans";
                        break;

                    case 2:
                    mTypeface = "serif";
                        mFamilyName = "serif";
                        break;

                    case 3:
                    mTypeface = "monospace";
                        mFamilyName = "monospace";
                        break;

                    default:
                    mTypeface = null;
                        mFamilyName = null;
                        break;
                }
            }
        }

        a.recycle();

@@ -112,15 +119,16 @@ public class TextAppearanceSpan extends MetricAffectingSpan implements Parcelabl
     */
    public TextAppearanceSpan(String family, int style, int size,
                              ColorStateList color, ColorStateList linkColor) {
        mTypeface = family;
        mFamilyName = family;
        mStyle = style;
        mTextSize = size;
        mTextColor = color;
        mTextColorLink = linkColor;
        mTypeface = null;
    }

    public TextAppearanceSpan(Parcel src) {
        mTypeface = src.readString();
        mFamilyName = src.readString();
        mStyle = src.readInt();
        mTextSize = src.readInt();
        if (src.readInt() != 0) {
@@ -133,6 +141,7 @@ public class TextAppearanceSpan extends MetricAffectingSpan implements Parcelabl
        } else {
            mTextColorLink = null;
        }
        mTypeface = LeakyTypefaceStorage.readTypefaceFromParcel(src);
    }

    public int getSpanTypeId() {
@@ -154,7 +163,7 @@ public class TextAppearanceSpan extends MetricAffectingSpan implements Parcelabl

    /** @hide */
    public void writeToParcelInternal(Parcel dest, int flags) {
        dest.writeString(mTypeface);
        dest.writeString(mFamilyName);
        dest.writeInt(mStyle);
        dest.writeInt(mTextSize);
        if (mTextColor != null) {
@@ -169,6 +178,7 @@ public class TextAppearanceSpan extends MetricAffectingSpan implements Parcelabl
        } else {
            dest.writeInt(0);
        }
        LeakyTypefaceStorage.writeTypefaceToParcel(mTypeface, dest);
    }

    /**
@@ -176,7 +186,7 @@ public class TextAppearanceSpan extends MetricAffectingSpan implements Parcelabl
     * if it does not specify one.
     */
    public String getFamily() {
        return mTypeface;
        return mFamilyName;
    }

    /**
@@ -226,25 +236,34 @@ public class TextAppearanceSpan extends MetricAffectingSpan implements Parcelabl

    @Override
    public void updateMeasureState(TextPaint ds) {
        if (mTypeface != null || mStyle != 0) {
            Typeface tf = ds.getTypeface();
        final Typeface styledTypeface;
        int style = 0;

        if (mTypeface != null) {
            style = mStyle;
            styledTypeface = Typeface.create(mTypeface, style);
        } else if (mFamilyName != null || mStyle != 0) {
            Typeface tf = ds.getTypeface();

            if (tf != null) {
                style = tf.getStyle();
            }

            style |= mStyle;

            if (mTypeface != null) {
                tf = Typeface.create(mTypeface, style);
            if (mFamilyName != null) {
                styledTypeface = Typeface.create(mFamilyName, style);
            } else if (tf == null) {
                tf = Typeface.defaultFromStyle(style);
                styledTypeface = Typeface.defaultFromStyle(style);
            } else {
                styledTypeface = Typeface.create(tf, style);
            }
        } else {
                tf = Typeface.create(tf, style);
            styledTypeface = null;
        }

            int fake = style & ~tf.getStyle();
        if (styledTypeface != null) {
            int fake = style & ~styledTypeface.getStyle();

            if ((fake & Typeface.BOLD) != 0) {
                ds.setFakeBoldText(true);
@@ -254,7 +273,7 @@ public class TextAppearanceSpan extends MetricAffectingSpan implements Parcelabl
                ds.setTextSkewX(-0.25f);
            }

            ds.setTypeface(tf);
            ds.setTypeface(styledTypeface);
        }

        if (mTextSize > 0) {
+86 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2017 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.
 */

package android.graphics;

import com.android.internal.annotations.GuardedBy;

import android.annotation.NonNull;
import android.annotation.Nullable;
import android.os.Parcel;
import android.os.Process;
import android.util.ArrayMap;

import java.util.ArrayList;

/**
 * This class is used for Parceling Typeface object.
 * Note: Typeface object can not be passed over the process boundary.
 *
 * @hide
 */
public class LeakyTypefaceStorage {
    private static final Object sLock = new Object();

    @GuardedBy("sLock")
    private static final ArrayList<Typeface> sStorage = new ArrayList<>();
    @GuardedBy("sLock")
    private static final ArrayMap<Typeface, Integer> sTypefaceMap = new ArrayMap<>();

    /**
     * Write typeface to parcel.
     *
     * You can't transfer Typeface to a different process. {@link readTypefaceFromParcel} will
     * return {@code null} if the {@link readTypefaceFromParcel} is called in a different process.
     *
     * @param typeface A {@link Typeface} to be written.
     * @param parcel A {@link Parcel} object.
     */
    public static void writeTypefaceToParcel(@Nullable Typeface typeface, @NonNull Parcel parcel) {
        parcel.writeInt(Process.myPid());
        synchronized (sLock) {
            final int id;
            final Integer i = sTypefaceMap.get(typeface);
            if (i != null) {
                id = i.intValue();
            } else {
                id = sStorage.size();
                sStorage.add(typeface);
                sTypefaceMap.put(typeface, id);
            }
            parcel.writeInt(id);
        }
    }

    /**
     * Read typeface from parcel.
     *
     * If the {@link Typeface} was created in another process, this method returns null.
     *
     * @param parcel A {@link Parcel} object
     * @return A {@link Typeface} object.
     */
    public static @Nullable Typeface readTypefaceFromParcel(@NonNull Parcel parcel) {
        final int pid = parcel.readInt();
        final int typefaceId = parcel.readInt();
        if (pid != Process.myPid()) {
            return null;  // The Typeface was created and written in another process.
        }
        synchronized (sLock) {
            return sStorage.get(typefaceId);
        }
    }
}