Loading core/tests/coretests/assets/fonts/StaticLayoutLineBreakingTestFont.ttf 0 → 100644 +864 B File added.No diff preview for this file type. View file core/tests/coretests/assets/fonts/StaticLayoutLineBreakingTestFont.ttx 0 → 100644 +207 −0 Original line number Diff line number Diff line <?xml version="1.0" encoding="UTF-8"?> <!-- 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. --> <ttFont sfntVersion="\x00\x01\x00\x00" ttLibVersion="3.0"> <GlyphOrder> <GlyphID id="0" name=".notdef"/> <GlyphID id="1" name="0em"/> <GlyphID id="2" name="1em"/> <GlyphID id="3" name="3em"/> <GlyphID id="4" name="5em"/> <GlyphID id="5" name="7em"/> <GlyphID id="6" name="10em"/> <GlyphID id="7" name="50em"/> <GlyphID id="8" name="100em"/> </GlyphOrder> <head> <tableVersion value="1.0"/> <fontRevision value="1.0"/> <checkSumAdjustment value="0x640cdb2f"/> <magicNumber value="0x5f0f3cf5"/> <flags value="00000000 00000011"/> <unitsPerEm value="100"/> <created value="Fri Mar 17 07:26:00 2017"/> <macStyle value="00000000 00000000"/> <lowestRecPPEM value="7"/> <fontDirectionHint value="2"/> <glyphDataFormat value="0"/> </head> <hhea> <tableVersion value="0x00010000"/> <ascent value="1000"/> <descent value="-200"/> <lineGap value="0"/> <caretSlopeRise value="1"/> <caretSlopeRun value="0"/> <caretOffset value="0"/> <reserved0 value="0"/> <reserved1 value="0"/> <reserved2 value="0"/> <reserved3 value="0"/> <metricDataFormat value="0"/> </hhea> <maxp> <tableVersion value="0x10000"/> <maxZones value="0"/> <maxTwilightPoints value="0"/> <maxStorage value="0"/> <maxFunctionDefs value="0"/> <maxInstructionDefs value="0"/> <maxStackElements value="0"/> <maxSizeOfInstructions value="0"/> <maxComponentElements value="0"/> </maxp> <OS_2> <!-- The fields 'usFirstCharIndex' and 'usLastCharIndex' will be recalculated by the compiler --> <version value="3"/> <xAvgCharWidth value="594"/> <usWeightClass value="400"/> <usWidthClass value="5"/> <fsType value="00000000 00001000"/> <ySubscriptXSize value="650"/> <ySubscriptYSize value="600"/> <ySubscriptXOffset value="0"/> <ySubscriptYOffset value="75"/> <ySuperscriptXSize value="650"/> <ySuperscriptYSize value="600"/> <ySuperscriptXOffset value="0"/> <ySuperscriptYOffset value="350"/> <yStrikeoutSize value="50"/> <yStrikeoutPosition value="300"/> <sFamilyClass value="0"/> <panose> <bFamilyType value="0"/> <bSerifStyle value="0"/> <bWeight value="5"/> <bProportion value="0"/> <bContrast value="0"/> <bStrokeVariation value="0"/> <bArmStyle value="0"/> <bLetterForm value="0"/> <bMidline value="0"/> <bXHeight value="0"/> </panose> <ulUnicodeRange1 value="00000000 00000000 00000000 00000001"/> <ulUnicodeRange2 value="00000000 00000000 00000000 00000000"/> <ulUnicodeRange3 value="00000000 00000000 00000000 00000000"/> <ulUnicodeRange4 value="00000000 00000000 00000000 00000000"/> <achVendID value="UKWN"/> <fsSelection value="00000000 01000000"/> <usFirstCharIndex value="32"/> <usLastCharIndex value="122"/> <sTypoAscender value="800"/> <sTypoDescender value="-200"/> <sTypoLineGap value="200"/> <usWinAscent value="1000"/> <usWinDescent value="200"/> <ulCodePageRange1 value="00000000 00000000 00000000 00000001"/> <ulCodePageRange2 value="00000000 00000000 00000000 00000000"/> <sxHeight value="500"/> <sCapHeight value="700"/> <usDefaultChar value="0"/> <usBreakChar value="32"/> <usMaxContext value="0"/> </OS_2> <hmtx> <mtx name=".notdef" width="50" lsb="0"/> <mtx name="0em" width="0" lsb="0"/> <mtx name="1em" width="100" lsb="0"/> <mtx name="3em" width="300" lsb="0"/> <mtx name="5em" width="500" lsb="0"/> <mtx name="7em" width="700" lsb="0"/> <mtx name="10em" width="1000" lsb="0"/> <mtx name="50em" width="5000" lsb="0"/> <mtx name="100em" width="10000" lsb="0"/> </hmtx> <cmap> <tableVersion version="0"/> <cmap_format_12 format="12" reserved="0" length="6" nGroups="1" platformID="3" platEncID="10" language="0"> <map code="0x0020" name="10em" /> <map code="0x002e" name="10em" /> <!-- . --> <map code="0x0043" name="100em" /> <!-- C --> <map code="0x0049" name="1em" /> <!-- I --> <map code="0x004c" name="50em" /> <!-- L --> <map code="0x0056" name="5em" /> <!-- V --> <map code="0x0058" name="10em" /> <!-- X --> <map code="0x005f" name="0em" /> <!-- _ --> <map code="0xfffd" name="7em" /> <!-- REPLACEMENT CHAR --> <map code="0x10331" name="10em" /> </cmap_format_12> </cmap> <loca> <!-- The 'loca' table will be calculated by the compiler --> </loca> <glyf> <TTGlyph name=".notdef" xMin="0" yMin="0" xMax="0" yMax="0" /> <TTGlyph name="0em" xMin="0" yMin="0" xMax="0" yMax="0" /> <TTGlyph name="1em" xMin="0" yMin="0" xMax="0" yMax="0" /> <TTGlyph name="3em" xMin="0" yMin="0" xMax="0" yMax="0" /> <TTGlyph name="5em" xMin="0" yMin="0" xMax="0" yMax="0" /> <TTGlyph name="7em" xMin="0" yMin="0" xMax="0" yMax="0" /> <TTGlyph name="10em" xMin="0" yMin="0" xMax="0" yMax="0" /> <TTGlyph name="50em" xMin="0" yMin="0" xMax="0" yMax="0" /> <TTGlyph name="100em" xMin="0" yMin="0" xMax="0" yMax="0" /> </glyf> <name> <namerecord nameID="1" platformID="1" platEncID="0" langID="0x0" unicode="True"> Font for StaticLayoutLineBreakingTest </namerecord> <namerecord nameID="2" platformID="1" platEncID="0" langID="0x0" unicode="True"> Regular </namerecord> <namerecord nameID="4" platformID="1" platEncID="0" langID="0x0" unicode="True"> Font for StaticLayoutLineBreakingTest </namerecord> <namerecord nameID="6" platformID="1" platEncID="0" langID="0x0" unicode="True"> SampleFont-Regular </namerecord> <namerecord nameID="1" platformID="3" platEncID="1" langID="0x409"> Sample Font </namerecord> <namerecord nameID="2" platformID="3" platEncID="1" langID="0x409"> Regular </namerecord> <namerecord nameID="4" platformID="3" platEncID="1" langID="0x409"> Sample Font </namerecord> <namerecord nameID="6" platformID="3" platEncID="1" langID="0x409"> SampleFont-Regular </namerecord> </name> <post> <formatType value="3.0"/> <italicAngle value="0.0"/> <underlinePosition value="-75"/> <underlineThickness value="50"/> <isFixedPitch value="0"/> <minMemType42 value="0"/> <maxMemType42 value="0"/> <minMemType1 value="0"/> <maxMemType1 value="0"/> </post> </ttFont> core/tests/coretests/src/android/text/StaticLayoutLineBreakingTest.java +27 −57 Original line number Diff line number Diff line Loading @@ -18,6 +18,9 @@ package android.text; import static org.junit.Assert.assertEquals; import android.content.Context;; import android.graphics.Typeface; import android.support.test.InstrumentationRegistry; import android.support.test.filters.SmallTest; import android.support.test.runner.AndroidJUnit4; import android.text.Layout.Alignment; Loading Loading @@ -45,57 +48,24 @@ public class StaticLayoutLineBreakingTest { private static final int[] NO_BREAK = new int[] {}; private static final TextPaint sTextPaint = new MockTextPaint(); private static class MockTextPaint extends TextPaint { @Override public float getTextRunAdvances(char[] chars, int index, int count, int contextIndex, int contextCount, boolean isRtl, float[] advances, int advancesIndex) { // Conditions copy pasted from Paint if (chars == null) { throw new IllegalArgumentException("text cannot be null"); } if ((index | count | contextIndex | contextCount | advancesIndex | (index - contextIndex) | (contextCount - count) | ((contextIndex + contextCount) - (index + count)) | (chars.length - (contextIndex + contextCount)) | (advances == null ? 0 : (advances.length - (advancesIndex + count)))) < 0) { throw new IndexOutOfBoundsException(); } float res = 0.0f; if (advances != null) { for (int i = 0; i < count; i++) { float width = getCharWidth(chars[index + i]); advances[advancesIndex + i] = width; res += width; } } return res; } } private static float getCharWidth(char c) { switch (Character.toUpperCase(c)) { // Roman figures case 'I': return 1.0f; case 'V': return 5.0f; case 'X': return 10.0f; case 'L': return 50.0f; case 'C': return 100.0f; // equals to WIDTH case ' ': return 10.0f; case '_': return 0.0f; // 0-width character case SURR_FIRST: return 7.0f; case SURR_SECOND: return 3.0f; // Sum of SURR_FIRST-SURR_SECOND is 10 default: return 10.0f; } private static final TextPaint sTextPaint = new TextPaint(); static { // The test font has following coverage and width. // U+0020: 10em // U+002E (,): 10em // U+0043 (C): 100em // U+0049 (I): 1em // U+004C (L): 50em // U+0056 (V): 5em // U+0058 (X): 10em // U+005F (_): 0em // U+FFFD (invalid surrogate will be replaced to this): 7em // U+10331 (\uD800\uDF31): 10em Context context = InstrumentationRegistry.getTargetContext(); sTextPaint.setTypeface(Typeface.createFromAsset(context.getAssets(), "fonts/StaticLayoutLineBreakingTestFont.ttf")); sTextPaint.setTextSize(1.0f); // Make 1em == 1px. } private static StaticLayout getStaticLayout(CharSequence source, int width) { Loading Loading @@ -406,13 +376,13 @@ public class StaticLayoutLineBreakingTest { public void testWithSurrogate() { layout("LX" + SURR_FIRST + SURR_SECOND, NO_BREAK); layout("LXXXX" + SURR_FIRST + SURR_SECOND, NO_BREAK); // LXXXXI (91) + SURR_FIRST (7) fits. But we should not break the surrogate pair // Bug: surrogate pair is broken, should be 6 (breaking after the 'V') // Maybe not: may be ok if the second character of a pair always has a 0-width layout("LXXXXI" + SURR_FIRST + SURR_SECOND, new int[] {7}); // LXXXXI (91) + SURR_FIRST + SURR_SECOND (10). Do not break in the middle point of // surrogatge pair. layout("LXXXXI" + SURR_FIRST + SURR_SECOND, new int[] {6}); // LXXXXI (95) + SURR_SECOND (3) fits, but this is not a valid surrogate pair, breaking it layout("LXXXXV" + SURR_SECOND + SURR_FIRST, new int[] {7}); // LXXXXI (91) + SURR_SECOND (replaced with REPLACEMENT CHARACTER. width is 7px) fits. // Break just after invalid trailing surrogate. layout("LXXXXI" + SURR_SECOND + SURR_FIRST, new int[] {7}); layout("C" + SURR_FIRST + SURR_SECOND, new int[] {1}); } Loading Loading
core/tests/coretests/assets/fonts/StaticLayoutLineBreakingTestFont.ttf 0 → 100644 +864 B File added.No diff preview for this file type. View file
core/tests/coretests/assets/fonts/StaticLayoutLineBreakingTestFont.ttx 0 → 100644 +207 −0 Original line number Diff line number Diff line <?xml version="1.0" encoding="UTF-8"?> <!-- 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. --> <ttFont sfntVersion="\x00\x01\x00\x00" ttLibVersion="3.0"> <GlyphOrder> <GlyphID id="0" name=".notdef"/> <GlyphID id="1" name="0em"/> <GlyphID id="2" name="1em"/> <GlyphID id="3" name="3em"/> <GlyphID id="4" name="5em"/> <GlyphID id="5" name="7em"/> <GlyphID id="6" name="10em"/> <GlyphID id="7" name="50em"/> <GlyphID id="8" name="100em"/> </GlyphOrder> <head> <tableVersion value="1.0"/> <fontRevision value="1.0"/> <checkSumAdjustment value="0x640cdb2f"/> <magicNumber value="0x5f0f3cf5"/> <flags value="00000000 00000011"/> <unitsPerEm value="100"/> <created value="Fri Mar 17 07:26:00 2017"/> <macStyle value="00000000 00000000"/> <lowestRecPPEM value="7"/> <fontDirectionHint value="2"/> <glyphDataFormat value="0"/> </head> <hhea> <tableVersion value="0x00010000"/> <ascent value="1000"/> <descent value="-200"/> <lineGap value="0"/> <caretSlopeRise value="1"/> <caretSlopeRun value="0"/> <caretOffset value="0"/> <reserved0 value="0"/> <reserved1 value="0"/> <reserved2 value="0"/> <reserved3 value="0"/> <metricDataFormat value="0"/> </hhea> <maxp> <tableVersion value="0x10000"/> <maxZones value="0"/> <maxTwilightPoints value="0"/> <maxStorage value="0"/> <maxFunctionDefs value="0"/> <maxInstructionDefs value="0"/> <maxStackElements value="0"/> <maxSizeOfInstructions value="0"/> <maxComponentElements value="0"/> </maxp> <OS_2> <!-- The fields 'usFirstCharIndex' and 'usLastCharIndex' will be recalculated by the compiler --> <version value="3"/> <xAvgCharWidth value="594"/> <usWeightClass value="400"/> <usWidthClass value="5"/> <fsType value="00000000 00001000"/> <ySubscriptXSize value="650"/> <ySubscriptYSize value="600"/> <ySubscriptXOffset value="0"/> <ySubscriptYOffset value="75"/> <ySuperscriptXSize value="650"/> <ySuperscriptYSize value="600"/> <ySuperscriptXOffset value="0"/> <ySuperscriptYOffset value="350"/> <yStrikeoutSize value="50"/> <yStrikeoutPosition value="300"/> <sFamilyClass value="0"/> <panose> <bFamilyType value="0"/> <bSerifStyle value="0"/> <bWeight value="5"/> <bProportion value="0"/> <bContrast value="0"/> <bStrokeVariation value="0"/> <bArmStyle value="0"/> <bLetterForm value="0"/> <bMidline value="0"/> <bXHeight value="0"/> </panose> <ulUnicodeRange1 value="00000000 00000000 00000000 00000001"/> <ulUnicodeRange2 value="00000000 00000000 00000000 00000000"/> <ulUnicodeRange3 value="00000000 00000000 00000000 00000000"/> <ulUnicodeRange4 value="00000000 00000000 00000000 00000000"/> <achVendID value="UKWN"/> <fsSelection value="00000000 01000000"/> <usFirstCharIndex value="32"/> <usLastCharIndex value="122"/> <sTypoAscender value="800"/> <sTypoDescender value="-200"/> <sTypoLineGap value="200"/> <usWinAscent value="1000"/> <usWinDescent value="200"/> <ulCodePageRange1 value="00000000 00000000 00000000 00000001"/> <ulCodePageRange2 value="00000000 00000000 00000000 00000000"/> <sxHeight value="500"/> <sCapHeight value="700"/> <usDefaultChar value="0"/> <usBreakChar value="32"/> <usMaxContext value="0"/> </OS_2> <hmtx> <mtx name=".notdef" width="50" lsb="0"/> <mtx name="0em" width="0" lsb="0"/> <mtx name="1em" width="100" lsb="0"/> <mtx name="3em" width="300" lsb="0"/> <mtx name="5em" width="500" lsb="0"/> <mtx name="7em" width="700" lsb="0"/> <mtx name="10em" width="1000" lsb="0"/> <mtx name="50em" width="5000" lsb="0"/> <mtx name="100em" width="10000" lsb="0"/> </hmtx> <cmap> <tableVersion version="0"/> <cmap_format_12 format="12" reserved="0" length="6" nGroups="1" platformID="3" platEncID="10" language="0"> <map code="0x0020" name="10em" /> <map code="0x002e" name="10em" /> <!-- . --> <map code="0x0043" name="100em" /> <!-- C --> <map code="0x0049" name="1em" /> <!-- I --> <map code="0x004c" name="50em" /> <!-- L --> <map code="0x0056" name="5em" /> <!-- V --> <map code="0x0058" name="10em" /> <!-- X --> <map code="0x005f" name="0em" /> <!-- _ --> <map code="0xfffd" name="7em" /> <!-- REPLACEMENT CHAR --> <map code="0x10331" name="10em" /> </cmap_format_12> </cmap> <loca> <!-- The 'loca' table will be calculated by the compiler --> </loca> <glyf> <TTGlyph name=".notdef" xMin="0" yMin="0" xMax="0" yMax="0" /> <TTGlyph name="0em" xMin="0" yMin="0" xMax="0" yMax="0" /> <TTGlyph name="1em" xMin="0" yMin="0" xMax="0" yMax="0" /> <TTGlyph name="3em" xMin="0" yMin="0" xMax="0" yMax="0" /> <TTGlyph name="5em" xMin="0" yMin="0" xMax="0" yMax="0" /> <TTGlyph name="7em" xMin="0" yMin="0" xMax="0" yMax="0" /> <TTGlyph name="10em" xMin="0" yMin="0" xMax="0" yMax="0" /> <TTGlyph name="50em" xMin="0" yMin="0" xMax="0" yMax="0" /> <TTGlyph name="100em" xMin="0" yMin="0" xMax="0" yMax="0" /> </glyf> <name> <namerecord nameID="1" platformID="1" platEncID="0" langID="0x0" unicode="True"> Font for StaticLayoutLineBreakingTest </namerecord> <namerecord nameID="2" platformID="1" platEncID="0" langID="0x0" unicode="True"> Regular </namerecord> <namerecord nameID="4" platformID="1" platEncID="0" langID="0x0" unicode="True"> Font for StaticLayoutLineBreakingTest </namerecord> <namerecord nameID="6" platformID="1" platEncID="0" langID="0x0" unicode="True"> SampleFont-Regular </namerecord> <namerecord nameID="1" platformID="3" platEncID="1" langID="0x409"> Sample Font </namerecord> <namerecord nameID="2" platformID="3" platEncID="1" langID="0x409"> Regular </namerecord> <namerecord nameID="4" platformID="3" platEncID="1" langID="0x409"> Sample Font </namerecord> <namerecord nameID="6" platformID="3" platEncID="1" langID="0x409"> SampleFont-Regular </namerecord> </name> <post> <formatType value="3.0"/> <italicAngle value="0.0"/> <underlinePosition value="-75"/> <underlineThickness value="50"/> <isFixedPitch value="0"/> <minMemType42 value="0"/> <maxMemType42 value="0"/> <minMemType1 value="0"/> <maxMemType1 value="0"/> </post> </ttFont>
core/tests/coretests/src/android/text/StaticLayoutLineBreakingTest.java +27 −57 Original line number Diff line number Diff line Loading @@ -18,6 +18,9 @@ package android.text; import static org.junit.Assert.assertEquals; import android.content.Context;; import android.graphics.Typeface; import android.support.test.InstrumentationRegistry; import android.support.test.filters.SmallTest; import android.support.test.runner.AndroidJUnit4; import android.text.Layout.Alignment; Loading Loading @@ -45,57 +48,24 @@ public class StaticLayoutLineBreakingTest { private static final int[] NO_BREAK = new int[] {}; private static final TextPaint sTextPaint = new MockTextPaint(); private static class MockTextPaint extends TextPaint { @Override public float getTextRunAdvances(char[] chars, int index, int count, int contextIndex, int contextCount, boolean isRtl, float[] advances, int advancesIndex) { // Conditions copy pasted from Paint if (chars == null) { throw new IllegalArgumentException("text cannot be null"); } if ((index | count | contextIndex | contextCount | advancesIndex | (index - contextIndex) | (contextCount - count) | ((contextIndex + contextCount) - (index + count)) | (chars.length - (contextIndex + contextCount)) | (advances == null ? 0 : (advances.length - (advancesIndex + count)))) < 0) { throw new IndexOutOfBoundsException(); } float res = 0.0f; if (advances != null) { for (int i = 0; i < count; i++) { float width = getCharWidth(chars[index + i]); advances[advancesIndex + i] = width; res += width; } } return res; } } private static float getCharWidth(char c) { switch (Character.toUpperCase(c)) { // Roman figures case 'I': return 1.0f; case 'V': return 5.0f; case 'X': return 10.0f; case 'L': return 50.0f; case 'C': return 100.0f; // equals to WIDTH case ' ': return 10.0f; case '_': return 0.0f; // 0-width character case SURR_FIRST: return 7.0f; case SURR_SECOND: return 3.0f; // Sum of SURR_FIRST-SURR_SECOND is 10 default: return 10.0f; } private static final TextPaint sTextPaint = new TextPaint(); static { // The test font has following coverage and width. // U+0020: 10em // U+002E (,): 10em // U+0043 (C): 100em // U+0049 (I): 1em // U+004C (L): 50em // U+0056 (V): 5em // U+0058 (X): 10em // U+005F (_): 0em // U+FFFD (invalid surrogate will be replaced to this): 7em // U+10331 (\uD800\uDF31): 10em Context context = InstrumentationRegistry.getTargetContext(); sTextPaint.setTypeface(Typeface.createFromAsset(context.getAssets(), "fonts/StaticLayoutLineBreakingTestFont.ttf")); sTextPaint.setTextSize(1.0f); // Make 1em == 1px. } private static StaticLayout getStaticLayout(CharSequence source, int width) { Loading Loading @@ -406,13 +376,13 @@ public class StaticLayoutLineBreakingTest { public void testWithSurrogate() { layout("LX" + SURR_FIRST + SURR_SECOND, NO_BREAK); layout("LXXXX" + SURR_FIRST + SURR_SECOND, NO_BREAK); // LXXXXI (91) + SURR_FIRST (7) fits. But we should not break the surrogate pair // Bug: surrogate pair is broken, should be 6 (breaking after the 'V') // Maybe not: may be ok if the second character of a pair always has a 0-width layout("LXXXXI" + SURR_FIRST + SURR_SECOND, new int[] {7}); // LXXXXI (91) + SURR_FIRST + SURR_SECOND (10). Do not break in the middle point of // surrogatge pair. layout("LXXXXI" + SURR_FIRST + SURR_SECOND, new int[] {6}); // LXXXXI (95) + SURR_SECOND (3) fits, but this is not a valid surrogate pair, breaking it layout("LXXXXV" + SURR_SECOND + SURR_FIRST, new int[] {7}); // LXXXXI (91) + SURR_SECOND (replaced with REPLACEMENT CHARACTER. width is 7px) fits. // Break just after invalid trailing surrogate. layout("LXXXXI" + SURR_SECOND + SURR_FIRST, new int[] {7}); layout("C" + SURR_FIRST + SURR_SECOND, new int[] {1}); } Loading