diff --git a/core/java/android/content/res/CompatibilityInfo.java b/core/java/android/content/res/CompatibilityInfo.java
index 6ce2242..ce6e1c7 100644
--- a/core/java/android/content/res/CompatibilityInfo.java
+++ b/core/java/android/content/res/CompatibilityInfo.java
@@ -563,6 +563,9 @@
         if (applyToSize) {
             inoutDm.widthPixels = (int) (inoutDm.widthPixels * invertedRatio + 0.5f);
             inoutDm.heightPixels = (int) (inoutDm.heightPixels * invertedRatio + 0.5f);
+
+            float fontScale = inoutDm.scaledDensity / inoutDm.density;
+            inoutDm.fontScaleConverter = FontScaleConverterFactory.forScale(fontScale);
         }
     }
 
diff --git a/core/java/android/content/res/FontScaleConverter.java b/core/java/android/content/res/FontScaleConverter.java
new file mode 100644
index 0000000..c7fdb16
--- /dev/null
+++ b/core/java/android/content/res/FontScaleConverter.java
@@ -0,0 +1,148 @@
+/*
+ * Copyright (C) 2022 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.content.res;
+
+import android.annotation.NonNull;
+import android.util.MathUtils;
+
+import com.android.internal.annotations.VisibleForTesting;
+
+import java.util.Arrays;
+
+/**
+ * A lookup table for non-linear font scaling. Converts font sizes given in "sp" dimensions to a
+ * "dp" dimension according to a non-linear curve.
+ *
+ * <p>This is meant to improve readability at larger font scales: larger fonts will scale up more
+ * slowly than smaller fonts, so we don't get ridiculously huge fonts that don't fit on the screen.
+ *
+ * <p>The thinking here is that large fonts are already big enough to read, but we still want to
+ * scale them slightly to preserve the visual hierarchy when compared to smaller fonts.
+ *
+ * @hide
+ */
+public class FontScaleConverter {
+    /**
+     * How close the given SP should be to a canonical SP in the array before they are considered
+     * the same for lookup purposes.
+     */
+    private static final float THRESHOLD_FOR_MATCHING_SP = 0.02f;
+
+    @VisibleForTesting
+    final float[] mFromSpValues;
+    @VisibleForTesting
+    final float[] mToDpValues;
+
+    /**
+     * Creates a lookup table for the given conversions.
+     *
+     * <p>Any "sp" value not in the lookup table will be derived via linear interpolation.
+     *
+     * <p>The arrays must be sorted ascending and monotonically increasing.
+     *
+     * @param fromSp array of dimensions in SP
+     * @param toDp array of dimensions in DP that correspond to an SP value in fromSp
+     *
+     * @throws IllegalArgumentException if the array lengths don't match or are empty
+     * @hide
+     */
+    @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE)
+    public FontScaleConverter(@NonNull float[] fromSp, @NonNull float[] toDp) {
+        if (fromSp.length != toDp.length || fromSp.length == 0) {
+            throw new IllegalArgumentException("Array lengths must match and be nonzero");
+        }
+
+        mFromSpValues = fromSp;
+        mToDpValues = toDp;
+    }
+
+    /**
+     * Convert a dimension in "sp" to "dp" using the lookup table.
+     *
+     * @hide
+     */
+    public float convertSpToDp(float sp) {
+        final float spPositive = Math.abs(sp);
+        // TODO(b/247861374): find a match at a higher index?
+        final int spRounded = Math.round(spPositive);
+        final float sign = Math.signum(sp);
+        final int index = Arrays.binarySearch(mFromSpValues, spRounded);
+        if (index >= 0 && Math.abs(spRounded - spPositive) < THRESHOLD_FOR_MATCHING_SP) {
+            // exact match, return the matching dp
+            return sign * mToDpValues[index];
+        } else {
+            // must be a value in between index and index + 1: interpolate.
+            final int lowerIndex = -(index + 1) - 1;
+
+            final float startSp;
+            final float endSp;
+            final float startDp;
+            final float endDp;
+
+            if (lowerIndex >= mFromSpValues.length - 1) {
+                // It's past our lookup table. Determine the last elements' scaling factor and use.
+                startSp = mFromSpValues[mFromSpValues.length - 1];
+                startDp = mToDpValues[mFromSpValues.length - 1];
+
+                if (startSp == 0) return 0;
+
+                final float scalingFactor = startDp / startSp;
+                return sp * scalingFactor;
+            } else if (lowerIndex == -1) {
+                // It's smaller than the smallest value in our table. Interpolate from 0.
+                startSp = 0;
+                startDp = 0;
+                endSp = mFromSpValues[0];
+                endDp = mToDpValues[0];
+            } else {
+                startSp = mFromSpValues[lowerIndex];
+                endSp = mFromSpValues[lowerIndex + 1];
+                startDp = mToDpValues[lowerIndex];
+                endDp = mToDpValues[lowerIndex + 1];
+            }
+
+            return sign * MathUtils.constrainedMap(startDp, endDp, startSp, endSp, spPositive);
+        }
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) return true;
+        if (o == null) return false;
+        if (!(o instanceof FontScaleConverter)) return false;
+        FontScaleConverter that = (FontScaleConverter) o;
+        return Arrays.equals(mFromSpValues, that.mFromSpValues)
+                && Arrays.equals(mToDpValues, that.mToDpValues);
+    }
+
+    @Override
+    public int hashCode() {
+        int result = Arrays.hashCode(mFromSpValues);
+        result = 31 * result + Arrays.hashCode(mToDpValues);
+        return result;
+    }
+
+    @Override
+    public String toString() {
+        return "FontScaleConverter{"
+                + "fromSpValues="
+                + Arrays.toString(mFromSpValues)
+                + ", toDpValues="
+                + Arrays.toString(mToDpValues)
+                + '}';
+    }
+}
diff --git a/core/java/android/content/res/FontScaleConverterFactory.java b/core/java/android/content/res/FontScaleConverterFactory.java
new file mode 100644
index 0000000..c77a372
--- /dev/null
+++ b/core/java/android/content/res/FontScaleConverterFactory.java
@@ -0,0 +1,119 @@
+/*
+ * Copyright (C) 2022 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.content.res;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.util.SparseArray;
+
+import com.android.internal.annotations.VisibleForTesting;
+
+/**
+ * Stores lookup tables for creating {@link FontScaleConverter}s at various scales.
+ *
+ * @hide
+ */
+public class FontScaleConverterFactory {
+    private static final float SCALE_KEY_MULTIPLIER = 100f;
+
+    @VisibleForTesting
+    static final SparseArray<FontScaleConverter> LOOKUP_TABLES = new SparseArray<>();
+
+    static {
+        // These were generated by frameworks/base/tools/fonts/font-scaling-array-generator.js and
+        // manually tweaked for optimum readability.
+        put(
+                /* scaleKey= */ 1.15f,
+                new FontScaleConverter(
+                        /* fromSp= */
+                        new float[] {   8f,   10f,   12f,   14f,   18f,   20f,   24f,   30f,  100},
+                        /* toDp=   */
+                        new float[] { 9.2f, 11.5f, 13.8f, 16.1f, 20.7f,   23f, 27.6f, 34.5f,  115})
+        );
+
+        put(
+                /* scaleKey= */ 1.3f,
+                new FontScaleConverter(
+                        /* fromSp= */
+                        new float[] {   8f,   10f,   12f,   14f,   18f,   20f,   24f,   30f,  100},
+                        /* toDp=   */
+                        new float[] {10.4f,   13f, 15.6f, 18.2f, 23.4f,   26f, 31.2f,   39f,  130})
+        );
+
+        put(
+                /* scaleKey= */ 1.5f,
+                new FontScaleConverter(
+                        /* fromSp= */
+                        new float[] {   8f,   10f,   12f,   14f,   18f,   20f,   24f,   30f,  100},
+                        /* toDp=   */
+                        new float[] {  12f,   15f,   18f,   21f,   27f,   30f,   36f,   45f,  150})
+        );
+
+        put(
+                /* scaleKey= */ 1.8f,
+                new FontScaleConverter(
+                        /* fromSp= */
+                        new float[] {   8f,   10f,   12f,   14f,   18f,   20f,   24f,   30f,  100},
+                        /* toDp=   */
+                        new float[] {14.4f,   18f, 21.6f, 25.2f, 32.4f,   36f, 43.2f,   54f,  180})
+        );
+
+        put(
+                /* scaleKey= */ 2f,
+                new FontScaleConverter(
+                        /* fromSp= */
+                        new float[] {   8f,   10f,   12f,   14f,   18f,   20f,   24f,   30f,  100},
+                        /* toDp=   */
+                        new float[] {  16f,   20f,   24f,   28f,   36f,   40f,   48f,   60f,  200})
+        );
+
+    }
+
+    private FontScaleConverterFactory() {}
+
+    /**
+     * Finds a matching FontScaleConverter for the given fontScale factor.
+     *
+     * @param fontScale the scale factor, usually from {@link Configuration#fontScale}.
+     *
+     * @return a converter for the given scale, or null if non-linear scaling should not be used.
+     *
+     * @hide
+     */
+    @Nullable
+    public static FontScaleConverter forScale(float fontScale) {
+        if (fontScale <= 1) {
+            // We don't need non-linear curves for shrinking text or for 100%.
+            // Also, fontScale==0 should not have a curve either
+            return null;
+        }
+
+        FontScaleConverter lookupTable = get(fontScale);
+        // TODO(b/247861716): interpolate between two tables when null
+
+        return lookupTable;
+    }
+
+    private static void put(float scaleKey, @NonNull FontScaleConverter fontScaleConverter) {
+        LOOKUP_TABLES.put((int) (scaleKey * SCALE_KEY_MULTIPLIER), fontScaleConverter);
+    }
+
+    @Nullable
+    private static FontScaleConverter get(float scaleKey) {
+        return LOOKUP_TABLES.get((int) (scaleKey * SCALE_KEY_MULTIPLIER));
+    }
+}
diff --git a/core/java/android/content/res/ResourcesImpl.java b/core/java/android/content/res/ResourcesImpl.java
index ff07291..50809ac 100644
--- a/core/java/android/content/res/ResourcesImpl.java
+++ b/core/java/android/content/res/ResourcesImpl.java
@@ -430,6 +430,8 @@
                 // Protect against an unset fontScale.
                 mMetrics.scaledDensity = mMetrics.density *
                         (mConfiguration.fontScale != 0 ? mConfiguration.fontScale : 1.0f);
+                mMetrics.fontScaleConverter =
+                        FontScaleConverterFactory.forScale(mConfiguration.fontScale);
 
                 final int width, height;
                 if (mMetrics.widthPixels >= mMetrics.heightPixels) {
diff --git a/core/java/android/util/DisplayMetrics.java b/core/java/android/util/DisplayMetrics.java
index 0a3e6b1..9ce7c93 100755
--- a/core/java/android/util/DisplayMetrics.java
+++ b/core/java/android/util/DisplayMetrics.java
@@ -18,6 +18,7 @@
 
 import android.annotation.Nullable;
 import android.compat.annotation.UnsupportedAppUsage;
+import android.content.res.FontScaleConverter;
 import android.os.SystemProperties;
 
 /**
@@ -265,6 +266,15 @@
      * increments at runtime based on a user preference for the font size.
      */
     public float scaledDensity;
+
+    /**
+     * If non-null, this will be used to calculate font sizes instead of {@link #scaledDensity}.
+     *
+     * @hide
+     */
+    @Nullable
+    public FontScaleConverter fontScaleConverter;
+
     /**
      * The exact physical pixels per inch of the screen in the X dimension.
      */
@@ -342,6 +352,7 @@
         noncompatScaledDensity = o.noncompatScaledDensity;
         noncompatXdpi = o.noncompatXdpi;
         noncompatYdpi = o.noncompatYdpi;
+        fontScaleConverter = o.fontScaleConverter;
     }
     
     public void setToDefaults() {
@@ -359,6 +370,7 @@
         noncompatScaledDensity = scaledDensity;
         noncompatXdpi = xdpi;
         noncompatYdpi = ydpi;
+        fontScaleConverter = null;
     }
 
     @Override
diff --git a/core/java/android/util/TypedValue.java b/core/java/android/util/TypedValue.java
index 19de396..de204a6 100644
--- a/core/java/android/util/TypedValue.java
+++ b/core/java/android/util/TypedValue.java
@@ -408,7 +408,14 @@
         case COMPLEX_UNIT_DIP:
             return value * metrics.density;
         case COMPLEX_UNIT_SP:
-            return value * metrics.scaledDensity;
+                if (metrics.fontScaleConverter != null) {
+                    return applyDimension(
+                            COMPLEX_UNIT_DIP,
+                            metrics.fontScaleConverter.convertSpToDp(value),
+                            metrics);
+                } else {
+                    return value * metrics.scaledDensity;
+                }
         case COMPLEX_UNIT_PT:
             return value * metrics.xdpi * (1.0f/72);
         case COMPLEX_UNIT_IN:
diff --git a/core/tests/coretests/Android.bp b/core/tests/coretests/Android.bp
index a767f83..cffc702 100644
--- a/core/tests/coretests/Android.bp
+++ b/core/tests/coretests/Android.bp
@@ -43,6 +43,7 @@
         "mockwebserver",
         "guava",
         "androidx.core_core",
+        "androidx.core_core-ktx",
         "androidx.test.espresso.core",
         "androidx.test.ext.junit",
         "androidx.test.runner",
diff --git a/core/tests/coretests/src/android/content/res/FontScaleConverterFactoryTest.kt b/core/tests/coretests/src/android/content/res/FontScaleConverterFactoryTest.kt
new file mode 100644
index 0000000..cfca037
--- /dev/null
+++ b/core/tests/coretests/src/android/content/res/FontScaleConverterFactoryTest.kt
@@ -0,0 +1,78 @@
+/*
+ * Copyright (C) 2022 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.content.res
+
+import androidx.core.util.forEach
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.SmallTest
+import com.google.common.truth.Truth.assertThat
+import org.junit.Test
+import org.junit.runner.RunWith
+
+@RunWith(AndroidJUnit4::class)
+class FontScaleConverterFactoryTest {
+
+    @Test
+    fun scale200IsTwiceAtSmallSizes() {
+        val table = FontScaleConverterFactory.forScale(2F)!!
+        assertThat(table.convertSpToDp(1F)).isWithin(CONVERSION_TOLERANCE).of(2f)
+        assertThat(table.convertSpToDp(8F)).isWithin(CONVERSION_TOLERANCE).of(16f)
+        assertThat(table.convertSpToDp(10F)).isWithin(CONVERSION_TOLERANCE).of(20f)
+        assertThat(table.convertSpToDp(5F)).isWithin(CONVERSION_TOLERANCE).of(10f)
+        assertThat(table.convertSpToDp(0F)).isWithin(CONVERSION_TOLERANCE).of(0f)
+    }
+
+    @SmallTest
+    fun missingLookupTableReturnsNull() {
+        assertThat(FontScaleConverterFactory.forScale(3F)).isNull()
+    }
+
+    @SmallTest
+    fun missingLookupTable105ReturnsNull() {
+        assertThat(FontScaleConverterFactory.forScale(1.05F)).isNull()
+    }
+
+    @SmallTest
+    fun missingLookupTableNegativeReturnsNull() {
+        assertThat(FontScaleConverterFactory.forScale(-1F)).isNull()
+    }
+
+    @SmallTest
+    fun unnecessaryFontScalesReturnsNull() {
+        assertThat(FontScaleConverterFactory.forScale(0F)).isNull()
+        assertThat(FontScaleConverterFactory.forScale(1F)).isNull()
+        assertThat(FontScaleConverterFactory.forScale(0.85F)).isNull()
+    }
+
+    @SmallTest
+    fun tablesMatchAndAreMonotonicallyIncreasing() {
+        FontScaleConverterFactory.LOOKUP_TABLES.forEach { _, lookupTable ->
+            assertThat(lookupTable.mToDpValues).hasLength(lookupTable.mFromSpValues.size)
+            assertThat(lookupTable.mToDpValues).isNotEmpty()
+
+            assertThat(lookupTable.mFromSpValues.asList()).isInStrictOrder()
+            assertThat(lookupTable.mToDpValues.asList()).isInStrictOrder()
+
+            assertThat(lookupTable.mFromSpValues.asList()).containsNoDuplicates()
+            assertThat(lookupTable.mToDpValues.asList()).containsNoDuplicates()
+        }
+    }
+
+    companion object {
+        private const val CONVERSION_TOLERANCE = 0.05f
+    }
+}
diff --git a/core/tests/coretests/src/android/content/res/FontScaleConverterTest.kt b/core/tests/coretests/src/android/content/res/FontScaleConverterTest.kt
new file mode 100644
index 0000000..e405c55
--- /dev/null
+++ b/core/tests/coretests/src/android/content/res/FontScaleConverterTest.kt
@@ -0,0 +1,95 @@
+/*
+ * Copyright (C) 2022 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.content.res
+
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import com.google.common.truth.Truth.assertThat
+import org.junit.Test
+import org.junit.runner.RunWith
+
+@RunWith(AndroidJUnit4::class)
+class FontScaleConverterTest {
+
+    @Test
+    fun straightInterpolation() {
+        val table = createTable(8f to 8f, 10f to 10f, 20f to 20f)
+        assertThat(table.convertSpToDp(1F)).isWithin(CONVERSION_TOLERANCE).of(1f)
+        assertThat(table.convertSpToDp(8F)).isWithin(CONVERSION_TOLERANCE).of(8f)
+        assertThat(table.convertSpToDp(10F)).isWithin(CONVERSION_TOLERANCE).of(10f)
+        assertThat(table.convertSpToDp(30F)).isWithin(CONVERSION_TOLERANCE).of(30f)
+        assertThat(table.convertSpToDp(20F)).isWithin(CONVERSION_TOLERANCE).of(20f)
+        assertThat(table.convertSpToDp(5F)).isWithin(CONVERSION_TOLERANCE).of(5f)
+        assertThat(table.convertSpToDp(0F)).isWithin(CONVERSION_TOLERANCE).of(0f)
+    }
+
+    @Test
+    fun interpolate200Percent() {
+        val table = createTable(8f to 16f, 10f to 20f, 30f to 60f)
+        assertThat(table.convertSpToDp(1F)).isWithin(CONVERSION_TOLERANCE).of(2f)
+        assertThat(table.convertSpToDp(8F)).isWithin(CONVERSION_TOLERANCE).of(16f)
+        assertThat(table.convertSpToDp(10F)).isWithin(CONVERSION_TOLERANCE).of(20f)
+        assertThat(table.convertSpToDp(30F)).isWithin(CONVERSION_TOLERANCE).of(60f)
+        assertThat(table.convertSpToDp(20F)).isWithin(CONVERSION_TOLERANCE).of(40f)
+        assertThat(table.convertSpToDp(5F)).isWithin(CONVERSION_TOLERANCE).of(10f)
+        assertThat(table.convertSpToDp(0F)).isWithin(CONVERSION_TOLERANCE).of(0f)
+    }
+
+    @Test
+    fun interpolate150Percent() {
+        val table = createTable(2f to 3f, 10f to 15f, 20f to 30f, 100f to 150f)
+        assertThat(table.convertSpToDp(2F)).isWithin(CONVERSION_TOLERANCE).of(3f)
+        assertThat(table.convertSpToDp(1F)).isWithin(CONVERSION_TOLERANCE).of(1.5f)
+        assertThat(table.convertSpToDp(8F)).isWithin(CONVERSION_TOLERANCE).of(12f)
+        assertThat(table.convertSpToDp(10F)).isWithin(CONVERSION_TOLERANCE).of(15f)
+        assertThat(table.convertSpToDp(20F)).isWithin(CONVERSION_TOLERANCE).of(30f)
+        assertThat(table.convertSpToDp(50F)).isWithin(CONVERSION_TOLERANCE).of(75f)
+        assertThat(table.convertSpToDp(5F)).isWithin(CONVERSION_TOLERANCE).of(7.5f)
+        assertThat(table.convertSpToDp(0F)).isWithin(CONVERSION_TOLERANCE).of(0f)
+    }
+
+    @Test
+    fun pastEndsUsesLastScalingFactor() {
+        val table = createTable(8f to 16f, 10f to 20f, 30f to 60f)
+        assertThat(table.convertSpToDp(100F)).isWithin(CONVERSION_TOLERANCE).of(200f)
+        assertThat(table.convertSpToDp(31F)).isWithin(CONVERSION_TOLERANCE).of(62f)
+        assertThat(table.convertSpToDp(1000F)).isWithin(CONVERSION_TOLERANCE).of(2000f)
+        assertThat(table.convertSpToDp(2000F)).isWithin(CONVERSION_TOLERANCE).of(4000f)
+        assertThat(table.convertSpToDp(10000F)).isWithin(CONVERSION_TOLERANCE).of(20000f)
+    }
+
+    @Test
+    fun negativeSpIsNegativeDp() {
+        val table = createTable(8f to 16f, 10f to 20f, 30f to 60f)
+        assertThat(table.convertSpToDp(-1F)).isWithin(CONVERSION_TOLERANCE).of(-2f)
+        assertThat(table.convertSpToDp(-8F)).isWithin(CONVERSION_TOLERANCE).of(-16f)
+        assertThat(table.convertSpToDp(-10F)).isWithin(CONVERSION_TOLERANCE).of(-20f)
+        assertThat(table.convertSpToDp(-30F)).isWithin(CONVERSION_TOLERANCE).of(-60f)
+        assertThat(table.convertSpToDp(-20F)).isWithin(CONVERSION_TOLERANCE).of(-40f)
+        assertThat(table.convertSpToDp(-5F)).isWithin(CONVERSION_TOLERANCE).of(-10f)
+        assertThat(table.convertSpToDp(-0F)).isWithin(CONVERSION_TOLERANCE).of(0f)
+    }
+
+    private fun createTable(vararg pairs: Pair<Float, Float>) =
+        FontScaleConverter(
+            pairs.map { it.first }.toFloatArray(),
+            pairs.map { it.second }.toFloatArray()
+        )
+
+    companion object {
+        private const val CONVERSION_TOLERANCE = 0.05f
+    }
+}
diff --git a/core/tests/coretests/src/android/util/TypedValueTest.kt b/core/tests/coretests/src/android/util/TypedValueTest.kt
index 7a05d97..7d98a7d 100644
--- a/core/tests/coretests/src/android/util/TypedValueTest.kt
+++ b/core/tests/coretests/src/android/util/TypedValueTest.kt
@@ -16,16 +16,17 @@
 
 package android.util
 
+import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.LargeTest
 import androidx.test.filters.SmallTest
-import androidx.test.runner.AndroidJUnit4
+import com.google.common.truth.Truth.assertThat
+import kotlin.math.abs
+import kotlin.math.min
+import kotlin.math.roundToInt
 import org.junit.Assert.assertEquals
 import org.junit.Test
 import org.junit.runner.RunWith
 import org.mockito.Mockito.mock
-import kotlin.math.abs
-import kotlin.math.min
-import kotlin.math.roundToInt
 
 @RunWith(AndroidJUnit4::class)
 class TypedValueTest {
@@ -152,4 +153,19 @@
         val widthPx = TypedValue.complexToDimensionPixelSize(widthDimen, metrics)
         assertEquals(widthFloat.roundToInt(), widthPx)
     }
-}
\ No newline at end of file
+
+    @SmallTest
+    @Test
+    fun testNonLinearFontScaling_nullLookupFallsBackToScaledDensity() {
+        val metrics: DisplayMetrics = mock(DisplayMetrics::class.java)
+        val fontScale = 2f
+        metrics.density = 1f
+        metrics.scaledDensity = fontScale * metrics.density
+        metrics.fontScaleConverter = null
+
+        assertThat(TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP, 10f, metrics))
+                .isEqualTo(20f)
+        assertThat(TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP, 50f, metrics))
+                .isEqualTo(100f)
+    }
+}
diff --git a/tools/fonts/font-scaling-array-generator.js b/tools/fonts/font-scaling-array-generator.js
new file mode 100644
index 0000000..9754697
--- /dev/null
+++ b/tools/fonts/font-scaling-array-generator.js
@@ -0,0 +1,195 @@
+/*
+ * Copyright (C) 2022 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.
+ */
+
+/**
+  Generates arrays for non-linear font scaling, to be pasted into
+  frameworks/base/core/java/android/content/res/FontScaleConverterFactory.java
+
+  To use:
+    `node font-scaling-array-generator.js`
+    or just open a browser, open DevTools, and paste into the Console.
+*/
+
+/**
+ * Modify this to match your packages/apps/Settings/res/arrays.xml#entryvalues_font_size
+ * array so that all possible scales are generated.
+ */
+const scales = [1.15, 1.30, 1.5, 1.8, 2];
+
+const commonSpSizes = [8, 10, 12, 14, 18, 20, 24, 30, 100];
+
+/**
+ * Enum for GENERATION_STYLE which determines how to generate the arrays.
+ */
+const GenerationStyle = {
+  /**
+   * Interpolates between hand-tweaked curves. This is the best option and
+   * shouldn't require any additional tweaking.
+   */
+  CUSTOM_TWEAKED: 'CUSTOM_TWEAKED',
+
+  /**
+   * Uses a curve equation that is mostly correct, but will need manual tweaking
+   * at some scales.
+   */
+  CURVE: 'CURVE',
+
+  /**
+   * Uses straight linear multiplication. Good starting point for manual
+   * tweaking.
+   */
+  LINEAR: 'LINEAR'
+}
+
+/**
+ * Determines how arrays are generated. Must be one of the GenerationStyle
+ * values.
+ */
+const GENERATION_STYLE = GenerationStyle.CUSTOM_TWEAKED;
+
+// These are hand-tweaked curves from which we will derive the other
+// interstitial curves using linear interpolation, in the case of using
+// GenerationStyle.CUSTOM_TWEAKED.
+const interpolationTargets = {
+  1.0: commonSpSizes,
+  1.5: [12, 15, 18, 22, 24, 26, 28, 30, 100],
+  2.0: [16, 20, 24, 26, 30, 34, 36, 38, 100]
+};
+
+/**
+ * Interpolate a value with specified extrema, to a new value between new
+ * extrema.
+ *
+ * @param value the current value
+ * @param inputMin minimum the input value can reach
+ * @param inputMax maximum the input value can reach
+ * @param outputMin minimum the output value can reach
+ * @param outputMax maximum the output value can reach
+ */
+function map(value, inputMin, inputMax, outputMin, outputMax) {
+  return outputMin + (outputMax - outputMin) * ((value - inputMin) / (inputMax - inputMin));
+}
+
+/***
+ * Interpolate between values a and b.
+ */
+function lerp(a, b, fraction) {
+  return (a * (1.0 - fraction)) + (b * fraction);
+}
+
+function generateRatios(scale) {
+  // Find the best two arrays to interpolate between.
+  let startTarget, endTarget;
+  let startTargetScale, endTargetScale;
+  const targetScales = Object.keys(interpolationTargets).sort();
+  for (let i = 0; i < targetScales.length - 1; i++) {
+    const targetScaleKey = targetScales[i];
+    const targetScale = parseFloat(targetScaleKey, 10);
+    const startTargetScaleKey = targetScaleKey;
+    const endTargetScaleKey = targetScales[i + 1];
+
+    if (scale < parseFloat(startTargetScaleKey, 10)) {
+      break;
+    }
+
+    startTargetScale = parseFloat(startTargetScaleKey, 10);
+    endTargetScale = parseFloat(endTargetScaleKey, 10);
+    startTarget = interpolationTargets[startTargetScaleKey];
+    endTarget = interpolationTargets[endTargetScaleKey];
+  }
+  const interpolationProgress = map(scale, startTargetScale, endTargetScale, 0, 1);
+
+  return commonSpSizes.map((sp, i) => {
+    const originalSizeDp = sp;
+    let newSizeDp;
+    switch (GENERATION_STYLE) {
+      case GenerationStyle.CUSTOM_TWEAKED:
+        newSizeDp = lerp(startTarget[i], endTarget[i], interpolationProgress);
+        break;
+      case GenerationStyle.CURVE: {
+        let coeff1;
+        let coeff2;
+        if (scale < 1) {
+          // \left(1.22^{-\left(x+5\right)}+0.5\right)\cdot x
+          coeff1 = -5;
+          coeff2 = scale;
+        } else {
+          // (1.22^{-\left(x-10\right)}+1\right)\cdot x
+          coeff1 = map(scale, 1, 2, 2, 8);
+          coeff2 = 1;
+        }
+        newSizeDp = ((Math.pow(1.22, (-(originalSizeDp - coeff1))) + coeff2) * originalSizeDp);
+        break;
+      }
+      case GenerationStyle.LINEAR:
+        newSizeDp = originalSizeDp * scale;
+        break;
+      default:
+        throw new Error('Invalid GENERATION_STYLE');
+    }
+    return {
+      fromSp: sp,
+      toDp: newSizeDp
+    }
+  });
+}
+
+const scaleArrays =
+    scales
+        .map(scale => {
+          const scaleString = (scale * 100).toFixed(0);
+          return {
+            scale,
+            name: `font_size_original_sp_to_scaled_dp_${scaleString}_percent`
+          }
+        })
+        .map(scaleArray => {
+          const items = generateRatios(scaleArray.scale);
+
+          return {
+            ...scaleArray,
+            items
+          }
+        });
+
+function formatDigit(d) {
+  const twoSignificantDigits = Math.round(d * 100) / 100;
+  return String(twoSignificantDigits).padStart(4, ' ');
+}
+
+console.log(
+    '' +
+    scaleArrays.reduce(
+        (previousScaleArray, currentScaleArray) => {
+          const itemsFromSp = currentScaleArray.items.map(d => d.fromSp)
+                                .map(formatDigit)
+                                .join('f, ');
+          const itemsToDp = currentScaleArray.items.map(d => d.toDp)
+                                .map(formatDigit)
+                                .join('f, ');
+
+          return previousScaleArray + `
+        put(
+                /* scaleKey= */ ${currentScaleArray.scale}f,
+                new FontScaleConverter(
+                        /* fromSp= */
+                        new float[] {${itemsFromSp}},
+                        /* toDp=   */
+                        new float[] {${itemsToDp}})
+        );
+     `;
+        },
+        ''));
