Index: src/orca/flat_review.py
===================================================================
--- src/orca/flat_review.py	(revision 4375)
+++ src/orca/flat_review.py	(working copy)
@@ -26,6 +26,7 @@
 __license__   = "LGPL"
 
 import re
+import time
 
 import pyatspi
 import braille
@@ -863,8 +864,59 @@
 
         offset = 0
         lastEndOffset = -1
+        loopcounter = 0
+        time0 = time.time()
+        upperMax = text.characterCount
+	upperMid = upperMax /2
+	upperMin = 0
+	oldMid = 0
+	uy = 0
+	cliprecty = cliprect.y
+	cliprectx = cliprect.x
+	cliprectwidth = cliprect.width
+	cliprectheight = cliprect.height
+	limit = cliprecty+cliprectheight
+	print("crx=%.2f cry=%.2f, crw=%.2f, crh=%.2f, limit=%.2f" %(cliprectx,cliprecty,cliprectwidth,cliprectheight,limit))
+	while oldMid != upperMid:
+	    oldMid = upperMid
+            # performing binary search to locate line before clipped area
+            [x, y, width, height] = text.getRangeExtents(upperMid, upperMid+1, 0)
+            uy = y
+	    if y > cliprecty:
+	        upperMax = upperMid
+	    else:
+	        upperMin = upperMid
+	    upperMid = (upperMax - upperMin) /2 + upperMin
+
+	lowerMax = text.characterCount
+	lowerMid = lowerMax /2
+	lowerMin = 0
+	oldMid = 0
+	ly = 0
+
+	while oldMid != lowerMid:
+            oldMid = lowerMid
+	    # performing binary search to locate line before clipped area
+            [x, y, width, height] = text.getRangeExtents(lowerMid, lowerMid+1, 0)
+            ly = y
+	    if y > limit:
+	        lowerMax = lowerMid
+	    else:
+	        lowerMin = lowerMid
+	    lowerMid = (lowerMax - lowerMin) /2 + lowerMin
+        time1 = time.time()
+        #print("umin=%.2f, umid=%.2f, umax=%.2f, lmin=%.2f, umid=%.2f umax=%.2f" %(upperMin,upperMid,upperMax,lowerMin,lowerMid,lowerMax))
+        print("uy=%.2f, ly=%.2f" %(uy,ly))
+        [fstring, startOffset, endOffset] = text.getTextAtOffset(upperMin,pyatspi.TEXT_BOUNDARY_LINE_START)
+        [lstring, startOffset, endOffset] = text.getTextAtOffset(lowerMin,pyatspi.TEXT_BOUNDARY_LINE_START)
+        print("first line :%s: last line :%s:" %(fstring,lstring))
+        print("my loops took %s" %(time1-time0))
+        # finding out the zones
+        #offset = upperMin
+        #length = lowerMin
         while offset < length:
 
+            loopcounter = loopcounter + 1
             [string, startOffset, endOffset] = text.getTextAtOffset(
                 offset,
                 pyatspi.TEXT_BOUNDARY_LINE_START)
@@ -920,7 +972,12 @@
                 offset = endOffset
                 lastEndOffset = endOffset
 
-            textZones = self.splitTextIntoZones(
+            textZones = []
+            [x, y, width, height] = text.getRangeExtents(startOffset, endOffset, 0)
+            if ( ((y + height) >= cliprect.y) & ((cliprect.y + cliprect.height) > y) ):
+                #print("we want: cr.x=%s, cr.y=%s cr.w=%s, cr.h=%s" % (cliprect.x,cliprect.y,cliprect.width,cliprect.height))
+                #print("currently got x=%s y=%s, w=%s h=%s" %(x,y,width,height))
+                textZones = self.splitTextIntoZones(
                 accessible, string, startOffset, cliprect)
 
             # We need to account for the fact that newlines at the end of 
@@ -953,6 +1010,8 @@
                 #
                 break
 
+        time2 = time.time()
+        print("loop took %s, and loopcounter=%s\n---" %(time2-time1, loopcounter))
         # We might have a zero length text area.  In that case, well,
         # lets hack if this is something whose sole purpose is to
         # act as a text entry area.
