Merge "Make Paint.hasGlyph variation selector aware."
This commit is contained in:
@@ -63,6 +63,11 @@ void MinikinUtils::doLayout(Layout* layout, const Paint* paint, int bidiFlags,
|
||||
layout->doLayout(buf, start, count, bufSize, bidiFlags, minikinStyle, minikinPaint);
|
||||
}
|
||||
|
||||
bool MinikinUtils::hasVariationSelector(TypefaceImpl* typeface, uint32_t codepoint, uint32_t vs) {
|
||||
const TypefaceImpl* resolvedFace = TypefaceImpl_resolveDefault(typeface);
|
||||
return resolvedFace->fFontCollection->hasVariationSelector(codepoint, vs);
|
||||
}
|
||||
|
||||
float MinikinUtils::xOffsetForTextAlign(Paint* paint, const Layout& layout) {
|
||||
switch (paint->getTextAlign()) {
|
||||
case Paint::kCenter_Align:
|
||||
|
||||
@@ -40,6 +40,8 @@ public:
|
||||
TypefaceImpl* typeface, const uint16_t* buf, size_t start, size_t count,
|
||||
size_t bufSize);
|
||||
|
||||
static bool hasVariationSelector(TypefaceImpl* typeface, uint32_t codepoint, uint32_t vs);
|
||||
|
||||
static float xOffsetForTextAlign(Paint* paint, const Layout& layout);
|
||||
|
||||
static float hOffsetForTextAlign(Paint* paint, const Layout& layout, const SkPath& path);
|
||||
|
||||
@@ -39,6 +39,7 @@
|
||||
|
||||
#include <minikin/GraphemeBreak.h>
|
||||
#include <minikin/Measurement.h>
|
||||
#include <unicode/utf16.h>
|
||||
#include "MinikinSkia.h"
|
||||
#include "MinikinUtils.h"
|
||||
#include "Paint.h"
|
||||
@@ -852,45 +853,44 @@ namespace PaintGlue {
|
||||
return false;
|
||||
}
|
||||
|
||||
static jboolean hasGlyphVariation(const Paint* paint, TypefaceImpl* typeface, jint bidiFlags,
|
||||
const jchar* chars, size_t size) {
|
||||
// TODO: query font for whether character has variation selector; requires a corresponding
|
||||
// function in Minikin.
|
||||
return false;
|
||||
}
|
||||
|
||||
static jboolean hasGlyph(JNIEnv *env, jclass, jlong paintHandle, jlong typefaceHandle,
|
||||
jint bidiFlags, jstring string) {
|
||||
const Paint* paint = reinterpret_cast<Paint*>(paintHandle);
|
||||
TypefaceImpl* typeface = reinterpret_cast<TypefaceImpl*>(typefaceHandle);
|
||||
ScopedStringChars str(env, string);
|
||||
|
||||
/* start by rejecting variation selectors (not supported yet) */
|
||||
/* Start by rejecting unsupported base code point and variation selector pairs. */
|
||||
size_t nChars = 0;
|
||||
const uint32_t kStartOfString = 0xFFFFFFFF;
|
||||
uint32_t prevCp = kStartOfString;
|
||||
for (size_t i = 0; i < str.size(); i++) {
|
||||
jchar c = str[i];
|
||||
if (0xDC00 <= c && c <= 0xDFFF) {
|
||||
jchar cu = str[i];
|
||||
uint32_t cp = cu;
|
||||
if (U16_IS_TRAIL(cu)) {
|
||||
// invalid UTF-16, unpaired trailing surrogate
|
||||
return false;
|
||||
} else if (0xD800 <= c && c <= 0xDBFF) {
|
||||
} else if (U16_IS_LEAD(cu)) {
|
||||
if (i + 1 == str.size()) {
|
||||
// invalid UTF-16, unpaired leading surrogate at end of string
|
||||
return false;
|
||||
}
|
||||
i++;
|
||||
jchar c2 = str[i];
|
||||
if (!(0xDC00 <= c2 && c2 <= 0xDFFF)) {
|
||||
jchar cu2 = str[i];
|
||||
if (!U16_IS_TRAIL(cu2)) {
|
||||
// invalid UTF-16, unpaired leading surrogate
|
||||
return false;
|
||||
}
|
||||
// UTF-16 encoding of range U+E0100..U+E01EF is DB40 DD00 .. DB40 DDEF
|
||||
if (c == 0xDB40 && 0xDD00 <= c2 && c2 <= 0xDDEF) {
|
||||
return hasGlyphVariation(paint, typeface, bidiFlags, str.get(), str.size());
|
||||
}
|
||||
} else if (0xFE00 <= c && c <= 0xFE0F) {
|
||||
return hasGlyphVariation(paint, typeface, bidiFlags, str.get(), str.size());
|
||||
cp = U16_GET_SUPPLEMENTARY(cu, cu2);
|
||||
}
|
||||
|
||||
if (prevCp != kStartOfString &&
|
||||
((0xFE00 <= cp && cp <= 0xFE0F) || (0xE0100 <= cp && cp <= 0xE01EF)) &&
|
||||
!MinikinUtils::hasVariationSelector(typeface, prevCp, cp)) {
|
||||
// No font has a glyph for the code point and variation selector pair.
|
||||
return false;
|
||||
}
|
||||
nChars++;
|
||||
prevCp = cp;
|
||||
}
|
||||
Layout layout;
|
||||
MinikinUtils::doLayout(&layout, paint, bidiFlags, typeface, str.get(), 0, str.size(),
|
||||
|
||||
BIN
core/tests/coretests/assets/fonts/hasGlyphTestFont.ttf
Normal file
BIN
core/tests/coretests/assets/fonts/hasGlyphTestFont.ttf
Normal file
Binary file not shown.
365
core/tests/coretests/assets/fonts/hasGlyphTestFont.ttx
Normal file
365
core/tests/coretests/assets/fonts/hasGlyphTestFont.ttx
Normal file
@@ -0,0 +1,365 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!-- Copyright (C) 2015 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>
|
||||
<!-- The 'id' attribute is only for humans; it is ignored when parsed. -->
|
||||
<GlyphID id="0" name=".notdef"/>
|
||||
<GlyphID id="1" name="BaseChar1"/>
|
||||
<GlyphID id="2" name="BaseChar1_VS1"/>
|
||||
<GlyphID id="3" name="BaseChar1_VS17"/>
|
||||
<GlyphID id="4" name="BaseChar1_VS18"/>
|
||||
<GlyphID id="5" name="BaseChar2"/>
|
||||
<GlyphID id="6" name="BaseChar2_VS2"/>
|
||||
<GlyphID id="7" name="BaseChar2_VS18"/>
|
||||
<GlyphID id="8" name="BaseChar2_VS19"/>
|
||||
<GlyphID id="9" name="BaseChar3"/>
|
||||
<GlyphID id="10" name="BaseChar4_VS3"/>
|
||||
<GlyphID id="11" name="BaseChar4_VS19"/>
|
||||
<GlyphID id="12" name="BaseChar4_VS20"/>
|
||||
<GlyphID id="13" name="BaseChar5"/>
|
||||
<GlyphID id="14" name="BaseChar5_VS1"/>
|
||||
<GlyphID id="15" name="BaseChar5_VS17"/>
|
||||
<GlyphID id="16" name="BaseChar5_VS18"/>
|
||||
<GlyphID id="17" name="BaseChar6"/>
|
||||
<GlyphID id="18" name="BaseChar6_VS2"/>
|
||||
<GlyphID id="19" name="BaseChar6_VS18"/>
|
||||
<GlyphID id="20" name="BaseChar6_VS19"/>
|
||||
<GlyphID id="21" name="BaseChar7"/>
|
||||
<GlyphID id="22" name="BaseChar8_VS3"/>
|
||||
<GlyphID id="23" name="BaseChar8_VS19"/>
|
||||
<GlyphID id="24" name="BaseChar8_VS20"/>
|
||||
</GlyphOrder>
|
||||
|
||||
<head>
|
||||
<!-- Most of this table will be recalculated by the compiler -->
|
||||
<tableVersion value="1.0"/>
|
||||
<fontRevision value="1.0"/>
|
||||
<checkSumAdjustment value="0x640cdb2f"/>
|
||||
<magicNumber value="0x5f0f3cf5"/>
|
||||
<flags value="00000000 00000011"/>
|
||||
<unitsPerEm value="1000"/>
|
||||
<created value="Wed Sep 9 08:01:17 2015"/>
|
||||
<modified value="Wed Sep 9 08:48:07 2015"/>
|
||||
<xMin value="30"/>
|
||||
<yMin value="-200"/>
|
||||
<xMax value="629"/>
|
||||
<yMax value="800"/>
|
||||
<macStyle value="00000000 00000000"/>
|
||||
<lowestRecPPEM value="7"/>
|
||||
<fontDirectionHint value="2"/>
|
||||
<indexToLocFormat value="0"/>
|
||||
<glyphDataFormat value="0"/>
|
||||
</head>
|
||||
|
||||
<hhea>
|
||||
<tableVersion value="1.0"/>
|
||||
<ascent value="1000"/>
|
||||
<descent value="-200"/>
|
||||
<lineGap value="0"/>
|
||||
<advanceWidthMax value="659"/>
|
||||
<minLeftSideBearing value="0"/>
|
||||
<minRightSideBearing value="30"/>
|
||||
<xMaxExtent value="629"/>
|
||||
<caretSlopeRise value="1"/>
|
||||
<caretSlopeRun value="0"/>
|
||||
<caretOffset value="0"/>
|
||||
<reserved0 value="0"/>
|
||||
<reserved1 value="0"/>
|
||||
<reserved2 value="0"/>
|
||||
<reserved3 value="0"/>
|
||||
<metricDataFormat value="0"/>
|
||||
<numberOfHMetrics value="18"/>
|
||||
</hhea>
|
||||
|
||||
<maxp>
|
||||
<!-- Most of this table will be recalculated by the compiler -->
|
||||
<tableVersion value="0x10000"/>
|
||||
<numGlyphs value="54"/>
|
||||
<maxPoints value="73"/>
|
||||
<maxContours value="10"/>
|
||||
<maxCompositePoints value="0"/>
|
||||
<maxCompositeContours value="0"/>
|
||||
<maxZones value="2"/>
|
||||
<maxTwilightPoints value="12"/>
|
||||
<maxStorage value="28"/>
|
||||
<maxFunctionDefs value="119"/>
|
||||
<maxInstructionDefs value="0"/>
|
||||
<maxStackElements value="61"/>
|
||||
<maxSizeOfInstructions value="2967"/>
|
||||
<maxComponentElements value="0"/>
|
||||
<maxComponentDepth 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="BaseChar1" width="500" lsb="93"/>
|
||||
<mtx name="BaseChar1_VS1" width="500" lsb="93"/>
|
||||
<mtx name="BaseChar1_VS17" width="500" lsb="93"/>
|
||||
<mtx name="BaseChar1_VS18" width="500" lsb="93"/>
|
||||
<mtx name="BaseChar2" width="500" lsb="93"/>
|
||||
<mtx name="BaseChar2_VS2" width="500" lsb="93"/>
|
||||
<mtx name="BaseChar2_VS18" width="500" lsb="93"/>
|
||||
<mtx name="BaseChar2_VS19" width="500" lsb="93"/>
|
||||
<mtx name="BaseChar3" width="500" lsb="93"/>
|
||||
<mtx name="BaseChar4_VS3" width="500" lsb="93"/>
|
||||
<mtx name="BaseChar4_VS19" width="500" lsb="93"/>
|
||||
<mtx name="BaseChar4_VS20" width="500" lsb="93"/>
|
||||
<mtx name="BaseChar5" width="500" lsb="93"/>
|
||||
<mtx name="BaseChar5_VS1" width="500" lsb="93"/>
|
||||
<mtx name="BaseChar5_VS17" width="500" lsb="93"/>
|
||||
<mtx name="BaseChar5_VS18" width="500" lsb="93"/>
|
||||
<mtx name="BaseChar6" width="500" lsb="93"/>
|
||||
<mtx name="BaseChar6_VS2" width="500" lsb="93"/>
|
||||
<mtx name="BaseChar6_VS18" width="500" lsb="93"/>
|
||||
<mtx name="BaseChar6_VS19" width="500" lsb="93"/>
|
||||
<mtx name="BaseChar7" width="500" lsb="93"/>
|
||||
<mtx name="BaseChar8_VS3" width="500" lsb="93"/>
|
||||
<mtx name="BaseChar8_VS19" width="500" lsb="93"/>
|
||||
<mtx name="BaseChar8_VS20" width="500" lsb="93"/>
|
||||
</hmtx>
|
||||
|
||||
<cmap>
|
||||
<tableVersion version="0"/>
|
||||
<cmap_format_12 format="12" reserved="0" length="6" nGroups="1" platformID="3" platEncID="10" language="0">
|
||||
<map code="0x0061" name="BaseChar1" />
|
||||
<map code="0x0062" name="BaseChar2" />
|
||||
<map code="0x0063" name="BaseChar3" />
|
||||
<!-- No cmap4 entry for BaseChar4 -->
|
||||
<map code="0x1F000" name="BaseChar5" />
|
||||
<map code="0x1F001" name="BaseChar6" />
|
||||
<map code="0x1F002" name="BaseChar7" />
|
||||
<!-- No cmap4 entry for BaseChar8 -->
|
||||
</cmap_format_12>
|
||||
<cmap_format_14 format="14" platformID="0" platEncID="5" length="24" numVarSelectorRecords="3">
|
||||
<map uvs="0xFE00" uv="0x0061" name="BaseChar1_VS1" />
|
||||
<map uvs="0xE0100" uv="0x0061" name="BaseChar1_VS17" />
|
||||
<map uvs="0xE0101" uv="0x0061" name="BaseChar1_VS18" />
|
||||
<map uvs="0xE0102" uv="0x0061" name="None" />
|
||||
|
||||
<map uvs="0xFE01" uv="0x0062" name="BaseChar2_VS2" />
|
||||
<map uvs="0xE0101" uv="0x0062" name="BaseChar2_VS18" />
|
||||
<map uvs="0xE0102" uv="0x0062" name="BaseChar2_VS19" />
|
||||
<map uvs="0xE0103" uv="0x0062" name="None" />
|
||||
|
||||
<map uvs="0xFE02" uv="0x0064" name="BaseChar4_VS3" />
|
||||
<map uvs="0xE0102" uv="0x0064" name="BaseChar4_VS19" />
|
||||
<map uvs="0xE0103" uv="0x0064" name="BaseChar4_VS20" />
|
||||
<!-- There is no default glyph for U+0064 U+E0104 but there is a entry for
|
||||
default UVS entry. hasGlyph should return false in this
|
||||
case. -->
|
||||
<map uvs="0xE0104" uv="0x0064" name="None" />
|
||||
|
||||
<map uvs="0xFE00" uv="0x1F000" name="BaseChar5_VS1" />
|
||||
<map uvs="0xE0100" uv="0x1F000" name="BaseChar5_VS17" />
|
||||
<map uvs="0xE0101" uv="0x1F000" name="BaseChar5_VS18" />
|
||||
<map uvs="0xE0102" uv="0x1F000" name="None" />
|
||||
|
||||
<map uvs="0xFE01" uv="0x1F001" name="BaseChar6_VS2" />
|
||||
<map uvs="0xE0101" uv="0x1F001" name="BaseChar6_VS18" />
|
||||
<map uvs="0xE0102" uv="0x1F001" name="BaseChar6_VS19" />
|
||||
<map uvs="0xE0103" uv="0x1F001" name="None" />
|
||||
|
||||
<map uvs="0xFE02" uv="0x1F003" name="BaseChar8_VS3" />
|
||||
<map uvs="0xE0102" uv="0x1F003" name="BaseChar8_VS19" />
|
||||
<map uvs="0xE0103" uv="0x1F003" name="BaseChar8_VS20" />
|
||||
<!-- There is no default glyph for U+1F003 U+E0104 but there is a entry for
|
||||
default UVS entry. hasGlyph should return false in this
|
||||
case. -->
|
||||
<map uvs="0xE0104" uv="0x1F003" name="None" />
|
||||
</cmap_format_14>
|
||||
</cmap>
|
||||
|
||||
<loca>
|
||||
<!-- The 'loca' table will be calculated by the compiler -->
|
||||
</loca>
|
||||
|
||||
<glyf>
|
||||
|
||||
<!-- The xMin, yMin, xMax and yMax values
|
||||
will be recalculated by the compiler. -->
|
||||
|
||||
<TTGlyph name=".notdef" xMin="0" yMin="0" xMax="0" yMax="0">
|
||||
<contour></contour><instructions><assembly></assembly></instructions>
|
||||
</TTGlyph>
|
||||
|
||||
<TTGlyph name="BaseChar1" xMin="0" yMin="0" xMax="0" yMax="0">
|
||||
<contour></contour><instructions><assembly></assembly></instructions>
|
||||
</TTGlyph>
|
||||
<TTGlyph name="BaseChar1_VS1" xMin="0" yMin="0" xMax="0" yMax="0">
|
||||
<contour></contour><instructions><assembly></assembly></instructions>
|
||||
</TTGlyph>
|
||||
<TTGlyph name="BaseChar1_VS17" xMin="0" yMin="0" xMax="0" yMax="0">
|
||||
<contour></contour><instructions><assembly></assembly></instructions>
|
||||
</TTGlyph>
|
||||
<TTGlyph name="BaseChar1_VS18" xMin="0" yMin="0" xMax="0" yMax="0">
|
||||
<contour></contour><instructions><assembly></assembly></instructions>
|
||||
</TTGlyph>
|
||||
<TTGlyph name="BaseChar2" xMin="0" yMin="0" xMax="0" yMax="0">
|
||||
<contour></contour><instructions><assembly></assembly></instructions>
|
||||
</TTGlyph>
|
||||
<TTGlyph name="BaseChar2_VS2" xMin="0" yMin="0" xMax="0" yMax="0">
|
||||
<contour></contour><instructions><assembly></assembly></instructions>
|
||||
</TTGlyph>
|
||||
<TTGlyph name="BaseChar2_VS18" xMin="0" yMin="0" xMax="0" yMax="0">
|
||||
<contour></contour><instructions><assembly></assembly></instructions>
|
||||
</TTGlyph>
|
||||
<TTGlyph name="BaseChar2_VS19" xMin="0" yMin="0" xMax="0" yMax="0">
|
||||
<contour></contour><instructions><assembly></assembly></instructions>
|
||||
</TTGlyph>
|
||||
<TTGlyph name="BaseChar3" xMin="0" yMin="0" xMax="0" yMax="0">
|
||||
<contour></contour><instructions><assembly></assembly></instructions>
|
||||
</TTGlyph>
|
||||
<TTGlyph name="BaseChar4_VS3" xMin="0" yMin="0" xMax="0" yMax="0">
|
||||
<contour></contour><instructions><assembly></assembly></instructions>
|
||||
</TTGlyph>
|
||||
<TTGlyph name="BaseChar4_VS19" xMin="0" yMin="0" xMax="0" yMax="0">
|
||||
<contour></contour><instructions><assembly></assembly></instructions>
|
||||
</TTGlyph>
|
||||
<TTGlyph name="BaseChar4_VS20" xMin="0" yMin="0" xMax="0" yMax="0">
|
||||
<contour></contour><instructions><assembly></assembly></instructions>
|
||||
</TTGlyph>
|
||||
<TTGlyph name="BaseChar5" xMin="0" yMin="0" xMax="0" yMax="0">
|
||||
<contour></contour><instructions><assembly></assembly></instructions>
|
||||
</TTGlyph>
|
||||
<TTGlyph name="BaseChar5_VS1" xMin="0" yMin="0" xMax="0" yMax="0">
|
||||
<contour></contour><instructions><assembly></assembly></instructions>
|
||||
</TTGlyph>
|
||||
<TTGlyph name="BaseChar5_VS17" xMin="0" yMin="0" xMax="0" yMax="0">
|
||||
<contour></contour><instructions><assembly></assembly></instructions>
|
||||
</TTGlyph>
|
||||
<TTGlyph name="BaseChar5_VS18" xMin="0" yMin="0" xMax="0" yMax="0">
|
||||
<contour></contour><instructions><assembly></assembly></instructions>
|
||||
</TTGlyph>
|
||||
<TTGlyph name="BaseChar6" xMin="0" yMin="0" xMax="0" yMax="0">
|
||||
<contour></contour><instructions><assembly></assembly></instructions>
|
||||
</TTGlyph>
|
||||
<TTGlyph name="BaseChar6_VS2" xMin="0" yMin="0" xMax="0" yMax="0">
|
||||
<contour></contour><instructions><assembly></assembly></instructions>
|
||||
</TTGlyph>
|
||||
<TTGlyph name="BaseChar6_VS18" xMin="0" yMin="0" xMax="0" yMax="0">
|
||||
<contour></contour><instructions><assembly></assembly></instructions>
|
||||
</TTGlyph>
|
||||
<TTGlyph name="BaseChar6_VS19" xMin="0" yMin="0" xMax="0" yMax="0">
|
||||
<contour></contour><instructions><assembly></assembly></instructions>
|
||||
</TTGlyph>
|
||||
<TTGlyph name="BaseChar7" xMin="0" yMin="0" xMax="0" yMax="0">
|
||||
<contour></contour><instructions><assembly></assembly></instructions>
|
||||
</TTGlyph>
|
||||
<TTGlyph name="BaseChar8_VS3" xMin="0" yMin="0" xMax="0" yMax="0">
|
||||
<contour></contour><instructions><assembly></assembly></instructions>
|
||||
</TTGlyph>
|
||||
<TTGlyph name="BaseChar8_VS19" xMin="0" yMin="0" xMax="0" yMax="0">
|
||||
<contour></contour><instructions><assembly></assembly></instructions>
|
||||
</TTGlyph>
|
||||
<TTGlyph name="BaseChar8_VS20" xMin="0" yMin="0" xMax="0" yMax="0">
|
||||
<contour></contour><instructions><assembly></assembly></instructions>
|
||||
</TTGlyph>
|
||||
</glyf>
|
||||
|
||||
<name>
|
||||
<namerecord nameID="1" platformID="1" platEncID="0" langID="0x0" unicode="True">
|
||||
Paint.hasGlyph Test
|
||||
</namerecord>
|
||||
<namerecord nameID="2" platformID="1" platEncID="0" langID="0x0" unicode="True">
|
||||
Regular
|
||||
</namerecord>
|
||||
<namerecord nameID="4" platformID="1" platEncID="0" langID="0x0" unicode="True">
|
||||
Paint.hasGlyph Test
|
||||
</namerecord>
|
||||
<namerecord nameID="6" platformID="1" platEncID="0" langID="0x0" unicode="True">
|
||||
hasGlyphTestFont-Regular
|
||||
</namerecord>
|
||||
<namerecord nameID="1" platformID="3" platEncID="1" langID="0x409">
|
||||
Paint.hasGlyph Test
|
||||
</namerecord>
|
||||
<namerecord nameID="2" platformID="3" platEncID="1" langID="0x409">
|
||||
Regular
|
||||
</namerecord>
|
||||
<namerecord nameID="4" platformID="3" platEncID="1" langID="0x409">
|
||||
hasGlyphTestFont Test
|
||||
</namerecord>
|
||||
<namerecord nameID="6" platformID="3" platEncID="1" langID="0x409">
|
||||
hasGlyphTestFont-Regular
|
||||
</namerecord>
|
||||
</name>
|
||||
|
||||
<post>
|
||||
<formatType value="3.0"/>
|
||||
<italicAngle value="0.0"/>
|
||||
<underlinePosition value="-75"/>
|
||||
<underlineThickness value="50"/>
|
||||
<isFixedPitch value="0"/>
|
||||
<minMemType42 value="0"/>
|
||||
<maxMemType42 value="0"/>
|
||||
<minMemType1 value="0"/>
|
||||
<maxMemType1 value="0"/>
|
||||
</post>
|
||||
|
||||
</ttFont>
|
||||
@@ -20,6 +20,9 @@ import android.graphics.Paint;
|
||||
import android.test.InstrumentationTestCase;
|
||||
import android.test.suitebuilder.annotation.SmallTest;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.HashSet;
|
||||
|
||||
/**
|
||||
* PaintTest tests {@link Paint}.
|
||||
*/
|
||||
@@ -94,4 +97,63 @@ public class PaintTest extends InstrumentationTestCase {
|
||||
testCase.mWidthWithHinting, widths);
|
||||
}
|
||||
}
|
||||
|
||||
private static class HasGlyphTestCase {
|
||||
public final int mBaseCodepoint;
|
||||
public final HashSet<Integer> mVariationSelectors;
|
||||
|
||||
public HasGlyphTestCase(int baseCodepoint, Integer[] variationSelectors) {
|
||||
mBaseCodepoint = baseCodepoint;
|
||||
mVariationSelectors = new HashSet<>(Arrays.asList(variationSelectors));
|
||||
}
|
||||
}
|
||||
|
||||
private static String codePointsToString(int[] codepoints) {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
for (int codepoint : codepoints) {
|
||||
sb.append(Character.toChars(codepoint));
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
public void testHasGlyph_variationSelectors() {
|
||||
final Typeface fontTypeface = Typeface.createFromAsset(
|
||||
getInstrumentation().getContext().getAssets(), "fonts/hasGlyphTestFont.ttf");
|
||||
Paint p = new Paint();
|
||||
p.setTypeface(fontTypeface);
|
||||
|
||||
// Usually latin letters U+0061..U+0064 and Mahjong Tiles U+1F000..U+1F003 don't have
|
||||
// variation selectors. This test may fail if system pre-installed fonts have a variation
|
||||
// selector support for U+0061..U+0064 and U+1F000..U+1F003.
|
||||
HasGlyphTestCase[] HAS_GLYPH_TEST_CASES = {
|
||||
new HasGlyphTestCase(0x0061, new Integer[] {0xFE00, 0xE0100, 0xE0101, 0xE0102}),
|
||||
new HasGlyphTestCase(0x0062, new Integer[] {0xFE01, 0xE0101, 0xE0102, 0xE0103}),
|
||||
new HasGlyphTestCase(0x0063, new Integer[] {}),
|
||||
new HasGlyphTestCase(0x0064, new Integer[] {0xFE02, 0xE0102, 0xE0103}),
|
||||
|
||||
new HasGlyphTestCase(0x1F000, new Integer[] {0xFE00, 0xE0100, 0xE0101, 0xE0102}),
|
||||
new HasGlyphTestCase(0x1F001, new Integer[] {0xFE01, 0xE0101, 0xE0102, 0xE0103}),
|
||||
new HasGlyphTestCase(0x1F002, new Integer[] {}),
|
||||
new HasGlyphTestCase(0x1F003, new Integer[] {0xFE02, 0xE0102, 0xE0103}),
|
||||
};
|
||||
|
||||
for (HasGlyphTestCase testCase : HAS_GLYPH_TEST_CASES) {
|
||||
for (int vs = 0xFE00; vs <= 0xE01EF; ++vs) {
|
||||
// Move to variation selector supplements after variation selectors.
|
||||
if (vs == 0xFF00) {
|
||||
vs = 0xE0100;
|
||||
}
|
||||
final String signature =
|
||||
"hasGlyph(U+" + Integer.toHexString(testCase.mBaseCodepoint) +
|
||||
" U+" + Integer.toHexString(vs) + ")";
|
||||
final String testString =
|
||||
codePointsToString(new int[] {testCase.mBaseCodepoint, vs});
|
||||
if (testCase.mVariationSelectors.contains(vs)) {
|
||||
assertTrue(signature + " is expected to be true", p.hasGlyph(testString));
|
||||
} else {
|
||||
assertFalse(signature + " is expected to be false", p.hasGlyph(testString));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user