Merge "Make Paint.hasGlyph variation selector aware."

This commit is contained in:
Seigo Nonaka
2015-11-20 05:45:26 +00:00
committed by Android (Google) Code Review
6 changed files with 453 additions and 19 deletions

View File

@@ -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:

View File

@@ -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);

View File

@@ -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(),

Binary file not shown.

View 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>

View File

@@ -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));
}
}
}
}
}