Loading core/api/current.txt +2 −0 Original line number Diff line number Diff line Loading @@ -17875,6 +17875,7 @@ package android.graphics.text { field public static final int HYPHENATION_FREQUENCY_FULL = 2; // 0x2 field public static final int HYPHENATION_FREQUENCY_NONE = 0; // 0x0 field public static final int HYPHENATION_FREQUENCY_NORMAL = 1; // 0x1 field @FlaggedApi("com.android.text.flags.inter_character_justification") public static final int JUSTIFICATION_MODE_INTER_CHARACTER = 2; // 0x2 field public static final int JUSTIFICATION_MODE_INTER_WORD = 1; // 0x1 field public static final int JUSTIFICATION_MODE_NONE = 0; // 0x0 } Loading Loading @@ -46954,6 +46955,7 @@ package android.text { field @NonNull public static final android.text.Layout.TextInclusionStrategy INCLUSION_STRATEGY_ANY_OVERLAP; field @NonNull public static final android.text.Layout.TextInclusionStrategy INCLUSION_STRATEGY_CONTAINS_ALL; field @NonNull public static final android.text.Layout.TextInclusionStrategy INCLUSION_STRATEGY_CONTAINS_CENTER; field @FlaggedApi("com.android.text.flags.inter_character_justification") public static final int JUSTIFICATION_MODE_INTER_CHARACTER = 2; // 0x2 field public static final int JUSTIFICATION_MODE_INTER_WORD = 1; // 0x1 field public static final int JUSTIFICATION_MODE_NONE = 0; // 0x0 } core/java/android/text/Layout.java +13 −5 Original line number Diff line number Diff line Loading @@ -152,7 +152,8 @@ public abstract class Layout { /** @hide */ @IntDef(prefix = { "JUSTIFICATION_MODE_" }, value = { LineBreaker.JUSTIFICATION_MODE_NONE, LineBreaker.JUSTIFICATION_MODE_INTER_WORD LineBreaker.JUSTIFICATION_MODE_INTER_WORD, LineBreaker.JUSTIFICATION_MODE_INTER_CHARACTER, }) @Retention(RetentionPolicy.SOURCE) public @interface JustificationMode {} Loading @@ -168,6 +169,13 @@ public abstract class Layout { public static final int JUSTIFICATION_MODE_INTER_WORD = LineBreaker.JUSTIFICATION_MODE_INTER_WORD; /** * Value for justification mode indicating the text is justified by stretching letter spacing. */ @FlaggedApi(FLAG_INTER_CHARACTER_JUSTIFICATION) public static final int JUSTIFICATION_MODE_INTER_CHARACTER = LineBreaker.JUSTIFICATION_MODE_INTER_CHARACTER; /* * Line spacing multiplier for default line spacing. */ Loading Loading @@ -809,7 +817,7 @@ public abstract class Layout { getEllipsisStart(lineNum) + getEllipsisCount(lineNum), isFallbackLineSpacingEnabled()); if (justify) { tl.justify(right - left - indentWidth); tl.justify(mJustificationMode, right - left - indentWidth); } tl.draw(canvas, x, ltop, lbaseline, lbottom); } Loading Loading @@ -1058,7 +1066,7 @@ public abstract class Layout { getEllipsisStart(line), getEllipsisStart(line) + getEllipsisCount(line), isFallbackLineSpacingEnabled()); if (isJustificationRequired(line)) { tl.justify(getJustifyWidth(line)); tl.justify(mJustificationMode, getJustifyWidth(line)); } tl.metrics(null, rectF, false, null); Loading Loading @@ -1794,7 +1802,7 @@ public abstract class Layout { getEllipsisStart(line), getEllipsisStart(line) + getEllipsisCount(line), isFallbackLineSpacingEnabled()); if (isJustificationRequired(line)) { tl.justify(getJustifyWidth(line)); tl.justify(mJustificationMode, getJustifyWidth(line)); } final float width = tl.metrics(null, null, mUseBoundsForWidth, null); TextLine.recycle(tl); Loading Loading @@ -1882,7 +1890,7 @@ public abstract class Layout { getEllipsisStart(line), getEllipsisStart(line) + getEllipsisCount(line), isFallbackLineSpacingEnabled()); if (isJustificationRequired(line)) { tl.justify(getJustifyWidth(line)); tl.justify(mJustificationMode, getJustifyWidth(line)); } final float width = tl.metrics(null, null, mUseBoundsForWidth, null); TextLine.recycle(tl); Loading core/java/android/text/TextLine.java +56 −12 Original line number Diff line number Diff line Loading @@ -100,9 +100,25 @@ public class TextLine { // Additional width of whitespace for justification. This value is per whitespace, thus // the line width will increase by mAddedWidthForJustify x (number of stretchable whitespaces). private float mAddedWidthForJustify; private float mAddedWordSpacingInPx; private float mAddedLetterSpacingInPx; private boolean mIsJustifying; @VisibleForTesting public float getAddedWordSpacingInPx() { return mAddedWordSpacingInPx; } @VisibleForTesting public float getAddedLetterSpacingInPx() { return mAddedLetterSpacingInPx; } @VisibleForTesting public boolean isJustifying() { return mIsJustifying; } private final TextPaint mWorkPaint = new TextPaint(); private final TextPaint mActivePaint = new TextPaint(); @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) Loading Loading @@ -259,7 +275,7 @@ public class TextLine { } } mTabs = tabStops; mAddedWidthForJustify = 0; mAddedWordSpacingInPx = 0; mIsJustifying = false; mEllipsisStart = ellipsisStart != ellipsisEnd ? ellipsisStart : 0; Loading @@ -274,19 +290,42 @@ public class TextLine { * Justify the line to the given width. */ @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE) public void justify(float justifyWidth) { public void justify(@Layout.JustificationMode int justificationMode, float justifyWidth) { int end = mLen; while (end > 0 && isLineEndSpace(mText.charAt(mStart + end - 1))) { end--; } if (justificationMode == Layout.JUSTIFICATION_MODE_INTER_WORD) { float width = Math.abs(measure(end, false, null, null, null)); final int spaces = countStretchableSpaces(0, end); if (spaces == 0) { // There are no stretchable spaces, so we can't help the justification by adding any // width. return; } final float width = Math.abs(measure(end, false, null, null, null)); mAddedWidthForJustify = (justifyWidth - width) / spaces; mAddedWordSpacingInPx = (justifyWidth - width) / spaces; mAddedLetterSpacingInPx = 0; } else { // justificationMode == Layout.JUSTIFICATION_MODE_INTER_CHARACTER LineInfo lineInfo = new LineInfo(); float width = Math.abs(measure(end, false, null, null, lineInfo)); int lettersCount = lineInfo.getClusterCount(); if (lettersCount < 2) { return; } mAddedLetterSpacingInPx = (justifyWidth - width) / (lettersCount - 1); if (mAddedLetterSpacingInPx > 0.03) { // If the letter spacing is more than 0.03em, the ligatures are automatically // disabled, so re-calculate everything without ligatures. final String oldFontFeatures = mPaint.getFontFeatureSettings(); mPaint.setFontFeatureSettings(oldFontFeatures + ", \"liga\" off, \"cliga\" off"); width = Math.abs(measure(end, false, null, null, lineInfo)); lettersCount = lineInfo.getClusterCount(); mAddedLetterSpacingInPx = (justifyWidth - width) / (lettersCount - 1); mPaint.setFontFeatureSettings(oldFontFeatures); } mAddedWordSpacingInPx = 0; } mIsJustifying = true; } Loading Loading @@ -529,6 +568,9 @@ public class TextLine { throw new IndexOutOfBoundsException( "offset(" + offset + ") should be less than line limit(" + mLen + ")"); } if (lineInfo != null) { lineInfo.setClusterCount(0); } final int target = trailing ? offset - 1 : offset; if (target < 0) { return 0; Loading Loading @@ -1076,7 +1118,8 @@ public class TextLine { TextPaint wp = mWorkPaint; wp.set(mPaint); if (mIsJustifying) { wp.setWordSpacing(mAddedWidthForJustify); wp.setWordSpacing(mAddedWordSpacingInPx); wp.setLetterSpacing(mAddedLetterSpacingInPx / wp.getTextSize()); // Convert to Em } int spanStart = runStart; Loading Loading @@ -1277,7 +1320,8 @@ public class TextLine { @Nullable float[] advances, int advancesIndex, @Nullable LineInfo lineInfo, int runFlag) { if (mIsJustifying) { wp.setWordSpacing(mAddedWidthForJustify); wp.setWordSpacing(mAddedWordSpacingInPx); wp.setLetterSpacing(mAddedLetterSpacingInPx / wp.getTextSize()); // Convert to Em } // Get metrics first (even for empty strings or "0" width runs) if (drawBounds != null && fmi == null) { Loading core/tests/coretests/src/android/text/TextLineJustificationTest.kt 0 → 100644 +129 −0 Original line number Diff line number Diff line /* * Copyright (C) 2024 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.text import android.platform.test.flag.junit.DeviceFlagsValueProvider import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest import com.google.common.truth.Truth.assertThat import org.junit.Rule import org.junit.Test import org.junit.runner.RunWith @SmallTest @RunWith(AndroidJUnit4::class) class TextLineJustificationTest { @Rule @JvmField val mCheckFlagsRule = DeviceFlagsValueProvider.createCheckFlagsRule() private val PAINT = TextPaint().apply { textSize = 10f // make 1em = 10px } private fun makeTextLine(cs: CharSequence, paint: TextPaint) = TextLine.obtain().apply { set(paint, cs, 0, cs.length, Layout.DIR_LEFT_TO_RIGHT, Layout.DIRS_ALL_LEFT_TO_RIGHT, false, null, 0, 0, false) } private fun getClusterCount(cs: CharSequence, paint: TextPaint) = TextLine.LineInfo().apply { makeTextLine(cs, paint).also { it.metrics(null, null, false, this) TextLine.recycle(it) } }.clusterCount fun justifyTest_WithoutJustify() { val line = "Hello, World." val tl = makeTextLine(line, PAINT) // Without calling justify method, justifying should be false and all added spaces should // be zeros. assertThat(tl.isJustifying).isFalse() assertThat(tl.addedWordSpacingInPx).isEqualTo(0) assertThat(tl.addedLetterSpacingInPx).isEqualTo(0) } @Test fun justifyTest_IntrCharacter_Latin() { val line = "Hello, World." val clusterCount = getClusterCount(line, PAINT) val originalWidth = Layout.getDesiredWidth(line, PAINT) val extraWidth = 100f val tl = makeTextLine(line, PAINT) tl.justify(Layout.JUSTIFICATION_MODE_INTER_CHARACTER, originalWidth + extraWidth) assertThat(tl.isJustifying).isTrue() assertThat(tl.addedWordSpacingInPx).isEqualTo(0) assertThat(tl.addedLetterSpacingInPx).isEqualTo(extraWidth / (clusterCount - 1)) TextLine.recycle(tl) } @Test fun justifyTest_IntrCharacter_Japanese() { val line = "\u672C\u65E5\u306F\u6674\u5929\u306A\u308A\u3002" val clusterCount = getClusterCount(line, PAINT) val originalWidth = Layout.getDesiredWidth(line, PAINT) val extraWidth = 100f val tl = makeTextLine(line, PAINT) tl.justify(Layout.JUSTIFICATION_MODE_INTER_CHARACTER, originalWidth + extraWidth) assertThat(tl.isJustifying).isTrue() assertThat(tl.addedWordSpacingInPx).isEqualTo(0) assertThat(tl.addedLetterSpacingInPx).isEqualTo(extraWidth / (clusterCount - 1)) TextLine.recycle(tl) } @Test fun justifyTest_IntrWord_Latin() { val line = "Hello, World." val originalWidth = Layout.getDesiredWidth(line, PAINT) val extraWidth = 100f val tl = makeTextLine(line, PAINT) tl.justify(Layout.JUSTIFICATION_MODE_INTER_WORD, originalWidth + extraWidth) assertThat(tl.isJustifying).isTrue() // This text contains only one whitespace, so word spacing should be same to the extraWidth. assertThat(tl.addedWordSpacingInPx).isEqualTo(extraWidth) assertThat(tl.addedLetterSpacingInPx).isEqualTo(0) TextLine.recycle(tl) } @Test fun justifyTest_IntrWord_Japanese() { val line = "\u672C\u65E5\u306F\u6674\u0020\u5929\u306A\u308A\u3002" val originalWidth = Layout.getDesiredWidth(line, PAINT) val extraWidth = 100f val tl = makeTextLine(line, PAINT) tl.justify(Layout.JUSTIFICATION_MODE_INTER_WORD, originalWidth + extraWidth) assertThat(tl.isJustifying).isTrue() // This text contains only one whitespace, so word spacing should be same to the extraWidth. assertThat(tl.addedWordSpacingInPx).isEqualTo(extraWidth) assertThat(tl.addedLetterSpacingInPx).isEqualTo(0) TextLine.recycle(tl) } } No newline at end of file core/tests/coretests/src/android/text/TextLineTest.java +1 −1 Original line number Diff line number Diff line Loading @@ -53,7 +53,7 @@ public class TextLineTest { final float originalWidth = tl.metrics(null, null, false, null); final float expandedWidth = 2 * originalWidth; tl.justify(expandedWidth); tl.justify(Layout.JUSTIFICATION_MODE_INTER_WORD, expandedWidth); final float newWidth = tl.metrics(null, null, false, null); TextLine.recycle(tl); return Math.abs(newWidth - expandedWidth) < 0.5; Loading Loading
core/api/current.txt +2 −0 Original line number Diff line number Diff line Loading @@ -17875,6 +17875,7 @@ package android.graphics.text { field public static final int HYPHENATION_FREQUENCY_FULL = 2; // 0x2 field public static final int HYPHENATION_FREQUENCY_NONE = 0; // 0x0 field public static final int HYPHENATION_FREQUENCY_NORMAL = 1; // 0x1 field @FlaggedApi("com.android.text.flags.inter_character_justification") public static final int JUSTIFICATION_MODE_INTER_CHARACTER = 2; // 0x2 field public static final int JUSTIFICATION_MODE_INTER_WORD = 1; // 0x1 field public static final int JUSTIFICATION_MODE_NONE = 0; // 0x0 } Loading Loading @@ -46954,6 +46955,7 @@ package android.text { field @NonNull public static final android.text.Layout.TextInclusionStrategy INCLUSION_STRATEGY_ANY_OVERLAP; field @NonNull public static final android.text.Layout.TextInclusionStrategy INCLUSION_STRATEGY_CONTAINS_ALL; field @NonNull public static final android.text.Layout.TextInclusionStrategy INCLUSION_STRATEGY_CONTAINS_CENTER; field @FlaggedApi("com.android.text.flags.inter_character_justification") public static final int JUSTIFICATION_MODE_INTER_CHARACTER = 2; // 0x2 field public static final int JUSTIFICATION_MODE_INTER_WORD = 1; // 0x1 field public static final int JUSTIFICATION_MODE_NONE = 0; // 0x0 }
core/java/android/text/Layout.java +13 −5 Original line number Diff line number Diff line Loading @@ -152,7 +152,8 @@ public abstract class Layout { /** @hide */ @IntDef(prefix = { "JUSTIFICATION_MODE_" }, value = { LineBreaker.JUSTIFICATION_MODE_NONE, LineBreaker.JUSTIFICATION_MODE_INTER_WORD LineBreaker.JUSTIFICATION_MODE_INTER_WORD, LineBreaker.JUSTIFICATION_MODE_INTER_CHARACTER, }) @Retention(RetentionPolicy.SOURCE) public @interface JustificationMode {} Loading @@ -168,6 +169,13 @@ public abstract class Layout { public static final int JUSTIFICATION_MODE_INTER_WORD = LineBreaker.JUSTIFICATION_MODE_INTER_WORD; /** * Value for justification mode indicating the text is justified by stretching letter spacing. */ @FlaggedApi(FLAG_INTER_CHARACTER_JUSTIFICATION) public static final int JUSTIFICATION_MODE_INTER_CHARACTER = LineBreaker.JUSTIFICATION_MODE_INTER_CHARACTER; /* * Line spacing multiplier for default line spacing. */ Loading Loading @@ -809,7 +817,7 @@ public abstract class Layout { getEllipsisStart(lineNum) + getEllipsisCount(lineNum), isFallbackLineSpacingEnabled()); if (justify) { tl.justify(right - left - indentWidth); tl.justify(mJustificationMode, right - left - indentWidth); } tl.draw(canvas, x, ltop, lbaseline, lbottom); } Loading Loading @@ -1058,7 +1066,7 @@ public abstract class Layout { getEllipsisStart(line), getEllipsisStart(line) + getEllipsisCount(line), isFallbackLineSpacingEnabled()); if (isJustificationRequired(line)) { tl.justify(getJustifyWidth(line)); tl.justify(mJustificationMode, getJustifyWidth(line)); } tl.metrics(null, rectF, false, null); Loading Loading @@ -1794,7 +1802,7 @@ public abstract class Layout { getEllipsisStart(line), getEllipsisStart(line) + getEllipsisCount(line), isFallbackLineSpacingEnabled()); if (isJustificationRequired(line)) { tl.justify(getJustifyWidth(line)); tl.justify(mJustificationMode, getJustifyWidth(line)); } final float width = tl.metrics(null, null, mUseBoundsForWidth, null); TextLine.recycle(tl); Loading Loading @@ -1882,7 +1890,7 @@ public abstract class Layout { getEllipsisStart(line), getEllipsisStart(line) + getEllipsisCount(line), isFallbackLineSpacingEnabled()); if (isJustificationRequired(line)) { tl.justify(getJustifyWidth(line)); tl.justify(mJustificationMode, getJustifyWidth(line)); } final float width = tl.metrics(null, null, mUseBoundsForWidth, null); TextLine.recycle(tl); Loading
core/java/android/text/TextLine.java +56 −12 Original line number Diff line number Diff line Loading @@ -100,9 +100,25 @@ public class TextLine { // Additional width of whitespace for justification. This value is per whitespace, thus // the line width will increase by mAddedWidthForJustify x (number of stretchable whitespaces). private float mAddedWidthForJustify; private float mAddedWordSpacingInPx; private float mAddedLetterSpacingInPx; private boolean mIsJustifying; @VisibleForTesting public float getAddedWordSpacingInPx() { return mAddedWordSpacingInPx; } @VisibleForTesting public float getAddedLetterSpacingInPx() { return mAddedLetterSpacingInPx; } @VisibleForTesting public boolean isJustifying() { return mIsJustifying; } private final TextPaint mWorkPaint = new TextPaint(); private final TextPaint mActivePaint = new TextPaint(); @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) Loading Loading @@ -259,7 +275,7 @@ public class TextLine { } } mTabs = tabStops; mAddedWidthForJustify = 0; mAddedWordSpacingInPx = 0; mIsJustifying = false; mEllipsisStart = ellipsisStart != ellipsisEnd ? ellipsisStart : 0; Loading @@ -274,19 +290,42 @@ public class TextLine { * Justify the line to the given width. */ @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE) public void justify(float justifyWidth) { public void justify(@Layout.JustificationMode int justificationMode, float justifyWidth) { int end = mLen; while (end > 0 && isLineEndSpace(mText.charAt(mStart + end - 1))) { end--; } if (justificationMode == Layout.JUSTIFICATION_MODE_INTER_WORD) { float width = Math.abs(measure(end, false, null, null, null)); final int spaces = countStretchableSpaces(0, end); if (spaces == 0) { // There are no stretchable spaces, so we can't help the justification by adding any // width. return; } final float width = Math.abs(measure(end, false, null, null, null)); mAddedWidthForJustify = (justifyWidth - width) / spaces; mAddedWordSpacingInPx = (justifyWidth - width) / spaces; mAddedLetterSpacingInPx = 0; } else { // justificationMode == Layout.JUSTIFICATION_MODE_INTER_CHARACTER LineInfo lineInfo = new LineInfo(); float width = Math.abs(measure(end, false, null, null, lineInfo)); int lettersCount = lineInfo.getClusterCount(); if (lettersCount < 2) { return; } mAddedLetterSpacingInPx = (justifyWidth - width) / (lettersCount - 1); if (mAddedLetterSpacingInPx > 0.03) { // If the letter spacing is more than 0.03em, the ligatures are automatically // disabled, so re-calculate everything without ligatures. final String oldFontFeatures = mPaint.getFontFeatureSettings(); mPaint.setFontFeatureSettings(oldFontFeatures + ", \"liga\" off, \"cliga\" off"); width = Math.abs(measure(end, false, null, null, lineInfo)); lettersCount = lineInfo.getClusterCount(); mAddedLetterSpacingInPx = (justifyWidth - width) / (lettersCount - 1); mPaint.setFontFeatureSettings(oldFontFeatures); } mAddedWordSpacingInPx = 0; } mIsJustifying = true; } Loading Loading @@ -529,6 +568,9 @@ public class TextLine { throw new IndexOutOfBoundsException( "offset(" + offset + ") should be less than line limit(" + mLen + ")"); } if (lineInfo != null) { lineInfo.setClusterCount(0); } final int target = trailing ? offset - 1 : offset; if (target < 0) { return 0; Loading Loading @@ -1076,7 +1118,8 @@ public class TextLine { TextPaint wp = mWorkPaint; wp.set(mPaint); if (mIsJustifying) { wp.setWordSpacing(mAddedWidthForJustify); wp.setWordSpacing(mAddedWordSpacingInPx); wp.setLetterSpacing(mAddedLetterSpacingInPx / wp.getTextSize()); // Convert to Em } int spanStart = runStart; Loading Loading @@ -1277,7 +1320,8 @@ public class TextLine { @Nullable float[] advances, int advancesIndex, @Nullable LineInfo lineInfo, int runFlag) { if (mIsJustifying) { wp.setWordSpacing(mAddedWidthForJustify); wp.setWordSpacing(mAddedWordSpacingInPx); wp.setLetterSpacing(mAddedLetterSpacingInPx / wp.getTextSize()); // Convert to Em } // Get metrics first (even for empty strings or "0" width runs) if (drawBounds != null && fmi == null) { Loading
core/tests/coretests/src/android/text/TextLineJustificationTest.kt 0 → 100644 +129 −0 Original line number Diff line number Diff line /* * Copyright (C) 2024 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.text import android.platform.test.flag.junit.DeviceFlagsValueProvider import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest import com.google.common.truth.Truth.assertThat import org.junit.Rule import org.junit.Test import org.junit.runner.RunWith @SmallTest @RunWith(AndroidJUnit4::class) class TextLineJustificationTest { @Rule @JvmField val mCheckFlagsRule = DeviceFlagsValueProvider.createCheckFlagsRule() private val PAINT = TextPaint().apply { textSize = 10f // make 1em = 10px } private fun makeTextLine(cs: CharSequence, paint: TextPaint) = TextLine.obtain().apply { set(paint, cs, 0, cs.length, Layout.DIR_LEFT_TO_RIGHT, Layout.DIRS_ALL_LEFT_TO_RIGHT, false, null, 0, 0, false) } private fun getClusterCount(cs: CharSequence, paint: TextPaint) = TextLine.LineInfo().apply { makeTextLine(cs, paint).also { it.metrics(null, null, false, this) TextLine.recycle(it) } }.clusterCount fun justifyTest_WithoutJustify() { val line = "Hello, World." val tl = makeTextLine(line, PAINT) // Without calling justify method, justifying should be false and all added spaces should // be zeros. assertThat(tl.isJustifying).isFalse() assertThat(tl.addedWordSpacingInPx).isEqualTo(0) assertThat(tl.addedLetterSpacingInPx).isEqualTo(0) } @Test fun justifyTest_IntrCharacter_Latin() { val line = "Hello, World." val clusterCount = getClusterCount(line, PAINT) val originalWidth = Layout.getDesiredWidth(line, PAINT) val extraWidth = 100f val tl = makeTextLine(line, PAINT) tl.justify(Layout.JUSTIFICATION_MODE_INTER_CHARACTER, originalWidth + extraWidth) assertThat(tl.isJustifying).isTrue() assertThat(tl.addedWordSpacingInPx).isEqualTo(0) assertThat(tl.addedLetterSpacingInPx).isEqualTo(extraWidth / (clusterCount - 1)) TextLine.recycle(tl) } @Test fun justifyTest_IntrCharacter_Japanese() { val line = "\u672C\u65E5\u306F\u6674\u5929\u306A\u308A\u3002" val clusterCount = getClusterCount(line, PAINT) val originalWidth = Layout.getDesiredWidth(line, PAINT) val extraWidth = 100f val tl = makeTextLine(line, PAINT) tl.justify(Layout.JUSTIFICATION_MODE_INTER_CHARACTER, originalWidth + extraWidth) assertThat(tl.isJustifying).isTrue() assertThat(tl.addedWordSpacingInPx).isEqualTo(0) assertThat(tl.addedLetterSpacingInPx).isEqualTo(extraWidth / (clusterCount - 1)) TextLine.recycle(tl) } @Test fun justifyTest_IntrWord_Latin() { val line = "Hello, World." val originalWidth = Layout.getDesiredWidth(line, PAINT) val extraWidth = 100f val tl = makeTextLine(line, PAINT) tl.justify(Layout.JUSTIFICATION_MODE_INTER_WORD, originalWidth + extraWidth) assertThat(tl.isJustifying).isTrue() // This text contains only one whitespace, so word spacing should be same to the extraWidth. assertThat(tl.addedWordSpacingInPx).isEqualTo(extraWidth) assertThat(tl.addedLetterSpacingInPx).isEqualTo(0) TextLine.recycle(tl) } @Test fun justifyTest_IntrWord_Japanese() { val line = "\u672C\u65E5\u306F\u6674\u0020\u5929\u306A\u308A\u3002" val originalWidth = Layout.getDesiredWidth(line, PAINT) val extraWidth = 100f val tl = makeTextLine(line, PAINT) tl.justify(Layout.JUSTIFICATION_MODE_INTER_WORD, originalWidth + extraWidth) assertThat(tl.isJustifying).isTrue() // This text contains only one whitespace, so word spacing should be same to the extraWidth. assertThat(tl.addedWordSpacingInPx).isEqualTo(extraWidth) assertThat(tl.addedLetterSpacingInPx).isEqualTo(0) TextLine.recycle(tl) } } No newline at end of file
core/tests/coretests/src/android/text/TextLineTest.java +1 −1 Original line number Diff line number Diff line Loading @@ -53,7 +53,7 @@ public class TextLineTest { final float originalWidth = tl.metrics(null, null, false, null); final float expandedWidth = 2 * originalWidth; tl.justify(expandedWidth); tl.justify(Layout.JUSTIFICATION_MODE_INTER_WORD, expandedWidth); final float newWidth = tl.metrics(null, null, false, null); TextLine.recycle(tl); return Math.abs(newWidth - expandedWidth) < 0.5; Loading