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 72e121825906443800a6878af402d2390b52bb4b..ef7ae4fe3434f69c6a4cb2bab8b28a38ce628f82 100644 |
--- a/third_party/WebKit/Source/platform/fonts/Font.cpp |
+++ b/third_party/WebKit/Source/platform/fonts/Font.cpp |
@@ -32,10 +32,8 @@ |
#include "platform/fonts/FontFallbackIterator.h" |
#include "platform/fonts/FontFallbackList.h" |
#include "platform/fonts/GlyphBuffer.h" |
-#include "platform/fonts/GlyphPageTreeNode.h" |
#include "platform/fonts/SimpleFontData.h" |
#include "platform/fonts/shaping/CachingWordShaper.h" |
-#include "platform/fonts/shaping/SimpleShaper.h" |
#include "platform/geometry/FloatRect.h" |
#include "platform/text/BidiResolver.h" |
#include "platform/text/Character.h" |
@@ -110,34 +108,16 @@ void Font::update(FontSelector* fontSelector) const { |
float Font::buildGlyphBuffer(const TextRunPaintInfo& runInfo, |
GlyphBuffer& glyphBuffer, |
const GlyphData* emphasisData) const { |
- if (codePath(runInfo) == ComplexPath) { |
- float width; |
- CachingWordShaper shaper(m_fontFallbackList->shapeCache(m_fontDescription)); |
- 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); |
- shaper.advance(runInfo.from); |
- shaper.advance(runInfo.to, &glyphBuffer); |
- float width = shaper.runWidthSoFar(); |
- |
- if (runInfo.run.rtl()) { |
- // Glyphs are shaped & stored in RTL advance order - reverse them for LTR |
- // drawing. |
- shaper.advance(runInfo.run.length()); |
- glyphBuffer.reverseForSimpleRTL(width, shaper.runWidthSoFar()); |
+ float width; |
+ CachingWordShaper shaper(m_fontFallbackList->shapeCache(m_fontDescription)); |
+ 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; |
} |
@@ -255,9 +235,7 @@ float Font::width(const TextRun& run, |
FloatRect* glyphBounds) const { |
FontCachePurgePreventer purgePreventer; |
- if (codePath(TextRunPaintInfo(run)) == ComplexPath) |
- return floatWidthForComplexText(run, fallbackFonts, glyphBounds); |
- return floatWidthForSimpleText(run, fallbackFonts, glyphBounds); |
+ return floatWidthForComplexText(run, fallbackFonts, glyphBounds); |
} |
namespace { |
@@ -499,9 +477,6 @@ FloatRect Font::selectionRectForText(const TextRun& run, |
FontCachePurgePreventer purgePreventer; |
- if (codePath(runInfo) != ComplexPath) |
- return pixelSnappedSelectionRect(selectionRectForSimpleText( |
- run, point, h, from, to, accountForGlyphBounds)); |
return pixelSnappedSelectionRect( |
selectionRectForComplexText(run, point, h, from, to)); |
} |
@@ -510,50 +485,9 @@ int Font::offsetForPosition(const TextRun& run, |
float x, |
bool includePartialGlyphs) const { |
FontCachePurgePreventer purgePreventer; |
- |
- if (codePath(TextRunPaintInfo(run)) != ComplexPath && |
- !getFontDescription().getTypesettingFeatures()) |
- return offsetForPositionForSimpleText(run, x, includePartialGlyphs); |
- |
return offsetForPositionForComplexText(run, x, includePartialGlyphs); |
} |
-CodePath Font::codePath(const TextRunPaintInfo& runInfo) const { |
- if (RuntimeEnabledFeatures::alwaysUseComplexTextEnabled() || |
- LayoutTestSupport::alwaysUseComplexTextForTest()) { |
- return ComplexPath; |
- } |
- |
- const TextRun& run = runInfo.run; |
- |
- if (getFontDescription().getTypesettingFeatures()) |
- return ComplexPath; |
- |
- if (m_fontDescription.featureSettings() && |
- m_fontDescription.featureSettings()->size() > 0) |
- return ComplexPath; |
- |
- if (m_fontDescription.isVerticalBaseline()) |
- return ComplexPath; |
- |
- if (m_fontDescription.widthVariant() != RegularWidth) |
- return ComplexPath; |
- |
- // FIXME: This really shouldn't be needed but for some reason the |
- // TextRendering setting doesn't propagate to typesettingFeatures in time |
- // for the prefs width calculation. |
- if (getFontDescription().textRendering() == OptimizeLegibility || |
- getFontDescription().textRendering() == GeometricPrecision) |
- return ComplexPath; |
- |
- if (run.is8Bit()) |
- return SimplePath; |
- |
- // Start from 0 since drawing and highlighting also measure the characters |
- // before run->from. |
- return Character::characterRangeCodePath(run.characters16(), run.length()); |
-} |
- |
bool Font::canShapeWordByWord() const { |
if (!m_shapeWordByWordComputed) { |
m_canShapeWordByWord = computeCanShapeWordByWord(); |
@@ -582,231 +516,12 @@ void Font::willUseFontData(const String& text) const { |
getFontDescription(), family.family(), text); |
} |
-static inline GlyphData glyphDataForNonCJKCharacterWithGlyphOrientation( |
- UChar32 character, |
- bool isUpright, |
- GlyphData& data, |
- unsigned pageNumber) { |
- if (isUpright) { |
- RefPtr<SimpleFontData> uprightFontData = |
- data.fontData->uprightOrientationFontData(); |
- GlyphPageTreeNode* uprightNode = GlyphPageTreeNode::getNormalRootChild( |
- uprightFontData.get(), pageNumber); |
- GlyphPage* uprightPage = uprightNode->page(); |
- if (uprightPage) { |
- GlyphData uprightData = uprightPage->glyphDataForCharacter(character); |
- // If the glyphs are the same, then we know we can just use the horizontal |
- // glyph rotated vertically to be upright. |
- if (data.glyph == uprightData.glyph) |
- return data; |
- // The glyphs are distinct, meaning that the font has a vertical-right |
- // glyph baked into it. We can't use that glyph, so we fall back to the |
- // upright data and use the horizontal glyph. |
- if (uprightData.fontData) |
- return uprightData; |
- } |
- } else { |
- RefPtr<SimpleFontData> verticalRightFontData = |
- data.fontData->verticalRightOrientationFontData(); |
- GlyphPageTreeNode* verticalRightNode = |
- GlyphPageTreeNode::getNormalRootChild(verticalRightFontData.get(), |
- pageNumber); |
- GlyphPage* verticalRightPage = verticalRightNode->page(); |
- if (verticalRightPage) { |
- GlyphData verticalRightData = |
- verticalRightPage->glyphDataForCharacter(character); |
- // If the glyphs are distinct, we will make the assumption that the font |
- // has a vertical-right glyph baked into it. |
- if (data.glyph != verticalRightData.glyph) |
- return data; |
- // The glyphs are identical, meaning that we should just use the |
- // horizontal glyph. |
- if (verticalRightData.fontData) |
- return verticalRightData; |
- } |
- } |
- return data; |
-} |
- |
PassRefPtr<FontFallbackIterator> Font::createFontFallbackIterator( |
FontFallbackPriority fallbackPriority) const { |
return FontFallbackIterator::create(m_fontDescription, m_fontFallbackList, |
fallbackPriority); |
} |
-GlyphData Font::glyphDataForCharacter(UChar32& c, |
- bool mirror, |
- bool normalizeSpace, |
- FontDataVariant variant) const { |
- ASSERT(isMainThread()); |
- |
- if (variant == AutoVariant) { |
- if (m_fontDescription.variantCaps() == FontDescription::SmallCaps) { |
- UChar32 upperC = |
- toUpper(c, LayoutLocale::localeString(m_fontDescription.locale())); |
- if (upperC != c) { |
- c = upperC; |
- variant = SmallCapsVariant; |
- } else { |
- variant = NormalVariant; |
- } |
- } else { |
- variant = NormalVariant; |
- } |
- } |
- |
- if (normalizeSpace && Character::isNormalizedCanvasSpaceCharacter(c)) |
- c = spaceCharacter; |
- |
- if (mirror) |
- c = mirroredChar(c); |
- |
- unsigned pageNumber = (c / GlyphPage::size); |
- |
- GlyphPageTreeNodeBase* node = m_fontFallbackList->getPageNode(pageNumber); |
- if (!node) { |
- node = GlyphPageTreeNode::getRootChild(fontDataAt(0), pageNumber); |
- m_fontFallbackList->setPageNode(pageNumber, node); |
- } |
- RELEASE_ASSERT(node); // Diagnosing crbug.com/446566 crash bug. |
- |
- GlyphPage* page = 0; |
- if (variant == NormalVariant) { |
- // Fastest loop, for the common case (normal variant). |
- while (true) { |
- page = node->page(m_fontDescription.script()); |
- if (page) { |
- GlyphData data = page->glyphDataForCharacter(c); |
- if (data.fontData) { |
- if (!data.fontData->platformData().isVerticalAnyUpright() || |
- data.fontData->isTextOrientationFallback()) |
- return data; |
- |
- bool isUpright = m_fontDescription.isVerticalUpright(c); |
- if (!isUpright || !Character::isCJKIdeographOrSymbol(c)) |
- return glyphDataForNonCJKCharacterWithGlyphOrientation( |
- c, isUpright, data, pageNumber); |
- |
- return data; |
- } |
- |
- if (node->isSystemFallback()) |
- break; |
- } |
- |
- // Proceed with the fallback list. |
- node = toGlyphPageTreeNode(node)->getChild(fontDataAt(node->level()), |
- pageNumber); |
- m_fontFallbackList->setPageNode(pageNumber, node); |
- } |
- } |
- if (variant != NormalVariant) { |
- while (true) { |
- page = node->page(m_fontDescription.script()); |
- if (page) { |
- GlyphData data = page->glyphDataForCharacter(c); |
- if (data.fontData) { |
- // The variantFontData function should not normally return 0. |
- // But if it does, we will just render the capital letter big. |
- RefPtr<SimpleFontData> variantFontData = |
- data.fontData->variantFontData(m_fontDescription, variant); |
- if (!variantFontData) |
- return data; |
- |
- GlyphPageTreeNode* variantNode = |
- GlyphPageTreeNode::getNormalRootChild(variantFontData.get(), |
- pageNumber); |
- GlyphPage* variantPage = variantNode->page(); |
- if (variantPage) { |
- GlyphData data = variantPage->glyphDataForCharacter(c); |
- if (data.fontData) |
- return data; |
- } |
- |
- // Do not attempt system fallback off the variantFontData. This is the |
- // very unlikely case that a font has the lowercase character but the |
- // small caps font does not have its uppercase version. |
- return variantFontData->missingGlyphData(); |
- } |
- |
- if (node->isSystemFallback()) |
- break; |
- } |
- |
- // Proceed with the fallback list. |
- node = toGlyphPageTreeNode(node)->getChild(fontDataAt(node->level()), |
- pageNumber); |
- m_fontFallbackList->setPageNode(pageNumber, node); |
- } |
- } |
- |
- ASSERT(page); |
- ASSERT(node->isSystemFallback()); |
- |
- // System fallback is character-dependent. When we get here, we |
- // know that the character in question isn't in the system fallback |
- // font's glyph page. Try to lazily create it here. |
- |
- // FIXME: Unclear if this should normalizeSpaces above 0xFFFF. |
- // Doing so changes fast/text/international/plane2-diffs.html |
- UChar32 characterToRender = c; |
- if (characterToRender <= 0xFFFF) |
- characterToRender = Character::normalizeSpaces(characterToRender); |
- |
- const FontData* fontData = fontDataAt(0); |
- if (fontData) { |
- const SimpleFontData* fontDataToSubstitute = |
- fontData->fontDataForCharacter(characterToRender); |
- RefPtr<SimpleFontData> characterFontData = |
- FontCache::fontCache()->fallbackFontForCharacter( |
- m_fontDescription, characterToRender, fontDataToSubstitute); |
- if (characterFontData && variant != NormalVariant) { |
- characterFontData = |
- characterFontData->variantFontData(m_fontDescription, variant); |
- } |
- if (characterFontData) { |
- // Got the fallback glyph and font. |
- unsigned pageNumberForRendering = characterToRender / GlyphPage::size; |
- GlyphPage* fallbackPage = |
- GlyphPageTreeNode::getRootChild(characterFontData.get(), |
- pageNumberForRendering) |
- ->page(); |
- GlyphData data = |
- fallbackPage && fallbackPage->glyphForCharacter(characterToRender) |
- ? fallbackPage->glyphDataForCharacter(characterToRender) |
- : characterFontData->missingGlyphData(); |
- // Cache it so we don't have to do system fallback again next time. |
- if (variant == NormalVariant) { |
- page->setGlyphDataForCharacter(c, data.glyph, data.fontData); |
- data.fontData->setMaxGlyphPageTreeLevel( |
- std::max(data.fontData->maxGlyphPageTreeLevel(), node->level())); |
- if (data.fontData->platformData().isVerticalAnyUpright() && |
- !data.fontData->isTextOrientationFallback() && |
- !Character::isCJKIdeographOrSymbol(characterToRender)) |
- return glyphDataForNonCJKCharacterWithGlyphOrientation( |
- characterToRender, |
- m_fontDescription.isVerticalUpright(characterToRender), data, |
- pageNumberForRendering); |
- } |
- return data; |
- } |
- } |
- |
- // Even system fallback can fail; use the missing glyph in that case. |
- // FIXME: It would be nicer to use the missing glyph from the last resort font |
- // instead. |
- DCHECK(primaryFont()); |
- if (!primaryFont()) |
- return GlyphData(); |
- GlyphData data = primaryFont()->missingGlyphData(); |
- if (variant == NormalVariant) { |
- page->setGlyphDataForCharacter(c, data.glyph, data.fontData); |
- data.fontData->setMaxGlyphPageTreeLevel( |
- std::max(data.fontData->maxGlyphPageTreeLevel(), node->level())); |
- } |
- return data; |
-} |
- |
bool Font::getEmphasisMarkGlyphData(const AtomicString& mark, |
GlyphData& glyphData) const { |
if (mark.isEmpty()) |
@@ -928,86 +643,6 @@ Vector<CharacterRange> Font::individualCharacterRanges( |
return ranges; |
} |
-float Font::floatWidthForSimpleText( |
- const TextRun& run, |
- HashSet<const SimpleFontData*>* fallbackFonts, |
- FloatRect* glyphBounds) const { |
- SimpleShaper shaper(this, run, nullptr, fallbackFonts, glyphBounds); |
- shaper.advance(run.length()); |
- return shaper.runWidthSoFar(); |
-} |
- |
-FloatRect Font::selectionRectForSimpleText(const TextRun& run, |
- const FloatPoint& point, |
- int h, |
- int from, |
- int to, |
- bool accountForGlyphBounds) const { |
- FloatRect bounds; |
- SimpleShaper shaper(this, run, nullptr, nullptr, |
- accountForGlyphBounds ? &bounds : nullptr); |
- shaper.advance(from); |
- float fromX = shaper.runWidthSoFar(); |
- shaper.advance(to); |
- float toX = shaper.runWidthSoFar(); |
- |
- if (run.rtl()) { |
- shaper.advance(run.length()); |
- float totalWidth = shaper.runWidthSoFar(); |
- float beforeWidth = fromX; |
- float afterWidth = toX; |
- fromX = totalWidth - afterWidth; |
- toX = totalWidth - beforeWidth; |
- } |
- |
- return FloatRect(point.x() + fromX, |
- accountForGlyphBounds ? bounds.y() : point.y(), toX - fromX, |
- accountForGlyphBounds ? bounds.maxY() - bounds.y() : h); |
-} |
- |
-int Font::offsetForPositionForSimpleText(const TextRun& run, |
- float x, |
- bool includePartialGlyphs) const { |
- float delta = x; |
- |
- SimpleShaper shaper(this, run); |
- unsigned offset; |
- if (run.rtl()) { |
- delta -= floatWidthForSimpleText(run); |
- while (1) { |
- offset = shaper.currentOffset(); |
- float w; |
- if (!shaper.advanceOneCharacter(w)) |
- break; |
- delta += w; |
- if (includePartialGlyphs) { |
- if (delta - w / 2 >= 0) |
- break; |
- } else { |
- if (delta >= 0) |
- break; |
- } |
- } |
- } else { |
- while (1) { |
- offset = shaper.currentOffset(); |
- float w; |
- if (!shaper.advanceOneCharacter(w)) |
- break; |
- delta -= w; |
- if (includePartialGlyphs) { |
- if (delta + w / 2 <= 0) |
- break; |
- } else { |
- if (delta <= 0) |
- break; |
- } |
- } |
- } |
- |
- return offset; |
-} |
- |
bool Font::loadingCustomFonts() const { |
return m_fontFallbackList && m_fontFallbackList->loadingCustomFonts(); |
} |