LayoutTests:
Reviewed by Mitz and Anders.
Tests for http://bugs.webkit.org/show_bug.cgi?id=11811
<rdar://problem/4947184> REGRESSION (r11783): Hebrew text in list boxes is reversed
* fast/text/international/bidi-listbox-expected.checksum: Added.
* fast/text/international/bidi-listbox-expected.png: Added.
* fast/text/international/bidi-listbox-expected.txt: Added.
* fast/text/international/bidi-listbox.html: Added.
* fast/text/international/bidi-listbox-atsui-expected.checksum: Added.
* fast/text/international/bidi-listbox-atsui-expected.png: Added.
* fast/text/international/bidi-listbox-atsui-expected.txt: Added.
* fast/text/international/bidi-listbox-atsui.html: Added.
WebCore:
Reviewed by Mitz and Anders.
Fix for http://bugs.webkit.org/show_bug.cgi?id=11811
<rdar://problem/4947184> REGRESSION (r11783): Hebrew text in list boxes is reversed
http://bugs.webkit.org/show_bug.cgi?id=11812
<rdar://problem/4960269> REGRESSION (Native file upload): Hebrew filenames are reversed
Tests:
fast/text/international/bidi-listbox.html
fast/text/international/bidi-listbox-atsui.html
* rendering/RenderBlock.h: Added static bidiReorderCharacters that will run the bidi algorithm on a character buffer.
* rendering/bidi.cpp:
(WebCore::RenderBlock::bidiReorderCharacters): Added. Creates an anonymous RenderBlock and RenderText to feed into bidiReorderLines.
(WebCore::RenderBlock::constructLine): Uses the new convenience methods on BidiRun.
* rendering/bidi.h:
(WebCore::BidiRun::reversed): Added convenience method.
(WebCore::BidiRun::dirOverride): ditto.
* rendering/RenderFileUploadControl.cpp: (WebCore::RenderFileUploadControl::paintObject): Creates a buffer and calls bidiReorderCharacters
to get a correctly ordered character buffer for drawText.
* rendering/RenderListBox.cpp: (WebCore::RenderListBox::paintItemForeground): ditto.
git-svn-id: http://svn.webkit.org/repository/webkit/trunk@19414 268f45cc-cd09-0410-ab3c-d52691b4dbfc
diff --git a/WebCore/rendering/bidi.cpp b/WebCore/rendering/bidi.cpp
index 2052b66..11f9da7 100644
--- a/WebCore/rendering/bidi.cpp
+++ b/WebCore/rendering/bidi.cpp
@@ -111,6 +111,68 @@
static void embed(Direction, BidiState&);
static void appendRun(BidiState&);
+void RenderBlock::bidiReorderCharacters(Document* document, RenderStyle* style, CharacterBuffer& characterBuffer)
+{
+ unsigned bufferLength = characterBuffer.size();
+ // Create a local copy of the buffer.
+ String string(characterBuffer.data(), bufferLength);
+
+ // Create anonymous RenderBlock
+ RenderStyle* blockStyle = new (document->renderArena()) RenderStyle();
+ blockStyle->inheritFrom(style);
+ blockStyle->setDisplay(BLOCK);
+ blockStyle->setWhiteSpace(PRE);
+ RenderBlock* block = new (document->renderArena()) RenderBlock(document);
+ block->setStyle(blockStyle);
+
+ // Create RenderText
+ RenderText* text = new (document->renderArena()) RenderText(document, string.impl());
+ text->setStyle(blockStyle);
+ block->addChild(text);
+
+ // Call bidiReorderLine
+ BidiState bidi;
+ BidiContext* startEmbed;
+ if (style->direction() == LTR) {
+ startEmbed = new BidiContext(0, LeftToRight, NULL, style->unicodeBidi() == Override);
+ bidi.status.eor = LeftToRight;
+ } else {
+ startEmbed = new BidiContext(1, RightToLeft, NULL, style->unicodeBidi() == Override);
+ bidi.status.eor = RightToLeft;
+ }
+ bidi.status.lastStrong = startEmbed->dir();
+ bidi.status.last = startEmbed->dir();
+ bidi.status.eor = startEmbed->dir();
+ bidi.context = startEmbed;
+ bidi.dir = OtherNeutral;
+ betweenMidpoints = false;
+
+ block->bidiReorderLine(BidiIterator(block, text, 0), BidiIterator(block, text, bufferLength), bidi);
+
+ // Fill the characterBuffer.
+ int index = 0;
+ BidiRun* r = sFirstBidiRun;
+ while (r) {
+ bool reversed = r->reversed(style->visuallyOrdered());
+ // If there's only one run, and it doesn't need to be reversed, return early
+ if (sBidiRunCount == 1 && !reversed)
+ break;
+ for (int i = r->start; i < r->stop; ++i) {
+ if (reversed)
+ characterBuffer[index] = string[r->stop + r->start - i - 1];
+ else
+ characterBuffer[index] = string[i];
+ ++index;
+ }
+ r = r->nextRun;
+ }
+
+ // Tear down temporary RenderBlock and RenderText
+ block->removeChild(text);
+ text->destroy();
+ block->destroy();
+}
+
static int getBPMWidth(int childValue, Length cssUnit)
{
if (!cssUnit.isIntrinsicOrAuto())
@@ -816,8 +878,8 @@
text->setStart(r->start);
text->setLen(r->stop - r->start);
bool visuallyOrdered = r->obj->style()->visuallyOrdered();
- text->m_reversed = r->level % 2 && !visuallyOrdered;
- text->m_dirOverride = r->override || visuallyOrdered;
+ text->m_reversed = r->reversed(visuallyOrdered);
+ text->m_dirOverride = r->dirOverride(visuallyOrdered);
}
}
}