summaryrefslogtreecommitdiffstats
path: root/libs/minikin
diff options
context:
space:
mode:
Diffstat (limited to 'libs/minikin')
-rw-r--r--libs/minikin/FontCollection.cpp15
-rw-r--r--libs/minikin/FontFamily.cpp21
-rw-r--r--libs/minikin/Layout.cpp22
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 {