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