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

Unified Diff: third_party/WebKit/Source/platform/fonts/shaping/ShapeResult.cpp

Issue 1561633002: Relocate ShapeResult's GlyphBuffer helpers to ShapeResultBuffer (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: rebased Created 4 years, 11 months 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/shaping/ShapeResult.cpp
diff --git a/third_party/WebKit/Source/platform/fonts/shaping/ShapeResult.cpp b/third_party/WebKit/Source/platform/fonts/shaping/ShapeResult.cpp
index 692c0a21c302bd354a4d127d421f1b79a0e5d9db..538bef547b051ae81a0f814a82c80cf3a93502ed 100644
--- a/third_party/WebKit/Source/platform/fonts/shaping/ShapeResult.cpp
+++ b/third_party/WebKit/Source/platform/fonts/shaping/ShapeResult.cpp
@@ -32,9 +32,7 @@
#include "platform/fonts/shaping/ShapeResult.h"
#include "platform/fonts/Font.h"
-#include "platform/fonts/GlyphBuffer.h"
#include "platform/fonts/shaping/ShapeResultInlineHeaders.h"
-#include "platform/text/TextBreakIterator.h"
namespace blink {
@@ -130,334 +128,6 @@ ShapeResult::~ShapeResult()
{
}
-static inline void addGlyphToBuffer(GlyphBuffer* glyphBuffer, float advance,
- hb_direction_t direction, const SimpleFontData* fontData,
- const HarfBuzzRunGlyphData& glyphData)
-{
- FloatPoint startOffset = HB_DIRECTION_IS_HORIZONTAL(direction)
- ? FloatPoint(advance, 0)
- : FloatPoint(0, advance);
- glyphBuffer->add(glyphData.glyph, fontData, startOffset + glyphData.offset);
-}
-
-template<TextDirection direction>
-float ShapeResult::fillGlyphBufferForRun(GlyphBuffer* glyphBuffer,
- const RunInfo* run, float initialAdvance, unsigned from, unsigned to,
- unsigned runOffset)
-{
- if (!run)
- return 0;
- float advanceSoFar = initialAdvance;
- const unsigned numGlyphs = run->m_glyphData.size();
- for (unsigned i = 0; i < numGlyphs; ++i) {
- const HarfBuzzRunGlyphData& glyphData = run->m_glyphData[i];
- uint16_t currentCharacterIndex = run->m_startIndex +
- glyphData.characterIndex + runOffset;
- if ((direction == RTL && currentCharacterIndex >= to)
- || (direction == LTR && currentCharacterIndex < from)) {
- advanceSoFar += glyphData.advance;
- } else if ((direction == RTL && currentCharacterIndex >= from)
- || (direction == LTR && currentCharacterIndex < to)) {
- addGlyphToBuffer(glyphBuffer, advanceSoFar, run->m_direction,
- run->m_fontData.get(), glyphData);
- advanceSoFar += glyphData.advance;
- }
- }
- return advanceSoFar - initialAdvance;
-}
-
-static inline unsigned countGraphemesInCluster(const UChar* str,
- unsigned strLength, uint16_t startIndex, uint16_t endIndex)
-{
- if (startIndex > endIndex) {
- uint16_t tempIndex = startIndex;
- startIndex = endIndex;
- endIndex = tempIndex;
- }
- uint16_t length = endIndex - startIndex;
- ASSERT(static_cast<unsigned>(startIndex + length) <= strLength);
- TextBreakIterator* cursorPosIterator = cursorMovementIterator(&str[startIndex], length);
-
- int cursorPos = cursorPosIterator->current();
- int numGraphemes = -1;
- while (0 <= cursorPos) {
- cursorPos = cursorPosIterator->next();
- numGraphemes++;
- }
- return std::max(0, numGraphemes);
-}
-
-static inline void addEmphasisMark(GlyphBuffer* buffer,
- const GlyphData* emphasisData, FloatPoint glyphCenter,
- float midGlyphOffset)
-{
- ASSERT(buffer);
- ASSERT(emphasisData);
-
- const SimpleFontData* emphasisFontData = emphasisData->fontData;
- ASSERT(emphasisFontData);
-
- bool isVertical = emphasisFontData->platformData().isVerticalAnyUpright()
- && emphasisFontData->verticalData();
-
- if (!isVertical) {
- buffer->add(emphasisData->glyph, emphasisFontData,
- midGlyphOffset - glyphCenter.x());
- } else {
- buffer->add(emphasisData->glyph, emphasisFontData,
- FloatPoint(-glyphCenter.x(), midGlyphOffset - glyphCenter.y()));
- }
-}
-
-float ShapeResult::fillGlyphBufferForTextEmphasisRun(GlyphBuffer* glyphBuffer,
- const RunInfo* run, const TextRun& textRun, const GlyphData* emphasisData,
- float initialAdvance, unsigned from, unsigned to, unsigned runOffset)
-{
- if (!run)
- return 0;
-
- unsigned graphemesInCluster = 1;
- float clusterAdvance = 0;
-
- FloatPoint glyphCenter = emphasisData->fontData->
- boundsForGlyph(emphasisData->glyph).center();
-
- TextDirection direction = textRun.direction();
-
- // A "cluster" in this context means a cluster as it is used by HarfBuzz:
- // The minimal group of characters and corresponding glyphs, that cannot be broken
- // down further from a text shaping point of view.
- // A cluster can contain multiple glyphs and grapheme clusters, with mutually
- // overlapping boundaries. Below we count grapheme clusters per HarfBuzz clusters,
- // then linearly split the sum of corresponding glyph advances by the number of
- // grapheme clusters in order to find positions for emphasis mark drawing.
- uint16_t clusterStart = static_cast<uint16_t>(direction == RTL
- ? run->m_startIndex + run->m_numCharacters + runOffset
- : run->glyphToCharacterIndex(0) + runOffset);
-
- float advanceSoFar = initialAdvance;
- const unsigned numGlyphs = run->m_glyphData.size();
- for (unsigned i = 0; i < numGlyphs; ++i) {
- const HarfBuzzRunGlyphData& glyphData = run->m_glyphData[i];
- uint16_t currentCharacterIndex = run->m_startIndex + glyphData.characterIndex + runOffset;
- bool isRunEnd = (i + 1 == numGlyphs);
- bool isClusterEnd = isRunEnd || (run->glyphToCharacterIndex(i + 1) + runOffset != currentCharacterIndex);
-
- if ((direction == RTL && currentCharacterIndex >= to) || (direction != RTL && currentCharacterIndex < from)) {
- advanceSoFar += glyphData.advance;
- direction == RTL ? --clusterStart : ++clusterStart;
- continue;
- }
-
- clusterAdvance += glyphData.advance;
-
- if (textRun.is8Bit()) {
- float glyphAdvanceX = glyphData.advance;
- if (Character::canReceiveTextEmphasis(textRun[currentCharacterIndex])) {
- addEmphasisMark(glyphBuffer, emphasisData, glyphCenter, advanceSoFar + glyphAdvanceX / 2);
- }
- advanceSoFar += glyphAdvanceX;
- } else if (isClusterEnd) {
- uint16_t clusterEnd;
- if (direction == RTL)
- clusterEnd = currentCharacterIndex;
- else
- clusterEnd = static_cast<uint16_t>(isRunEnd ? run->m_startIndex + run->m_numCharacters + runOffset : run->glyphToCharacterIndex(i + 1) + runOffset);
-
- graphemesInCluster = countGraphemesInCluster(textRun.characters16(), textRun.charactersLength(), clusterStart, clusterEnd);
- if (!graphemesInCluster || !clusterAdvance)
- continue;
-
- float glyphAdvanceX = clusterAdvance / graphemesInCluster;
- for (unsigned j = 0; j < graphemesInCluster; ++j) {
- // Do not put emphasis marks on space, separator, and control characters.
- if (Character::canReceiveTextEmphasis(textRun[currentCharacterIndex]))
- addEmphasisMark(glyphBuffer, emphasisData, glyphCenter, advanceSoFar + glyphAdvanceX / 2);
- advanceSoFar += glyphAdvanceX;
- }
- clusterStart = clusterEnd;
- clusterAdvance = 0;
- }
- }
- return advanceSoFar - initialAdvance;
-}
-
-float ShapeResult::fillFastHorizontalGlyphBuffer(const ShapeResultBuffer& resultsBuffer,
- GlyphBuffer* glyphBuffer, TextDirection dir)
-{
- ASSERT(!resultsBuffer.hasVerticalOffsets());
-
- const auto& results = resultsBuffer.results();
- float advance = 0;
-
- for (unsigned i = 0; i < results.size(); ++i) {
- const auto& wordResult =
- isLeftToRightDirection(dir) ? results[i] : results[results.size() - 1 - i];
- ASSERT(!wordResult->hasVerticalOffsets());
-
- for (const auto& run : wordResult->m_runs) {
- ASSERT(run);
- ASSERT(HB_DIRECTION_IS_HORIZONTAL(run->m_direction));
-
- for (const auto& glyphData : run->m_glyphData) {
- ASSERT(!glyphData.offset.height());
-
- glyphBuffer->add(glyphData.glyph, run->m_fontData.get(),
- advance + glyphData.offset.width());
- advance += glyphData.advance;
- }
- }
- }
-
- ASSERT(!glyphBuffer->hasVerticalOffsets());
-
- return advance;
-}
-
-float ShapeResult::fillGlyphBuffer(const ShapeResultBuffer& resultsBuffer,
- GlyphBuffer* glyphBuffer, const TextRun& textRun,
- unsigned from, unsigned to)
-{
- // Fast path: full run with no vertical offsets
- if (!from && to == static_cast<unsigned>(textRun.length()) && !resultsBuffer.hasVerticalOffsets())
- return fillFastHorizontalGlyphBuffer(resultsBuffer, glyphBuffer, textRun.direction());
-
- const auto& results = resultsBuffer.results();
- float advance = 0;
-
- if (textRun.rtl()) {
- unsigned wordOffset = textRun.length();
- for (unsigned j = 0; j < results.size(); j++) {
- unsigned resolvedIndex = results.size() - 1 - j;
- const RefPtr<ShapeResult>& wordResult = results[resolvedIndex];
- for (unsigned i = 0; i < wordResult->m_runs.size(); i++) {
- advance += wordResult->fillGlyphBufferForRun<RTL>(glyphBuffer,
- wordResult->m_runs[i].get(), advance, from, to,
- wordOffset - wordResult->numCharacters());
- }
- wordOffset -= wordResult->numCharacters();
- }
- } else {
- unsigned wordOffset = 0;
- for (unsigned j = 0; j < results.size(); j++) {
- const RefPtr<ShapeResult>& wordResult = results[j];
- for (unsigned i = 0; i < wordResult->m_runs.size(); i++) {
- advance += wordResult->fillGlyphBufferForRun<LTR>(glyphBuffer,
- wordResult->m_runs[i].get(), advance, from, to, wordOffset);
- }
- wordOffset += wordResult->numCharacters();
- }
- }
-
- return advance;
-}
-
-float ShapeResult::fillGlyphBufferForTextEmphasis(const ShapeResultBuffer& resultsBuffer,
- GlyphBuffer* glyphBuffer, const TextRun& textRun, const GlyphData* emphasisData,
- unsigned from, unsigned to)
-{
- const auto& results = resultsBuffer.results();
- float advance = 0;
- unsigned wordOffset = textRun.rtl() ? textRun.length() : 0;
-
- for (unsigned j = 0; j < results.size(); j++) {
- unsigned resolvedIndex = textRun.rtl() ? results.size() - 1 - j : j;
- const RefPtr<ShapeResult>& wordResult = results[resolvedIndex];
- for (unsigned i = 0; i < wordResult->m_runs.size(); i++) {
- unsigned resolvedOffset = wordOffset -
- (textRun.rtl() ? wordResult->numCharacters() : 0);
- advance += wordResult->fillGlyphBufferForTextEmphasisRun(
- glyphBuffer, wordResult->m_runs[i].get(), textRun, emphasisData,
- advance, from, to, resolvedOffset);
- }
- wordOffset += wordResult->numCharacters() * (textRun.rtl() ? -1 : 1);
- }
-
- return advance;
-}
-
-FloatRect ShapeResult::selectionRect(const ShapeResultBuffer& resultsBuffer,
- TextDirection direction, float totalWidth, const FloatPoint& point,
- int height, unsigned absoluteFrom, unsigned absoluteTo)
-{
- const auto& results = resultsBuffer.results();
- float currentX = 0;
- float fromX = 0;
- float toX = 0;
- bool foundFromX = false;
- bool foundToX = false;
-
- if (direction == RTL)
- currentX = totalWidth;
-
- // The absoluteFrom and absoluteTo arguments represent the start/end offset
- // for the entire run, from/to are continuously updated to be relative to
- // the current word (ShapeResult instance).
- int from = absoluteFrom;
- int to = absoluteTo;
-
- unsigned totalNumCharacters = 0;
- for (unsigned j = 0; j < results.size(); j++) {
- const RefPtr<ShapeResult> result = results[j];
- if (direction == RTL) {
- // Convert logical offsets to visual offsets, because results are in
- // logical order while runs are in visual order.
- if (!foundFromX && from >= 0 && static_cast<unsigned>(from) < result->numCharacters())
- from = result->numCharacters() - from - 1;
- if (!foundToX && to >= 0 && static_cast<unsigned>(to) < result->numCharacters())
- to = result->numCharacters() - to - 1;
- currentX -= result->width();
- }
- for (unsigned i = 0; i < result->m_runs.size(); i++) {
- if (!result->m_runs[i])
- continue;
- ASSERT((direction == RTL) == result->m_runs[i]->rtl());
- int numCharacters = result->m_runs[i]->m_numCharacters;
- if (!foundFromX && from >= 0 && from < numCharacters) {
- fromX = result->m_runs[i]->xPositionForVisualOffset(from) + currentX;
- foundFromX = true;
- } else {
- from -= numCharacters;
- }
-
- if (!foundToX && to >= 0 && to < numCharacters) {
- toX = result->m_runs[i]->xPositionForVisualOffset(to) + currentX;
- foundToX = true;
- } else {
- to -= numCharacters;
- }
-
- if (foundFromX && foundToX)
- break;
- currentX += result->m_runs[i]->m_width;
- }
- if (direction == RTL)
- currentX -= result->width();
- totalNumCharacters += result->numCharacters();
- }
-
- // The position in question might be just after the text.
- if (!foundFromX && absoluteFrom == totalNumCharacters) {
- fromX = direction == RTL ? 0 : totalWidth;
- foundFromX = true;
- }
- if (!foundToX && absoluteTo == totalNumCharacters) {
- toX = direction == RTL ? 0 : totalWidth;
- foundToX = true;
- }
- if (!foundFromX)
- fromX = 0;
- if (!foundToX)
- toX = direction == RTL ? 0 : totalWidth;
-
- // None of our runs is part of the selection, possibly invalid arguments.
- if (!foundToX && !foundFromX)
- fromX = toX = 0;
- if (fromX < toX)
- return FloatRect(point.x() + fromX, point.y(), toX - fromX, height);
- return FloatRect(point.x() + toX, point.y(), fromX - toX, height);
-}
-
size_t ShapeResult::byteSize()
{
size_t selfByteSize = sizeof(this);
@@ -467,41 +137,7 @@ size_t ShapeResult::byteSize()
return selfByteSize;
}
-int ShapeResult::offsetForPosition(const ShapeResultBuffer& resultsBuffer,
- const TextRun& run, float targetX)
-{
- const auto& results = resultsBuffer.results();
- unsigned totalOffset;
- if (run.rtl()) {
- totalOffset = run.length();
- for (unsigned i = results.size(); i; --i) {
- const RefPtr<ShapeResult>& wordResult = results[i - 1];
- if (!wordResult)
- continue;
- totalOffset -= wordResult->numCharacters();
- if (targetX >= 0 && targetX <= wordResult->width()) {
- int offsetForWord = wordResult->offsetForPosition(targetX);
- return totalOffset + offsetForWord;
- }
- targetX -= wordResult->width();
- }
- } else {
- totalOffset = 0;
- for (const auto& wordResult : results) {
- if (!wordResult)
- continue;
- int offsetForWord = wordResult->offsetForPosition(targetX);
- ASSERT(offsetForWord >= 0);
- totalOffset += offsetForWord;
- if (targetX >= 0 && targetX <= wordResult->width())
- return totalOffset;
- targetX -= wordResult->width();
- }
- }
- return totalOffset;
-}
-
-int ShapeResult::offsetForPosition(float targetX)
+int ShapeResult::offsetForPosition(float targetX) const
{
int charactersSoFar = 0;
float currentX = 0;

Powered by Google App Engine
This is Rietveld 408576698