diff options
Diffstat (limited to 'libs/minikin')
-rw-r--r-- | libs/minikin/FontCollection.cpp | 15 | ||||
-rw-r--r-- | libs/minikin/FontFamily.cpp | 21 | ||||
-rw-r--r-- | libs/minikin/Layout.cpp | 22 |
3 files changed, 40 insertions, 18 deletions
diff --git a/libs/minikin/FontCollection.cpp b/libs/minikin/FontCollection.cpp index c13670e..6115ecc 100644 --- a/libs/minikin/FontCollection.cpp +++ b/libs/minikin/FontCollection.cpp @@ -52,7 +52,7 @@ FontCollection::FontCollection(const vector<FontFamily*>& typefaces) : FontInstance* instance = &mInstances.back(); instance->mFamily = family; instance->mCoverage = new SparseBitSet; - MinikinFont* typeface = family->getClosestMatch(defaultStyle); + MinikinFont* typeface = family->getClosestMatch(defaultStyle).font; if (typeface == NULL) { ALOGE("FontCollection: closest match was null"); // TODO: we shouldn't hit this, as there should be more robust @@ -171,11 +171,9 @@ void FontCollection::itemize(const uint16_t *string, size_t string_size, FontSty result->push_back(dummy); run = &result->back(); if (instance == NULL) { - run->font = NULL; // maybe we should do something different here + run->fakedFont.font = NULL; } else { - run->font = instance->mFamily->getClosestMatch(style); - // TODO: simplify refcounting (FontCollection lifetime dominates) - run->font->RefLocked(); + run->fakedFont = instance->mFamily->getClosestMatch(style); } lastInstance = instance; run->start = i; @@ -186,13 +184,16 @@ void FontCollection::itemize(const uint16_t *string, size_t string_size, FontSty } MinikinFont* FontCollection::baseFont(FontStyle style) { + return baseFontFaked(style).font; +} + +FakedFont FontCollection::baseFontFaked(FontStyle style) { if (mInstances.empty()) { - return NULL; + return FakedFont(); } return mInstances[0].mFamily->getClosestMatch(style); } - uint32_t FontCollection::getId() const { return mId; } diff --git a/libs/minikin/FontFamily.cpp b/libs/minikin/FontFamily.cpp index 0fb98ae..9106f63 100644 --- a/libs/minikin/FontFamily.cpp +++ b/libs/minikin/FontFamily.cpp @@ -109,7 +109,7 @@ void FontFamily::addFontLocked(MinikinFont* typeface, FontStyle style) { type } // Compute a matching metric between two styles - 0 is an exact match -int computeMatch(FontStyle style1, FontStyle style2) { +static int computeMatch(FontStyle style1, FontStyle style2) { if (style1 == style2) return 0; int score = abs(style1.getWeight() - style2.getWeight()); if (style1.getItalic() != style2.getItalic()) { @@ -118,7 +118,15 @@ int computeMatch(FontStyle style1, FontStyle style2) { return score; } -MinikinFont* FontFamily::getClosestMatch(FontStyle style) const { +static FontFakery computeFakery(FontStyle wanted, FontStyle actual) { + // If desired weight is 2 or more grades higher than actual + // (for example, medium 500 -> bold 700), then select fake bold. + bool isFakeBold = (wanted.getWeight() - actual.getWeight()) >= 2; + bool isFakeItalic = wanted.getItalic() && !actual.getItalic(); + return FontFakery(isFakeBold, isFakeItalic); +} + +FakedFont FontFamily::getClosestMatch(FontStyle style) const { const Font* bestFont = NULL; int bestMatch = 0; for (size_t i = 0; i < mFonts.size(); i++) { @@ -129,7 +137,14 @@ MinikinFont* FontFamily::getClosestMatch(FontStyle style) const { bestMatch = match; } } - return bestFont == NULL ? NULL : bestFont->typeface; + FakedFont result; + if (bestFont == NULL) { + result.font = NULL; + } else { + result.font = bestFont->typeface; + result.fakery = computeFakery(style, bestFont->style); + } + return result; } size_t FontFamily::getNumFonts() const { diff --git a/libs/minikin/Layout.cpp b/libs/minikin/Layout.cpp index 3cab673..709393d 100644 --- a/libs/minikin/Layout.cpp +++ b/libs/minikin/Layout.cpp @@ -328,10 +328,10 @@ void Layout::dump() const { } } -int Layout::findFace(MinikinFont* face, LayoutContext* ctx) { +int Layout::findFace(FakedFont face, LayoutContext* ctx) { unsigned int ix; for (ix = 0; ix < mFaces.size(); ix++) { - if (mFaces[ix] == face) { + if (mFaces[ix].font == face.font) { return ix; } } @@ -339,7 +339,7 @@ int Layout::findFace(MinikinFont* face, LayoutContext* ctx) { // Note: ctx == NULL means we're copying from the cache, no need to create // corresponding hb_font object. if (ctx != NULL) { - hb_font_t* font = create_hb_font(face, &ctx->paint); + hb_font_t* font = create_hb_font(face.font, &ctx->paint); ctx->hbFonts.push_back(font); } return ix; @@ -631,12 +631,13 @@ void Layout::doLayoutRun(const uint16_t* buf, size_t start, size_t count, size_t float y = 0; for (size_t run_ix = 0; run_ix < items.size(); run_ix++) { FontCollection::Run &run = items[run_ix]; - if (run.font == NULL) { + if (run.fakedFont.font == NULL) { ALOGE("no font for run starting u+%04x length %d", buf[run.start], run.end - run.start); continue; } - int font_ix = findFace(run.font, ctx); - ctx->paint.font = mFaces[font_ix]; + int font_ix = findFace(run.fakedFont, ctx); + ctx->paint.font = mFaces[font_ix].font; + ctx->paint.fakery = mFaces[font_ix].fakery; hb_font_t* hbFont = ctx->hbFonts[font_ix]; #ifdef VERBOSE std::cout << "Run " << run_ix << ", font " << font_ix << @@ -729,7 +730,7 @@ void Layout::draw(Bitmap* surface, int x0, int y0, float size) const { */ for (size_t i = 0; i < mGlyphs.size(); i++) { const LayoutGlyph& glyph = mGlyphs[i]; - MinikinFont* mf = mFaces[glyph.font_ix]; + MinikinFont* mf = mFaces[glyph.font_ix].font; MinikinFontFreeType* face = static_cast<MinikinFontFreeType*>(mf); GlyphBitmap glyphBitmap; MinikinPaint paint; @@ -754,7 +755,12 @@ size_t Layout::nGlyphs() const { MinikinFont* Layout::getFont(int i) const { const LayoutGlyph& glyph = mGlyphs[i]; - return mFaces[glyph.font_ix]; + return mFaces[glyph.font_ix].font; +} + +FontFakery Layout::getFakery(int i) const { + const LayoutGlyph& glyph = mGlyphs[i]; + return mFaces[glyph.font_ix].fakery; } unsigned int Layout::getGlyphId(int i) const { |