Test and generalize font configuration parser

Add a basic unit test for the Android font configuration parser.
Add a check for the new LMP file format; on detection, switch to a new
(as-yet unwritten) parser.

R=bungeman@google.com, djsollen@google.com, tomhudson@google.com

Author: tomhudson@chromium.org

Review URL: https://codereview.chromium.org/439813002
This commit is contained in:
tomhudson 2014-08-05 06:36:11 -07:00 committed by Commit bot
parent 8f961b373b
commit f79673bbae
8 changed files with 905 additions and 40 deletions

View File

@ -26,6 +26,17 @@
'tools.gyp:sk_tool_utils',
],
'conditions': [
[ 'skia_os == "android"', {
'dependencies': [
'ports.gyp:ports',
],
'include_dirs': [
'../src/ports',
],
'sources': [
'../tests/FontConfigParser.cpp',
],
}],
[ 'skia_android_framework == 1', {
'libraries': [
'-ldl',

View File

@ -0,0 +1,77 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
Fallback Fonts
This file specifies the fonts, and the priority order, that will be searched for any
glyphs not handled by the default fonts specified in /system/etc/system_fonts.xml.
Each entry consists of a family tag and a list of files (file names) which support that
family. The fonts for each family are listed in the order of the styles that they
handle (the order is: regular, bold, italic, and bold-italic). The order in which the
families are listed in this file represents the order in which these fallback fonts
will be searched for glyphs that are not supported by the default system fonts (which are
found in /system/etc/system_fonts.xml).
Note that there is not nameset for fallback fonts, unlike the fonts specified in
system_fonts.xml. The ability to support specific names in fallback fonts may be supported
in the future. For now, the lack of files entries here is an indicator to the system that
these are fallback fonts, instead of default named system fonts.
There is another optional file in /vendor/etc/fallback_fonts.xml. That file can be used to
provide references to other font families that should be used in addition to the default
fallback fonts. That file can also specify the order in which the fallback fonts should be
searched, to ensure that a vendor-provided font will be used before another fallback font
which happens to handle the same glyph.
-->
<familyset>
<family>
<fileset>
<file>DroidNaskh-Regular.ttf</file>
</fileset>
</family>
<family>
<fileset>
<file>DroidSansEthiopic-Regular.ttf</file>
</fileset>
</family>
<family>
<fileset>
<file>DroidSansHebrew-Regular.ttf</file>
<file>DroidSansHebrew-Bold.ttf</file>
</fileset>
</family>
<family>
<fileset>
<file>DroidSansThai.ttf</file>
</fileset>
</family>
<family>
<fileset>
<file>DroidSansArmenian.ttf</file>
</fileset>
</family>
<family>
<fileset>
<file>DroidSansGeorgian.ttf</file>
</fileset>
</family>
<family>
<fileset>
<file>Lohit-Devanagari.ttf</file>
</fileset>
</family>
<family>
<fileset>
<file>Lohit-Bengali.ttf</file>
</fileset>
</family>
<family>
<fileset>
<file>Lohit-Tamil.ttf</file>
</fileset>
</family>
<family>
<fileset>
<file>DroidSansFallback.ttf</file>
</fileset>
</family>
</familyset>

View File

@ -0,0 +1,80 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
System Fonts
This file lists the font families that will be used by default for all supported glyphs.
Each entry consists of a family, various names that are supported by that family, and
up to four font files. The font files are listed in the order of the styles which they
support: regular, bold, italic and bold-italic. If less than four styles are listed, then
the styles with no associated font file will be supported by the other font files listed.
The first family is also the default font, which handles font request that have not specified
specific font names.
Any glyph that is not handled by the system fonts will cause a search of the fallback fonts.
The default fallback fonts are specified in the file /system/etc/fallback_fonts.xml, and there
is an optional file which may be supplied by vendors to specify other fallback fonts to use
in /vendor/etc/fallback_fonts.xml.
-->
<familyset>
<family>
<nameset>
<name>sans-serif</name>
<name>arial</name>
<name>helvetica</name>
<name>tahoma</name>
<name>verdana</name>
</nameset>
<fileset>
<file>Roboto-Regular.ttf</file>
<file>Roboto-Bold.ttf</file>
<file>Roboto-Italic.ttf</file>
<file>Roboto-BoldItalic.ttf</file>
</fileset>
</family>
<family>
<nameset>
<name>serif</name>
<name>times</name>
<name>times new roman</name>
<name>palatino</name>
<name>georgia</name>
<name>baskerville</name>
<name>goudy</name>
<name>fantasy</name>
<name>cursive</name>
<name>ITC Stone Serif</name>
</nameset>
<fileset>
<file>DroidSerif-Regular.ttf</file>
<file>DroidSerif-Bold.ttf</file>
<file>DroidSerif-Italic.ttf</file>
<file>DroidSerif-BoldItalic.ttf</file>
</fileset>
</family>
<family>
<nameset>
<name>Droid Sans</name>
</nameset>
<fileset>
<file>DroidSans.ttf</file>
<file>DroidSans-Bold.ttf</file>
</fileset>
</family>
<family>
<nameset>
<name>monospace</name>
<name>courier</name>
<name>courier new</name>
<name>monaco</name>
</nameset>
<fileset>
<file>DroidSansMono.ttf</file>
</fileset>
</family>
</familyset>

View File

@ -0,0 +1,213 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
Fallback Fonts
This file specifies the fonts, and the priority order, that will be searched for any
glyphs not handled by the default fonts specified in /system/etc/system_fonts.xml.
Each entry consists of a family tag and a list of files (file names) which support that
family. The fonts for each family are listed in the order of the styles that they
handle (the order is: regular, bold, italic, and bold-italic). The order in which the
families are listed in this file represents the order in which these fallback fonts
will be searched for glyphs that are not supported by the default system fonts (which are
found in /system/etc/system_fonts.xml).
Note that there is not nameset for fallback fonts, unlike the fonts specified in
system_fonts.xml. The ability to support specific names in fallback fonts may be supported
in the future. For now, the lack of files entries here is an indicator to the system that
these are fallback fonts, instead of default named system fonts.
There is another optional file in /vendor/etc/fallback_fonts.xml. That file can be used to
provide references to other font families that should be used in addition to the default
fallback fonts. That file can also specify the order in which the fallback fonts should be
searched, to ensure that a vendor-provided font will be used before another fallback font
which happens to handle the same glyph.
Han languages (Chinese, Japanese, and Korean) share a common range of unicode characters;
their ordering in the fallback or vendor files gives priority to the first in the list.
Language-specific ordering can be configured by adding a BCP 47-style "lang" attribute to
a "file" element; fonts matching the language of text being drawn will be prioritised over
all others.
-->
<familyset>
<family>
<fileset>
<file variant="elegant">DroidNaskh-Regular.ttf</file>
</fileset>
</family>
<family>
<fileset>
<file variant="compact">DroidNaskhUI-Regular.ttf</file>
</fileset>
</family>
<family>
<fileset>
<file>DroidSansEthiopic-Regular.ttf</file>
</fileset>
</family>
<family>
<fileset>
<file>DroidSansHebrew-Regular.ttf</file>
<file>DroidSansHebrew-Bold.ttf</file>
</fileset>
</family>
<family>
<fileset>
<file variant="elegant">NotoSansThai-Regular.ttf</file>
<file variant="elegant">NotoSansThai-Bold.ttf</file>
</fileset>
</family>
<family>
<fileset>
<file variant="compact">NotoSansThaiUI-Regular.ttf</file>
<file variant="compact">NotoSansThaiUI-Bold.ttf</file>
</fileset>
</family>
<family>
<fileset>
<file>DroidSansArmenian.ttf</file>
</fileset>
</family>
<family>
<fileset>
<file>DroidSansGeorgian.ttf</file>
</fileset>
</family>
<family>
<fileset>
<file variant="elegant">NotoSansDevanagari-Regular.ttf</file>
<file variant="elegant">NotoSansDevanagari-Bold.ttf</file>
</fileset>
</family>
<family>
<fileset>
<file variant="compact">NotoSansDevanagariUI-Regular.ttf</file>
<file variant="compact">NotoSansDevanagariUI-Bold.ttf</file>
</fileset>
</family>
<family>
<fileset>
<file variant="elegant">NotoSansTamil-Regular.ttf</file>
<file variant="elegant">NotoSansTamil-Bold.ttf</file>
</fileset>
</family>
<family>
<fileset>
<file variant="compact">NotoSansTamilUI-Regular.ttf</file>
<file variant="compact">NotoSansTamilUI-Bold.ttf</file>
</fileset>
</family>
<family>
<fileset>
<file variant="elegant">NotoSansMalayalam-Regular.ttf</file>
<file variant="elegant">NotoSansMalayalam-Bold.ttf</file>
</fileset>
</family>
<family>
<fileset>
<file variant="compact">NotoSansMalayalamUI-Regular.ttf</file>
<file variant="compact">NotoSansMalayalamUI-Bold.ttf</file>
</fileset>
</family>
<family>
<fileset>
<file variant="elegant">NotoSansBengali-Regular.ttf</file>
<file variant="elegant">NotoSansBengali-Bold.ttf</file>
</fileset>
</family>
<family>
<fileset>
<file variant="compact">NotoSansBengaliUI-Regular.ttf</file>
<file variant="compact">NotoSansBengaliUI-Bold.ttf</file>
</fileset>
</family>
<family>
<fileset>
<file variant="elegant">NotoSansTelugu-Regular.ttf</file>
<file variant="elegant">NotoSansTelugu-Bold.ttf</file>
</fileset>
</family>
<family>
<fileset>
<file variant="compact">NotoSansTeluguUI-Regular.ttf</file>
<file variant="compact">NotoSansTeluguUI-Bold.ttf</file>
</fileset>
</family>
<family>
<fileset>
<file variant="elegant">NotoSansKannada-Regular.ttf</file>
<file variant="elegant">NotoSansKannada-Bold.ttf</file>
</fileset>
</family>
<family>
<fileset>
<file variant="compact">NotoSansKannadaUI-Regular.ttf</file>
<file variant="compact">NotoSansKannadaUI-Bold.ttf</file>
</fileset>
</family>
<family>
<fileset>
<file variant="elegant">NotoSansKhmer-Regular.ttf</file>
<file variant="elegant">NotoSansKhmer-Bold.ttf</file>
</fileset>
</family>
<family>
<fileset>
<file variant="compact">NotoSansKhmerUI-Regular.ttf</file>
<file variant="compact">NotoSansKhmerUI-Bold.ttf</file>
</fileset>
</family>
<family>
<fileset>
<file variant="elegant">NotoSansLao-Regular.ttf</file>
<file variant="elegant">NotoSansLao-Bold.ttf</file>
</fileset>
</family>
<family>
<fileset>
<file variant="compact">NotoSansLaoUI-Regular.ttf</file>
<file variant="compact">NotoSansLaoUI-Bold.ttf</file>
</fileset>
</family>
<family>
<fileset>
<file>NanumGothic.ttf</file>
</fileset>
</family>
<family>
<fileset>
<file>Padauk-book.ttf</file>
<file>Padauk-bookbold.ttf</file>
</fileset>
</family>
<family>
<fileset>
<file>NotoSansSymbols-Regular.ttf</file>
</fileset>
</family>
<family>
<fileset>
<file>AndroidEmoji.ttf</file>
</fileset>
</family>
<family>
<fileset>
<file>NotoColorEmoji.ttf</file>
</fileset>
</family>
<family>
<fileset>
<file>DroidSansFallback.ttf</file>
</fileset>
</family>
<family>
<fileset>
<file lang="ja">MTLmr3m.ttf</file>
</fileset>
</family>
<!-- Note: complex scripts (i.e. those requiring shaping in Harfbuzz) have
a cumulative limit of 64k glyphs. Thus, if they are placed after the
large fonts such as DroidSansFallback, they are likely to render
incorrectly. Please use caution when putting fonts toward the end of
the list.
-->
</familyset>

View File

@ -0,0 +1,138 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
System Fonts
This file lists the font families that will be used by default for all supported glyphs.
Each entry consists of a family, various names that are supported by that family, and
up to four font files. The font files are listed in the order of the styles which they
support: regular, bold, italic and bold-italic. If less than four styles are listed, then
the styles with no associated font file will be supported by the other font files listed.
The first family is also the default font, which handles font request that have not specified
specific font names.
Any glyph that is not handled by the system fonts will cause a search of the fallback fonts.
The default fallback fonts are specified in the file /system/etc/fallback_fonts.xml, and there
is an optional file which may be supplied by vendors to specify other fallback fonts to use
in /vendor/etc/fallback_fonts.xml.
-->
<familyset>
<family>
<nameset>
<name>sans-serif</name>
<name>arial</name>
<name>helvetica</name>
<name>tahoma</name>
<name>verdana</name>
</nameset>
<fileset>
<file>Roboto-Regular.ttf</file>
<file>Roboto-Bold.ttf</file>
<file>Roboto-Italic.ttf</file>
<file>Roboto-BoldItalic.ttf</file>
</fileset>
</family>
<family>
<nameset>
<name>sans-serif-light</name>
</nameset>
<fileset>
<file>Roboto-Light.ttf</file>
<file>Roboto-LightItalic.ttf</file>
</fileset>
</family>
<family>
<nameset>
<name>sans-serif-thin</name>
</nameset>
<fileset>
<file>Roboto-Thin.ttf</file>
<file>Roboto-ThinItalic.ttf</file>
</fileset>
</family>
<family>
<nameset>
<name>sans-serif-condensed</name>
</nameset>
<fileset>
<file>RobotoCondensed-Regular.ttf</file>
<file>RobotoCondensed-Bold.ttf</file>
<file>RobotoCondensed-Italic.ttf</file>
<file>RobotoCondensed-BoldItalic.ttf</file>
</fileset>
</family>
<family>
<nameset>
<name>serif</name>
<name>times</name>
<name>times new roman</name>
<name>palatino</name>
<name>georgia</name>
<name>baskerville</name>
<name>goudy</name>
<name>fantasy</name>
<name>ITC Stone Serif</name>
</nameset>
<fileset>
<file>DroidSerif-Regular.ttf</file>
<file>DroidSerif-Bold.ttf</file>
<file>DroidSerif-Italic.ttf</file>
<file>DroidSerif-BoldItalic.ttf</file>
</fileset>
</family>
<family>
<nameset>
<name>Droid Sans</name>
</nameset>
<fileset>
<file>DroidSans.ttf</file>
<file>DroidSans-Bold.ttf</file>
</fileset>
</family>
<family>
<nameset>
<name>monospace</name>
<name>courier</name>
<name>courier new</name>
<name>monaco</name>
</nameset>
<fileset>
<file>DroidSansMono.ttf</file>
</fileset>
</family>
<family>
<nameset>
<name>casual</name>
</nameset>
<fileset>
<file>ComingSoon.ttf</file>
</fileset>
</family>
<family>
<nameset>
<name>cursive</name>
</nameset>
<fileset>
<file>DancingScript-Regular.ttf</file>
<file>DancingScript-Bold.ttf</file>
</fileset>
</family>
<family>
<nameset>
<name>sans-serif-smallcaps</name>
</nameset>
<fileset>
<file>CarroisGothicSC-Regular.ttf</file>
</fileset>
</family>
</familyset>

View File

@ -0,0 +1,232 @@
<?xml version="1.0" encoding="utf-8"?>
<familyset version="21">
<!-- first font is default -->
<family name="sans-serif">
<font weight="100" style="normal">Roboto-Thin.ttf</font>
<font weight="100" style="italic">Roboto-ThinItalic.ttf</font>
<font weight="300" style="normal">Roboto-Light.ttf</font>
<font weight="300" style="italic">Roboto-LightItalic.ttf</font>
<font weight="400" style="normal">Roboto-Regular.ttf</font>
<font weight="400" style="italic">Roboto-Italic.ttf</font>
<font weight="500" style="normal">Roboto-Medium.ttf</font>
<font weight="500" style="italic">Roboto-MediumItalic.ttf</font>
<font weight="700" style="normal">Roboto-Bold.ttf</font>
<font weight="700" style="italic">Roboto-BoldItalic.ttf</font>
<font weight="900" style="normal">Roboto-Black.ttf</font>
<font weight="900" style="italic">Roboto-BlackItalic.ttf</font>
</family>
<alias name="sans-serif-thin" to="sans-serif" weight="100" />
<alias name="sans-serif-light" to="sans-serif" weight="300" />
<alias name="sans-serif-black" to="sans-serif" weight="900" />
<alias name="arial" to="sans-serif" />
<alias name="helvetica" to="sans-serif" />
<alias name="tahoma" to="sans-serif" />
<alias name="verdana" to="sans-serif" />
<family name="sans-serif-condensed">
<font weight="300" style="normal">RobotoCondensed-Light.ttf</font>
<font weight="300" style="italic">RobotoCondensed-LightItalic.ttf</font>
<font weight="400" style="normal">RobotoCondensed-Regular.ttf</font>
<font weight="400" style="italic">RobotoCondensed-Italic.ttf</font>
<font weight="700" style="normal">RobotoCondensed-Bold.ttf</font>
<font weight="700" style="italic">RobotoCondensed-BoldItalic.ttf</font>
</family>
<alias name="sans-serif-condensed-light" to="sans-serif-condensed" weight="300" />
<!--- rest of fonts from system_fonts.xml go here -->
<family name="serif">
<font weight="400" style="normal">NotoSerif-Regular.ttf</font>
<font weight="700" style="normal">NotoSerif-Bold.ttf</font>
<font weight="400" style="italic">NotoSerif-Italic.ttf</font>
<font weight="700" style="italic">NotoSerif-BoldItalic.ttf</font>
</family>
<alias name="times" to="serif" />
<alias name="times new roman" to="serif" />
<alias name="palatino" to="serif" />
<alias name="georgia" to="serif" />
<alias name="baskerville" to="serif" />
<alias name="goudy" to="serif" />
<alias name="fantasy" to="serif" />
<alias name="ITC Stone Serif" to="serif" />
<family name="monospace">
<font weight="400" style="normal">DroidSansMono.ttf</font>
</family>
<alias name="courier" to="monospace" />
<alias name="courier new" to="monospace" />
<alias name="monaco" to="monospace" />
<family name="casual">
<font weight="400" style="normal">ComingSoon.ttf</font>
</family>
<family name="cursive">
<font weight="400" style="normal">DancingScript-Regular.ttf</font>
<font weight="700" style="normal">DancingScript-Bold.ttf</font>
</family>
<family name="ans-serif-smallcaps">
<font weight="400" style="normal">CarroisGothicSC-Regular.ttf</font>
</family>
<!-- fallback fonts -->
<family variant="elegant">
<font weight="400" style="normal">NotoNaskh-Regular.ttf</font>
<font weight="700" style="normal">NotoNaskh-Bold.ttf</font>
</family>
<family variant="compact">
<font weight="400" style="normal">NotoNaskhUI-Regular.ttf</font>
<font weight="700" style="normal">NotoNaskhUI-Bold.ttf</font>
</family>
<family>
<font weight="400" style="normal">NotoSansEthiopic-Regular.ttf</font>
<font weight="700" style="normal">NotoSansEthiopic-Bold.ttf</font>
</family>
<family>
<font weight="400" style="normal">NotoSansHebrew-Regular.ttf</font>
<font weight="700" style="normal">NotoSansHebrew-Bold.ttf</font>
</family>
<family variant="elegant">
<font weight="400" style="normal">NotoSansThai-Regular.ttf</font>
<font weight="700" style="normal">NotoSansThai-Bold.ttf</font>
</family>
<family variant="compact">
<font weight="400" style="normal">NotoSansThaiUI-Regular.ttf</font>
<font weight="700" style="normal">NotoSansThaiUI-Bold.ttf</font>
</family>
<family>
<font weight="400" style="normal">NotoSansArmenian-Regular.ttf</font>
<font weight="700" style="normal">NotoSansArmenian-Bold.ttf</font>
</family>
<family>
<font weight="400" style="normal">NotoSansGeorgian-Regular.ttf</font>
<font weight="700" style="normal">NotoSansGeorgian-Bold.ttf</font>
</family>
<family variant="elegant">
<font weight="400" style="normal">NotoSansDevanagari-Regular.ttf</font>
<font weight="700" style="normal">NotoSansDevanagari-Bold.ttf</font>
</family>
<family variant="compact">
<font weight="400" style="normal">NotoSansDevanagariUI-Regular.ttf</font>
<font weight="700" style="normal">NotoSansDevanagariUI-Bold.ttf</font>
</family>
<!-- Gujarati should come after Devanagari -->
<family variant="elegant">
<font weight="400" style="normal">NotoSansGujarati-Regular.ttf</font>
<font weight="700" style="normal">NotoSansGujarati-Bold.ttf</font>
</family>
<family variant="compact">
<font weight="400" style="normal">NotoSansGujaratiUI-Regular.ttf</font>
<font weight="700" style="normal">NotoSansGujaratiUI-Bold.ttf</font>
</family>
<!-- Gurmukhi should come after Devanagari -->
<family variant="elegant">
<font weight="400" style="normal">NotoSansGurmukhi-Regular.ttf</font>
<font weight="700" style="normal">NotoSansGurmukhi-Bold.ttf</font>
</family>
<family variant="compact">
<font weight="400" style="normal">NotoSansGurmukhiUI-Regular.ttf</font>
<font weight="700" style="normal">NotoSansGurmukhiUI-Bold.ttf</font>
</family>
<family variant="elegant">
<font weight="400" style="normal">NotoSansTamil-Regular.ttf</font>
<font weight="700" style="normal">NotoSansTamil-Bold.ttf</font>
</family>
<family variant="compact">
<font weight="400" style="normal">NotoSansTamilUI-Regular.ttf</font>
<font weight="700" style="normal">NotoSansTamilUI-Bold.ttf</font>
</family>
<family variant="elegant">
<font weight="400" style="normal">NotoSansMalayalam-Regular.ttf</font>
<font weight="700" style="normal">NotoSansMalayalam-Bold.ttf</font>
</family>
<family variant="compact">
<font weight="400" style="normal">NotoSansMalayalamUI-Regular.ttf</font>
<font weight="700" style="normal">NotoSansMalayalamUI-Bold.ttf</font>
</family>
<family variant="elegant">
<font weight="400" style="normal">NotoSansBengali-Regular.ttf</font>
<font weight="700" style="normal">NotoSansBengali-Bold.ttf</font>
</family>
<family variant="compact">
<font weight="400" style="normal">NotoSansBengaliUI-Regular.ttf</font>
<font weight="700" style="normal">NotoSansBengaliUI-Bold.ttf</font>
</family>
<family variant="elegant">
<font weight="400" style="normal">NotoSansTelugu-Regular.ttf</font>
<font weight="700" style="normal">NotoSansTelugu-Bold.ttf</font>
</family>
<family variant="compact">
<font weight="400" style="normal">NotoSansTeluguUI-Regular.ttf</font>
<font weight="700" style="normal">NotoSansTeluguUI-Bold.ttf</font>
</family>
<family variant="elegant">
<font weight="400" style="normal">NotoSansKannada-Regular.ttf</font>
<font weight="700" style="normal">NotoSansKannada-Bold.ttf</font>
</family>
<family variant="compact">
<font weight="400" style="normal">NotoSansKannadaUI-Regular.ttf</font>
<font weight="700" style="normal">NotoSansKannadaUI-Bold.ttf</font>
</family>
<family>
<font weight="400" style="normal">NotoSansSinhala-Regular.ttf</font>
<font weight="700" style="normal">NotoSansSinhala-Bold.ttf</font>
</family>
<family variant="elegant">
<font weight="400" style="normal">NotoSansKhmer-Regular.ttf</font>
<font weight="700" style="normal">NotoSansKhmer-Bold.ttf</font>
</family>
<family variant="compact">
<font weight="400" style="normal">NotoSansKhmerUI-Regular.ttf</font>
<font weight="700" style="normal">NotoSansKhmerUI-Bold.ttf</font>
</family>
<family variant="elegant">
<font weight="400" style="normal">NotoSansLao-Regular.ttf</font>
<font weight="700" style="normal">NotoSansLao-Bold.ttf</font>
</family>
<family variant="compact">
<font weight="400" style="normal">NotoSansLaoUI-Regular.ttf</font>
<font weight="700" style="normal">NotoSansLaoUI-Bold.ttf</font>
</family>
<family variant="elegant">
<font weight="400" style="normal">NotoSansMyanmar-Regular.ttf</font>
<font weight="700" style="normal">NotoSansMyanmar-Bold.ttf</font>
</family>
<family variant="compact">
<font weight="400" style="normal">NotoSansMyanmarUI-Regular.ttf</font>
<font weight="700" style="normal">NotoSansMyanmarUI-Bold.ttf</font>
</family>
<family>
<font weight="400" style="normal">NotoSansCherokee-Regular.ttf</font>
</family>
<family>
<font weight="400" style="normal">NotoSansCanadianAboriginal-Regular.ttf</font>
</family>
<family>
<font weight="400" style="normal">NotoSansYi-Regular.ttf</font>
</family>
<family lang="zh-Hans">
<font weight="400" style="normal">NotoSansHans-Regular.otf</font>
</family>
<family lang="zh-Hant">
<font weight="400" style="normal">NotoSansHant-Regular.otf</font>
</family>
<family lang="ja">
<font weight="400" style="normal">NotoSansJP-Regular.otf</font>
</family>
<family lang="ko">
<font weight="400" style="normal">NotoSansKR-Regular.otf</font>
</family>
<family>
<font weight="400" style="normal">NanumGothic.ttf</font>
</family>
<family>
<font weight="400" style="normal">NotoSansSymbols-Regular-Subsetted.ttf</font>
</family>
<family>
<font weight="400" style="normal">NotoColorEmoji.ttf</font>
</family>
<family lang="ja">
<font weight="400" style="normal">MTLmr3m.ttf</font>
</family>
</familyset>

View File

@ -20,6 +20,13 @@
#define FALLBACK_FONTS_FILE "/system/etc/fallback_fonts.xml"
#define VENDOR_FONTS_FILE "/vendor/etc/fallback_fonts.xml"
/**
* This file contains TWO parsers: one for JB and earlier (system_fonts.xml /
* fallback_fonts.xml), one for LMP and later (fonts.xml).
* We start with the JB parser, and if we detect a <familyset> tag with
* version 21 or higher we switch to the LMP parser.
*/
// These defines are used to determine the kind of tag that we're currently
// populating with data. We only care about the sibling tags nameset and fileset
// for now.
@ -46,6 +53,45 @@ struct FamilyData {
int currentTag; // A flag to indicate whether we're in nameset/fileset tags
};
/** http://www.w3.org/TR/html-markup/datatypes.html#common.data.integer.non-negative-def */
template <typename T> static bool parseNonNegativeInteger(const char* s, T* value) {
SK_COMPILE_ASSERT(std::numeric_limits<T>::is_integer, T_must_be_integer);
const T nMax = std::numeric_limits<T>::max() / 10;
const T dMax = std::numeric_limits<T>::max() - (nMax * 10);
T n = 0;
for (; *s; ++s) {
// Check if digit
if (*s < '0' || '9' < *s) {
return false;
}
int d = *s - '0';
// Check for overflow
if (n > nMax || (n == nMax && d > dMax)) {
return false;
}
n = (n * 10) + d;
}
*value = n;
return true;
}
namespace lmpParser {
void startElementHandler(void* data, const char* tag,
const char** attributes) {
//SkDebugf("lmp started %s", tag);
}
void endElementHandler(void* data, const char* tag) {
//SkDebugf("lmp ended %s", tag);
}
} // lmpParser
namespace jbParser {
/**
* Handler for arbitrary text. This is used to parse the text inside each name
* or file tag. The resulting strings are put into the fNames or FontFileInfo arrays.
@ -73,34 +119,11 @@ static void textHandler(void *data, const char *s, int len) {
}
}
/** http://www.w3.org/TR/html-markup/datatypes.html#common.data.integer.non-negative-def */
template <typename T> static bool parseNonNegativeInteger(const char* s, T* value) {
SK_COMPILE_ASSERT(std::numeric_limits<T>::is_integer, T_must_be_integer);
const T nMax = std::numeric_limits<T>::max() / 10;
const T dMax = std::numeric_limits<T>::max() - (nMax * 10);
T n = 0;
for (; *s; ++s) {
// Check if digit
if (*s < '0' || '9' < *s) {
return false;
}
int d = *s - '0';
// Check for overflow
if (n > nMax || (n == nMax && d > dMax)) {
return false;
}
n = (n * 10) + d;
}
*value = n;
return true;
}
/**
* Handler for font files. This processes the attributes for language and
* variants then lets textHandler handle the actual file name
*/
static void fontFileElementHandler(FamilyData *familyData, const char **attributes) {
FontFileInfo& newFileInfo = familyData->currentFamily->fFontFiles.push_back();
if (attributes) {
int currentAttributeIndex = 0;
@ -109,15 +132,16 @@ static void fontFileElementHandler(FamilyData *familyData, const char **attribut
const char* attributeValue = attributes[currentAttributeIndex+1];
int nameLength = strlen(attributeName);
int valueLength = strlen(attributeValue);
if (strncmp(attributeName, "variant", nameLength) == 0) {
if (strncmp(attributeValue, "elegant", valueLength) == 0) {
if (nameLength == 7 && strncmp(attributeName, "variant", nameLength) == 0) {
if (valueLength == 7 && strncmp(attributeValue, "elegant", valueLength) == 0) {
newFileInfo.fPaintOptions.setFontVariant(SkPaintOptionsAndroid::kElegant_Variant);
} else if (strncmp(attributeValue, "compact", valueLength) == 0) {
} else if (valueLength == 7 &&
strncmp(attributeValue, "compact", valueLength) == 0) {
newFileInfo.fPaintOptions.setFontVariant(SkPaintOptionsAndroid::kCompact_Variant);
}
} else if (strncmp(attributeName, "lang", nameLength) == 0) {
} else if (nameLength == 4 && strncmp(attributeName, "lang", nameLength) == 0) {
newFileInfo.fPaintOptions.setLanguage(attributeValue);
} else if (strncmp(attributeName, "index", nameLength) == 0) {
} else if (nameLength == 5 && strncmp(attributeName, "index", nameLength) == 0) {
int value;
if (parseNonNegativeInteger(attributeValue, &value)) {
newFileInfo.fIndex = value;
@ -134,13 +158,26 @@ static void fontFileElementHandler(FamilyData *familyData, const char **attribut
}
/**
* Handler for the start of a tag. The only tags we expect are family, nameset,
* fileset, name, and file.
* Handler for the start of a tag. The only tags we expect are familyset, family,
* nameset, fileset, name, and file.
*/
static void startElementHandler(void *data, const char *tag, const char **atts) {
FamilyData *familyData = (FamilyData*) data;
int len = strlen(tag);
if (strncmp(tag, "family", len)== 0) {
if (len == 9 && strncmp(tag, "familyset", len) == 0) {
// The familyset tag has an optional "version" attribute with an integer value >= 0
for (int i = 0; atts[i] != NULL; i += 2) {
int nameLen = strlen(atts[i]);
if (nameLen == 7 && strncmp(atts[i], "version", nameLen)) continue;
const char* valueString = atts[i+1];
int version;
if (parseNonNegativeInteger(valueString, &version) && (version >= 21)) {
XML_SetElementHandler(*familyData->parser,
lmpParser::startElementHandler,
lmpParser::endElementHandler);
}
}
} else if (len == 6 && strncmp(tag, "family", len) == 0) {
familyData->currentFamily = new FontFamily();
familyData->currentFamily->order = -1;
// The Family tag has an optional "order" attribute with an integer value >= 0
@ -148,8 +185,7 @@ static void startElementHandler(void *data, const char *tag, const char **atts)
for (int i = 0; atts[i] != NULL; i += 2) {
const char* valueString = atts[i+1];
int value;
int len = sscanf(valueString, "%d", &value);
if (len > 0) {
if (parseNonNegativeInteger(valueString, &value)) {
familyData->currentFamily->order = value;
}
}
@ -157,10 +193,10 @@ static void startElementHandler(void *data, const char *tag, const char **atts)
familyData->currentTag = NAMESET_TAG;
} else if (len == 7 && strncmp(tag, "fileset", len) == 0) {
familyData->currentTag = FILESET_TAG;
} else if (strncmp(tag, "name", len) == 0 && familyData->currentTag == NAMESET_TAG) {
} else if (len == 4 && strncmp(tag, "name", len) == 0 && familyData->currentTag == NAMESET_TAG) {
// If it's a Name, parse the text inside
XML_SetCharacterDataHandler(*familyData->parser, textHandler);
} else if (strncmp(tag, "file", len) == 0 && familyData->currentTag == FILESET_TAG) {
} else if (len == 4 && strncmp(tag, "file", len) == 0 && familyData->currentTag == FILESET_TAG) {
// If it's a file, parse the attributes, then parse the text inside
fontFileElementHandler(familyData, atts);
}
@ -173,7 +209,7 @@ static void startElementHandler(void *data, const char *tag, const char **atts)
static void endElementHandler(void *data, const char *tag) {
FamilyData *familyData = (FamilyData*) data;
int len = strlen(tag);
if (strncmp(tag, "family", len)== 0) {
if (len == 6 && strncmp(tag, "family", len)== 0) {
// Done parsing a Family - store the created currentFamily in the families array
*familyData->families.append() = familyData->currentFamily;
familyData->currentFamily = NULL;
@ -181,13 +217,19 @@ static void endElementHandler(void *data, const char *tag) {
familyData->currentTag = NO_TAG;
} else if (len == 7 && strncmp(tag, "fileset", len) == 0) {
familyData->currentTag = NO_TAG;
} else if ((strncmp(tag, "name", len) == 0 && familyData->currentTag == NAMESET_TAG) ||
(strncmp(tag, "file", len) == 0 && familyData->currentTag == FILESET_TAG)) {
} else if ((len == 4 &&
strncmp(tag, "name", len) == 0 &&
familyData->currentTag == NAMESET_TAG) ||
(len == 4 &&
strncmp(tag, "file", len) == 0 &&
familyData->currentTag == FILESET_TAG)) {
// Disable the arbitrary text handler installed to load Name data
XML_SetCharacterDataHandler(*familyData->parser, NULL);
}
}
} // namespace jbParser
/**
* This function parses the given filename and stores the results in the given
* families array.
@ -237,7 +279,8 @@ static void parseConfigFile(const char *filename, SkTDArray<FontFamily*> &famili
XML_Parser parser = XML_ParserCreate(NULL);
FamilyData *familyData = new FamilyData(&parser, families);
XML_SetUserData(parser, familyData);
XML_SetElementHandler(parser, startElementHandler, endElementHandler);
// Start parsing oldschool; switch these in flight if we detect a newer version of the file.
XML_SetElementHandler(parser, jbParser::startElementHandler, jbParser::endElementHandler);
char buffer[512];
bool done = false;
@ -309,7 +352,9 @@ void SkFontConfigParser::GetTestFontFamilies(SkTDArray<FontFamily*> &fontFamilie
parseConfigFile(testMainConfigFile, fontFamilies);
SkTDArray<FontFamily*> fallbackFonts;
parseConfigFile(testFallbackConfigFile, fallbackFonts);
if (NULL != testFallbackConfigFile) {
parseConfigFile(testFallbackConfigFile, fallbackFonts);
}
// Append all fallback fonts to system fonts
for (int i = 0; i < fallbackFonts.count(); ++i) {

View File

@ -0,0 +1,69 @@
/*
* Copyright 2014 Google Inc.
*
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
#include "Resources.h"
#include "SkFontConfigParser_android.h"
#include "Test.h"
void ValidateLoadedFonts(SkTDArray<FontFamily*> fontFamilies,
skiatest::Reporter* reporter) {
REPORTER_ASSERT(reporter, fontFamilies[0]->fNames.count() == 5);
REPORTER_ASSERT(reporter, !strcmp(fontFamilies[0]->fNames[0].c_str(), "sans-serif"));
REPORTER_ASSERT(reporter,
!strcmp(fontFamilies[0]->fFontFiles[0].fFileName.c_str(),
"Roboto-Regular.ttf"));
REPORTER_ASSERT(reporter, !fontFamilies[0]->fIsFallbackFont);
}
void DumpLoadedFonts(SkTDArray<FontFamily*> fontFamilies) {
#if SK_DEBUG_FONTS
for (int i = 0; i < fontFamilies.count(); ++i) {
SkDebugf("Family %d:\n", i);
for (int j = 0; j < fontFamilies[i]->fNames.count(); ++j) {
SkDebugf(" name %s\n", fontFamilies[i]->fNames[j].c_str());
}
}
#endif // SK_DEBUG_FONTS
}
DEF_TEST(FontConfigParserAndroid, reporter) {
SkTDArray<FontFamily*> preV17FontFamilies;
SkFontConfigParser::GetTestFontFamilies(preV17FontFamilies,
GetResourcePath("android_fonts/pre_v17/system_fonts.xml").c_str(),
GetResourcePath("android_fonts/pre_v17/fallback_fonts.xml").c_str());
REPORTER_ASSERT(reporter, preV17FontFamilies.count() == 14);
DumpLoadedFonts(preV17FontFamilies);
ValidateLoadedFonts(preV17FontFamilies, reporter);
SkTDArray<FontFamily*> v17FontFamilies;
SkFontConfigParser::GetTestFontFamilies(v17FontFamilies,
GetResourcePath("android_fonts/v17/system_fonts.xml").c_str(),
GetResourcePath("android_fonts/v17/fallback_fonts.xml").c_str());
REPORTER_ASSERT(reporter, v17FontFamilies.count() == 41);
DumpLoadedFonts(v17FontFamilies);
ValidateLoadedFonts(v17FontFamilies, reporter);
SkTDArray<FontFamily*> v22FontFamilies;
SkFontConfigParser::GetTestFontFamilies(v22FontFamilies,
GetResourcePath("android_fonts/v22/fonts.xml").c_str(),
NULL);
//REPORTER_ASSERT(reporter, v22FontFamilies.count() > 0);
if (v22FontFamilies.count() > 0) {
REPORTER_ASSERT(reporter, v22FontFamilies[0]->fNames.count() > 0);
}
//ValidateLoadedFonts(v22FontFamilies, reporter);
}