--- org/fbreader-0.8.1/fbreader/src/textview/TextView.cpp	2007-03-22 05:12:11.000000000 +0200
+++ fbreader-0.8.1/fbreader/src/textview/TextView.cpp	2007-03-22 13:44:53.000000000 +0200
@@ -31,6 +31,59 @@
 #include "../model/TextModel.h"
 #include "../model/Paragraph.h"
 
+int strrevbidi( char *d, const char *s, int f, int t) {
+        /* reverse string if it is hebrew - check first 3 letters for hebrew.
+         * */
+        int i,j,k,l, h, hc;
+        h=0;
+        hc=0;
+        i=t-f-1;
+        j=f;
+        while(j<t) {
+                k=0;
+                if((s[j]&0x80) == 0) k=0 ; else
+                if((s[j]&0xe0) == 0xc0) k=1; else
+                if((s[j]&0xf0) == 0xe0) k=2; else
+                if((s[j]&0xf8) == 0xf0) k=3;
+                l=k+1;
+                if(!h) {
+                        int ch;
+                        if(k==1) {
+                                ch=(s[j+1]&0x3f) | ((s[j]&0x1f)<<6);
+                                if(ch>=0x590 && ch<=0x6ff) h=1;
+                                if(h && !d) return 1;
+                        }
+                        if(!h && hc++ > 2) {
+                                if(d)memcpy(d, s+f, t-f+1);
+                                return 0;
+                        }
+                }
+                while(k>=0) {
+                        if(d)d[i--]=s[j+k];
+                        k--;
+                }
+                j+=l;
+        }
+        if(h && d){
+                d[t-f]=0;
+                for(i=0;i<t-f;i++) switch(d[i]) {
+                        case '(':
+                                d[i]=')';
+                                break;
+                        case ')':
+                                d[i]='(';
+                                break;
+                        default:
+                                break;
+                }
+        }
+        if(!h) { /* if too short and no hebrew char found */
+                if(d)memcpy(d, s+f, t-f+1);
+        }
+        return h;
+}
+
+
 TextView::TextView(ZLApplication &application, ZLPaintContext &context) : ZLView(application, context), myPaintState(NOTHING_TO_PAINT), myOldWidth(-1), myOldHeight(-1), myStyle(context), myTreeStateIsFrozen(false) {
 }
 
@@ -245,6 +298,7 @@
 
 void TextView::drawTextLine(const LineInfo &info) {
 	myStyle.setStyle(info.StartStyle);
+	int isBIDI;
 	int y = context().y();
 	myParagraphMap.push_back(
 		ParagraphPosition(info.RealStart.paragraphCursor().index(), y + 1, y + info.Height)
@@ -260,6 +314,7 @@
 	bool wordOccured = false;
 
 	context().moveXTo(0);
+	
 	if (!info.NodeInfo.isNull()) {
 		drawTreeLines(*info.NodeInfo, info.Height, info.VSpaceAfter);
 	}
@@ -284,7 +339,33 @@
 
 	const ParagraphCursor &paragraph = info.RealStart.paragraphCursor();
 	int paragraphNumber = paragraph.index();
-	for (WordCursor pos = info.RealStart; !pos.sameElementAs(info.End); pos.nextWord()) {
+	WordCursor pos, lastword;
+
+	isBIDI=0;
+	for(pos=info.RealStart ; !pos.sameElementAs(info.End) ; pos.nextWord()) {
+		const TextElement &element = paragraph[pos.wordNumber()];
+		TextElement::Kind kind = element.kind();
+		Word &word=(Word&)element;
+		if(kind==TextElement::WORD_ELEMENT)
+			isBIDI+=strrevbidi(NULL, word.Data, 0, word.Size);
+	}
+
+	if(isBIDI) {
+		pos=info.End;
+		lastword=info.RealStart;
+		if(myStyle.style()->alignment()==ALIGN_JUSTIFY) {
+			if( info.Start.isStartOfParagraph() )
+				context().moveX(-myStyle.style()->firstLineIndentDelta());
+			if(endOfParagraph)
+				context().moveX(context().width() - myStyle.style()->rightIndent() - info.Width);
+		}
+
+	} else {
+		pos=info.RealStart;
+		lastword=info.End;
+	}
+	for (; !pos.sameElementAs(lastword); ) {
+		if(isBIDI) pos.previousWord();
 		const TextElement &element = paragraph[pos.wordNumber()];
 		TextElement::Kind kind = element.kind();
 		int x = context().x();
@@ -336,6 +417,7 @@
 				);
 			}
 		}
+		if(!isBIDI) pos.nextWord();
 	}
 	if (!endOfParagraph && (info.End.element().kind() == TextElement::WORD_ELEMENT)) {
 		int len = info.End.charNumber();
@@ -507,8 +589,10 @@
 }
 
 void TextView::drawWord(int x, int y, const Word &word, int start, int length, bool addHyphenationSign) {
+	char str[1024];
 	if ((start == 0) && (length == -1)) {
-		drawString(x, y, word.Data, word.Size, word.mark(), 0);
+		strrevbidi(str, word.Data, 0, word.Size);
+		drawString(x, y, str, word.Size, word.mark(), 0);
 	} else {
 		int startPos = ZLUnicodeUtil::length(word.Data, start);
 		int endPos = (length == -1) ? word.Size : ZLUnicodeUtil::length(word.Data, start + length);
