// This installs a default typeface (from a hardcoded path) that allows // layouts to work (not crash on null pointer) before the default // typeface is set. // TODO: investigate why layouts are being created before Typeface.java // class initialization. static FontCollection *makeFontCollection() { std::vector<FontFamily *>typefaces; const char *fns[] = { "/system/fonts/Roboto-Regular.ttf", }; FontFamily *family = new FontFamily(); for (size_t i = 0; i < sizeof(fns)/sizeof(fns[0]); i++) { const char *fn = fns[i]; ALOGD("makeFontCollection adding %s", fn); SkTypeface *skFace = SkTypeface::CreateFromFile(fn); if (skFace != NULL) { // TODO: might be a nice optimization to get access to the underlying font // data, but would require us opening the file ourselves and passing that // to the appropriate Create method of SkTypeface. MinikinFont *font = new MinikinFontSkia(skFace, NULL, 0, 0); family->addFont(font); font->Unref(); } else { ALOGE("failed to create font %s", fn); } } typefaces.push_back(family); FontCollection *result = new FontCollection(typefaces); family->Unref(); return result; }
static hb_position_t harfbuzzGetGlyphHorizontalAdvance(hb_font_t* hbFont, void* fontData, hb_codepoint_t glyph, void* userData) { MinikinPaint* paint = reinterpret_cast<MinikinPaint*>(fontData); MinikinFont* font = paint->font; float advance = font->GetHorizontalAdvance(glyph, *paint); return 256 * advance + 0.5; }
static Boolean addSkTypeface( /* [in] */ android::FontFamily* family, /* [in] */ SkTypeface* face) { MinikinFont* minikinFont = new MinikinFontSkia(face); bool result = family->addFont(minikinFont); minikinFont->Unref(); return result ? TRUE : FALSE; }
static hb_bool_t harfbuzzGetGlyph(hb_font_t* hbFont, void* fontData, hb_codepoint_t unicode, hb_codepoint_t variationSelector, hb_codepoint_t* glyph, void* userData) { MinikinPaint* paint = reinterpret_cast<MinikinPaint*>(fontData); MinikinFont* font = paint->font; uint32_t glyph_id; /* HarfBuzz replaces broken input codepoints with (unsigned int) -1. * Skia expects valid Unicode. * Replace invalid codepoints with U+FFFD REPLACEMENT CHARACTER. */ if (unicode > 0x10FFFF) unicode = 0xFFFD; bool ok = font->GetGlyph(unicode, &glyph_id); if (ok) { *glyph = glyph_id; } return ok; }
Boolean FontFamily::NativeAddFontWeightStyle( /* [in] */ Int64 familyPtr, /* [in] */ const String& path, /* [in] */ Int32 weight, /* [in] */ Boolean isItalic) { if (path.IsNull()) { return FALSE; } SkTypeface* face = SkTypeface::CreateFromFile(path.string()); if (face == NULL) { Logger::E(String("FontFamily"), String("addFont failed to create font %s"), path.string()); return FALSE; } android::FontFamily* fontFamily = reinterpret_cast<android::FontFamily*>(familyPtr); MinikinFont* minikinFont = new MinikinFontSkia(face); fontFamily->addFont(minikinFont, android::FontStyle(weight / 100, isItalic)); minikinFont->Unref(); return TRUE; }
hb_blob_t* referenceTable(hb_face_t* face, hb_tag_t tag, void* userData) { MinikinFont* font = reinterpret_cast<MinikinFont*>(userData); size_t length = 0; bool ok = font->GetTable(tag, NULL, &length); if (!ok) { return 0; } char* buffer = reinterpret_cast<char*>(malloc(length)); if (!buffer) { return 0; } ok = font->GetTable(tag, reinterpret_cast<uint8_t*>(buffer), &length); printf("referenceTable %c%c%c%c length=%d %d\n", (tag >>24) & 0xff, (tag>>16)&0xff, (tag>>8)&0xff, tag&0xff, length, ok); if (!ok) { free(buffer); return 0; } return hb_blob_create(const_cast<char*>(buffer), length, HB_MEMORY_MODE_WRITABLE, buffer, free); }