Don't trust glyph runs in XPS.

In XPS if a glyph is out of range, ignore it. Also resolve the default
font in the new way, removing the last user of SkTypefacePriv.

In PDF handle fonts with zero glyphs correctly.

Rewrite SkBitSet to keep track of its size, move properly, and make it
more obvious when certain checks are actually made instead of relying on
undefined behavior.

Add a test in a GM to ensure we don't draw anything when a glyph is
out of range on all backends.

Fix the DirectWrite SkScalerContext to pass this new test for
consistency.

Bug: chromium:1071311
Change-Id: I2583970bf1425f59d0d64e3dd7d28109991f9ea9
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/286776
Reviewed-by: Herb Derby <herb@google.com>
Commit-Queue: Ben Wagner <bungeman@google.com>
diff --git a/src/pdf/SkPDFDevice.cpp b/src/pdf/SkPDFDevice.cpp
index ea1c8f6..dc55238 100644
--- a/src/pdf/SkPDFDevice.cpp
+++ b/src/pdf/SkPDFDevice.cpp
@@ -868,7 +868,7 @@
 
     ScopedOutputMarkedContentTags mark(fNodeId, fDocument, out);
 
-    const SkGlyphID maxGlyphID = SkToU16(typeface->countGlyphs() - 1);
+    const int numGlyphs = typeface->countGlyphs();
 
     if (clusterator.reversedChars()) {
         out->writeText("/ReversedChars BMC\n");
@@ -920,7 +920,7 @@
         }
         for (; index < glyphLimit; ++index) {
             SkGlyphID gid = glyphIDs[index];
-            if (gid > maxGlyphID) {
+            if (numGlyphs <= gid) {
                 continue;
             }
             SkPoint xy = glyphRun.positions()[index];