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

Unified Diff: Source/core/rendering/svg/SVGTextMetricsBuilder.cpp

Issue 253823002: Compute and use BiDi information in SVGTextMetricsBuilder (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: TestExpectations. Created 6 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 | « Source/core/rendering/svg/SVGTextMetrics.cpp ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: Source/core/rendering/svg/SVGTextMetricsBuilder.cpp
diff --git a/Source/core/rendering/svg/SVGTextMetricsBuilder.cpp b/Source/core/rendering/svg/SVGTextMetricsBuilder.cpp
index 5bac22f285e59b086e211f7a27742a375222fe96..fa70571456701d52e89f2c895e47aba83c4597aa 100644
--- a/Source/core/rendering/svg/SVGTextMetricsBuilder.cpp
+++ b/Source/core/rendering/svg/SVGTextMetricsBuilder.cpp
@@ -25,8 +25,12 @@
#include "core/rendering/svg/RenderSVGText.h"
#include "core/rendering/svg/SVGTextMetrics.h"
#include "platform/fonts/WidthIterator.h"
+#include "platform/text/BidiCharacterRun.h"
+#include "platform/text/BidiResolver.h"
+#include "platform/text/TextDirection.h"
#include "platform/text/TextPath.h"
#include "platform/text/TextRun.h"
+#include "platform/text/TextRunIterator.h"
#include "wtf/Vector.h"
namespace WebCore {
@@ -34,6 +38,7 @@ namespace WebCore {
class SVGTextMetricsCalculator {
public:
SVGTextMetricsCalculator(RenderSVGInlineText*);
+ ~SVGTextMetricsCalculator();
SVGTextMetrics computeMetricsForCharacter(unsigned textPosition);
unsigned textLength() const { return static_cast<unsigned>(m_run.charactersLength()); }
@@ -48,13 +53,17 @@ public:
}
private:
+ void setupBidiRuns();
SVGTextMetrics computeMetricsForCharacterSimple(unsigned textPosition);
SVGTextMetrics computeMetricsForCharacterComplex(unsigned textPosition);
RenderSVGInlineText* m_text;
+ BidiCharacterRun* m_bidiRun;
TextRun m_run;
+ BidiResolver<TextRunIterator, BidiCharacterRun> m_bidiResolver;
bool m_isComplexText;
float m_totalWidth;
+ TextDirection m_textDirection;
// Simple text only.
OwnPtr<WidthIterator> m_simpleWidthIterator;
@@ -62,6 +71,7 @@ private:
SVGTextMetricsCalculator::SVGTextMetricsCalculator(RenderSVGInlineText* text)
: m_text(text)
+ , m_bidiRun(0)
, m_run(SVGTextMetrics::constructTextRun(text, 0, text->textLength()))
, m_isComplexText(false)
, m_totalWidth(0)
@@ -73,6 +83,32 @@ SVGTextMetricsCalculator::SVGTextMetricsCalculator(RenderSVGInlineText* text)
if (!m_isComplexText)
m_simpleWidthIterator = adoptPtr(new WidthIterator(&scaledFont, m_run));
+ else
+ setupBidiRuns();
+}
+
+SVGTextMetricsCalculator::~SVGTextMetricsCalculator()
+{
+ if (m_bidiRun)
+ m_bidiResolver.runs().deleteRuns();
+}
+
+void SVGTextMetricsCalculator::setupBidiRuns()
+{
+ RenderStyle* style = m_text->style();
+ m_textDirection = style->direction();
+ if (isOverride(style->unicodeBidi()))
+ return;
+
+ BidiStatus status(LTR, false);
+ 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);
+ BidiRunList<BidiCharacterRun>& bidiRuns = m_bidiResolver.runs();
+ m_bidiRun = bidiRuns.firstRun();
}
SVGTextMetrics SVGTextMetricsCalculator::computeMetricsForCharacterSimple(unsigned textPosition)
@@ -92,10 +128,12 @@ SVGTextMetrics SVGTextMetricsCalculator::computeMetricsForCharacterSimple(unsign
SVGTextMetrics SVGTextMetricsCalculator::computeMetricsForCharacterComplex(unsigned textPosition)
{
unsigned metricsLength = characterStartsSurrogatePair(textPosition) ? 2 : 1;
- SVGTextMetrics metrics = SVGTextMetrics::measureCharacterRange(m_text, textPosition, metricsLength);
+ SVGTextMetrics metrics = SVGTextMetrics::measureCharacterRange(m_text, textPosition, metricsLength, m_textDirection);
ASSERT(metrics.length() == metricsLength);
- SVGTextMetrics complexStartToCurrentMetrics = SVGTextMetrics::measureCharacterRange(m_text, 0, textPosition + metricsLength);
+ unsigned startPosition = m_bidiRun ? m_bidiRun->start() : 0;
+ ASSERT(startPosition <= textPosition);
+ SVGTextMetrics complexStartToCurrentMetrics = SVGTextMetrics::measureCharacterRange(m_text, startPosition, textPosition - startPosition + metricsLength, m_textDirection);
// Frequent case for Arabic text: when measuring a single character the arabic isolated form is taken
// when rendering the glyph "in context" (with it's surrounding characters) it changes due to shaping.
// So whenever currentWidth != currentMetrics.width(), we are processing a text run whose length is
@@ -110,6 +148,17 @@ SVGTextMetrics SVGTextMetricsCalculator::computeMetricsForCharacterComplex(unsig
SVGTextMetrics SVGTextMetricsCalculator::computeMetricsForCharacter(unsigned textPosition)
{
+ if (m_bidiRun) {
+ if (textPosition >= static_cast<unsigned>(m_bidiRun->stop())) {
+ m_bidiRun = m_bidiRun->next();
+ // New BiDi run means new reference position for measurements, so reset |m_totalWidth|.
+ m_totalWidth = 0;
+ }
+ ASSERT(m_bidiRun);
+ ASSERT(static_cast<int>(textPosition) < m_bidiRun->stop());
+ m_textDirection = m_bidiRun->direction();
+ }
+
if (m_isComplexText)
return computeMetricsForCharacterComplex(textPosition);
« no previous file with comments | « Source/core/rendering/svg/SVGTextMetrics.cpp ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698