Reviewed by Sam.
Add support for xml:space="preserve" for SVG text.
It can be modeled by using white-space="pre" and replace \n by spaces.
Handle xml:space="default" correctly.
Always remove tabs from SVG text - as demanded by spec.
Added test: svg/custom/text-whitespace-handling.svg
git-svn-id: http://svn.webkit.org/repository/webkit/trunk@19390 268f45cc-cd09-0410-ab3c-d52691b4dbfc
diff --git a/WebCore/rendering/bidi.cpp b/WebCore/rendering/bidi.cpp
index 35f8976..2052b66 100644
--- a/WebCore/rendering/bidi.cpp
+++ b/WebCore/rendering/bidi.cpp
@@ -1912,6 +1912,16 @@
return style->collapseWhiteSpace() || (style->whiteSpace() == PRE_WRAP && (!isLineEmpty || !previousLineBrokeCleanly));
}
+static inline bool shouldPreserveNewline(RenderObject* object)
+{
+#ifdef SVG_SUPPORT
+ if (object->isSVGText())
+ return false;
+#endif
+
+ return object->style()->preserveNewline();
+}
+
int RenderBlock::skipWhitespace(BidiIterator &it, BidiState &bidi)
{
// FIXME: The entire concept of the skipWhitespace function is flawed, since we really need to be building
@@ -1920,7 +1930,7 @@
// object iteration process.
int w = lineWidth(m_height);
while (!it.atEnd() && (it.obj->isInlineFlow() || (shouldCollapseWhiteSpace(it.obj->style()) && !it.obj->isBR() &&
- (it.current() == ' ' || it.current() == '\t' || (!it.obj->style()->preserveNewline() && it.current() == '\n') ||
+ (it.current() == ' ' || it.current() == '\t' || (!shouldPreserveNewline(it.obj) && it.current() == '\n') ||
it.current() == softHyphen || skipNonBreakingSpace(it) || it.obj->isFloatingOrPositioned())))) {
if (it.obj->isFloatingOrPositioned()) {
RenderObject *o = it.obj;
@@ -2008,7 +2018,13 @@
bool autoWrap = RenderStyle::autoWrap(currWS);
autoWrapWasEverTrueOnLine = autoWrapWasEverTrueOnLine || autoWrap;
+
+#ifdef SVG_SUPPORT
+ bool preserveNewline = o->isSVGText() ? false : RenderStyle::preserveNewline(currWS);
+#else
bool preserveNewline = RenderStyle::preserveNewline(currWS);
+#endif
+
bool collapseWhiteSpace = RenderStyle::collapseWhiteSpace(currWS);
if (o->isBR()) {
@@ -2276,7 +2292,7 @@
}
}
if (lineWasTooWide || w + tmpW > width) {
- if (lBreak.obj && lBreak.obj->style()->preserveNewline() && lBreak.obj->isText() && static_cast<RenderText*>(lBreak.obj)->characters()[lBreak.pos] == '\n') {
+ if (lBreak.obj && shouldPreserveNewline(lBreak.obj) && lBreak.obj->isText() && static_cast<RenderText*>(lBreak.obj)->characters()[lBreak.pos] == '\n') {
if (!stoppedIgnoringSpaces && pos > 0) {
// We need to stop right before the newline and then start up again.
BidiIterator midpoint(0, o, pos);
@@ -2393,7 +2409,7 @@
RenderText* nextText = static_cast<RenderText*>(next);
if (nextText->textLength() != 0) {
UChar c = nextText->characters()[0];
- if (c == ' ' || c == '\t' || (c == '\n' && !next->style()->preserveNewline()))
+ if (c == ' ' || c == '\t' || (c == '\n' && !shouldPreserveNewline(next)))
// If the next item on the line is text, and if we did not end with
// a space, then the next text run continues our word (and so it needs to
// keep adding to |tmpW|. Just update and continue.
@@ -2470,7 +2486,7 @@
if (lBreak == start && !lBreak.obj->isBR()) {
// we just add as much as possible
- if (style()->preserveNewline()) {
+ if (shouldPreserveNewline(this)) {
// FIXME: Don't really understand this case.
if (pos != 0) {
lBreak.obj = o;