| Index: Source/platform/fonts/Font.cpp
|
| diff --git a/Source/platform/fonts/Font.cpp b/Source/platform/fonts/Font.cpp
|
| index 2a3f5d3a1fdf23b067c134bf2b964035291dcb20..5ee5e3bc2178439359efe0f6f685a9d759e1423a 100644
|
| --- a/Source/platform/fonts/Font.cpp
|
| +++ b/Source/platform/fonts/Font.cpp
|
| @@ -35,6 +35,7 @@
|
| #include "platform/fonts/GlyphBuffer.h"
|
| #include "platform/fonts/GlyphPageTreeNode.h"
|
| #include "platform/fonts/SimpleFontData.h"
|
| +#include "platform/fonts/shaping/HarfBuzzFace.h"
|
| #include "platform/fonts/shaping/HarfBuzzShaper.h"
|
| #include "platform/fonts/shaping/SimpleShaper.h"
|
| #include "platform/geometry/FloatRect.h"
|
| @@ -60,12 +61,16 @@ Font::Font()
|
|
|
| Font::Font(const FontDescription& fd)
|
| : m_fontDescription(fd)
|
| + , m_canShapeWordByWord(0)
|
| + , m_shapeWordByWordComputed(0)
|
| {
|
| }
|
|
|
| Font::Font(const Font& other)
|
| : m_fontDescription(other.m_fontDescription)
|
| , m_fontFallbackList(other.m_fontFallbackList)
|
| + , m_canShapeWordByWord(0)
|
| + , m_shapeWordByWordComputed(0)
|
| {
|
| }
|
|
|
| @@ -73,6 +78,8 @@ Font& Font::operator=(const Font& other)
|
| {
|
| m_fontDescription = other.m_fontDescription;
|
| m_fontFallbackList = other.m_fontFallbackList;
|
| + m_canShapeWordByWord = other.m_canShapeWordByWord;
|
| + m_shapeWordByWordComputed = other.m_shapeWordByWordComputed;
|
| return *this;
|
| }
|
|
|
| @@ -103,10 +110,17 @@ float Font::buildGlyphBuffer(const TextRunPaintInfo& runInfo, GlyphBuffer& glyph
|
| const GlyphData* emphasisData) const
|
| {
|
| if (codePath(runInfo) == ComplexPath) {
|
| - HarfBuzzShaper shaper(this, runInfo.run, emphasisData);
|
| - shaper.setDrawRange(runInfo.from, runInfo.to);
|
| - shaper.shape(&glyphBuffer);
|
| - return shaper.totalWidth();
|
| + float width;
|
| + CachingWordShaper& shaper = m_fontFallbackList->cachingWordShaper();
|
| + if (emphasisData) {
|
| + width = shaper.fillGlyphBufferForTextEmphasis(this, runInfo.run,
|
| + emphasisData, &glyphBuffer, runInfo.from, runInfo.to);
|
| + } else {
|
| + width = shaper.fillGlyphBuffer(this, runInfo.run, nullptr,
|
| + &glyphBuffer, runInfo.from, runInfo.to);
|
| + }
|
| +
|
| + return width;
|
| }
|
|
|
| SimpleShaper shaper(this, runInfo.run, emphasisData, nullptr /* fallbackFonts */, nullptr);
|
| @@ -337,6 +351,25 @@ CodePath Font::codePath(const TextRunPaintInfo& runInfo) const
|
| return Character::characterRangeCodePath(run.characters16(), run.length());
|
| }
|
|
|
| +bool Font::canShapeWordByWord() const
|
| +{
|
| + if (!m_shapeWordByWordComputed) {
|
| + m_canShapeWordByWord = computeCanShapeWordByWord();
|
| + m_shapeWordByWordComputed = true;
|
| + }
|
| + return m_canShapeWordByWord;
|
| +};
|
| +
|
| +bool Font::computeCanShapeWordByWord() const
|
| +{
|
| + if (!fontDescription().typesettingFeatures())
|
| + return true;
|
| +
|
| + const FontPlatformData& platformData = primaryFont()->platformData();
|
| + TypesettingFeatures features = fontDescription().typesettingFeatures();
|
| + return !platformData.hasSpaceInLigaturesOrKerning(features);
|
| +};
|
| +
|
| void Font::willUseFontData(UChar32 character) const
|
| {
|
| const FontFamily& family = fontDescription().family();
|
| @@ -663,39 +696,11 @@ void Font::drawTextBlob(SkCanvas* canvas, const SkPaint& paint, const SkTextBlob
|
| canvas->drawTextBlob(blob, origin.x(), origin.y(), paint);
|
| }
|
|
|
| -float Font::floatWidthForComplexText(const TextRun& run, HashSet<const SimpleFontData*>* fallbackFonts, FloatRect* outGlyphBounds) const
|
| +float Font::floatWidthForComplexText(const TextRun& run, HashSet<const SimpleFontData*>* fallbackFonts, FloatRect* glyphBounds) const
|
| {
|
| - bool hasWordSpacingOrLetterSpacing = fontDescription().wordSpacing()
|
| - || fontDescription().letterSpacing();
|
| - // Word spacing and letter spacing can change the width of a word.
|
| - // If a tab occurs inside a word, the width of the word varies based on its
|
| - // position on the line.
|
| - bool isCacheable = !hasWordSpacingOrLetterSpacing && !run.allowTabs();
|
| -
|
| - WidthCacheEntry* cacheEntry = isCacheable
|
| - ? m_fontFallbackList->widthCache().add(run, WidthCacheEntry())
|
| - : 0;
|
| - if (cacheEntry && cacheEntry->isValid()) {
|
| - if (outGlyphBounds)
|
| - *outGlyphBounds = cacheEntry->glyphBounds;
|
| - return cacheEntry->width;
|
| - }
|
| -
|
| - FloatRect glyphBounds;
|
| - HarfBuzzShaper shaper(this, run, nullptr, fallbackFonts, &glyphBounds);
|
| - if (!shaper.shape())
|
| - return 0;
|
| -
|
| - float result = shaper.totalWidth();
|
| -
|
| - if (cacheEntry && (!fallbackFonts || fallbackFonts->isEmpty())) {
|
| - cacheEntry->glyphBounds = glyphBounds;
|
| - cacheEntry->width = result;
|
| - }
|
| -
|
| - if (outGlyphBounds)
|
| - *outGlyphBounds = glyphBounds;
|
| - return result;
|
| + CachingWordShaper& shaper = m_fontFallbackList->cachingWordShaper();
|
| + float width = shaper.width(this, run, fallbackFonts, glyphBounds);
|
| + return width;
|
| }
|
|
|
| // Return the code point index for the given |x| offset into the text run.
|
| @@ -703,19 +708,18 @@ int Font::offsetForPositionForComplexText(const TextRun& run, float xFloat,
|
| bool includePartialGlyphs) const
|
| {
|
| HarfBuzzShaper shaper(this, run);
|
| - if (!shaper.shape())
|
| + RefPtr<ShapeResult> shapeResult = shaper.shapeResult();
|
| + if (!shapeResult)
|
| return 0;
|
| - return shaper.offsetForPosition(xFloat);
|
| + return shapeResult->offsetForPosition(xFloat);
|
| }
|
|
|
| // Return the rectangle for selecting the given range of code-points in the TextRun.
|
| FloatRect Font::selectionRectForComplexText(const TextRun& run,
|
| const FloatPoint& point, int height, int from, int to) const
|
| {
|
| - HarfBuzzShaper shaper(this, run);
|
| - if (!shaper.shape())
|
| - return FloatRect();
|
| - return shaper.selectionRect(point, height, from, to);
|
| + CachingWordShaper& shaper = m_fontFallbackList->cachingWordShaper();
|
| + return shaper.selectionRect(this, run, point, height, from, to);
|
| }
|
|
|
| void Font::drawGlyphBuffer(SkCanvas* canvas, const SkPaint& paint, const TextRunPaintInfo& runInfo, const GlyphBuffer& glyphBuffer, const FloatPoint& point, float deviceScaleFactor) const
|
|
|