mirror of
https://github.com/flutter/flutter.git
synced 2026-02-20 02:29:02 +08:00
am 23801bf4: Support for scaleX and skewX
* commit '23801bf449e5bfa467729b1a61af324a7afbee19': Support for scaleX and skewX
This commit is contained in:
commit
a367eb1998
@ -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) {
|
||||
|
||||
@ -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 {
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
@ -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);
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user