summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Raph Levien <raph@google.com> 2014-06-06 18:05:22 -0700
committer Raph Levien <raph@google.com> 2014-06-10 11:37:55 -0700
commit1fc0fa87d42ce9268ece76b85b9edc834593e53a (patch)
tree6fc9b25d541dcbc69a9768e3dd9e4c5583c0ef9b
parentdcdce7730b169c61924005bacad91136f7bd07dd (diff)
Support for fake bold in Minikin builds
Part of the fix for bug 15436379 Fake bold doesn't fully work (Minikin) This patch queries the Minikin layout for when fake bold is needed, and applies that to both shaping and drawing paint. Also simplifies refcounting (the lifetime of all MinikinFont objects is subsumed by the enclosing FontCollection). Note: the fake bold flag set by the user is ignored in this patch. Fake italics would be possible using the same mechanism, but it's slightly more complicated (fake and user-set textSkewX values would need to be combined, and the latter restored after drawing). Change-Id: Ica2c4604846cbb37e5a783778b18d8993c9d4563
-rw-r--r--core/jni/android/graphics/Canvas.cpp5
-rw-r--r--core/jni/android/graphics/MinikinSkia.cpp17
-rw-r--r--core/jni/android/graphics/MinikinSkia.h5
-rw-r--r--core/jni/android/graphics/MinikinUtils.h19
-rw-r--r--core/jni/android/graphics/Paint.cpp9
-rw-r--r--core/jni/android/graphics/TypefaceImpl.cpp2
-rw-r--r--core/jni/android_view_GLES20Canvas.cpp5
7 files changed, 35 insertions, 27 deletions
diff --git a/core/jni/android/graphics/Canvas.cpp b/core/jni/android/graphics/Canvas.cpp
index 8b75e7dbdd16..3b44f97a0f8e 100644
--- a/core/jni/android/graphics/Canvas.cpp
+++ b/core/jni/android/graphics/Canvas.cpp
@@ -776,13 +776,12 @@ public:
: layout(layout), canvas(canvas), x(x), y(y), paint(paint), glyphs(glyphs),
pos(pos) { }
- void operator()(SkTypeface* t, size_t start, size_t end) {
+ void operator()(size_t start, size_t end) {
for (size_t i = start; i < end; i++) {
glyphs[i] = layout.getGlyphId(i);
pos[i].fX = x + layout.getX(i);
pos[i].fY = y + layout.getY(i);
}
- paint->setTypeface(t);
canvas->drawPosText(glyphs + start, (end - start) << 1, pos + start, *paint);
}
private:
@@ -805,7 +804,7 @@ public:
paint->setTextAlign(SkPaint::kLeft_Align);
paint->setTextEncoding(SkPaint::kGlyphID_TextEncoding);
DrawTextFunctor f(layout, canvas, x, y, paint, glyphs, pos);
- MinikinUtils::forFontRun(layout, f);
+ MinikinUtils::forFontRun(layout, paint, f);
doDrawTextDecorations(canvas, x, y, layout.getAdvance(), paint);
paint->setTextAlign(align);
delete[] glyphs;
diff --git a/core/jni/android/graphics/MinikinSkia.cpp b/core/jni/android/graphics/MinikinSkia.cpp
index 2b96f1b66104..a0796c626023 100644
--- a/core/jni/android/graphics/MinikinSkia.cpp
+++ b/core/jni/android/graphics/MinikinSkia.cpp
@@ -43,13 +43,14 @@ bool MinikinFontSkia::GetGlyph(uint32_t codepoint, uint32_t *glyph) const {
return !!glyph;
}
-static void MinikinFontSkia_SetSkiaPaint(SkTypeface* typeface, SkPaint* skPaint, const MinikinPaint& paint) {
- skPaint->setTypeface(typeface);
+static void MinikinFontSkia_SetSkiaPaint(const MinikinFont* font, SkPaint* skPaint, const MinikinPaint& paint) {
skPaint->setTextEncoding(SkPaint::kGlyphID_TextEncoding);
skPaint->setTextSize(paint.size);
skPaint->setTextScaleX(paint.scaleX);
skPaint->setTextSkewX(paint.skewX);
MinikinFontSkia::unpackPaintFlags(skPaint, paint.paintFlags);
+ // Apply font fakery on top of user-supplied flags.
+ MinikinFontSkia::populateSkPaint(skPaint, font, paint.fakery);
}
float MinikinFontSkia::GetHorizontalAdvance(uint32_t glyph_id,
@@ -57,7 +58,7 @@ float MinikinFontSkia::GetHorizontalAdvance(uint32_t glyph_id,
SkPaint skPaint;
uint16_t glyph16 = glyph_id;
SkScalar skWidth;
- MinikinFontSkia_SetSkiaPaint(mTypeface, &skPaint, paint);
+ MinikinFontSkia_SetSkiaPaint(this, &skPaint, paint);
skPaint.getTextWidths(&glyph16, sizeof(glyph16), &skWidth, NULL);
#ifdef VERBOSE
ALOGD("width for typeface %d glyph %d = %f", mTypeface->uniqueID(), glyph_id, skWidth);
@@ -70,7 +71,7 @@ void MinikinFontSkia::GetBounds(MinikinRect* bounds, uint32_t glyph_id,
SkPaint skPaint;
uint16_t glyph16 = glyph_id;
SkRect skBounds;
- MinikinFontSkia_SetSkiaPaint(mTypeface, &skPaint, paint);
+ MinikinFontSkia_SetSkiaPaint(this, &skPaint, paint);
skPaint.getTextWidths(&glyph16, sizeof(glyph16), NULL, &skBounds);
bounds->mLeft = skBounds.fLeft;
bounds->mTop = skBounds.fTop;
@@ -90,7 +91,7 @@ bool MinikinFontSkia::GetTable(uint32_t tag, uint8_t *buf, size_t *size) {
}
}
-SkTypeface *MinikinFontSkia::GetSkTypeface() {
+SkTypeface *MinikinFontSkia::GetSkTypeface() const {
return mTypeface;
}
@@ -115,4 +116,10 @@ void MinikinFontSkia::unpackPaintFlags(SkPaint* paint, uint32_t paintFlags) {
paint->setHinting(static_cast<SkPaint::Hinting>(paintFlags >> 16));
}
+void MinikinFontSkia::populateSkPaint(SkPaint* paint, const MinikinFont* font, FontFakery fakery) {
+ paint->setTypeface(reinterpret_cast<const MinikinFontSkia*>(font)->GetSkTypeface());
+ paint->setFakeBoldText(fakery.isFakeBold());
+ // TODO: fake italics
+}
+
}
diff --git a/core/jni/android/graphics/MinikinSkia.h b/core/jni/android/graphics/MinikinSkia.h
index 0452c57ed2fd..ac4d2a08ef43 100644
--- a/core/jni/android/graphics/MinikinSkia.h
+++ b/core/jni/android/graphics/MinikinSkia.h
@@ -36,10 +36,13 @@ public:
int32_t GetUniqueId() const;
- SkTypeface *GetSkTypeface();
+ SkTypeface* GetSkTypeface() const;
static uint32_t packPaintFlags(const SkPaint* paint);
static void unpackPaintFlags(SkPaint* paint, uint32_t paintFlags);
+
+ // set typeface and fake bold/italic parameters
+ static void populateSkPaint(SkPaint* paint, const MinikinFont* font, FontFakery fakery);
private:
SkTypeface *mTypeface;
};
diff --git a/core/jni/android/graphics/MinikinUtils.h b/core/jni/android/graphics/MinikinUtils.h
index ea7eb5d69e7c..47ab6166c18e 100644
--- a/core/jni/android/graphics/MinikinUtils.h
+++ b/core/jni/android/graphics/MinikinUtils.h
@@ -36,23 +36,24 @@ public:
static float xOffsetForTextAlign(SkPaint* paint, const Layout& layout);
- // f is a functor of type void f(SkTypeface *, size_t start, size_t end);
+ // f is a functor of type void f(size_t start, size_t end);
template <typename F>
- static void forFontRun(const Layout& layout, F& f) {
- SkTypeface* lastFace = NULL;
+ static void forFontRun(const Layout& layout, SkPaint* paint, F& f) {
+ MinikinFont* curFont = NULL;
size_t start = 0;
size_t nGlyphs = layout.nGlyphs();
for (size_t i = 0; i < nGlyphs; i++) {
- MinikinFontSkia* mfs = static_cast<MinikinFontSkia*>(layout.getFont(i));
- SkTypeface* skFace = mfs->GetSkTypeface();
- if (i > 0 && skFace != lastFace) {
- f(lastFace, start, i);
+ MinikinFont* nextFont = layout.getFont(i);
+ if (i > 0 && nextFont != curFont) {
+ MinikinFontSkia::populateSkPaint(paint, curFont, layout.getFakery(start));
+ f(start, i);
start = i;
}
- lastFace = skFace;
+ curFont = nextFont;
}
if (nGlyphs > start) {
- f(lastFace, start, nGlyphs);
+ MinikinFontSkia::populateSkPaint(paint, curFont, layout.getFakery(start));
+ f(start, nGlyphs);
}
}
};
diff --git a/core/jni/android/graphics/Paint.cpp b/core/jni/android/graphics/Paint.cpp
index 24731ac0bd45..74f7085d5913 100644
--- a/core/jni/android/graphics/Paint.cpp
+++ b/core/jni/android/graphics/Paint.cpp
@@ -439,8 +439,8 @@ public:
#ifdef USE_MINIKIN
TypefaceImpl* typeface = GraphicsJNI::getNativeTypeface(env, jpaint);
typeface = TypefaceImpl_resolveDefault(typeface);
- MinikinFont* baseFont = typeface->fFontCollection->baseFont(typeface->fStyle);
- paint->setTypeface(reinterpret_cast<MinikinFontSkia*>(baseFont)->GetSkTypeface());
+ FakedFont baseFont = typeface->fFontCollection->baseFontFaked(typeface->fStyle);
+ MinikinFontSkia::populateSkPaint(paint, baseFont.font, baseFont.fakery);
#endif
SkScalar spacing = paint->getFontMetrics(metrics);
SkPaintOptionsAndroid paintOpts = paint->getPaintOptionsAndroid();
@@ -837,13 +837,12 @@ public:
: layout(layout), path(path), x(x), y(y), paint(paint), glyphs(glyphs), pos(pos) {
}
- void operator()(SkTypeface* t, size_t start, size_t end) {
+ void operator()(size_t start, size_t end) {
for (size_t i = start; i < end; i++) {
glyphs[i] = layout.getGlyphId(i);
pos[i].fX = x + layout.getX(i);
pos[i].fY = y + layout.getY(i);
}
- paint->setTypeface(t);
if (start == 0) {
paint->getPosTextPath(glyphs + start, (end - start) << 1, pos + start, path);
} else {
@@ -878,7 +877,7 @@ public:
paint->setTextAlign(SkPaint::kLeft_Align);
paint->setTextEncoding(SkPaint::kGlyphID_TextEncoding);
GetTextFunctor f(layout, path, x, y, paint, glyphs, pos);
- MinikinUtils::forFontRun(layout, f);
+ MinikinUtils::forFontRun(layout, paint, f);
paint->setTextAlign(align);
delete[] glyphs;
delete[] pos;
diff --git a/core/jni/android/graphics/TypefaceImpl.cpp b/core/jni/android/graphics/TypefaceImpl.cpp
index 27df7cf0e215..1800d0c841f9 100644
--- a/core/jni/android/graphics/TypefaceImpl.cpp
+++ b/core/jni/android/graphics/TypefaceImpl.cpp
@@ -173,7 +173,7 @@ TypefaceImpl* TypefaceImpl_createFromFamilies(const jlong* families, size_t size
} else {
const FontStyle defaultStyle;
FontFamily* firstFamily = reinterpret_cast<FontFamily*>(families[0]);
- MinikinFont* mf = firstFamily->getClosestMatch(defaultStyle);
+ MinikinFont* mf = firstFamily->getClosestMatch(defaultStyle).font;
SkTypeface* skTypeface = reinterpret_cast<MinikinFontSkia*>(mf)->GetSkTypeface();
// TODO: probably better to query more precise style from family, will be important
// when we open up API to access 100..900 weights
diff --git a/core/jni/android_view_GLES20Canvas.cpp b/core/jni/android_view_GLES20Canvas.cpp
index 33fd346488e4..9fa5ec93af35 100644
--- a/core/jni/android_view_GLES20Canvas.cpp
+++ b/core/jni/android_view_GLES20Canvas.cpp
@@ -599,13 +599,12 @@ public:
uirenderer::Rect& bounds)
: layout(layout), renderer(renderer), x(x), y(y), paint(paint), glyphs(glyphs),
pos(pos), totalAdvance(totalAdvance), bounds(bounds) { }
- void operator()(SkTypeface* t, size_t start, size_t end) {
+ void operator()(size_t start, size_t end) {
for (size_t i = start; i < end; i++) {
glyphs[i] = layout.getGlyphId(i);
pos[2 * i] = layout.getX(i);
pos[2 * i + 1] = layout.getY(i);
}
- paint->setTypeface(t);
size_t glyphsCount = end - start;
int bytesCount = glyphsCount * sizeof(jchar);
renderer->drawText((const char*) (glyphs + start), bytesCount, glyphsCount,
@@ -635,7 +634,7 @@ static void renderTextLayout(OpenGLRenderer* renderer, Layout* layout,
float totalAdvance = layout->getAdvance();
RenderTextFunctor f(*layout, renderer, x, y, paint, glyphs, pos, totalAdvance, bounds);
- MinikinUtils::forFontRun(*layout, f);
+ MinikinUtils::forFontRun(*layout, paint, f);
delete[] glyphs;
delete[] pos;
}