On 28/03/2017 22:11, hh via use-livecode wrote:
Hi Alex,
below you will find a tested binary search for the visible lines which
uses item 4 of the formattedRect for the topLine and item 2 of the
formattedRect for the bottomLine.
That's great - thank you.

However, I do have a couple of questions :

1. this uses a linear-interpolation for its initial guess for the topline (i.e. the percentage, set to vs / formattedheight). This is good. But it then uses that same value of percentage for the initial guess of the bottomline - which seems totally wrong. Should it not use a different percentage (specifically, the height of the field / (formattedheight - vs) with maybe a minor tweak for margins) for starting on the bottomline calculation?

2. After the initial percentage calculation, all the recursive calls just revert to simple binary search (i.e. percentage = 0.5). Since the initial one is just an estimate, and can be thrown off by variable line heights, this initial guess could be on the "wrong" side of the actual answer - and hence all the rest of the recursive iterations are done this "slow" way.
Why not recalculate the percentage for each recursive call ?

3. not so much a question as a bit of philosophical question ....
is a line "visible" if it occupies screen real-estate but has no visible pixels on the screen ? i.e. the formattedRect has the same problem (if it is a problem) with spacebelow as I mentioned earlier for formattedheight, so if the top line within the visible field consists solely of the spacebelow a line, then that line will not be included in the visibleTextLines().

Like I said, that's probably a philosophical question - but it does have implications for how one could then set up the lineNumbers field; I think you have to start it on the line before the "topline" form this calculation, and then set the vscroll of the linenumbers field to match the formattedrect of the next line of the original field (because you can't set a negative vscroll value, so this is needed to push the first visible line number downwards).




TMHO your method is so fast for visible lines of a field on usual
screensizes only that you could do that for each single of these lines.

The spaceBelow issue you describe has probably the (inavoidable) reason
of LC's ignoring a last linedelimiter in nearly all cases.

## The script is part of the result of a thread BerndN and I had once
## in the forum about the visible text of a styled field.
-- Determining the visible text lines of a field (may be styled).
-- pT = the short name of the field
function visibleTextLines pT
   lock screen; lock messages
   put the vscroll of fld pT into vs
   put the scrollbarWidth of fld pT into sw
   put the margins of fld pT into m
   put (m,m,m,m) into m -- now we have always at least 4 items
   -- 5 is the minimum textsize
   put  4 + (item 2 of m) + (the top    of fld pT) into t
   put -4 - (item 4 of m) + (the bottom of fld pT) into b
   if the hscrollbar of fld pT then subtract sw from b
   put the num of lines of fld pT into n
   put vs/(the formattedHeight of fld pT) into pct
   put findTopLine(pT,pct,t-5,1,n) into L1
   put findBottomLine(pT,pct,b+5,max(1,L1-1),n) into L2
   return (L1,L2)
end visibleTextLines

-- percentage p% is a percentage of 1, for example p=0.5 (for 50%)

-- p=%, x=bott of fld pT, n1=start, n=max
function findTopLine pT,p,x,n1,n
   put n1+trunc((n-n1)*p) into m
   if item 4 of the formattedRect of line (m+1) of fld pT >= x then
     if item 4 of the formattedRect of line m of fld pT < x then
       return m+1
     else
       if m <= n1 then return n1
       else return findTopLine(pT,0.5,x,n1,m-1)
     end if
   else
     if m>=n then return n
     else return findTopLine(pT,0.5,x,m+1,n)
   end if
end findTopLine

-- p=%, x=bott of fld pT, n1=start, n=max
function findBottomLine pT,p,x,n1,n
   put n1+trunc((n-n1)*p) into m
   if m<n1 then return n1; else if m >n then return n
   if item 2 of the formattedRect of line (m+1) of fld pT > x then
     if item 2 of the formattedRect of line m of fld pT <= x then
       return m
     else return findBottomLine(pT,0.5,x,n1,m-1)
   else return findBottomLine(pT,0.5,x,m+1,n)
end findBottomLine

There is a bit of a problem I encountered trying to code this up.

I'm not 100% sure yet if it's a bug, though I think it must be. Comments
anyone ?


Alex T. wrote:
If I set the 'spacebelow' of the last (Nth) line of a field, and get the
formattedheight of the field, that includes the spacebelow value just set.

However, none of
    the formattedheight of line N of fld ...
    the formattedheight of line 1 to N of fld ...
    the formattedheight of line 1 to -1 of fld ...
include it.  The same is true of 'internal' lines - it's not just the
last one in the field - the formattedheight of a chunk doesn't include
any spacebelow set on the last line of the chunk.

This makes it near impossible to use a binary search accurately (or
indeed to reliably use "the formattedheight of chunk xx of fld yy").

So now that I've describe it like that, I'm pretty sure it is a bug ....
but comments welcome before I report it.

-- Alex.
_______________________________________________
use-livecode mailing list
use-livecode@lists.runrev.com
Please visit this url to subscribe, unsubscribe and manage your subscription 
preferences:
http://lists.runrev.com/mailman/listinfo/use-livecode


_______________________________________________
use-livecode mailing list
use-livecode@lists.runrev.com
Please visit this url to subscribe, unsubscribe and manage your subscription 
preferences:
http://lists.runrev.com/mailman/listinfo/use-livecode

Reply via email to