forked from firka/flutter
Support for context in API
This patch completes support for adding context for complex script layout, for example when a string with joins straddles two spans. Part of the fix for 15431028: "Properly support context for joining scripts (Minikin)" Change-Id: I65b0833be92eb477aa531bbef0ac6eddeb3a962a
This commit is contained in:
@@ -105,7 +105,7 @@ private:
|
|||||||
|
|
||||||
// Lay out a single bidi run
|
// Lay out a single bidi run
|
||||||
void doLayoutRunCached(const uint16_t* buf, size_t start, size_t count, size_t bufSize,
|
void doLayoutRunCached(const uint16_t* buf, size_t start, size_t count, size_t bufSize,
|
||||||
bool isRtl, LayoutContext* ctx);
|
bool isRtl, LayoutContext* ctx, size_t dstStart);
|
||||||
|
|
||||||
// Lay out a single word
|
// Lay out a single word
|
||||||
void doLayoutWord(const uint16_t* buf, size_t start, size_t count, size_t bufSize,
|
void doLayoutWord(const uint16_t* buf, size_t start, size_t count, size_t bufSize,
|
||||||
|
|||||||
@@ -485,17 +485,6 @@ void Layout::doLayout(const uint16_t* buf, size_t nchars) {
|
|||||||
doLayout(buf, 0, nchars, nchars, mCssString);
|
doLayout(buf, 0, nchars, nchars, mCssString);
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: use some standard implementation
|
|
||||||
template<typename T>
|
|
||||||
static T mymin(const T& a, const T& b) {
|
|
||||||
return a < b ? a : b;
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
static T mymax(const T& a, const T& b) {
|
|
||||||
return a > b ? a : b;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void clearHbFonts(LayoutContext* ctx) {
|
static void clearHbFonts(LayoutContext* ctx) {
|
||||||
for (size_t i = 0; i < ctx->hbFonts.size(); i++) {
|
for (size_t i = 0; i < ctx->hbFonts.size(); i++) {
|
||||||
hb_font_destroy(ctx->hbFonts[i]);
|
hb_font_destroy(ctx->hbFonts[i]);
|
||||||
@@ -503,7 +492,6 @@ static void clearHbFonts(LayoutContext* ctx) {
|
|||||||
ctx->hbFonts.clear();
|
ctx->hbFonts.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: API should probably take context
|
|
||||||
void Layout::doLayout(const uint16_t* buf, size_t start, size_t count, size_t bufSize,
|
void Layout::doLayout(const uint16_t* buf, size_t start, size_t count, size_t bufSize,
|
||||||
const string& css) {
|
const string& css) {
|
||||||
AutoMutex _l(gMinikinLock);
|
AutoMutex _l(gMinikinLock);
|
||||||
@@ -560,9 +548,14 @@ void Layout::doLayout(const uint16_t* buf, size_t start, size_t count, size_t bu
|
|||||||
// skip the invalid run
|
// skip the invalid run
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
isRtl = (runDir == UBIDI_RTL);
|
int32_t endRun = std::min(startRun + lengthRun, int32_t(start + count));
|
||||||
// TODO: min/max with context
|
startRun = std::max(startRun, int32_t(start));
|
||||||
doLayoutRunCached(buf, startRun, lengthRun, bufSize, isRtl, &ctx);
|
lengthRun = endRun - startRun;
|
||||||
|
if (lengthRun > 0) {
|
||||||
|
isRtl = (runDir == UBIDI_RTL);
|
||||||
|
doLayoutRunCached(buf, startRun, lengthRun, bufSize, isRtl, &ctx,
|
||||||
|
start);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@@ -574,22 +567,22 @@ void Layout::doLayout(const uint16_t* buf, size_t start, size_t count, size_t bu
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (doSingleRun) {
|
if (doSingleRun) {
|
||||||
doLayoutRunCached(buf, start, count, bufSize, isRtl, &ctx);
|
doLayoutRunCached(buf, start, count, bufSize, isRtl, &ctx, start);
|
||||||
}
|
}
|
||||||
clearHbFonts(&ctx);
|
clearHbFonts(&ctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Layout::doLayoutRunCached(const uint16_t* buf, size_t start, size_t count, size_t bufSize,
|
void Layout::doLayoutRunCached(const uint16_t* buf, size_t start, size_t count, size_t bufSize,
|
||||||
bool isRtl, LayoutContext* ctx) {
|
bool isRtl, LayoutContext* ctx, size_t dstStart) {
|
||||||
if (!isRtl) {
|
if (!isRtl) {
|
||||||
// left to right
|
// left to right
|
||||||
size_t wordstart = start == bufSize ? start : getPrevWordBreak(buf, start + 1);
|
size_t wordstart = start == bufSize ? start : getPrevWordBreak(buf, start + 1);
|
||||||
size_t wordend;
|
size_t wordend;
|
||||||
for (size_t iter = start; iter < start + count; iter = wordend) {
|
for (size_t iter = start; iter < start + count; iter = wordend) {
|
||||||
wordend = getNextWordBreak(buf, iter, bufSize);
|
wordend = getNextWordBreak(buf, iter, bufSize);
|
||||||
size_t wordcount = mymin(start + count, wordend) - iter;
|
size_t wordcount = std::min(start + count, wordend) - iter;
|
||||||
doLayoutWord(buf + wordstart, iter - wordstart, wordcount, wordend - wordstart,
|
doLayoutWord(buf + wordstart, iter - wordstart, wordcount, wordend - wordstart,
|
||||||
isRtl, ctx, iter);
|
isRtl, ctx, iter - dstStart);
|
||||||
wordstart = wordend;
|
wordstart = wordend;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@@ -599,9 +592,9 @@ void Layout::doLayoutRunCached(const uint16_t* buf, size_t start, size_t count,
|
|||||||
size_t wordend = end == 0 ? 0 : getNextWordBreak(buf, end - 1, bufSize);
|
size_t wordend = end == 0 ? 0 : getNextWordBreak(buf, end - 1, bufSize);
|
||||||
for (size_t iter = end; iter > start; iter = wordstart) {
|
for (size_t iter = end; iter > start; iter = wordstart) {
|
||||||
wordstart = getPrevWordBreak(buf, iter);
|
wordstart = getPrevWordBreak(buf, iter);
|
||||||
size_t bufStart = mymax(start, wordstart);
|
size_t bufStart = std::max(start, wordstart);
|
||||||
doLayoutWord(buf + wordstart, bufStart - wordstart, iter - bufStart,
|
doLayoutWord(buf + wordstart, bufStart - wordstart, iter - bufStart,
|
||||||
wordend - wordstart, isRtl, ctx, bufStart);
|
wordend - wordstart, isRtl, ctx, bufStart - dstStart);
|
||||||
wordend = wordstart;
|
wordend = wordstart;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user