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

Unified Diff: third_party/WebKit/Source/core/layout/svg/SVGTextMetricsBuilder.cpp

Issue 1879453003: Move SVGTextMetricsCalculator to LayoutSVGInlineText.cpp (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 4 years, 8 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
« no previous file with comments | « third_party/WebKit/Source/core/layout/svg/SVGTextMetricsBuilder.h ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: third_party/WebKit/Source/core/layout/svg/SVGTextMetricsBuilder.cpp
diff --git a/third_party/WebKit/Source/core/layout/svg/SVGTextMetricsBuilder.cpp b/third_party/WebKit/Source/core/layout/svg/SVGTextMetricsBuilder.cpp
deleted file mode 100644
index fc03d131ed0f8b8629ff03de1ff1bd293fd27bde..0000000000000000000000000000000000000000
--- a/third_party/WebKit/Source/core/layout/svg/SVGTextMetricsBuilder.cpp
+++ /dev/null
@@ -1,263 +0,0 @@
-/*
- * Copyright (C) Research In Motion Limited 2010-2012. All rights reserved.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public License
- * along with this library; see the file COPYING.LIB. If not, write to
- * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- * Boston, MA 02110-1301, USA.
- */
-
-#include "core/layout/svg/SVGTextMetricsBuilder.h"
-
-#include "core/layout/api/LineLayoutSVGInlineText.h"
-#include "core/layout/svg/LayoutSVGInlineText.h"
-#include "core/layout/svg/SVGTextMetrics.h"
-#include "platform/fonts/CharacterRange.h"
-#include "platform/text/BidiCharacterRun.h"
-#include "platform/text/BidiResolver.h"
-#include "platform/text/TextDirection.h"
-#include "platform/text/TextRun.h"
-#include "platform/text/TextRunIterator.h"
-#include "wtf/Vector.h"
-
-namespace blink {
-
-namespace {
-
-inline bool characterStartsSurrogatePair(const TextRun& run, unsigned index)
-{
- if (!U16_IS_LEAD(run[index]))
- return false;
- if (index + 1 >= static_cast<unsigned>(run.charactersLength()))
- return false;
- return U16_IS_TRAIL(run[index + 1]);
-}
-
-class SVGTextMetricsCalculator {
-public:
- SVGTextMetricsCalculator(LayoutSVGInlineText&);
- ~SVGTextMetricsCalculator();
-
- bool advancePosition();
- unsigned currentPosition() const { return m_currentPosition; }
-
- SVGTextMetrics currentCharacterMetrics();
-
- // TODO(pdr): Character-based iteration is ambiguous and error-prone. It
- // should be unified under a single concept. See: https://crbug.com/593570
- bool currentCharacterStartsSurrogatePair() const
- {
- return characterStartsSurrogatePair(m_run, m_currentPosition);
- }
- bool currentCharacterIsWhiteSpace() const
- {
- return m_run[m_currentPosition] == ' ';
- }
- unsigned characterCount() const
- {
- return static_cast<unsigned>(m_run.charactersLength());
- }
-
-private:
- void setupBidiRuns();
-
- static TextRun constructTextRun(LayoutSVGInlineText&, unsigned position, unsigned length, TextDirection);
-
- // Ensure |m_subrunRanges| is updated for the current bidi run, or the
- // complete m_run if no bidi runs are present. Returns the current position
- // in the subrun which can be used to index into |m_subrunRanges|.
- unsigned updateSubrunRangesForCurrentPosition();
-
- // Current character position in m_text.
- unsigned m_currentPosition;
-
- LayoutSVGInlineText& m_text;
- float m_fontScalingFactor;
- float m_cachedFontHeight;
- TextRun m_run;
-
- BidiCharacterRun* m_bidiRun;
- BidiResolver<TextRunIterator, BidiCharacterRun> m_bidiResolver;
-
- // Ranges for the current bidi run if present, or the entire run otherwise.
- Vector<CharacterRange> m_subrunRanges;
-};
-
-TextRun SVGTextMetricsCalculator::constructTextRun(LayoutSVGInlineText& text, unsigned position, unsigned length, TextDirection textDirection)
-{
- const ComputedStyle& style = text.styleRef();
-
- TextRun run(static_cast<const LChar*>(nullptr) // characters, will be set below if non-zero.
- , 0 // length, will be set below if non-zero.
- , 0 // xPos, only relevant with allowTabs=true
- , 0 // padding, only relevant for justified text, not relevant for SVG
- , TextRun::AllowTrailingExpansion
- , textDirection
- , isOverride(style.unicodeBidi()) /* directionalOverride */);
-
- if (length) {
- if (text.is8Bit())
- run.setText(text.characters8() + position, length);
- else
- run.setText(text.characters16() + position, length);
- }
-
- // We handle letter & word spacing ourselves.
- run.disableSpacing();
-
- // Propagate the maximum length of the characters buffer to the TextRun, even when we're only processing a substring.
- run.setCharactersLength(text.textLength() - position);
- ASSERT(run.charactersLength() >= run.length());
- return run;
-}
-
-SVGTextMetricsCalculator::SVGTextMetricsCalculator(LayoutSVGInlineText& text)
- : m_currentPosition(0)
- , m_text(text)
- , m_fontScalingFactor(m_text.scalingFactor())
- , m_cachedFontHeight(m_text.scaledFont().getFontMetrics().floatHeight() / m_fontScalingFactor)
- , m_run(constructTextRun(m_text, 0, m_text.textLength(), m_text.styleRef().direction()))
- , m_bidiRun(nullptr)
-{
- setupBidiRuns();
-}
-
-SVGTextMetricsCalculator::~SVGTextMetricsCalculator()
-{
- m_bidiResolver.runs().deleteRuns();
-}
-
-void SVGTextMetricsCalculator::setupBidiRuns()
-{
- BidiRunList<BidiCharacterRun>& bidiRuns = m_bidiResolver.runs();
- bool bidiOverride = isOverride(m_text.styleRef().unicodeBidi());
- BidiStatus status(LTR, bidiOverride);
- if (m_run.is8Bit() || bidiOverride) {
- WTF::Unicode::CharDirection direction = WTF::Unicode::LeftToRight;
- // If BiDi override is in effect, use the specified direction.
- if (bidiOverride && !m_text.styleRef().isLeftToRightDirection())
- direction = WTF::Unicode::RightToLeft;
- bidiRuns.addRun(new BidiCharacterRun(0, m_run.charactersLength(), status.context.get(), direction));
- } else {
- status.last = status.lastStrong = WTF::Unicode::OtherNeutral;
- m_bidiResolver.setStatus(status);
- m_bidiResolver.setPositionIgnoringNestedIsolates(TextRunIterator(&m_run, 0));
- const bool hardLineBreak = false;
- const bool reorderRuns = false;
- m_bidiResolver.createBidiRunsForLine(TextRunIterator(&m_run, m_run.length()), NoVisualOverride, hardLineBreak, reorderRuns);
- }
- m_bidiRun = bidiRuns.firstRun();
-}
-
-bool SVGTextMetricsCalculator::advancePosition()
-{
- m_currentPosition += currentCharacterStartsSurrogatePair() ? 2 : 1;
- return m_currentPosition < characterCount();
-}
-
-// TODO(pdr): We only have per-glyph data so we need to synthesize per-grapheme
-// data. E.g., if 'fi' is shaped into a single glyph, we do not know the 'i'
-// position. The code below synthesizes an average glyph width when characters
-// share a single position. This will incorrectly split combining diacritics.
-// See: https://crbug.com/473476.
-static void synthesizeGraphemeWidths(const TextRun& run, Vector<CharacterRange>& ranges)
-{
- unsigned distributeCount = 0;
- for (int rangeIndex = static_cast<int>(ranges.size()) - 1; rangeIndex >= 0; --rangeIndex) {
- CharacterRange& currentRange = ranges[rangeIndex];
- if (currentRange.width() == 0) {
- distributeCount++;
- } else if (distributeCount != 0) {
- // Only count surrogate pairs as a single character.
- bool surrogatePair = characterStartsSurrogatePair(run, rangeIndex);
- if (!surrogatePair)
- distributeCount++;
-
- float newWidth = currentRange.width() / distributeCount;
- currentRange.end = currentRange.start + newWidth;
- float lastEndPosition = currentRange.end;
- for (unsigned distribute = 1; distribute < distributeCount; distribute++) {
- // This surrogate pair check will skip processing of the second
- // character forming the surrogate pair.
- unsigned distributeIndex = rangeIndex + distribute + (surrogatePair ? 1 : 0);
- ranges[distributeIndex].start = lastEndPosition;
- ranges[distributeIndex].end = lastEndPosition + newWidth;
- lastEndPosition = ranges[distributeIndex].end;
- }
-
- distributeCount = 0;
- }
- }
-}
-
-unsigned SVGTextMetricsCalculator::updateSubrunRangesForCurrentPosition()
-{
- ASSERT(m_bidiRun);
- if (m_currentPosition >= static_cast<unsigned>(m_bidiRun->stop())) {
- m_bidiRun = m_bidiRun->next();
- // Ensure new subrange ranges are computed below.
- m_subrunRanges.clear();
- }
- ASSERT(m_bidiRun);
- ASSERT(static_cast<int>(m_currentPosition) < m_bidiRun->stop());
-
- unsigned positionInRun = m_currentPosition - m_bidiRun->start();
- if (positionInRun >= m_subrunRanges.size()) {
- TextRun subRun = constructTextRun(m_text, m_bidiRun->start(),
- m_bidiRun->stop() - m_bidiRun->start(), m_bidiRun->direction());
- m_subrunRanges = m_text.scaledFont().individualCharacterRanges(subRun);
- synthesizeGraphemeWidths(subRun, m_subrunRanges);
- }
-
- ASSERT(m_subrunRanges.size() && positionInRun < m_subrunRanges.size());
- return positionInRun;
-}
-
-SVGTextMetrics SVGTextMetricsCalculator::currentCharacterMetrics()
-{
- unsigned currentSubrunPosition = updateSubrunRangesForCurrentPosition();
- unsigned length = currentCharacterStartsSurrogatePair() ? 2 : 1;
- float width = m_subrunRanges[currentSubrunPosition].width();
- return SVGTextMetrics(length, width / m_fontScalingFactor, m_cachedFontHeight);
-}
-
-} // namespace
-
-void SVGTextMetricsBuilder::updateTextMetrics(LayoutSVGInlineText& text, bool& lastCharacterWasWhiteSpace)
-{
- Vector<SVGTextMetrics>& metricsList = text.metricsList();
- metricsList.clear();
-
- if (!text.textLength())
- return;
-
- // TODO(pdr): This loop is too tightly coupled to SVGTextMetricsCalculator.
- // We should refactor SVGTextMetricsCalculator to be a simple bidi run
- // iterator and move all subrun logic to a single function.
- SVGTextMetricsCalculator calculator(text);
- bool preserveWhiteSpace = text.styleRef().whiteSpace() == PRE;
- do {
- bool currentCharacterIsWhiteSpace = calculator.currentCharacterIsWhiteSpace();
- if (!preserveWhiteSpace && lastCharacterWasWhiteSpace && currentCharacterIsWhiteSpace) {
- metricsList.append(SVGTextMetrics(SVGTextMetrics::SkippedSpaceMetrics));
- ASSERT(calculator.currentCharacterMetrics().length() == 1);
- continue;
- }
-
- metricsList.append(calculator.currentCharacterMetrics());
-
- lastCharacterWasWhiteSpace = currentCharacterIsWhiteSpace;
- } while (calculator.advancePosition());
-}
-
-} // namespace blink
« no previous file with comments | « third_party/WebKit/Source/core/layout/svg/SVGTextMetricsBuilder.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698