Line numbers for soft-wrapped styled text?

hh hh at hyperhh.de
Tue Mar 28 17:11:12 EDT 2017


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.

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.




More information about the use-livecode mailing list