private final int mWeight;
private final boolean mIsItalic;
private Uri mUri;
- private final String mFallbackFor;
/**
* @hide
*/
public Font(@NonNull String fontName, int ttcIndex, @NonNull FontVariationAxis[] axes,
- int weight, boolean isItalic, String fallbackFor) {
+ int weight, boolean isItalic) {
mFontName = fontName;
mTtcIndex = ttcIndex;
mAxes = axes;
mWeight = weight;
mIsItalic = isItalic;
- mFallbackFor = fallbackFor;
}
/**
public void setUri(@NonNull Uri uri) {
mUri = uri;
}
-
- public String getFallbackFor() {
- return mFallbackFor;
- }
}
/**
+++ /dev/null
-<?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="1em"/>
- <GlyphID id="2" name="3em"/>
- </GlyphOrder>
-
- <head>
- <tableVersion value="1.0"/>
- <fontRevision value="1.0"/>
- <checkSumAdjustment value="0x640cdb2f"/>
- <magicNumber value="0x5f0f3cf5"/>
- <flags value="00000000 00000011"/>
- <unitsPerEm value="1000"/>
- <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="1.0"/>
- <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="500" lsb="93"/>
- <mtx name="1em" width="1000" lsb="93"/>
- <mtx name="3em" width="3000" lsb="93"/>
- </hmtx>
-
- <cmap>
- <tableVersion version="0"/>
- <cmap_format_4 platformID="3" platEncID="10" language="0">
- <map code="0x0061" name="3em" />
- <map code="0x0062" name="1em" />
- <map code="0x0063" name="1em" />
- <map code="0x0064" name="1em" />
- <map code="0x0065" name="1em" />
- </cmap_format_4>
- </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="1em" xMin="0" yMin="0" xMax="0" yMax="0" />
- <TTGlyph name="3em" xMin="0" yMin="0" xMax="0" yMax="0" />
- </glyf>
-
- <name>
- <namerecord nameID="0" platformID="3" platEncID="1" langID="0x409">
- Copyright (C) 2017 The Android Open Source Project
- </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>
- <namerecord nameID="13" platformID="3" platEncID="1" langID="0x409">
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- 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.
- </namerecord>
- <namerecord nameID="14" platformID="3" platEncID="1" langID="0x409">
- http://www.apache.org/licenses/LICENSE-2.0
- </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>
+++ /dev/null
-<?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="2em"/>
- </GlyphOrder>
-
- <head>
- <tableVersion value="1.0"/>
- <fontRevision value="1.0"/>
- <checkSumAdjustment value="0x640cdb2f"/>
- <magicNumber value="0x5f0f3cf5"/>
- <flags value="00000000 00000011"/>
- <unitsPerEm value="1000"/>
- <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="1.0"/>
- <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="500" lsb="93"/>
- <mtx name="2em" width="1000" lsb="93"/>
- </hmtx>
-
- <cmap>
- <tableVersion version="0"/>
- <cmap_format_4 platformID="3" platEncID="10" language="0">
- <map code="0x0061" name="2em" />
- <map code="0x0062" name="2em" />
- <map code="0x0063" name="2em" />
- <map code="0x0064" name="2em" />
- <map code="0x0065" name="2em" />
- </cmap_format_4>
- </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="2em" xMin="0" yMin="0" xMax="0" yMax="0" />
- </glyf>
-
- <name>
- <namerecord nameID="0" platformID="3" platEncID="1" langID="0x409">
- Copyright (C) 2017 The Android Open Source Project
- </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>
- <namerecord nameID="13" platformID="3" platEncID="1" langID="0x409">
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- 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.
- </namerecord>
- <namerecord nameID="14" platformID="3" platEncID="1" langID="0x409">
- http://www.apache.org/licenses/LICENSE-2.0
- </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>
+++ /dev/null
-<?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="1em"/>
- <GlyphID id="2" name="3em"/>
- </GlyphOrder>
-
- <head>
- <tableVersion value="1.0"/>
- <fontRevision value="1.0"/>
- <checkSumAdjustment value="0x640cdb2f"/>
- <magicNumber value="0x5f0f3cf5"/>
- <flags value="00000000 00000011"/>
- <unitsPerEm value="1000"/>
- <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="1.0"/>
- <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="500" lsb="93"/>
- <mtx name="1em" width="1000" lsb="93"/>
- <mtx name="3em" width="3000" lsb="93"/>
- </hmtx>
-
- <cmap>
- <tableVersion version="0"/>
- <cmap_format_4 platformID="3" platEncID="10" language="0">
- <map code="0x0061" name="1em" />
- <map code="0x0062" name="3em" />
- <map code="0x0063" name="1em" />
- <map code="0x0064" name="1em" />
- <map code="0x0065" name="1em" />
- </cmap_format_4>
- </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="1em" xMin="0" yMin="0" xMax="0" yMax="0" />
- <TTGlyph name="3em" xMin="0" yMin="0" xMax="0" yMax="0" />
- </glyf>
-
- <name>
- <namerecord nameID="0" platformID="3" platEncID="1" langID="0x409">
- Copyright (C) 2017 The Android Open Source Project
- </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>
- <namerecord nameID="13" platformID="3" platEncID="1" langID="0x409">
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- 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.
- </namerecord>
- <namerecord nameID="14" platformID="3" platEncID="1" langID="0x409">
- http://www.apache.org/licenses/LICENSE-2.0
- </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>
+++ /dev/null
-<?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="1em"/>
- <GlyphID id="2" name="3em"/>
- </GlyphOrder>
-
- <head>
- <tableVersion value="1.0"/>
- <fontRevision value="1.0"/>
- <checkSumAdjustment value="0x640cdb2f"/>
- <magicNumber value="0x5f0f3cf5"/>
- <flags value="00000000 00000011"/>
- <unitsPerEm value="1000"/>
- <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="1.0"/>
- <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="500" lsb="93"/>
- <mtx name="1em" width="1000" lsb="93"/>
- <mtx name="3em" width="3000" lsb="93"/>
- </hmtx>
-
- <cmap>
- <tableVersion version="0"/>
- <cmap_format_4 platformID="3" platEncID="10" language="0">
- <map code="0x0061" name="1em" />
- <map code="0x0062" name="1em" />
- <map code="0x0063" name="3em" />
- <map code="0x0064" name="1em" />
- <map code="0x0065" name="1em" />
- </cmap_format_4>
- </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="1em" xMin="0" yMin="0" xMax="0" yMax="0" />
- <TTGlyph name="3em" xMin="0" yMin="0" xMax="0" yMax="0" />
- </glyf>
-
- <name>
- <namerecord nameID="0" platformID="3" platEncID="1" langID="0x409">
- Copyright (C) 2017 The Android Open Source Project
- </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>
- <namerecord nameID="13" platformID="3" platEncID="1" langID="0x409">
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- 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.
- </namerecord>
- <namerecord nameID="14" platformID="3" platEncID="1" langID="0x409">
- http://www.apache.org/licenses/LICENSE-2.0
- </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>
+++ /dev/null
-<?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="dummy"/>
- </GlyphOrder>
-
- <head>
- <tableVersion value="1.0"/>
- <fontRevision value="1.0"/>
- <checkSumAdjustment value="0x640cdb2f"/>
- <magicNumber value="0x5f0f3cf5"/>
- <flags value="00000000 00000011"/>
- <unitsPerEm value="1000"/>
- <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="1.0"/>
- <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="500" lsb="93"/>
- <mtx name="dummy" width="500" lsb="93"/>
- </hmtx>
-
- <cmap>
- <tableVersion version="0"/>
- <cmap_format_4 platformID="3" platEncID="10" language="0">
- <map code="0xFFFD" name="dummy" /> <!-- dummy entry -->
- </cmap_format_4>
- </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="dummy" xMin="0" yMin="0" xMax="0" yMax="0" />
- </glyf>
-
- <name>
- <namerecord nameID="0" platformID="3" platEncID="1" langID="0x409">
- Copyright (C) 2017 The Android Open Source Project
- </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>
- <namerecord nameID="13" platformID="3" platEncID="1" langID="0x409">
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- 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.
- </namerecord>
- <namerecord nameID="14" platformID="3" platEncID="1" langID="0x409">
- http://www.apache.org/licenses/LICENSE-2.0
- </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>
+++ /dev/null
-/*
- * 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 static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertTrue;
-
-import android.content.Context;
-import android.content.res.AssetManager;
-import android.support.test.InstrumentationRegistry;
-import android.support.test.filters.SmallTest;
-import android.support.test.runner.AndroidJUnit4;
-import android.util.ArrayMap;
-
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-import java.io.File;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.nio.charset.Charset;
-import java.nio.file.Files;
-import java.nio.file.StandardCopyOption;
-
-@SmallTest
-@RunWith(AndroidJUnit4.class)
-public class TypefaceSystemFallbackTest {
- private static final String SYSTEM_FONT_DIR = "/system/fonts/";
- private static final String SYSTEM_FONTS_XML = "/system/etc/fonts.xml";
-
- private static final String[] TEST_FONT_FILES = {
- "a3em.ttf", // Supports "a","b","c". The width of "a" is 3em, others are 1em.
- "b3em.ttf", // Supports "a","b","c". The width of "b" is 3em, others are 1em.
- "c3em.ttf", // Supports "a","b","c". The width of "c" is 3em, others are 1em.
- "all2em.ttf", // Supports "a,","b","c". All of them have the same width of 2em.
- "no_coverage.ttf", // This font doesn't support any characters.
- };
- private static final String TEST_FONTS_XML;
- private static final String TEST_FONT_DIR;
-
- private static final float GLYPH_1EM_WIDTH;
- private static final float GLYPH_2EM_WIDTH;
- private static final float GLYPH_3EM_WIDTH;
-
- static {
- final Context targetCtx = InstrumentationRegistry.getInstrumentation().getTargetContext();
- final File cacheDir = new File(targetCtx.getCacheDir(), "TypefaceSystemFallbackTest");
- if (!cacheDir.isDirectory()) {
- cacheDir.mkdirs();
- }
- TEST_FONT_DIR = cacheDir.getAbsolutePath() + "/";
- TEST_FONTS_XML = new File(cacheDir, "fonts.xml").getAbsolutePath();
-
- final AssetManager am =
- InstrumentationRegistry.getInstrumentation().getContext().getAssets();
- final Paint paint = new Paint();
- paint.setTypeface(new Typeface.Builder(am, "fonts/a3em.ttf").build());
- GLYPH_3EM_WIDTH = paint.measureText("a");
- GLYPH_1EM_WIDTH = paint.measureText("b");
-
- paint.setTypeface(new Typeface.Builder(am, "fonts/all2em.ttf").build());
- GLYPH_2EM_WIDTH = paint.measureText("a");
- }
-
- @Before
- public void setUp() {
- final AssetManager am =
- InstrumentationRegistry.getInstrumentation().getContext().getAssets();
- for (final String fontFile : TEST_FONT_FILES) {
- final String sourceInAsset = "fonts/" + fontFile;
- final File outInCache = new File(TEST_FONT_DIR, fontFile);
- try (InputStream is = am.open(sourceInAsset)) {
- Files.copy(is, outInCache.toPath(), StandardCopyOption.REPLACE_EXISTING);
- } catch (IOException e) {
- throw new RuntimeException(e);
- }
- }
- }
-
- @After
- public void tearDown() {
- for (final String fontFile : TEST_FONT_FILES) {
- final File outInCache = new File(TEST_FONT_DIR, fontFile);
- outInCache.delete();
- }
- }
-
- private static void buildSystemFallback(String xml,
- ArrayMap<String, Typeface> fontMap, ArrayMap<String, FontFamily[]> fallbackMap) {
- try (FileOutputStream fos = new FileOutputStream(TEST_FONTS_XML)) {
- fos.write(xml.getBytes(Charset.forName("UTF-8")));
- } catch (IOException e) {
- throw new RuntimeException(e);
- }
- Typeface.buildSystemFallback(TEST_FONTS_XML, TEST_FONT_DIR, fontMap, fallbackMap);
- }
-
- @Test
- public void testBuildSystemFallback() {
- final ArrayMap<String, Typeface> fontMap = new ArrayMap<>();
- final ArrayMap<String, FontFamily[]> fallbackMap = new ArrayMap<>();
-
- Typeface.buildSystemFallback(SYSTEM_FONTS_XML, SYSTEM_FONT_DIR, fontMap, fallbackMap);
-
- assertFalse(fontMap.isEmpty());
- assertFalse(fallbackMap.isEmpty());
- }
-
- @Test
- public void testBuildSystemFallback_NonExistentFontShouldBeIgnored() {
- final String xml = "<?xml version='1.0' encoding='UTF-8'?>"
- + "<familyset version='22'>"
- + " <family name='sans-serif'>"
- + " <font weight='400' style='normal'>a3em.ttf</font>"
- + " <font weight='400' style='normal'>NoSuchFont.ttf</font>"
- + " </family>"
- + " <family name='NoSuchFont'>"
- + " <font weight='400' style='normal'>NoSuchFont.ttf</font>"
- + " </family>"
- + " <family>"
- + " <font weight='400' style='normal'>NoSuchFont.ttf</font>"
- + " </family>"
- + "</familyset>";
- final ArrayMap<String, Typeface> fontMap = new ArrayMap<>();
- final ArrayMap<String, FontFamily[]> fallbackMap = new ArrayMap<>();
-
- buildSystemFallback(xml, fontMap, fallbackMap);
-
- assertEquals(1, fontMap.size());
- assertTrue(fontMap.containsKey("sans-serif"));
- assertEquals(1, fallbackMap.size());
- assertTrue(fallbackMap.containsKey("sans-serif"));
- }
-
- @Test
- public void testBuildSystemFallback_NamedFamily() {
- final String xml = "<?xml version='1.0' encoding='UTF-8'?>"
- + "<familyset version='22'>"
- + " <family name='sans-serif'>"
- + " <font weight='400' style='normal'>a3em.ttf</font>"
- + " </family>"
- + " <family name='test'>"
- + " <font weight='400' style='normal'>b3em.ttf</font>"
- + " </family>"
- + " <family name='test2'>"
- + " <font weight='400' style='normal'>c3em.ttf</font>"
- + " </family>"
- + " <family>"
- + " <font weight='400' style='normal'>all2em.ttf</font>"
- + " </family>"
- + "</familyset>";
- final ArrayMap<String, Typeface> fontMap = new ArrayMap<>();
- final ArrayMap<String, FontFamily[]> fallbackMap = new ArrayMap<>();
-
- buildSystemFallback(xml, fontMap, fallbackMap);
-
- final Paint paint = new Paint();
-
- final Typeface sansSerifTypeface = fontMap.get("sans-serif");
- assertNotNull(sansSerifTypeface);
- paint.setTypeface(sansSerifTypeface);
- assertEquals(GLYPH_3EM_WIDTH, paint.measureText("a"), 0.0f);
- assertEquals(GLYPH_1EM_WIDTH, paint.measureText("b"), 0.0f);
- assertEquals(GLYPH_1EM_WIDTH, paint.measureText("c"), 0.0f);
-
- final Typeface testTypeface = fontMap.get("test");
- assertNotNull(testTypeface);
- paint.setTypeface(testTypeface);
- assertEquals(GLYPH_1EM_WIDTH, paint.measureText("a"), 0.0f);
- assertEquals(GLYPH_3EM_WIDTH, paint.measureText("b"), 0.0f);
- assertEquals(GLYPH_1EM_WIDTH, paint.measureText("c"), 0.0f);
-
- final Typeface test2Typeface = fontMap.get("test2");
- assertNotNull(test2Typeface);
- paint.setTypeface(test2Typeface);
- assertEquals(GLYPH_1EM_WIDTH, paint.measureText("a"), 0.0f);
- assertEquals(GLYPH_1EM_WIDTH, paint.measureText("b"), 0.0f);
- assertEquals(GLYPH_3EM_WIDTH, paint.measureText("c"), 0.0f);
- }
-
- @Test
- public void testBuildSystemFallback_defaultFallback() {
- final String xml = "<?xml version='1.0' encoding='UTF-8'?>"
- + "<familyset version='22'>"
- + " <family name='sans-serif'>"
- + " <font weight='400' style='normal'>no_coverage.ttf</font>"
- + " </family>"
- + " <family name='test'>"
- + " <font weight='400' style='normal'>no_coverage.ttf</font>"
- + " </family>"
- + " <family>"
- + " <font weight='400' style='normal'>a3em.ttf</font>"
- + " </family>"
- + " <family>"
- + " <font weight='400' style='normal'>all2em.ttf</font>"
- + " </family>"
- + "</familyset>";
- final ArrayMap<String, Typeface> fontMap = new ArrayMap<>();
- final ArrayMap<String, FontFamily[]> fallbackMap = new ArrayMap<>();
-
- buildSystemFallback(xml, fontMap, fallbackMap);
-
- final Paint paint = new Paint();
-
- final Typeface sansSerifTypeface = fontMap.get("sans-serif");
- assertNotNull(sansSerifTypeface);
- paint.setTypeface(sansSerifTypeface);
- assertEquals(GLYPH_3EM_WIDTH, paint.measureText("a"), 0.0f);
- assertEquals(GLYPH_1EM_WIDTH, paint.measureText("b"), 0.0f);
- assertEquals(GLYPH_1EM_WIDTH, paint.measureText("c"), 0.0f);
-
- final Typeface testTypeface = fontMap.get("test");
- assertNotNull(testTypeface);
- paint.setTypeface(testTypeface);
- assertEquals(GLYPH_3EM_WIDTH, paint.measureText("a"), 0.0f);
- assertEquals(GLYPH_1EM_WIDTH, paint.measureText("b"), 0.0f);
- assertEquals(GLYPH_1EM_WIDTH, paint.measureText("c"), 0.0f);
- }
-
- @Test
- public void testBuildSystemFallback_namedFallbackFamily() {
- final String xml = "<?xml version='1.0' encoding='UTF-8'?>"
- + "<familyset version='22'>"
- + " <family name='sans-serif'>"
- + " <font weight='400' style='normal'>no_coverage.ttf</font>"
- + " </family>"
- + " <family name='test'>"
- + " <font weight='400' style='normal'>no_coverage.ttf</font>"
- + " </family>"
- + " <family name='test2'>"
- + " <font weight='400' style='normal'>no_coverage.ttf</font>"
- + " </family>"
- + " <family>"
- + " <font weight='400' style='normal' fallbackFor='test'>a3em.ttf</font>"
- + " </family>"
- + " <family>"
- + " <font weight='400' style='normal' fallbackFor='test2'>b3em.ttf</font>"
- + " </family>"
- + " <family>"
- + " <font weight='400' style='normal'>all2em.ttf</font>"
- + " </family>"
- + "</familyset>";
- final ArrayMap<String, Typeface> fontMap = new ArrayMap<>();
- final ArrayMap<String, FontFamily[]> fallbackMap = new ArrayMap<>();
-
- buildSystemFallback(xml, fontMap, fallbackMap);
-
- final Paint paint = new Paint();
-
- final Typeface sansSerifTypeface = fontMap.get("sans-serif");
- assertNotNull(sansSerifTypeface);
- paint.setTypeface(sansSerifTypeface);
- assertEquals(GLYPH_2EM_WIDTH, paint.measureText("a"), 0.0f);
- assertEquals(GLYPH_2EM_WIDTH, paint.measureText("b"), 0.0f);
- assertEquals(GLYPH_2EM_WIDTH, paint.measureText("c"), 0.0f);
-
- final Typeface testTypeface = fontMap.get("test");
- assertNotNull(testTypeface);
- paint.setTypeface(testTypeface);
- assertEquals(GLYPH_3EM_WIDTH, paint.measureText("a"), 0.0f);
- assertEquals(GLYPH_1EM_WIDTH, paint.measureText("b"), 0.0f);
- assertEquals(GLYPH_1EM_WIDTH, paint.measureText("c"), 0.0f);
-
- final Typeface test2Typeface = fontMap.get("test2");
- assertNotNull(test2Typeface);
- paint.setTypeface(test2Typeface);
- assertEquals(GLYPH_1EM_WIDTH, paint.measureText("a"), 0.0f);
- assertEquals(GLYPH_3EM_WIDTH, paint.measureText("b"), 0.0f);
- assertEquals(GLYPH_1EM_WIDTH, paint.measureText("c"), 0.0f);
- }
-
- @Test
- public void testBuildSystemFallback_namedFallbackFamily2() {
- final String xml = "<?xml version='1.0' encoding='UTF-8'?>"
- + "<familyset version='22'>"
- + " <family name='sans-serif'>"
- + " <font weight='400' style='normal'>no_coverage.ttf</font>"
- + " </family>"
- + " <family name='test'>"
- + " <font weight='400' style='normal'>no_coverage.ttf</font>"
- + " </family>"
- + " <family name='test2'>"
- + " <font weight='400' style='normal'>no_coverage.ttf</font>"
- + " </family>"
- + " <family>"
- + " <font weight='400' style='normal' fallbackFor='test'>a3em.ttf</font>"
- + " <font weight='400' style='normal'>b3em.ttf</font>"
- + " </family>"
- + " <family>"
- + " <font weight='400' style='normal'>all2em.ttf</font>"
- + " </family>"
- + "</familyset>";
- final ArrayMap<String, Typeface> fontMap = new ArrayMap<>();
- final ArrayMap<String, FontFamily[]> fallbackMap = new ArrayMap<>();
-
- buildSystemFallback(xml, fontMap, fallbackMap);
-
- final Paint paint = new Paint();
-
- final Typeface sansSerifTypeface = fontMap.get("sans-serif");
- assertNotNull(sansSerifTypeface);
- paint.setTypeface(sansSerifTypeface);
- assertEquals(GLYPH_1EM_WIDTH, paint.measureText("a"), 0.0f);
- assertEquals(GLYPH_3EM_WIDTH, paint.measureText("b"), 0.0f);
- assertEquals(GLYPH_1EM_WIDTH, paint.measureText("c"), 0.0f);
-
- final Typeface testTypeface = fontMap.get("test");
- assertNotNull(testTypeface);
- paint.setTypeface(testTypeface);
- assertEquals(GLYPH_3EM_WIDTH, paint.measureText("a"), 0.0f);
- assertEquals(GLYPH_1EM_WIDTH, paint.measureText("b"), 0.0f);
- assertEquals(GLYPH_1EM_WIDTH, paint.measureText("c"), 0.0f);
-
- final Typeface test2Typeface = fontMap.get("test2");
- assertNotNull(test2Typeface);
- paint.setTypeface(test2Typeface);
- assertEquals(GLYPH_1EM_WIDTH, paint.measureText("a"), 0.0f);
- assertEquals(GLYPH_3EM_WIDTH, paint.measureText("b"), 0.0f);
- assertEquals(GLYPH_1EM_WIDTH, paint.measureText("c"), 0.0f);
- }
-
- @Test
- public void testBuildSystemFallback_ImplicitSansSerifFallback() {
- final String xml = "<?xml version='1.0' encoding='UTF-8'?>"
- + "<familyset version='22'>"
- + " <family name='sans-serif'>"
- + " <font weight='400' style='normal'>a3em.ttf</font>"
- + " </family>"
- + " <family name='test'>"
- + " <font weight='400' style='normal'>no_coverage.ttf</font>"
- + " </family>"
- + " <family name='test2'>"
- + " <font weight='400' style='normal'>no_coverage.ttf</font>"
- + " </family>"
- + " <family>"
- + " <font weight='400' style='normal'>all2em.ttf</font>"
- + " </family>"
- + "</familyset>";
- final ArrayMap<String, Typeface> fontMap = new ArrayMap<>();
- final ArrayMap<String, FontFamily[]> fallbackMap = new ArrayMap<>();
-
- buildSystemFallback(xml, fontMap, fallbackMap);
-
- final Paint paint = new Paint();
-
- final Typeface testTypeface = fontMap.get("test");
- assertNotNull(testTypeface);
- paint.setTypeface(testTypeface);
- assertEquals(GLYPH_3EM_WIDTH, paint.measureText("a"), 0.0f);
- assertEquals(GLYPH_1EM_WIDTH, paint.measureText("b"), 0.0f);
- assertEquals(GLYPH_1EM_WIDTH, paint.measureText("c"), 0.0f);
-
- final Typeface test2Typeface = fontMap.get("test2");
- assertNotNull(test2Typeface);
- paint.setTypeface(test2Typeface);
- assertEquals(GLYPH_3EM_WIDTH, paint.measureText("a"), 0.0f);
- assertEquals(GLYPH_1EM_WIDTH, paint.measureText("b"), 0.0f);
- assertEquals(GLYPH_1EM_WIDTH, paint.measureText("c"), 0.0f);
- }
-
- @Test
- public void testBuildSystemFallback_ElegantFallback() {
- final String xml = "<?xml version='1.0' encoding='UTF-8'?>"
- + "<familyset version='22'>"
- + " <family name='sans-serif'>"
- + " <font weight='400' style='normal'>no_coverage.ttf</font>"
- + " </family>"
- + " <family name='serif'>"
- + " <font weight='400' style='normal'>no_coverage.ttf</font>"
- + " </family>"
- + " <family variant='elegant'>"
- + " <font weight='400' style='normal'>a3em.ttf</font>"
- + " </family>"
- + " <family variant='compact'>"
- + " <font weight='400' style='normal'>b3em.ttf</font>"
- + " </family>"
- + "</familyset>";
- final ArrayMap<String, Typeface> fontMap = new ArrayMap<>();
- final ArrayMap<String, FontFamily[]> fallbackMap = new ArrayMap<>();
-
- buildSystemFallback(xml, fontMap, fallbackMap);
-
- final Paint paint = new Paint();
-
- final Typeface testTypeface = fontMap.get("serif");
- assertNotNull(testTypeface);
- paint.setTypeface(testTypeface);
- paint.setElegantTextHeight(true);
- assertEquals(GLYPH_3EM_WIDTH, paint.measureText("a"), 0.0f);
- assertEquals(GLYPH_1EM_WIDTH, paint.measureText("b"), 0.0f);
- assertEquals(GLYPH_1EM_WIDTH, paint.measureText("c"), 0.0f);
-
- paint.setElegantTextHeight(false);
- assertEquals(GLYPH_1EM_WIDTH, paint.measureText("a"), 0.0f);
- assertEquals(GLYPH_3EM_WIDTH, paint.measureText("b"), 0.0f);
- assertEquals(GLYPH_1EM_WIDTH, paint.measureText("c"), 0.0f);
- }
-
- @Test
- public void testBuildSystemFallback_ElegantFallback_customFallback() {
- final String xml = "<?xml version='1.0' encoding='UTF-8'?>"
- + "<familyset version='22'>"
- + " <family name='sans-serif'>"
- + " <font weight='400' style='normal'>no_coverage.ttf</font>"
- + " </family>"
- + " <family name='serif'>"
- + " <font weight='400' style='normal'>no_coverage.ttf</font>"
- + " </family>"
- + " <family variant='elegant'>"
- + " <font weight='400' style='normal'>a3em.ttf</font>"
- + " <font weight='400' style='normal' fallbackFor='serif'>b3em.ttf</font>"
- + " </family>"
- + " <family variant='compact'>"
- + " <font weight='400' style='normal'>c3em.ttf</font>"
- + " </family>"
- + "</familyset>";
- final ArrayMap<String, Typeface> fontMap = new ArrayMap<>();
- final ArrayMap<String, FontFamily[]> fallbackMap = new ArrayMap<>();
-
- buildSystemFallback(xml, fontMap, fallbackMap);
-
- final Paint paint = new Paint();
-
- Typeface testTypeface = fontMap.get("serif");
- assertNotNull(testTypeface);
- paint.setTypeface(testTypeface);
- paint.setElegantTextHeight(true);
- assertEquals(GLYPH_1EM_WIDTH, paint.measureText("a"), 0.0f);
- assertEquals(GLYPH_3EM_WIDTH, paint.measureText("b"), 0.0f);
- assertEquals(GLYPH_1EM_WIDTH, paint.measureText("c"), 0.0f);
-
- paint.setElegantTextHeight(false);
- assertEquals(GLYPH_1EM_WIDTH, paint.measureText("a"), 0.0f);
- assertEquals(GLYPH_1EM_WIDTH, paint.measureText("b"), 0.0f);
- assertEquals(GLYPH_3EM_WIDTH, paint.measureText("c"), 0.0f);
-
- testTypeface = fontMap.get("sans-serif");
- assertNotNull(testTypeface);
- paint.setTypeface(testTypeface);
- paint.setElegantTextHeight(true);
- assertEquals(GLYPH_3EM_WIDTH, paint.measureText("a"), 0.0f);
- assertEquals(GLYPH_1EM_WIDTH, paint.measureText("b"), 0.0f);
- assertEquals(GLYPH_1EM_WIDTH, paint.measureText("c"), 0.0f);
-
- paint.setElegantTextHeight(false);
- assertEquals(GLYPH_1EM_WIDTH, paint.measureText("a"), 0.0f);
- assertEquals(GLYPH_1EM_WIDTH, paint.measureText("b"), 0.0f);
- assertEquals(GLYPH_3EM_WIDTH, paint.measureText("c"), 0.0f);
- }
-}
String weightStr = parser.getAttributeValue(null, "weight");
int weight = weightStr == null ? 400 : Integer.parseInt(weightStr);
boolean isItalic = "italic".equals(parser.getAttributeValue(null, "style"));
- String fallbackFor = parser.getAttributeValue(null, "fallbackFor");
StringBuilder filename = new StringBuilder();
while (parser.next() != XmlPullParser.END_TAG) {
if (parser.getEventType() == XmlPullParser.TEXT) {
}
String sanitizedName = FILENAME_WHITESPACE_PATTERN.matcher(filename).replaceAll("");
return new FontConfig.Font(sanitizedName, index,
- axes.toArray(new FontVariationAxis[axes.size()]), weight, isItalic, fallbackFor);
+ axes.toArray(new FontVariationAxis[axes.size()]), weight, isItalic);
}
private static FontVariationAxis readAxis(XmlPullParser parser)
import android.provider.FontRequest;
import android.provider.FontsContract;
import android.text.FontConfig;
-import android.util.ArrayMap;
import android.util.Base64;
import android.util.Log;
import android.util.LongSparseArray;
import android.util.SparseArray;
import com.android.internal.annotations.GuardedBy;
-import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.util.Preconditions;
import libcore.io.IoUtils;
private static final LruCache<String, Typeface> sDynamicTypefaceCache = new LruCache<>(16);
static Typeface sDefaultTypeface;
- static final Map<String, Typeface> sSystemFontMap;
- static final Map<String, FontFamily[]> sSystemFallbackMap;
+ static Map<String, Typeface> sSystemFontMap;
+ static FontFamily[] sFallbackFonts;
private static final Object sLock = new Object();
+ static final String FONTS_CONFIG = "fonts.xml";
+
/**
* @hide
*/
// Must be the same as the C++ constant in core/jni/android/graphics/FontFamily.cpp
/** @hide */
public static final int RESOLVE_BY_FONT_TABLE = -1;
- private static final String DEFAULT_FAMILY = "sans-serif";
// Style value for building typeface.
private static final int STYLE_NORMAL = 0;
*/
@Nullable
public static Typeface createFromResources(AssetManager mgr, String path, int cookie) {
- synchronized (sDynamicTypefaceCache) {
- final String key = Builder.createAssetUid(
- mgr, path, 0 /* ttcIndex */, null /* axes */,
- RESOLVE_BY_FONT_TABLE /* weight */, RESOLVE_BY_FONT_TABLE /* italic */,
- DEFAULT_FAMILY);
- Typeface typeface = sDynamicTypefaceCache.get(key);
- if (typeface != null) return typeface;
-
- FontFamily fontFamily = new FontFamily();
- // TODO: introduce ttc index and variation settings to resource type font.
- if (fontFamily.addFontFromAssetManager(mgr, path, cookie, false /* isAsset */,
- 0 /* ttcIndex */, RESOLVE_BY_FONT_TABLE /* weight */,
- RESOLVE_BY_FONT_TABLE /* italic */, null /* axes */)) {
- if (!fontFamily.freeze()) {
- return null;
+ if (sFallbackFonts != null) {
+ synchronized (sDynamicTypefaceCache) {
+ final String key = Builder.createAssetUid(
+ mgr, path, 0 /* ttcIndex */, null /* axes */,
+ RESOLVE_BY_FONT_TABLE /* weight */, RESOLVE_BY_FONT_TABLE /* italic */);
+ Typeface typeface = sDynamicTypefaceCache.get(key);
+ if (typeface != null) return typeface;
+
+ FontFamily fontFamily = new FontFamily();
+ // TODO: introduce ttc index and variation settings to resource type font.
+ if (fontFamily.addFontFromAssetManager(mgr, path, cookie, false /* isAsset */,
+ 0 /* ttcIndex */, RESOLVE_BY_FONT_TABLE /* weight */,
+ RESOLVE_BY_FONT_TABLE /* italic */, null /* axes */)) {
+ if (!fontFamily.freeze()) {
+ return null;
+ }
+ FontFamily[] families = {fontFamily};
+ typeface = createFromFamiliesWithDefault(families,
+ RESOLVE_BY_FONT_TABLE, RESOLVE_BY_FONT_TABLE);
+ sDynamicTypefaceCache.put(key, typeface);
+ return typeface;
}
- FontFamily[] families = {fontFamily};
- typeface = createFromFamiliesWithDefault(families, DEFAULT_FAMILY,
- RESOLVE_BY_FONT_TABLE, RESOLVE_BY_FONT_TABLE);
- sDynamicTypefaceCache.put(key, typeface);
- return typeface;
}
}
return null;
@Nullable
public static Typeface createFromResources(
FamilyResourceEntry entry, AssetManager mgr, String path) {
- if (entry instanceof ProviderResourceEntry) {
- final ProviderResourceEntry providerEntry = (ProviderResourceEntry) entry;
- // Downloadable font
- List<List<String>> givenCerts = providerEntry.getCerts();
- List<List<byte[]>> certs = new ArrayList<>();
- if (givenCerts != null) {
- for (int i = 0; i < givenCerts.size(); i++) {
- List<String> certSet = givenCerts.get(i);
- List<byte[]> byteArraySet = new ArrayList<>();
- for (int j = 0; j < certSet.size(); j++) {
- byteArraySet.add(Base64.decode(certSet.get(j), Base64.DEFAULT));
+ if (sFallbackFonts != null) {
+ if (entry instanceof ProviderResourceEntry) {
+ final ProviderResourceEntry providerEntry = (ProviderResourceEntry) entry;
+ // Downloadable font
+ List<List<String>> givenCerts = providerEntry.getCerts();
+ List<List<byte[]>> certs = new ArrayList<>();
+ if (givenCerts != null) {
+ for (int i = 0; i < givenCerts.size(); i++) {
+ List<String> certSet = givenCerts.get(i);
+ List<byte[]> byteArraySet = new ArrayList<>();
+ for (int j = 0; j < certSet.size(); j++) {
+ byteArraySet.add(Base64.decode(certSet.get(j), Base64.DEFAULT));
+ }
+ certs.add(byteArraySet);
}
- certs.add(byteArraySet);
}
+ // Downloaded font and it wasn't cached, request it again and return a
+ // default font instead (nothing we can do now).
+ FontRequest request = new FontRequest(providerEntry.getAuthority(),
+ providerEntry.getPackage(), providerEntry.getQuery(), certs);
+ Typeface typeface = FontsContract.getFontSync(request);
+ return typeface == null ? DEFAULT : typeface;
}
- // Downloaded font and it wasn't cached, request it again and return a
- // default font instead (nothing we can do now).
- FontRequest request = new FontRequest(providerEntry.getAuthority(),
- providerEntry.getPackage(), providerEntry.getQuery(), certs);
- Typeface typeface = FontsContract.getFontSync(request);
- return typeface == null ? DEFAULT : typeface;
- }
- Typeface typeface = findFromCache(mgr, path);
- if (typeface != null) return typeface;
+ Typeface typeface = findFromCache(mgr, path);
+ if (typeface != null) return typeface;
- // family is FontFamilyFilesResourceEntry
- final FontFamilyFilesResourceEntry filesEntry = (FontFamilyFilesResourceEntry) entry;
+ // family is FontFamilyFilesResourceEntry
+ final FontFamilyFilesResourceEntry filesEntry =
+ (FontFamilyFilesResourceEntry) entry;
- FontFamily fontFamily = new FontFamily();
- for (final FontFileResourceEntry fontFile : filesEntry.getEntries()) {
- // TODO: Add ttc and variation font support. (b/37853920)
- if (!fontFamily.addFontFromAssetManager(mgr, fontFile.getFileName(),
- 0 /* resourceCookie */, false /* isAsset */, 0 /* ttcIndex */,
- fontFile.getWeight(), fontFile.getItalic(), null /* axes */)) {
+ FontFamily fontFamily = new FontFamily();
+ for (final FontFileResourceEntry fontFile : filesEntry.getEntries()) {
+ // TODO: Add ttc and variation font support. (b/37853920)
+ if (!fontFamily.addFontFromAssetManager(mgr, fontFile.getFileName(),
+ 0 /* resourceCookie */, false /* isAsset */, 0 /* ttcIndex */,
+ fontFile.getWeight(), fontFile.getItalic(), null /* axes */)) {
+ return null;
+ }
+ }
+ if (!fontFamily.freeze()) {
return null;
}
+ FontFamily[] familyChain = { fontFamily };
+ typeface = createFromFamiliesWithDefault(familyChain,
+ RESOLVE_BY_FONT_TABLE, RESOLVE_BY_FONT_TABLE);
+ synchronized (sDynamicTypefaceCache) {
+ final String key = Builder.createAssetUid(mgr, path, 0 /* ttcIndex */,
+ null /* axes */, RESOLVE_BY_FONT_TABLE /* weight */,
+ RESOLVE_BY_FONT_TABLE /* italic */);
+ sDynamicTypefaceCache.put(key, typeface);
+ }
+ return typeface;
}
- if (!fontFamily.freeze()) {
- return null;
- }
- FontFamily[] familyChain = { fontFamily };
- typeface = createFromFamiliesWithDefault(familyChain, DEFAULT_FAMILY,
- RESOLVE_BY_FONT_TABLE, RESOLVE_BY_FONT_TABLE);
- synchronized (sDynamicTypefaceCache) {
- final String key = Builder.createAssetUid(mgr, path, 0 /* ttcIndex */,
- null /* axes */, RESOLVE_BY_FONT_TABLE /* weight */,
- RESOLVE_BY_FONT_TABLE /* italic */, DEFAULT_FAMILY);
- sDynamicTypefaceCache.put(key, typeface);
- }
- return typeface;
+ return null;
}
/**
public static Typeface findFromCache(AssetManager mgr, String path) {
synchronized (sDynamicTypefaceCache) {
final String key = Builder.createAssetUid(mgr, path, 0 /* ttcIndex */, null /* axes */,
- RESOLVE_BY_FONT_TABLE /* weight */, RESOLVE_BY_FONT_TABLE /* italic */,
- DEFAULT_FAMILY);
+ RESOLVE_BY_FONT_TABLE /* weight */, RESOLVE_BY_FONT_TABLE /* italic */);
Typeface typeface = sDynamicTypefaceCache.get(key);
if (typeface != null) {
return typeface;
* @return Unique id for a given AssetManager and asset path.
*/
private static String createAssetUid(final AssetManager mgr, String path, int ttcIndex,
- @Nullable FontVariationAxis[] axes, int weight, int italic, String fallback) {
+ @Nullable FontVariationAxis[] axes, int weight, int italic) {
final SparseArray<String> pkgs = mgr.getAssignedPackageIdentifiers();
final StringBuilder builder = new StringBuilder();
final int size = pkgs.size();
builder.append(Integer.toString(weight));
builder.append("-");
builder.append(Integer.toString(italic));
- // Family name may contain hyphen. Use double hyphen for avoiding key conflicts before
- // and after appending falblack name.
- builder.append("--");
- builder.append(fallback);
- builder.append("--");
+ builder.append("-");
if (axes != null) {
for (FontVariationAxis axis : axes) {
builder.append(axis.getTag());
return resolveFallbackTypeface();
}
FontFamily[] families = { fontFamily };
- return createFromFamiliesWithDefault(families, mFallbackFamilyName, mWeight,
- mItalic);
+ return createFromFamiliesWithDefault(families, mWeight, mItalic);
} catch (IOException e) {
return resolveFallbackTypeface();
}
} else if (mAssetManager != null) { // Builder is created with asset manager.
final String key = createAssetUid(
- mAssetManager, mPath, mTtcIndex, mAxes, mWeight, mItalic,
- mFallbackFamilyName);
+ mAssetManager, mPath, mTtcIndex, mAxes, mWeight, mItalic);
synchronized (sLock) {
Typeface typeface = sDynamicTypefaceCache.get(key);
if (typeface != null) return typeface;
return resolveFallbackTypeface();
}
FontFamily[] families = { fontFamily };
- typeface = createFromFamiliesWithDefault(families, mFallbackFamilyName,
- mWeight, mItalic);
+ typeface = createFromFamiliesWithDefault(families, mWeight, mItalic);
sDynamicTypefaceCache.put(key, typeface);
return typeface;
}
return resolveFallbackTypeface();
}
FontFamily[] families = { fontFamily };
- return createFromFamiliesWithDefault(families, mFallbackFamilyName, mWeight,
- mItalic);
+ return createFromFamiliesWithDefault(families, mWeight, mItalic);
} else if (mFonts != null) {
final FontFamily fontFamily = new FontFamily();
boolean atLeastOneFont = false;
}
fontFamily.freeze();
FontFamily[] families = { fontFamily };
- return createFromFamiliesWithDefault(families, mFallbackFamilyName, mWeight,
- mItalic);
+ return createFromFamiliesWithDefault(families, mWeight, mItalic);
}
// Must not reach here.
* @return The best matching typeface.
*/
public static Typeface create(String familyName, int style) {
- return create(sSystemFontMap.get(familyName), style);
+ if (sSystemFontMap != null) {
+ return create(sSystemFontMap.get(familyName), style);
+ }
+ return null;
}
/**
if (path == null) {
throw new NullPointerException(); // for backward compatibility
}
- synchronized (sLock) {
- Typeface typeface = new Builder(mgr, path).build();
- if (typeface != null) return typeface;
+ if (sFallbackFonts != null) {
+ synchronized (sLock) {
+ Typeface typeface = new Builder(mgr, path).build();
+ if (typeface != null) return typeface;
- final String key = Builder.createAssetUid(mgr, path, 0 /* ttcIndex */,
- null /* axes */, RESOLVE_BY_FONT_TABLE, RESOLVE_BY_FONT_TABLE,
- DEFAULT_FAMILY);
- typeface = sDynamicTypefaceCache.get(key);
- if (typeface != null) return typeface;
+ final String key = Builder.createAssetUid(mgr, path, 0 /* ttcIndex */,
+ null /* axes */, RESOLVE_BY_FONT_TABLE, RESOLVE_BY_FONT_TABLE);
+ typeface = sDynamicTypefaceCache.get(key);
+ if (typeface != null) return typeface;
- final FontFamily fontFamily = new FontFamily();
- if (fontFamily.addFontFromAssetManager(mgr, path, 0, true /* isAsset */,
- 0 /* ttc index */, RESOLVE_BY_FONT_TABLE, RESOLVE_BY_FONT_TABLE,
- null /* axes */)) {
- // Due to backward compatibility, even if the font is not supported by our font
- // stack, we need to place the empty font at the first place. The typeface with
- // empty font behaves different from default typeface especially in fallback
- // font selection.
- fontFamily.allowUnsupportedFont();
- fontFamily.freeze();
- final FontFamily[] families = { fontFamily };
- typeface = createFromFamiliesWithDefault(families, DEFAULT_FAMILY,
- RESOLVE_BY_FONT_TABLE, RESOLVE_BY_FONT_TABLE);
- sDynamicTypefaceCache.put(key, typeface);
- return typeface;
- } else {
- fontFamily.abortCreation();
+ final FontFamily fontFamily = new FontFamily();
+ if (fontFamily.addFontFromAssetManager(mgr, path, 0, true /* isAsset */,
+ 0 /* ttc index */, RESOLVE_BY_FONT_TABLE, RESOLVE_BY_FONT_TABLE,
+ null /* axes */)) {
+ // Due to backward compatibility, even if the font is not supported by our font
+ // stack, we need to place the empty font at the first place. The typeface with
+ // empty font behaves different from default typeface especially in fallback
+ // font selection.
+ fontFamily.allowUnsupportedFont();
+ fontFamily.freeze();
+ final FontFamily[] families = { fontFamily };
+ typeface = createFromFamiliesWithDefault(families, RESOLVE_BY_FONT_TABLE,
+ RESOLVE_BY_FONT_TABLE);
+ sDynamicTypefaceCache.put(key, typeface);
+ return typeface;
+ } else {
+ fontFamily.abortCreation();
+ }
}
}
throw new RuntimeException("Font asset not found " + path);
* @return The new typeface.
*/
public static Typeface createFromFile(@Nullable String path) {
- final FontFamily fontFamily = new FontFamily();
- if (fontFamily.addFont(path, 0 /* ttcIndex */, null /* axes */,
- RESOLVE_BY_FONT_TABLE, RESOLVE_BY_FONT_TABLE)) {
- // Due to backward compatibility, even if the font is not supported by our font
- // stack, we need to place the empty font at the first place. The typeface with
- // empty font behaves different from default typeface especially in fallback font
- // selection.
- fontFamily.allowUnsupportedFont();
- fontFamily.freeze();
- FontFamily[] families = { fontFamily };
- return createFromFamiliesWithDefault(families, DEFAULT_FAMILY,
- RESOLVE_BY_FONT_TABLE, RESOLVE_BY_FONT_TABLE);
- } else {
- fontFamily.abortCreation();
+ if (sFallbackFonts != null) {
+ final FontFamily fontFamily = new FontFamily();
+ if (fontFamily.addFont(path, 0 /* ttcIndex */, null /* axes */,
+ RESOLVE_BY_FONT_TABLE, RESOLVE_BY_FONT_TABLE)) {
+ // Due to backward compatibility, even if the font is not supported by our font
+ // stack, we need to place the empty font at the first place. The typeface with
+ // empty font behaves different from default typeface especially in fallback font
+ // selection.
+ fontFamily.allowUnsupportedFont();
+ fontFamily.freeze();
+ FontFamily[] families = { fontFamily };
+ return createFromFamiliesWithDefault(families, RESOLVE_BY_FONT_TABLE,
+ RESOLVE_BY_FONT_TABLE);
+ } else {
+ fontFamily.abortCreation();
+ }
}
throw new RuntimeException("Font not found " + path);
}
/**
* Create a new typeface from an array of font families, including
* also the font families in the fallback list.
- * @param fallbackName the family name. If given families don't support characters, the
- * characters will be rendered with this family.
* @param weight the weight for this family. {@link RESOLVE_BY_FONT_TABLE} can be used. In that
* case, the table information in the first family's font is used. If the first
* family has multiple fonts, the closest to the regular weight and upright font
* @param families array of font families
*/
private static Typeface createFromFamiliesWithDefault(FontFamily[] families,
- String fallbackName, int weight, int italic) {
- FontFamily[] fallback = sSystemFallbackMap.get(fallbackName);
- if (fallback == null) {
- fallback = sSystemFallbackMap.get(DEFAULT_FAMILY);
- }
- long[] ptrArray = new long[families.length + fallback.length];
+ int weight, int italic) {
+ long[] ptrArray = new long[families.length + sFallbackFonts.length];
for (int i = 0; i < families.length; i++) {
ptrArray[i] = families[i].mNativePtr;
}
- for (int i = 0; i < fallback.length; i++) {
- ptrArray[i + families.length] = fallback[i].mNativePtr;
+ for (int i = 0; i < sFallbackFonts.length; i++) {
+ ptrArray[i + families.length] = sFallbackFonts[i].mNativePtr;
}
return new Typeface(nativeCreateFromArray(ptrArray, weight, italic));
}
mWeight = nativeGetWeight(ni);
}
- private static @Nullable ByteBuffer mmap(String fullPath) {
- try (FileInputStream file = new FileInputStream(fullPath)) {
- final FileChannel fileChannel = file.getChannel();
- final long fontSize = fileChannel.size();
- return fileChannel.map(FileChannel.MapMode.READ_ONLY, 0, fontSize);
- } catch (IOException e) {
- Log.e(TAG, "Error mapping font file " + fullPath);
- return null;
- }
- }
-
- private static @Nullable FontFamily createFontFamily(
- String familyName, List<FontConfig.Font> fonts, String languageTag, int variant,
- Map<String, ByteBuffer> cache, String fontDir) {
- final FontFamily family = new FontFamily(languageTag, variant);
- for (int i = 0; i < fonts.size(); i++) {
- final FontConfig.Font font = fonts.get(i);
- final String fullPath = fontDir + font.getFontName();
- ByteBuffer buffer = cache.get(fullPath);
- if (buffer == null) {
- if (cache.containsKey(fullPath)) {
- continue; // Already failed to mmap. Skip it.
- }
- buffer = mmap(fullPath);
- cache.put(fullPath, buffer);
- if (buffer == null) {
+ private static FontFamily makeFamilyFromParsed(FontConfig.Family family,
+ Map<String, ByteBuffer> bufferForPath) {
+ FontFamily fontFamily = new FontFamily(family.getLanguage(), family.getVariant());
+ for (FontConfig.Font font : family.getFonts()) {
+ String fullPathName = "/system/fonts/" + font.getFontName();
+ ByteBuffer fontBuffer = bufferForPath.get(fullPathName);
+ if (fontBuffer == null) {
+ try (FileInputStream file = new FileInputStream(fullPathName)) {
+ FileChannel fileChannel = file.getChannel();
+ long fontSize = fileChannel.size();
+ fontBuffer = fileChannel.map(FileChannel.MapMode.READ_ONLY, 0, fontSize);
+ bufferForPath.put(fullPathName, fontBuffer);
+ } catch (IOException e) {
+ Log.e(TAG, "Error mapping font file " + fullPathName);
continue;
}
}
- if (!family.addFontFromBuffer(buffer, font.getTtcIndex(), font.getAxes(),
+ if (!fontFamily.addFontFromBuffer(fontBuffer, font.getTtcIndex(), font.getAxes(),
font.getWeight(), font.isItalic() ? STYLE_ITALIC : STYLE_NORMAL)) {
- Log.e(TAG, "Error creating font " + fullPath + "#" + font.getTtcIndex());
+ Log.e(TAG, "Error creating font " + fullPathName + "#" + font.getTtcIndex());
}
}
- if (!family.freeze()) {
- Log.e(TAG, "Unable to load Family: " + familyName + " : " + languageTag);
+ if (!fontFamily.freeze()) {
+ // Treat as system error since reaching here means that a system pre-installed font
+ // can't be used by our font stack.
+ Log.e(TAG, "Unable to load Family: " + family.getName() + ":" + family.getLanguage());
return null;
}
- return family;
+ return fontFamily;
}
- private static void pushFamilyToFallback(FontConfig.Family xmlFamily,
- ArrayMap<String, ArrayList<FontFamily>> fallbackMap,
- Map<String, ByteBuffer> cache,
- String fontDir) {
-
- final String languageTag = xmlFamily.getLanguage();
- final int variant = xmlFamily.getVariant();
-
- final ArrayList<FontConfig.Font> defaultFonts = new ArrayList<>();
- final ArrayMap<String, ArrayList<FontConfig.Font>> specificFallbackFonts = new ArrayMap<>();
-
- // Collect default fallback and specific fallback fonts.
- for (final FontConfig.Font font : xmlFamily.getFonts()) {
- final String fallbackName = font.getFallbackFor();
- if (fallbackName == null) {
- defaultFonts.add(font);
- } else {
- ArrayList<FontConfig.Font> fallback = specificFallbackFonts.get(fallbackName);
- if (fallback == null) {
- fallback = new ArrayList<>();
- specificFallbackFonts.put(fallbackName, fallback);
- }
- fallback.add(font);
- }
- }
-
- final FontFamily defaultFamily = defaultFonts.isEmpty() ? null : createFontFamily(
- xmlFamily.getName(), defaultFonts, languageTag, variant, cache, fontDir);
-
- // Insert family into fallback map.
- for (int i = 0; i < fallbackMap.size(); i++) {
- final ArrayList<FontConfig.Font> fallback =
- specificFallbackFonts.get(fallbackMap.keyAt(i));
- if (fallback == null) {
- if (defaultFamily != null) {
- fallbackMap.valueAt(i).add(defaultFamily);
- }
- } else {
- final FontFamily family = createFontFamily(
- xmlFamily.getName(), fallback, languageTag, variant, cache, fontDir);
- if (family != null) {
- fallbackMap.valueAt(i).add(family);
- }
- }
- }
- }
-
- /**
- * Build the system fallback from xml file.
+ /*
+ * (non-Javadoc)
*
- * @param xmlPath A full path string to the fonts.xml file.
- * @param fontDir A full path string to the system font directory. This must end with
- * slash('/').
- * @param fontMap An output system font map. Caller must pass empty map.
- * @param fallbackMap An output system fallback map. Caller must pass empty map.
- * @hide
+ * This should only be called once, from the static class initializer block.
*/
- @VisibleForTesting
- public static void buildSystemFallback(String xmlPath, String fontDir,
- ArrayMap<String, Typeface> fontMap, ArrayMap<String, FontFamily[]> fallbackMap) {
+ private static void init() {
+ // Load font config and initialize Minikin state
+ File systemFontConfigLocation = getSystemFontConfigLocation();
+ File configFilename = new File(systemFontConfigLocation, FONTS_CONFIG);
try {
- final FileInputStream fontsIn = new FileInputStream(xmlPath);
- final FontConfig fontConfig = FontListParser.parse(fontsIn);
-
- final HashMap<String, ByteBuffer> bufferCache = new HashMap<String, ByteBuffer>();
- final FontConfig.Family[] xmlFamilies = fontConfig.getFamilies();
-
- final ArrayMap<String, ArrayList<FontFamily>> fallbackListMap = new ArrayMap<>();
- // First traverse families which have a 'name' attribute to create fallback map.
- for (final FontConfig.Family xmlFamily : xmlFamilies) {
- final String familyName = xmlFamily.getName();
- if (familyName == null) {
- continue;
- }
- final FontFamily family = createFontFamily(
- xmlFamily.getName(), Arrays.asList(xmlFamily.getFonts()),
- xmlFamily.getLanguage(), xmlFamily.getVariant(), bufferCache, fontDir);
- if (family == null) {
- continue;
- }
- final ArrayList<FontFamily> fallback = new ArrayList<>();
- fallback.add(family);
- fallbackListMap.put(familyName, fallback);
- }
-
- // Then, add fallback fonts to the each fallback map.
- for (int i = 0; i < xmlFamilies.length; i++) {
- final FontConfig.Family xmlFamily = xmlFamilies[i];
- // The first family (usually the sans-serif family) is always placed immediately
- // after the primary family in the fallback.
- if (i == 0 || xmlFamily.getName() == null) {
- pushFamilyToFallback(xmlFamily, fallbackListMap, bufferCache, fontDir);
+ FileInputStream fontsIn = new FileInputStream(configFilename);
+ FontConfig fontConfig = FontListParser.parse(fontsIn);
+
+ Map<String, ByteBuffer> bufferForPath = new HashMap<String, ByteBuffer>();
+
+ List<FontFamily> familyList = new ArrayList<FontFamily>();
+ // Note that the default typeface is always present in the fallback list;
+ // this is an enhancement from pre-Minikin behavior.
+ for (int i = 0; i < fontConfig.getFamilies().length; i++) {
+ FontConfig.Family f = fontConfig.getFamilies()[i];
+ if (i == 0 || f.getName() == null) {
+ FontFamily family = makeFamilyFromParsed(f, bufferForPath);
+ if (family != null) {
+ familyList.add(family);
+ }
}
}
-
- // Build the font map and fallback map.
- for (int i = 0; i < fallbackListMap.size(); i++) {
- final String fallbackName = fallbackListMap.keyAt(i);
- final List<FontFamily> familyList = fallbackListMap.valueAt(i);
- final FontFamily[] families = familyList.toArray(new FontFamily[familyList.size()]);
-
- fallbackMap.put(fallbackName, families);
- final long[] ptrArray = new long[families.length];
- for (int j = 0; j < families.length; j++) {
- ptrArray[j] = families[j].mNativePtr;
+ sFallbackFonts = familyList.toArray(new FontFamily[familyList.size()]);
+ setDefault(Typeface.createFromFamilies(sFallbackFonts));
+
+ Map<String, Typeface> systemFonts = new HashMap<String, Typeface>();
+ for (int i = 0; i < fontConfig.getFamilies().length; i++) {
+ Typeface typeface;
+ FontConfig.Family f = fontConfig.getFamilies()[i];
+ if (f.getName() != null) {
+ if (i == 0) {
+ // The first entry is the default typeface; no sense in
+ // duplicating the corresponding FontFamily.
+ typeface = sDefaultTypeface;
+ } else {
+ FontFamily fontFamily = makeFamilyFromParsed(f, bufferForPath);
+ if (fontFamily == null) {
+ continue;
+ }
+ FontFamily[] families = { fontFamily };
+ typeface = Typeface.createFromFamiliesWithDefault(families,
+ RESOLVE_BY_FONT_TABLE, RESOLVE_BY_FONT_TABLE);
+ }
+ systemFonts.put(f.getName(), typeface);
}
- fontMap.put(fallbackName, new Typeface(nativeCreateFromArray(
- ptrArray, RESOLVE_BY_FONT_TABLE, RESOLVE_BY_FONT_TABLE)));
}
-
- // Insert alias to font maps.
- for (final FontConfig.Alias alias : fontConfig.getAliases()) {
- Typeface base = fontMap.get(alias.getToName());
+ for (FontConfig.Alias alias : fontConfig.getAliases()) {
+ Typeface base = systemFonts.get(alias.getToName());
Typeface newFace = base;
int weight = alias.getWeight();
if (weight != 400) {
newFace = new Typeface(nativeCreateWeightAlias(base.native_instance, weight));
}
- fontMap.put(alias.getName(), newFace);
+ systemFonts.put(alias.getName(), newFace);
}
+ sSystemFontMap = systemFonts;
+
} catch (RuntimeException e) {
Log.w(TAG, "Didn't create default family (most likely, non-Minikin build)", e);
// TODO: normal in non-Minikin case, remove or make error when Minikin-only
} catch (FileNotFoundException e) {
- Log.e(TAG, "Error opening " + xmlPath, e);
+ Log.e(TAG, "Error opening " + configFilename, e);
} catch (IOException e) {
- Log.e(TAG, "Error reading " + xmlPath, e);
+ Log.e(TAG, "Error reading " + configFilename, e);
} catch (XmlPullParserException e) {
- Log.e(TAG, "XML parse exception for " + xmlPath, e);
+ Log.e(TAG, "XML parse exception for " + configFilename, e);
}
}
static {
- final ArrayMap<String, Typeface> systemFontMap = new ArrayMap<>();
- final ArrayMap<String, FontFamily[]> systemFallbackMap = new ArrayMap<>();
- buildSystemFallback("/system/etc/fonts.xml", "/system/fonts/", systemFontMap,
- systemFallbackMap);
- sSystemFontMap = Collections.unmodifiableMap(systemFontMap);
- sSystemFallbackMap = Collections.unmodifiableMap(systemFallbackMap);
-
- setDefault(sSystemFontMap.get(DEFAULT_FAMILY));
-
+ init();
// Set up defaults and typefaces exposed in public API
DEFAULT = create((String) null, 0);
DEFAULT_BOLD = create((String) null, Typeface.BOLD);
}
+ private static File getSystemFontConfigLocation() {
+ return new File("/system/etc/");
+ }
+
@Override
protected void finalize() throws Throwable {
try {
Typeface* gDefaultTypeface = NULL;
Typeface* Typeface::resolveDefault(Typeface* src) {
- LOG_ALWAYS_FATAL_IF(src == nullptr && gDefaultTypeface == nullptr);
+ LOG_ALWAYS_FATAL_IF(gDefaultTypeface == nullptr);
return src == nullptr ? gDefaultTypeface : src;
}