Glyph SimpleFontData::glyphForCharacter(UChar32 codepoint) const { uint16_t glyph; SkTypeface* typeface = platformData().typeface(); RELEASE_ASSERT(typeface); typeface->charsToGlyphs(&codepoint, SkTypeface::kUTF32_Encoding, &glyph, 1); return glyph; }
bool SimpleFontData::fillGlyphPage(GlyphPage* pageToFill, unsigned offset, unsigned length, UChar* buffer, unsigned bufferLength) const { if (U16_IS_LEAD(buffer[bufferLength - 1])) { SkDebugf("%s last char is high-surrogate", __FUNCTION__); return false; } SkAutoSTMalloc<GlyphPage::size, uint16_t> glyphStorage(length); uint16_t* glyphs = glyphStorage.get(); SkTypeface* typeface = platformData().typeface(); typeface->charsToGlyphs(buffer, SkTypeface::kUTF16_Encoding, glyphs, length); bool haveGlyphs = false; for (unsigned i = 0; i < length; i++) { if (glyphs[i]) { pageToFill->setGlyphDataForIndex(offset + i, glyphs[i], this); haveGlyphs = true; } } return haveGlyphs; }
bool SimpleFontData::fillGlyphPage(GlyphPage* pageToFill, unsigned offset, unsigned length, UChar* buffer, unsigned bufferLength) const { if (U16_IS_LEAD(buffer[bufferLength-1])) { DLOG(ERROR) << "Last UTF-16 code unit is high-surrogate."; return false; } SkTypeface* typeface = platformData().typeface(); if (!typeface) { DLOG(ERROR) << "fillGlyphPage called on an empty Skia typeface."; return false; } SkAutoSTMalloc<GlyphPage::size, uint16_t> glyphStorage(length); uint16_t* glyphs = glyphStorage.get(); typeface->charsToGlyphs(buffer, SkTypeface::kUTF16_Encoding, glyphs, length); bool haveGlyphs = false; for (unsigned i = 0; i < length; i++) { if (glyphs[i]) { pageToFill->setGlyphDataForIndex(offset + i, glyphs[i], this); haveGlyphs = true; } } return haveGlyphs; }
static void charsToGlyphsNull_proc(int loops, const SkPaint& paint, const void* text, size_t len, int glyphCount) { SkTypeface::Encoding encoding = paint2Encoding(paint); SkTypeface* face = paint.getTypeface(); for (int i = 0; i < loops; ++i) { face->charsToGlyphs(text, encoding, NULL, glyphCount); } }
DEF_TEST(Paint_cmap, reporter) { // need to implement charsToGlyphs on other backends (e.g. linux, win) // before we can run this tests everywhere return; static const int NGLYPHS = 64; SkUnichar src[NGLYPHS]; SkUnichar dst[NGLYPHS]; // used for utf8, utf16, utf32 storage static const struct { size_t (*fSeedTextProc)(const SkUnichar[], void* dst, int count); SkPaint::TextEncoding fEncoding; } gRec[] = { { uni_to_utf8, SkPaint::kUTF8_TextEncoding }, { uni_to_utf16, SkPaint::kUTF16_TextEncoding }, { uni_to_utf32, SkPaint::kUTF32_TextEncoding }, }; SkRandom rand; SkPaint paint; paint.setTypeface(SkTypeface::RefDefault())->unref(); SkTypeface* face = paint.getTypeface(); for (int i = 0; i < 1000; ++i) { // generate some random text for (int j = 0; j < NGLYPHS; ++j) { src[j] = ' ' + j; } // inject some random chars, to sometimes abort early src[rand.nextU() & 63] = rand.nextU() & 0xFFF; for (size_t k = 0; k < SK_ARRAY_COUNT(gRec); ++k) { paint.setTextEncoding(gRec[k].fEncoding); size_t len = gRec[k].fSeedTextProc(src, dst, NGLYPHS); uint16_t glyphs0[NGLYPHS], glyphs1[NGLYPHS]; bool contains = paint.containsText(dst, len); int nglyphs = paint.textToGlyphs(dst, len, glyphs0); int first = face->charsToGlyphs(dst, paint2encoding(paint), glyphs1, NGLYPHS); int index = find_first_zero(glyphs1, NGLYPHS); REPORTER_ASSERT(reporter, NGLYPHS == nglyphs); REPORTER_ASSERT(reporter, index == first); REPORTER_ASSERT(reporter, 0 == memcmp(glyphs0, glyphs1, NGLYPHS * sizeof(uint16_t))); if (contains) { REPORTER_ASSERT(reporter, NGLYPHS == first); } else { REPORTER_ASSERT(reporter, NGLYPHS > first); } } } }
static void charsToGlyphs_proc(int loops, const SkPaint& paint, const void* text, size_t len, int glyphCount) { SkTypeface::Encoding encoding = paint2Encoding(paint); uint16_t glyphs[NGLYPHS]; SkASSERT(glyphCount <= NGLYPHS); SkTypeface* face = paint.getTypeface(); for (int i = 0; i < loops; ++i) { face->charsToGlyphs(text, encoding, glyphs, glyphCount); } }