summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRaph Levien <raph@google.com>2014-05-30 23:38:56 -0700
committerRaph Levien <raph@google.com>2014-06-03 17:05:51 -0700
commit448b0fd720d7ba902b9be224a287d08abe3ebea8 (patch)
tree8474d0b8258f84b63a4f17cb96619ae7870cce4d
parent066e8575af64fb452617ac6005de6ccf6509553b (diff)
downloadandroid_frameworks_minikin-448b0fd720d7ba902b9be224a287d08abe3ebea8.tar.gz
android_frameworks_minikin-448b0fd720d7ba902b9be224a287d08abe3ebea8.tar.bz2
android_frameworks_minikin-448b0fd720d7ba902b9be224a287d08abe3ebea8.zip
Support for scaleX and skewX
Adds pseudo-css properties for scaleX and skewX, as well as paint flags, and plumb them through to the MinikinPaint abstraction and to Harfbuzz, to support nontrivial scale and stretch of text. This is the Minikin part of the fix for bug 15186705 "Usability of the suggestion strip in recent OTA's is severely reduced" Change-Id: Ifa60355e086e4691ff92c5d50d84eb7cea0fea95
-rw-r--r--include/minikin/CssParse.h8
-rw-r--r--include/minikin/MinikinFont.h4
-rw-r--r--libs/minikin/CssParse.cpp3
-rw-r--r--libs/minikin/Layout.cpp43
4 files changed, 43 insertions, 15 deletions
diff --git a/include/minikin/CssParse.h b/include/minikin/CssParse.h
index 519056d..ae2aac6 100644
--- a/include/minikin/CssParse.h
+++ b/include/minikin/CssParse.h
@@ -24,24 +24,30 @@ namespace android {
enum CssTag {
unknown,
+ fontScaleX,
fontSize,
+ fontSkewX,
fontStyle,
fontWeight,
cssLang,
minikinBidi,
minikinHinting,
minikinVariant,
+ paintFlags,
};
const std::string cssTagNames[] = {
"unknown",
+ "font-scale-x",
"font-size",
+ "font-skew-x",
"font-style",
"font-weight",
"lang",
"-minikin-bidi",
"-minikin-hinting",
"-minikin-variant",
+ "-paint-flags",
};
class CssValue {
@@ -62,7 +68,7 @@ public:
mType(FLOAT), floatValue(v), mUnits(SCALAR) { }
Type getType() const { return mType; }
double getFloatValue() const { return floatValue; }
- int getIntValue() const { return floatValue; }
+ int32_t getIntValue() const { return floatValue; }
std::string getStringValue() const { return stringValue; }
std::string toString(CssTag tag) const;
void setFloatValue(double v) {
diff --git a/include/minikin/MinikinFont.h b/include/minikin/MinikinFont.h
index dbb89f8..1f6894c 100644
--- a/include/minikin/MinikinFont.h
+++ b/include/minikin/MinikinFont.h
@@ -31,7 +31,9 @@ class MinikinFont;
struct MinikinPaint {
MinikinFont *font;
float size;
- // todo: skew, stretch, hinting
+ float scaleX;
+ float skewX;
+ int32_t paintFlags;
};
struct MinikinRect {
diff --git a/libs/minikin/CssParse.cpp b/libs/minikin/CssParse.cpp
index 5e96007..147f330 100644
--- a/libs/minikin/CssParse.cpp
+++ b/libs/minikin/CssParse.cpp
@@ -37,7 +37,9 @@ static CssTag parseTag(const string str, size_t off, size_t len) {
if (len == 0) return unknown;
char c = str[off];
if (c == 'f') {
+ if (strEqC(str, off, len, "font-scale-x")) return fontScaleX;
if (strEqC(str, off, len, "font-size")) return fontSize;
+ if (strEqC(str, off, len, "font-skew-x")) return fontSkewX;
if (strEqC(str, off, len, "font-weight")) return fontWeight;
if (strEqC(str, off, len, "font-style")) return fontStyle;
} else if (c == 'l') {
@@ -46,6 +48,7 @@ static CssTag parseTag(const string str, size_t off, size_t len) {
if (strEqC(str, off, len, "-minikin-bidi")) return minikinBidi;
if (strEqC(str, off, len, "-minikin-hinting")) return minikinHinting;
if (strEqC(str, off, len, "-minikin-variant")) return minikinVariant;
+ if (strEqC(str, off, len, "-paint-flags")) return paintFlags;
}
return unknown;
}
diff --git a/libs/minikin/Layout.cpp b/libs/minikin/Layout.cpp
index 4028d9e..c13aed8 100644
--- a/libs/minikin/Layout.cpp
+++ b/libs/minikin/Layout.cpp
@@ -63,7 +63,8 @@ public:
LayoutCacheKey(const FontCollection* collection, const MinikinPaint& paint, FontStyle style,
const uint16_t* chars, size_t start, size_t count, size_t nchars, bool dir)
: mStart(start), mCount(count), mId(collection->getId()), mStyle(style),
- mSize(paint.size), mIsRtl(dir) {
+ mSize(paint.size), mScaleX(paint.scaleX), mSkewX(paint.skewX),
+ mPaintFlags(paint.paintFlags), mIsRtl(dir) {
mText.setTo(chars, nchars);
}
bool operator==(const LayoutCacheKey &other) const;
@@ -78,6 +79,9 @@ private:
uint32_t mId; // for the font collection
FontStyle mStyle;
float mSize;
+ float mScaleX;
+ float mSkewX;
+ int mPaintFlags;
bool mIsRtl;
// Note: any fields added to MinikinPaint must also be reflected here.
// TODO: language matching (possibly integrate into style)
@@ -133,13 +137,16 @@ public:
ANDROID_SINGLETON_STATIC_INSTANCE(LayoutEngine);
bool LayoutCacheKey::operator==(const LayoutCacheKey& other) const {
- return mId == other.mId &&
- mStart == other.mStart &&
- mCount == other.mCount &&
- mStyle == other.mStyle &&
- mSize == other.mSize &&
- mIsRtl == other.mIsRtl &&
- mText == other.mText;
+ return mId == other.mId
+ && mStart == other.mStart
+ && mCount == other.mCount
+ && mStyle == other.mStyle
+ && mSize == other.mSize
+ && mScaleX == other.mScaleX
+ && mSkewX == other.mSkewX
+ && mPaintFlags == other.mPaintFlags
+ && mIsRtl == other.mIsRtl
+ && mText == other.mText;
}
hash_t LayoutCacheKey::hash() const {
@@ -148,6 +155,9 @@ hash_t LayoutCacheKey::hash() const {
hash = JenkinsHashMix(hash, mCount);
hash = JenkinsHashMix(hash, hash_type(mStyle));
hash = JenkinsHashMix(hash, hash_type(mSize));
+ hash = JenkinsHashMix(hash, hash_type(mScaleX));
+ hash = JenkinsHashMix(hash, hash_type(mSkewX));
+ hash = JenkinsHashMix(hash, hash_type(mPaintFlags));
hash = JenkinsHashMix(hash, hash_type(mIsRtl));
hash = JenkinsHashMixShorts(hash, mText.string(), mText.size());
return JenkinsHashWhiten(hash);
@@ -502,8 +512,13 @@ void Layout::doLayout(const uint16_t* buf, size_t start, size_t count, size_t bu
ctx.props.parse(css);
ctx.style = styleFromCss(ctx.props);
- double size = ctx.props.value(fontSize).getFloatValue();
- ctx.paint.size = size;
+ ctx.paint.size = ctx.props.value(fontSize).getFloatValue();
+ ctx.paint.scaleX = ctx.props.hasTag(fontScaleX)
+ ? ctx.props.value(fontScaleX).getFloatValue() : 1;
+ ctx.paint.skewX = ctx.props.hasTag(fontSkewX)
+ ? ctx.props.value(fontSkewX).getFloatValue() : 0;
+ ctx.paint.paintFlags = ctx.props.hasTag(paintFlags)
+ ?ctx.props.value(paintFlags).getIntValue() : 0;
int bidiFlags = ctx.props.hasTag(minikinBidi) ? ctx.props.value(minikinBidi).getIntValue() : 0;
bool isRtl = (bidiFlags & kDirection_Mask) != 0;
bool doSingleRun = true;
@@ -635,8 +650,9 @@ void Layout::doLayoutRun(const uint16_t* buf, size_t start, size_t count, size_t
" [" << run.start << ":" << run.end << "]" << std::endl;
#endif
double size = ctx->paint.size;
- hb_font_set_ppem(hbFont, size, size);
- hb_font_set_scale(hbFont, HBFloatToFixed(size), HBFloatToFixed(size));
+ double scaleX = ctx->paint.scaleX;
+ hb_font_set_ppem(hbFont, size * scaleX, size);
+ hb_font_set_scale(hbFont, HBFloatToFixed(size * scaleX), HBFloatToFixed(size));
// TODO: if there are multiple scripts within a font in an RTL run,
// we need to reorder those runs. This is unlikely with our current
@@ -665,7 +681,8 @@ void Layout::doLayoutRun(const uint16_t* buf, size_t start, size_t count, size_t
#endif
hb_codepoint_t glyph_ix = info[i].codepoint;
float xoff = HBFixedToFloat(positions[i].x_offset);
- float yoff = HBFixedToFloat(positions[i].y_offset);
+ float yoff = -HBFixedToFloat(positions[i].y_offset);
+ xoff += yoff * ctx->paint.skewX;
LayoutGlyph glyph = {font_ix, glyph_ix, x + xoff, y + yoff};
mGlyphs.push_back(glyph);
float xAdvance = HBFixedToFloat(positions[i].x_advance);