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);
             }
         }
     }