| Index: third_party/WebKit/Source/platform/fonts/shaping/ShapeResultBuffer.cpp
|
| diff --git a/third_party/WebKit/Source/platform/fonts/shaping/ShapeResult.cpp b/third_party/WebKit/Source/platform/fonts/shaping/ShapeResultBuffer.cpp
|
| similarity index 53%
|
| copy from third_party/WebKit/Source/platform/fonts/shaping/ShapeResult.cpp
|
| copy to third_party/WebKit/Source/platform/fonts/shaping/ShapeResultBuffer.cpp
|
| index 692c0a21c302bd354a4d127d421f1b79a0e5d9db..f59d23008d2565c51e43a9a4617875ec13c0495f 100644
|
| --- a/third_party/WebKit/Source/platform/fonts/shaping/ShapeResult.cpp
|
| +++ b/third_party/WebKit/Source/platform/fonts/shaping/ShapeResultBuffer.cpp
|
| @@ -1,148 +1,78 @@
|
| -/*
|
| - * Copyright (c) 2012 Google Inc. All rights reserved.
|
| - * Copyright (C) 2013 BlackBerry Limited. All rights reserved.
|
| - *
|
| - * Redistribution and use in source and binary forms, with or without
|
| - * modification, are permitted provided that the following conditions are
|
| - * met:
|
| - *
|
| - * * Redistributions of source code must retain the above copyright
|
| - * notice, this list of conditions and the following disclaimer.
|
| - * * Redistributions in binary form must reproduce the above
|
| - * copyright notice, this list of conditions and the following disclaimer
|
| - * in the documentation and/or other materials provided with the
|
| - * distribution.
|
| - * * Neither the name of Google Inc. nor the names of its
|
| - * contributors may be used to endorse or promote products derived from
|
| - * this software without specific prior written permission.
|
| - *
|
| - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
| - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
| - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
| - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
| - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
| - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
| - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
| - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
| - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
| - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
| - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
| - */
|
| -
|
| -#include "platform/fonts/shaping/ShapeResult.h"
|
| -
|
| -#include "platform/fonts/Font.h"
|
| +// Copyright 2016 The Chromium Authors. All rights reserved.
|
| +// Use of this source code is governed by a BSD-style license that can be
|
| +// found in the LICENSE file.
|
| +
|
| +#include "platform/fonts/shaping/ShapeResultBuffer.h"
|
| +
|
| +#include "platform/fonts/Character.h"
|
| #include "platform/fonts/GlyphBuffer.h"
|
| +#include "platform/fonts/SimpleFontData.h"
|
| #include "platform/fonts/shaping/ShapeResultInlineHeaders.h"
|
| +#include "platform/geometry/FloatPoint.h"
|
| #include "platform/text/TextBreakIterator.h"
|
| +#include "platform/text/TextDirection.h"
|
|
|
| namespace blink {
|
|
|
| -float ShapeResult::RunInfo::xPositionForVisualOffset(unsigned offset) const
|
| -{
|
| - ASSERT(offset < m_numCharacters);
|
| - if (rtl())
|
| - offset = m_numCharacters - offset - 1;
|
| - return xPositionForOffset(offset);
|
| -}
|
| +namespace {
|
|
|
| -float ShapeResult::RunInfo::xPositionForOffset(unsigned offset) const
|
| +inline void addGlyphToBuffer(GlyphBuffer* glyphBuffer, float advance, hb_direction_t direction,
|
| + const SimpleFontData* fontData, const HarfBuzzRunGlyphData& glyphData)
|
| {
|
| - ASSERT(offset <= m_numCharacters);
|
| - const unsigned numGlyphs = m_glyphData.size();
|
| - unsigned glyphIndex = 0;
|
| - float position = 0;
|
| - if (rtl()) {
|
| - while (glyphIndex < numGlyphs && m_glyphData[glyphIndex].characterIndex > offset) {
|
| - position += m_glyphData[glyphIndex].advance;
|
| - ++glyphIndex;
|
| - }
|
| - // For RTL, we need to return the right side boundary of the character.
|
| - // Add advance of glyphs which are part of the character.
|
| - while (glyphIndex < numGlyphs - 1 && m_glyphData[glyphIndex].characterIndex == m_glyphData[glyphIndex + 1].characterIndex) {
|
| - position += m_glyphData[glyphIndex].advance;
|
| - ++glyphIndex;
|
| - }
|
| - position += m_glyphData[glyphIndex].advance;
|
| - } else {
|
| - while (glyphIndex < numGlyphs && m_glyphData[glyphIndex].characterIndex < offset) {
|
| - position += m_glyphData[glyphIndex].advance;
|
| - ++glyphIndex;
|
| - }
|
| - }
|
| - return position;
|
| + FloatPoint startOffset = HB_DIRECTION_IS_HORIZONTAL(direction)
|
| + ? FloatPoint(advance, 0)
|
| + : FloatPoint(0, advance);
|
| + glyphBuffer->add(glyphData.glyph, fontData, startOffset + glyphData.offset);
|
| }
|
|
|
| -int ShapeResult::RunInfo::characterIndexForXPosition(float targetX) const
|
| +inline void addEmphasisMark(GlyphBuffer* buffer,
|
| + const GlyphData* emphasisData, FloatPoint glyphCenter,
|
| + float midGlyphOffset)
|
| {
|
| - ASSERT(targetX <= m_width);
|
| - const unsigned numGlyphs = m_glyphData.size();
|
| - float currentX = 0;
|
| - float currentAdvance = m_glyphData[0].advance;
|
| - unsigned glyphIndex = 0;
|
| -
|
| - // Sum up advances that belong to the first character.
|
| - while (glyphIndex < numGlyphs - 1 && m_glyphData[glyphIndex].characterIndex == m_glyphData[glyphIndex + 1].characterIndex)
|
| - currentAdvance += m_glyphData[++glyphIndex].advance;
|
| - currentAdvance = currentAdvance / 2.0;
|
| - if (targetX <= currentAdvance)
|
| - return rtl() ? m_numCharacters : 0;
|
| -
|
| - currentX = currentAdvance;
|
| - ++glyphIndex;
|
| - while (glyphIndex < numGlyphs) {
|
| - unsigned prevCharacterIndex = m_glyphData[glyphIndex - 1].characterIndex;
|
| - float prevAdvance = currentAdvance;
|
| - currentAdvance = m_glyphData[glyphIndex].advance;
|
| - while (glyphIndex < numGlyphs - 1 && m_glyphData[glyphIndex].characterIndex == m_glyphData[glyphIndex + 1].characterIndex)
|
| - currentAdvance += m_glyphData[++glyphIndex].advance;
|
| - currentAdvance = currentAdvance / 2.0;
|
| - float nextX = currentX + prevAdvance + currentAdvance;
|
| - if (currentX <= targetX && targetX <= nextX)
|
| - return rtl() ? prevCharacterIndex : m_glyphData[glyphIndex].characterIndex;
|
| - currentX = nextX;
|
| - ++glyphIndex;
|
| - }
|
| + ASSERT(buffer);
|
| + ASSERT(emphasisData);
|
|
|
| - return rtl() ? 0 : m_numCharacters;
|
| -}
|
| + const SimpleFontData* emphasisFontData = emphasisData->fontData;
|
| + ASSERT(emphasisFontData);
|
|
|
| -void ShapeResult::RunInfo::setGlyphAndPositions(unsigned index,
|
| - uint16_t glyphId, float advance, float offsetX, float offsetY)
|
| -{
|
| - HarfBuzzRunGlyphData& data = m_glyphData[index];
|
| - data.glyph = glyphId;
|
| - data.advance = advance;
|
| - data.offset = FloatSize(offsetX, offsetY);
|
| -}
|
| + bool isVertical = emphasisFontData->platformData().isVerticalAnyUpright()
|
| + && emphasisFontData->verticalData();
|
|
|
| -ShapeResult::ShapeResult(const Font* font, unsigned numCharacters, TextDirection direction)
|
| - : m_width(0)
|
| - , m_primaryFont(const_cast<SimpleFontData*>(font->primaryFont()))
|
| - , m_numCharacters(numCharacters)
|
| - , m_numGlyphs(0)
|
| - , m_direction(direction)
|
| - , m_hasVerticalOffsets(0)
|
| -{
|
| + if (!isVertical) {
|
| + buffer->add(emphasisData->glyph, emphasisFontData,
|
| + midGlyphOffset - glyphCenter.x());
|
| + } else {
|
| + buffer->add(emphasisData->glyph, emphasisFontData,
|
| + FloatPoint(-glyphCenter.x(), midGlyphOffset - glyphCenter.y()));
|
| + }
|
| }
|
|
|
| -ShapeResult::~ShapeResult()
|
| +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);
|
|
|
| -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);
|
| + int cursorPos = cursorPosIterator->current();
|
| + int numGraphemes = -1;
|
| + while (0 <= cursorPos) {
|
| + cursorPos = cursorPosIterator->next();
|
| + numGraphemes++;
|
| + }
|
| + return std::max(0, numGraphemes);
|
| }
|
|
|
| +} // anonymous namespace
|
| +
|
| template<TextDirection direction>
|
| -float ShapeResult::fillGlyphBufferForRun(GlyphBuffer* glyphBuffer,
|
| - const RunInfo* run, float initialAdvance, unsigned from, unsigned to,
|
| +float ShapeResultBuffer::fillGlyphBufferForRun(GlyphBuffer* glyphBuffer,
|
| + const ShapeResult::RunInfo* run, float initialAdvance, unsigned from, unsigned to,
|
| unsigned runOffset)
|
| {
|
| if (!run)
|
| @@ -166,51 +96,8 @@ float ShapeResult::fillGlyphBufferForRun(GlyphBuffer* glyphBuffer,
|
| 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 ShapeResultBuffer::fillGlyphBufferForTextEmphasisRun(GlyphBuffer* glyphBuffer,
|
| + const ShapeResult::RunInfo* run, const TextRun& textRun, const GlyphData* emphasisData,
|
| float initialAdvance, unsigned from, unsigned to, unsigned runOffset)
|
| {
|
| if (!run)
|
| @@ -282,17 +169,16 @@ float ShapeResult::fillGlyphBufferForTextEmphasisRun(GlyphBuffer* glyphBuffer,
|
| return advanceSoFar - initialAdvance;
|
| }
|
|
|
| -float ShapeResult::fillFastHorizontalGlyphBuffer(const ShapeResultBuffer& resultsBuffer,
|
| - GlyphBuffer* glyphBuffer, TextDirection dir)
|
| +float ShapeResultBuffer::fillFastHorizontalGlyphBuffer(GlyphBuffer* glyphBuffer,
|
| + TextDirection dir) const
|
| {
|
| - ASSERT(!resultsBuffer.hasVerticalOffsets());
|
| + ASSERT(!hasVerticalOffsets());
|
|
|
| - const auto& results = resultsBuffer.results();
|
| float advance = 0;
|
|
|
| - for (unsigned i = 0; i < results.size(); ++i) {
|
| + for (unsigned i = 0; i < m_results.size(); ++i) {
|
| const auto& wordResult =
|
| - isLeftToRightDirection(dir) ? results[i] : results[results.size() - 1 - i];
|
| + isLeftToRightDirection(dir) ? m_results[i] : m_results[m_results.size() - 1 - i];
|
| ASSERT(!wordResult->hasVerticalOffsets());
|
|
|
| for (const auto& run : wordResult->m_runs) {
|
| @@ -314,24 +200,22 @@ float ShapeResult::fillFastHorizontalGlyphBuffer(const ShapeResultBuffer& result
|
| return advance;
|
| }
|
|
|
| -float ShapeResult::fillGlyphBuffer(const ShapeResultBuffer& resultsBuffer,
|
| - GlyphBuffer* glyphBuffer, const TextRun& textRun,
|
| - unsigned from, unsigned to)
|
| +float ShapeResultBuffer::fillGlyphBuffer(GlyphBuffer* glyphBuffer, const TextRun& textRun,
|
| + unsigned from, unsigned to) const
|
| {
|
| // Fast path: full run with no vertical offsets
|
| - if (!from && to == static_cast<unsigned>(textRun.length()) && !resultsBuffer.hasVerticalOffsets())
|
| - return fillFastHorizontalGlyphBuffer(resultsBuffer, glyphBuffer, textRun.direction());
|
| + if (!from && to == static_cast<unsigned>(textRun.length()) && !hasVerticalOffsets())
|
| + return fillFastHorizontalGlyphBuffer(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 j = 0; j < m_results.size(); j++) {
|
| + unsigned resolvedIndex = m_results.size() - 1 - j;
|
| + const RefPtr<ShapeResult>& wordResult = m_results[resolvedIndex];
|
| for (unsigned i = 0; i < wordResult->m_runs.size(); i++) {
|
| - advance += wordResult->fillGlyphBufferForRun<RTL>(glyphBuffer,
|
| + advance += fillGlyphBufferForRun<RTL>(glyphBuffer,
|
| wordResult->m_runs[i].get(), advance, from, to,
|
| wordOffset - wordResult->numCharacters());
|
| }
|
| @@ -339,10 +223,10 @@ float ShapeResult::fillGlyphBuffer(const ShapeResultBuffer& resultsBuffer,
|
| }
|
| } else {
|
| unsigned wordOffset = 0;
|
| - for (unsigned j = 0; j < results.size(); j++) {
|
| - const RefPtr<ShapeResult>& wordResult = results[j];
|
| + for (unsigned j = 0; j < m_results.size(); j++) {
|
| + const RefPtr<ShapeResult>& wordResult = m_results[j];
|
| for (unsigned i = 0; i < wordResult->m_runs.size(); i++) {
|
| - advance += wordResult->fillGlyphBufferForRun<LTR>(glyphBuffer,
|
| + advance += fillGlyphBufferForRun<LTR>(glyphBuffer,
|
| wordResult->m_runs[i].get(), advance, from, to, wordOffset);
|
| }
|
| wordOffset += wordResult->numCharacters();
|
| @@ -352,21 +236,19 @@ float ShapeResult::fillGlyphBuffer(const ShapeResultBuffer& resultsBuffer,
|
| return advance;
|
| }
|
|
|
| -float ShapeResult::fillGlyphBufferForTextEmphasis(const ShapeResultBuffer& resultsBuffer,
|
| - GlyphBuffer* glyphBuffer, const TextRun& textRun, const GlyphData* emphasisData,
|
| - unsigned from, unsigned to)
|
| +float ShapeResultBuffer::fillGlyphBufferForTextEmphasis(GlyphBuffer* glyphBuffer,
|
| + const TextRun& textRun, const GlyphData* emphasisData, unsigned from, unsigned to) const
|
| {
|
| - 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 j = 0; j < m_results.size(); j++) {
|
| + unsigned resolvedIndex = textRun.rtl() ? m_results.size() - 1 - j : j;
|
| + const RefPtr<ShapeResult>& wordResult = m_results[resolvedIndex];
|
| for (unsigned i = 0; i < wordResult->m_runs.size(); i++) {
|
| unsigned resolvedOffset = wordOffset -
|
| (textRun.rtl() ? wordResult->numCharacters() : 0);
|
| - advance += wordResult->fillGlyphBufferForTextEmphasisRun(
|
| + advance += fillGlyphBufferForTextEmphasisRun(
|
| glyphBuffer, wordResult->m_runs[i].get(), textRun, emphasisData,
|
| advance, from, to, resolvedOffset);
|
| }
|
| @@ -376,11 +258,9 @@ float ShapeResult::fillGlyphBufferForTextEmphasis(const ShapeResultBuffer& resul
|
| return advance;
|
| }
|
|
|
| -FloatRect ShapeResult::selectionRect(const ShapeResultBuffer& resultsBuffer,
|
| - TextDirection direction, float totalWidth, const FloatPoint& point,
|
| - int height, unsigned absoluteFrom, unsigned absoluteTo)
|
| +FloatRect ShapeResultBuffer::selectionRect(TextDirection direction, float totalWidth,
|
| + const FloatPoint& point, int height, unsigned absoluteFrom, unsigned absoluteTo) const
|
| {
|
| - const auto& results = resultsBuffer.results();
|
| float currentX = 0;
|
| float fromX = 0;
|
| float toX = 0;
|
| @@ -397,8 +277,8 @@ FloatRect ShapeResult::selectionRect(const ShapeResultBuffer& resultsBuffer,
|
| int to = absoluteTo;
|
|
|
| unsigned totalNumCharacters = 0;
|
| - for (unsigned j = 0; j < results.size(); j++) {
|
| - const RefPtr<ShapeResult> result = results[j];
|
| + for (unsigned j = 0; j < m_results.size(); j++) {
|
| + const RefPtr<ShapeResult> result = m_results[j];
|
| if (direction == RTL) {
|
| // Convert logical offsets to visual offsets, because results are in
|
| // logical order while runs are in visual order.
|
| @@ -458,24 +338,13 @@ FloatRect ShapeResult::selectionRect(const ShapeResultBuffer& resultsBuffer,
|
| return FloatRect(point.x() + toX, point.y(), fromX - toX, height);
|
| }
|
|
|
| -size_t ShapeResult::byteSize()
|
| +int ShapeResultBuffer::offsetForPosition(const TextRun& run, float targetX) const
|
| {
|
| - size_t selfByteSize = sizeof(this);
|
| - for (unsigned i = 0; i < m_runs.size(); ++i) {
|
| - selfByteSize += m_runs[i]->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];
|
| + for (unsigned i = m_results.size(); i; --i) {
|
| + const RefPtr<ShapeResult>& wordResult = m_results[i - 1];
|
| if (!wordResult)
|
| continue;
|
| totalOffset -= wordResult->numCharacters();
|
| @@ -487,7 +356,7 @@ int ShapeResult::offsetForPosition(const ShapeResultBuffer& resultsBuffer,
|
| }
|
| } else {
|
| totalOffset = 0;
|
| - for (const auto& wordResult : results) {
|
| + for (const auto& wordResult : m_results) {
|
| if (!wordResult)
|
| continue;
|
| int offsetForWord = wordResult->offsetForPosition(targetX);
|
| @@ -501,54 +370,4 @@ int ShapeResult::offsetForPosition(const ShapeResultBuffer& resultsBuffer,
|
| return totalOffset;
|
| }
|
|
|
| -int ShapeResult::offsetForPosition(float targetX)
|
| -{
|
| - int charactersSoFar = 0;
|
| - float currentX = 0;
|
| -
|
| - if (m_direction == RTL) {
|
| - charactersSoFar = m_numCharacters;
|
| - for (unsigned i = 0; i < m_runs.size(); ++i) {
|
| - if (!m_runs[i])
|
| - continue;
|
| - charactersSoFar -= m_runs[i]->m_numCharacters;
|
| - float nextX = currentX + m_runs[i]->m_width;
|
| - float offsetForRun = targetX - currentX;
|
| - if (offsetForRun >= 0 && offsetForRun <= m_runs[i]->m_width) {
|
| - // The x value in question is within this script run.
|
| - const unsigned index = m_runs[i]->characterIndexForXPosition(offsetForRun);
|
| - return charactersSoFar + index;
|
| - }
|
| - currentX = nextX;
|
| - }
|
| - } else {
|
| - for (unsigned i = 0; i < m_runs.size(); ++i) {
|
| - if (!m_runs[i])
|
| - continue;
|
| - float nextX = currentX + m_runs[i]->m_width;
|
| - float offsetForRun = targetX - currentX;
|
| - if (offsetForRun >= 0 && offsetForRun <= m_runs[i]->m_width) {
|
| - const unsigned index = m_runs[i]->characterIndexForXPosition(offsetForRun);
|
| - return charactersSoFar + index;
|
| - }
|
| - charactersSoFar += m_runs[i]->m_numCharacters;
|
| - currentX = nextX;
|
| - }
|
| - }
|
| -
|
| - return charactersSoFar;
|
| -}
|
| -
|
| -void ShapeResult::fallbackFonts(HashSet<const SimpleFontData*>* fallback) const
|
| -{
|
| - ASSERT(fallback);
|
| - ASSERT(m_primaryFont);
|
| - for (unsigned i = 0; i < m_runs.size(); ++i) {
|
| - if (m_runs[i] && m_runs[i]->m_fontData != m_primaryFont
|
| - && !m_runs[i]->m_fontData->isTextOrientationFallbackOf(m_primaryFont.get())) {
|
| - fallback->add(m_runs[i]->m_fontData.get());
|
| - }
|
| - }
|
| -}
|
| -
|
| } // namespace blink
|
|
|