Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1842)

Unified Diff: third_party/WebKit/Source/platform/fonts/Font.cpp

Issue 2598393002: Do not skip ink for ideographic scripts (Closed)
Patch Set: Fix not to compute twice Created 4 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: third_party/WebKit/Source/platform/fonts/Font.cpp
diff --git a/third_party/WebKit/Source/platform/fonts/Font.cpp b/third_party/WebKit/Source/platform/fonts/Font.cpp
index 838080911c8a562cb2cf2ca0061863304cbaf698..035677889b1f68ba97446d4378a75e702b7d2598 100644
--- a/third_party/WebKit/Source/platform/fonts/Font.cpp
+++ b/third_party/WebKit/Source/platform/fonts/Font.cpp
@@ -257,18 +257,25 @@ class GlyphBufferBloberizer {
m_deviceScaleFactor(deviceScaleFactor),
m_hasVerticalOffsets(buffer.hasVerticalOffsets()),
m_index(0),
+ m_endIndex(m_buffer.size()),
m_blobCount(0),
m_rotation(buffer.isEmpty() ? NoRotation : computeBlobRotation(
- buffer.fontDataAt(0))) {}
+ buffer.fontDataAt(0))),
+ m_skipGlyphs(nullptr) {}
- bool done() const { return m_index >= m_buffer.size(); }
+ bool done() const { return m_index >= m_endIndex; }
unsigned blobCount() const { return m_blobCount; }
std::pair<sk_sp<SkTextBlob>, BlobRotation> next() {
ASSERT(!done());
const BlobRotation currentRotation = m_rotation;
- while (m_index < m_buffer.size()) {
+ while (m_index < m_endIndex) {
+ if (m_skipGlyphs) {
+ while (m_index < m_endIndex && (*m_skipGlyphs)[m_index])
+ m_index++;
+ }
+
const SimpleFontData* fontData = m_buffer.fontDataAt(m_index);
ASSERT(fontData);
@@ -282,8 +289,8 @@ class GlyphBufferBloberizer {
}
const unsigned start = m_index++;
- while (m_index < m_buffer.size() &&
- m_buffer.fontDataAt(m_index) == fontData)
+ while (m_index < m_endIndex && m_buffer.fontDataAt(m_index) == fontData &&
+ !(m_skipGlyphs && (*m_skipGlyphs)[m_index]))
m_index++;
appendRun(start, m_index - start, fontData);
@@ -293,6 +300,15 @@ class GlyphBufferBloberizer {
return std::make_pair(m_builder.make(), currentRotation);
}
+ void setSkipGlyphs(const Vector<bool>* skipGlyphs) {
+ m_skipGlyphs = skipGlyphs;
+ m_endIndex = m_buffer.size();
+ if (m_skipGlyphs) {
+ while (m_endIndex > 0 && (*m_skipGlyphs)[m_endIndex - 1])
+ m_endIndex--;
+ }
+ }
+
private:
static BlobRotation computeBlobRotation(const SimpleFontData* font) {
// For vertical upright text we need to compensate the inherited 90deg CW
@@ -343,8 +359,10 @@ class GlyphBufferBloberizer {
SkTextBlobBuilder m_builder;
unsigned m_index;
+ unsigned m_endIndex;
unsigned m_blobCount;
BlobRotation m_rotation;
+ const Vector<bool>* m_skipGlyphs;
};
} // anonymous namespace
@@ -386,14 +404,71 @@ void Font::drawGlyphBuffer(SkCanvas* canvas,
}
}
+static std::unique_ptr<Vector<bool>> glyphsToSkipIntercepts(
+ const TextRun& run,
+ const GlyphBuffer& glyphBuffer) {
+ // Skipping ink leads to undesirable renderings for some scripts. Determine
+ // glyphs not to skip ink on a character-by-character basis.
+ DCHECK(!run.is8Bit());
+ std::unique_ptr<Vector<bool>> skipIndexes =
+ WTF::makeUnique<Vector<bool>>(glyphBuffer.size());
+ bool hasAnySkip = false;
+ for (unsigned index = 0; index < glyphBuffer.size(); index++) {
+ unsigned characterIndex = glyphBuffer.characterIndex(index);
+ UChar32 baseCharacter = run.codepointAt(characterIndex);
drott 2017/01/02 15:07:45 Can we reuse Character::isCJKIdeographOrSymbol for
+ UBlockCode blockCode = ublock_getCode(baseCharacter);
+ switch (blockCode) {
+ case UBLOCK_BOPOMOFO:
+ case UBLOCK_BOPOMOFO_EXTENDED:
+ case UBLOCK_CJK_COMPATIBILITY:
+ case UBLOCK_CJK_COMPATIBILITY_FORMS:
+ case UBLOCK_CJK_COMPATIBILITY_IDEOGRAPHS:
+ case UBLOCK_CJK_COMPATIBILITY_IDEOGRAPHS_SUPPLEMENT:
+ case UBLOCK_CJK_RADICALS_SUPPLEMENT:
+ case UBLOCK_CJK_STROKES:
+ case UBLOCK_CJK_SYMBOLS_AND_PUNCTUATION:
+ case UBLOCK_CJK_UNIFIED_IDEOGRAPHS:
+ case UBLOCK_CJK_UNIFIED_IDEOGRAPHS_EXTENSION_A:
+ case UBLOCK_CJK_UNIFIED_IDEOGRAPHS_EXTENSION_B:
+ case UBLOCK_CJK_UNIFIED_IDEOGRAPHS_EXTENSION_C:
+ case UBLOCK_CJK_UNIFIED_IDEOGRAPHS_EXTENSION_D:
+ case UBLOCK_CJK_UNIFIED_IDEOGRAPHS_EXTENSION_E:
+ case UBLOCK_ENCLOSED_CJK_LETTERS_AND_MONTHS:
+ case UBLOCK_ENCLOSED_IDEOGRAPHIC_SUPPLEMENT:
+ case UBLOCK_HANGUL_COMPATIBILITY_JAMO:
+ case UBLOCK_HANGUL_JAMO:
+ case UBLOCK_HANGUL_JAMO_EXTENDED_A:
+ case UBLOCK_HANGUL_JAMO_EXTENDED_B:
+ case UBLOCK_HANGUL_SYLLABLES:
+ case UBLOCK_HIRAGANA:
+ case UBLOCK_IDEOGRAPHIC_DESCRIPTION_CHARACTERS:
+ case UBLOCK_IDEOGRAPHIC_SYMBOLS_AND_PUNCTUATION:
+ case UBLOCK_KATAKANA:
+ case UBLOCK_LINEAR_B_IDEOGRAMS:
+ case UBLOCK_TANGUT:
+ case UBLOCK_TANGUT_COMPONENTS:
+ (*skipIndexes)[index] = true;
+ hasAnySkip = true;
+ break;
+ default:
+ break;
+ }
+ }
+ if (!hasAnySkip)
+ return nullptr;
+ return skipIndexes;
+}
+
static int getInterceptsFromBloberizer(const GlyphBuffer& glyphBuffer,
const Font* font,
const SkPaint& paint,
float deviceScaleFactor,
const std::tuple<float, float>& bounds,
+ const Vector<bool>* skipGlyphs,
SkScalar* interceptsBuffer) {
SkScalar boundsArray[2] = {std::get<0>(bounds), std::get<1>(bounds)};
GlyphBufferBloberizer bloberizer(glyphBuffer, font, deviceScaleFactor);
+ bloberizer.setSkipGlyphs(skipGlyphs);
std::pair<sk_sp<SkTextBlob>, BlobRotation> blob;
int numIntervals = 0;
@@ -439,20 +514,28 @@ void Font::getTextIntercepts(const TextRunPaintInfo& runInfo,
}
GlyphBuffer glyphBuffer;
- buildGlyphBuffer(runInfo, glyphBuffer);
+ std::unique_ptr<Vector<bool>> skipGlyphs;
+ if (runInfo.run.is8Bit()) {
+ buildGlyphBuffer(runInfo, glyphBuffer);
+ } else {
+ glyphBuffer.saveCharacterIndexes();
+ buildGlyphBuffer(runInfo, glyphBuffer);
+ skipGlyphs = glyphsToSkipIntercepts(runInfo.run, glyphBuffer);
+ }
// Get the number of intervals, without copying the actual values by
// specifying nullptr for the buffer, following the Skia allocation model for
// retrieving text intercepts.
- int numIntervals = getInterceptsFromBloberizer(
- glyphBuffer, this, paint, deviceScaleFactor, bounds, nullptr);
+ int numIntervals =
+ getInterceptsFromBloberizer(glyphBuffer, this, paint, deviceScaleFactor,
+ bounds, skipGlyphs.get(), nullptr);
if (!numIntervals)
return;
DCHECK_EQ(numIntervals % 2, 0);
intercepts.resize(numIntervals / 2);
getInterceptsFromBloberizer(glyphBuffer, this, paint, deviceScaleFactor,
- bounds,
+ bounds, skipGlyphs.get(),
reinterpret_cast<SkScalar*>(intercepts.data()));
}

Powered by Google App Engine
This is Rietveld 408576698