explicit SkFontStyleSet_Android(const FontFamily& family, const SkTypeface_FreeType::Scanner& scanner) { const SkString* cannonicalFamilyName = NULL; if (family.fNames.count() > 0) { cannonicalFamilyName = &family.fNames[0]; } // TODO? make this lazy for (int i = 0; i < family.fFonts.count(); ++i) { const FontFileInfo& fontFile = family.fFonts[i]; SkString pathName(family.fBasePath); pathName.append(fontFile.fFileName); SkAutoTDelete<SkStream> stream(SkStream::NewFromFile(pathName.c_str())); if (!stream.get()) { SkDEBUGF(("Requested font file %s does not exist or cannot be opened.\n", pathName.c_str())); continue; } const int ttcIndex = fontFile.fIndex; SkString familyName; SkFontStyle style; bool isFixedWidth; if (!scanner.scanFont(stream.get(), ttcIndex, &familyName, &style, &isFixedWidth)) { SkDEBUGF(("Requested font file %s exists, but is not a valid font.\n", pathName.c_str())); continue; } int weight = fontFile.fWeight != 0 ? fontFile.fWeight : style.weight(); SkFontStyle::Slant slant = style.slant(); switch (fontFile.fStyle) { case FontFileInfo::Style::kAuto: slant = style.slant(); break; case FontFileInfo::Style::kNormal: slant = SkFontStyle::kUpright_Slant; break; case FontFileInfo::Style::kItalic: slant = SkFontStyle::kItalic_Slant; break; default: SkASSERT(false); break; } style = SkFontStyle(weight, style.width(), slant); const SkLanguage& lang = family.fLanguage; uint32_t variant = family.fVariant; if (kDefault_FontVariant == variant) { variant = kCompact_FontVariant | kElegant_FontVariant; } // The first specified family name overrides the family name found in the font. // TODO: SkTypeface_AndroidSystem::onCreateFamilyNameIterator should return // all of the specified family names in addition to the names found in the font. if (cannonicalFamilyName != NULL) { familyName = *cannonicalFamilyName; } fStyles.push_back().reset(SkNEW_ARGS(SkTypeface_AndroidSystem, (pathName, ttcIndex, style, isFixedWidth, familyName, lang, variant))); } }
static int match_score(const SkFontStyle& pattern, const SkFontStyle& candidate) { int score = 0; score += SkTAbs((pattern.width() - candidate.width()) * 100); score += SkTAbs((pattern.slant() == candidate.slant()) ? 0 : 1000); score += SkTAbs(pattern.weight() - candidate.weight()); return score; }
sk_sp<SkTypeface> SkTypeface::MakeFromName(const char name[], SkFontStyle fontStyle) { if (gCreateTypefaceDelegate) { sk_sp<SkTypeface> result = (*gCreateTypefaceDelegate)(name, fontStyle); if (result) { return result; } } if (nullptr == name && (fontStyle.slant() == SkFontStyle::kItalic_Slant || fontStyle.slant() == SkFontStyle::kUpright_Slant) && (fontStyle.weight() == SkFontStyle::kBold_Weight || fontStyle.weight() == SkFontStyle::kNormal_Weight)) { return MakeDefault(static_cast<SkTypeface::Style>( (fontStyle.slant() == SkFontStyle::kItalic_Slant ? SkTypeface::kItalic : SkTypeface::kNormal) | (fontStyle.weight() == SkFontStyle::kBold_Weight ? SkTypeface::kBold : SkTypeface::kNormal))); } SkAutoTUnref<SkFontMgr> fm(SkFontMgr::RefDefault()); return sk_sp<SkTypeface>(fm->legacyCreateTypeface(name, fontStyle)); }
explicit DWriteStyle(const SkFontStyle& pattern) { switch (pattern.slant()) { case SkFontStyle::kUpright_Slant: fSlant = DWRITE_FONT_STYLE_NORMAL; break; case SkFontStyle::kItalic_Slant: fSlant = DWRITE_FONT_STYLE_ITALIC; break; default: SkASSERT(false); } fWeight = (DWRITE_FONT_WEIGHT)pattern.weight(); fWidth = (DWRITE_FONT_STRETCH)pattern.width(); }
void SkGlyphCache::dump() const { const SkTypeface* face = fScalerContext->getTypeface(); const SkScalerContextRec& rec = fScalerContext->getRec(); SkMatrix matrix; rec.getSingleMatrix(&matrix); matrix.preScale(SkScalarInvert(rec.fTextSize), SkScalarInvert(rec.fTextSize)); SkString name; face->getFamilyName(&name); SkString msg; SkFontStyle style = face->fontStyle(); msg.printf("cache typeface:%x %25s:(%d,%d,%d)\n %s glyphs:%3d", face->uniqueID(), name.c_str(), style.weight(), style.width(), style.slant(), rec.dump().c_str(), fGlyphMap.count()); SkDebugf("%s\n", msg.c_str()); }
void onDraw(SkCanvas* canvas) override { SkScalar y = 20; SkPaint paint; paint.setAntiAlias(true); paint.setLCDRenderText(true); paint.setSubpixelText(true); paint.setTextSize(17); SkFontMgr* fm = fFM; int count = SkMin32(fm->countFamilies(), MAX_FAMILIES); for (int i = 0; i < count; ++i) { SkString familyName; fm->getFamilyName(i, &familyName); paint.setTypeface(nullptr); (void)drawString(canvas, familyName, 20, y, paint); SkScalar x = 220; SkAutoTUnref<SkFontStyleSet> set(fm->createStyleSet(i)); for (int j = 0; j < set->count(); ++j) { SkString sname; SkFontStyle fs; set->getStyle(j, &fs, &sname); sname.appendf(" [%d %d %d]", fs.weight(), fs.width(), fs.slant()); SkSafeUnref(paint.setTypeface(set->createTypeface(j))); x = drawString(canvas, sname, x, y, paint) + 20; // check to see that we get different glyphs in japanese and chinese x = drawCharacter(canvas, 0x5203, x, y, paint, fm, familyName.c_str(), &zh, 1, fs); x = drawCharacter(canvas, 0x5203, x, y, paint, fm, familyName.c_str(), &ja, 1, fs); // check that emoji characters are found x = drawCharacter(canvas, 0x1f601, x, y, paint, fm, familyName.c_str(), nullptr,0, fs); } y += 24; } }
sk_sp<SkTypeface> create_font(const char* name, SkFontStyle style) { SkTestFontData* fontData = nullptr; const SubFont* sub; if (name) { for (int index = 0; index < gSubFontsCount; ++index) { sub = &gSubFonts[index]; if (!strcmp(name, sub->fName) && sub->fStyle == style) { fontData = &sub->fFont; break; } } if (!fontData) { // Once all legacy callers to portable fonts are converted, replace this with // SK_ABORT(); SkDebugf("missing %s weight %d, width %d, slant %d\n", name, style.weight(), style.width(), style.slant()); // If we called SkTypeface::CreateFromName() here we'd recurse infinitely, // so we reimplement its core logic here inline without the recursive aspect. sk_sp<SkFontMgr> fm(SkFontMgr::RefDefault()); return fm->legacyMakeTypeface(name, style); } } else { sub = &gSubFonts[gDefaultFontIndex]; fontData = &sub->fFont; } sk_sp<SkTestFont> font; { SkAutoMutexAcquire ac(gTestFontMutex); if (fontData->fCachedFont) { font = fontData->fCachedFont; } else { font = sk_make_sp<SkTestFont>(*fontData); fontData->fCachedFont = font; } } return sk_make_sp<SkTestTypeface>(std::move(font), style); }