Line numbers for soft-wrapped styled text?

classic Classic list List threaded Threaded
31 messages Options
12
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Line numbers for soft-wrapped styled text?

Monte Goulding via use-livecode
I have an app that allows the user to write styled text, in which any
portion of that text may have a variety of styles and sizes, and may be
long enough to soft-wrap.

I'd like to add a line-number field next to it, but I haven't come up
with an efficient way of setting up those line numbers so that they
align vertically with the lines next to them.

Ideally the line numbers would reflect true lines, separated by CRs, as
opposed to any soft-wrapped lines.

What I'm after is common in many apps that support line numbers for
style text, but alas I don't have a ready solution.

Anyone here done this?  Any tips you can share for doing this efficiently?

--
  Richard Gaskin
  Fourth World Systems
  Software Design and Development for the Desktop, Mobile, and the Web
  ____________________________________________________________________
  [hidden email]                http://www.FourthWorld.com

_______________________________________________
use-livecode mailing list
[hidden email]
Please visit this url to subscribe, unsubscribe and manage your subscription preferences:
http://lists.runrev.com/mailman/listinfo/use-livecode
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Line numbers for soft-wrapped styled text?

Monte Goulding via use-livecode
On 03/25/2017 08:36 AM, Richard Gaskin via use-livecode wrote:

> I have an app that allows the user to write styled text, in which any
> portion of that text may have a variety of styles and sizes, and may be
> long enough to soft-wrap.
>
> I'd like to add a line-number field next to it, but I haven't come up
> with an efficient way of setting up those line numbers so that they
> align vertically with the lines next to them.
>
> Ideally the line numbers would reflect true lines, separated by CRs, as
> opposed to any soft-wrapped lines.
>
> What I'm after is common in many apps that support line numbers for
> style text, but alas I don't have a ready solution.
>
> Anyone here done this?  Any tips you can share for doing this efficiently?
>

I looked into that for the glx2 script editor and gave up. Soft line
wrapping by itself isn't a problem, and line numbering by itself isn't a
problem, but there's no message generated that lets you know when
wrapping is happening, and no indication in the text fields that a line
has been wrapped.

The only ugly solution I could think of was to iterate through each of
the lines of text, comparing the line length and character width with
the length of the field, and flagging an overflow as a wrapped line. And
do this every time the field got resized and text added or deleted. If
you're dealing with a field with mixed styles then your problems are
even worse.

--
  Mark Wieder
  [hidden email]

_______________________________________________
use-livecode mailing list
[hidden email]
Please visit this url to subscribe, unsubscribe and manage your subscription preferences:
http://lists.runrev.com/mailman/listinfo/use-livecode
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Line numbers for soft-wrapped styled text?

Monte Goulding via use-livecode
In reply to this post by Monte Goulding via use-livecode
Never done it, but I had a quick play ....

and found a way to do it  - but  whether it would count as "efficiently"
or not is debatable :-(

It does about 4 lines of text per millisecond on my elderly MacBook Pro
(with LC 9.0.0 DP6)

If you have a way of determining which line(s) are being changed, then
you could run this only from that line onward  to save some time ....


Here's the code snippet I was playing with; it assumes

field "F1" - the text

field "f2" - the line numbers, these two fields should have matching
base, height, etc.

Basically, it runs through the original field finding the formatted
height of each line. I can't find any way to get that except as the
formattedHeight of an entire field, so it has to loop through each line
in turn. The easy way to do that (simply adding each line) is painfully
slow, so instead it loops through the lines, add each one in turn *as
the second line*, so it get the height difference between that and a
single line. [ hmmm - not very clear ! Feel free to ask me to explain
myself better :-)  ]

and finally restores the original field "F1"

Then it runs through the lines of field "F2" setting the 'spacebelow' of
each line so that it matches the height of the styled & soft-wrapped
line of the text field.

Like I said - it works (at least for my simple testing), but it ain't
superfast ....

-- Alex.

local  sHeights
on mouseUp pK
    local tA, tB
    local temp, t1, t2, t3, tt, tBase

    put the millisecs into t1
    set the lockscreen to true
    set the textHeight of fld "f2" to 12
    put the styledtext of fld "f1" into tA
    put empty into tB
    put empty into sHeights
    put 0 into sHeights[0]
    put tA[1] into tB[1]
    -- and make it single line
    put empty into tB[1]["runs"]
    put "abc" into tB[1]["runs"][1]["text"]

    -- and then get the differential height of one simple line
    put tB[1] into tB[2]
    set the styledText of fld "f1" to tB
    put the  formattedHeight of fld "f1"  into tBase

    repeat with i = 1 to the number of lines in the keys of tA
       put tA[i] into tB[2]
       set the styledText of fld "f1" to tB
       put the  formattedHeight of fld "f1" into sHeights[i]
       --       put i && the number of lines in fld "f1" && sHeights[i]
&CR after msg
    end repeat
    set the styledText of fld "f1" to tA
    put empty into fld "f2"
    repeat with i = 1 to the number of lines in fld "f1"
       put i &CR after tt
    end repeat
    set the text of fld "f2" to tt
    put the millisecs into t2
    repeat with i = 1 to the number of lines in fld "f1"
       put sHeights[i] - tBase into temp
       if temp > 0 then
          set the spacebelow of line i of fld "f2" to temp
       end if
    end repeat
    put the millisecs into t3
    set the lockscreen to false
    put t2 - t1 && t3 - t2 && t3 - t1 &CR after msg
    --put sLineNum && the formattedheight of fld "f2" && tR

end mouseUp




On 25/03/2017 15:36, Richard Gaskin via use-livecode wrote:

> I have an app that allows the user to write styled text, in which any
> portion of that text may have a variety of styles and sizes, and may
> be long enough to soft-wrap.
>
> I'd like to add a line-number field next to it, but I haven't come up
> with an efficient way of setting up those line numbers so that they
> align vertically with the lines next to them.
>
> Ideally the line numbers would reflect true lines, separated by CRs,
> as opposed to any soft-wrapped lines.
>
> What I'm after is common in many apps that support line numbers for
> style text, but alas I don't have a ready solution.
>
> Anyone here done this?  Any tips you can share for doing this
> efficiently?
>


_______________________________________________
use-livecode mailing list
[hidden email]
Please visit this url to subscribe, unsubscribe and manage your subscription preferences:
http://lists.runrev.com/mailman/listinfo/use-livecode
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Line numbers for soft-wrapped styled text?

Monte Goulding via use-livecode
Nicely done, Alex - thanks!

--
  Richard Gaskin
  Fourth World Systems
  Software Design and Development for the Desktop, Mobile, and the Web
  ____________________________________________________________________
  [hidden email]                http://www.FourthWorld.com

_______________________________________________
use-livecode mailing list
[hidden email]
Please visit this url to subscribe, unsubscribe and manage your subscription preferences:
http://lists.runrev.com/mailman/listinfo/use-livecode
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Line numbers for soft-wrapped styled text?

dunbarx
In reply to this post by Monte Goulding via use-livecode
Hi.

Make two small fields, both with lineWrap set to "false". Line up the two field horizontally. Put some wrapped text into vld 1. Put this in a button somewhere:

on mouseUp
   lock screen
   put fld 1 into storage
   replace return with return & numToChar(208) in fld 1
   put fld 1 into workingText
   put the formattedText of fld 1 into temp
   put 1 into line 1 of lineCounter
   put 1 into lineTracker
   repeat with y = 1 to the number of lines of temp
      if line y of temp contains numToChar(208) then
         add 1 to lineTracker
         put lineTracker into line y of lineCounter
      end if
   end repeat
   put storage into fld 1
   put lineCounter into fld 2
end mouseUp

I needed to pollute the source field in order to use the formattedText and identify the hard returns.
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Line numbers for soft-wrapped styled text?

Monte Goulding via use-livecode
Hi.

That works for "simple" fields which may contain soft-wrapped lines -
but it doesn't account for styled text (e.g. where different lines may
be different font sizes (or even mixed sizes), or where paragraph
spacing has been set, or .... all the complex kinds of text we can now do.

but for situations where those complexities can be avoided, it is much
simpler and faster :-)

-- Alex.


On 25/03/2017 23:40, dunbarx via use-livecode wrote:

> Hi.
>
> Make two small fields, both with lineWrap set to "false". Line up the two
> field horizontally. Put some wrapped text into vld 1. Put this in a button
> somewhere:
>
> on mouseUp
>     lock screen
>     put fld 1 into storage
>     replace return with return & numToChar(208) in fld 1
>     put fld 1 into workingText
>     put the formattedText of fld 1 into temp
>     put 1 into line 1 of lineCounter
>     put 1 into lineTracker
>     repeat with y = 1 to the number of lines of temp
>        if line y of temp contains numToChar(208) then
>           add 1 to lineTracker
>           put lineTracker into line y of lineCounter
>        end if
>     end repeat
>     put storage into fld 1
>     put lineCounter into fld 2
> end mouseUp
>
> I needed to pollute the source field in order to use the formattedText and
> identify the hard returns.
>
>
>
> --
> View this message in context: http://runtime-revolution.278305.n4.nabble.com/Line-numbers-for-soft-wrapped-styled-text-tp4713343p4713356.html
> Sent from the Revolution - User mailing list archive at Nabble.com.
>
> _______________________________________________
> use-livecode mailing list
> [hidden email]
> Please visit this url to subscribe, unsubscribe and manage your subscription preferences:
> http://lists.runrev.com/mailman/listinfo/use-livecode


_______________________________________________
use-livecode mailing list
[hidden email]
Please visit this url to subscribe, unsubscribe and manage your subscription preferences:
http://lists.runrev.com/mailman/listinfo/use-livecode
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Line numbers for soft-wrapped styled text?

dunbarx
Sannyasin.

I know.

I offer it just because I saw right away when I read the OP's post how to harvest soft-wrapped lines, and just wanted to play with the idea. I find it just a bit ugly to be required to "pollute", as I said, the source field in order to "find" the hard wraps..

So, just lock the text and move on...

Craig
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Line numbers for soft-wrapped styled text?

Monte Goulding via use-livecode
In reply to this post by Monte Goulding via use-livecode
On 03/25/2017 04:00 PM, Alex Tweedly via use-livecode wrote:
> Never done it, but I had a quick play ....

Hmmm... nice approach. And clever use of spacebelow.

> If you have a way of determining which line(s) are being changed, then
> you could run this only from that line onward  to save some time ....

No, I don't think that would work. First of all, you'd need to keep
track of how many lines before the changed line were already wrapped, so
that you could know what line number to start with. So you'd have to
have already predetermined the relationships of the line starts to the
line numbers and either stored that somewhere and keep updating the
list; or work out the line starts each time.

Secondly, you'll need to trap some events in a frontscript and handle
things like inserting and deleting text, resizing the field/card, etc.

--
  Mark Wieder
  [hidden email]


_______________________________________________
use-livecode mailing list
[hidden email]
Please visit this url to subscribe, unsubscribe and manage your subscription preferences:
http://lists.runrev.com/mailman/listinfo/use-livecode
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Line numbers for soft-wrapped styled text?

Monte Goulding via use-livecode
On 26/03/2017 02:25, Mark Wieder via use-livecode wrote:

> On 03/25/2017 04:00 PM, Alex Tweedly via use-livecode wrote:
>> Never done it, but I had a quick play ....
>
> Hmmm... nice approach. And clever use of spacebelow.
>
>> If you have a way of determining which line(s) are being changed, then
>> you could run this only from that line onward  to save some time ....
>
> No, I don't think that would work. First of all, you'd need to keep
> track of how many lines before the changed line were already wrapped,
> so that you could know what line number to start with. So you'd have
> to have already predetermined the relationships of the line starts to
> the line numbers and either stored that somewhere and keep updating
> the list; or work out the line starts each time.
No, not necessary. This all works *entirely* with the "original" (i.e.
unwrapped) lines. It has no knowledge of which lines are wrapped - only
of the height taken by each *original* line in  the rendered field (as
given by formattedheight).

So if you make a change wholly within one line, then *all* you need to
do is
  - calculate the revised height of the render of this line (say, line N)
  - update sHeights[N]
  - update spacebelow of line N of field "linenumbersfield"

However, if you add or delete lines (including things like merging two
lines, inserting a CR, etc.) then you need to
  - for delete: 'compact' the sHeights array to move all subsequent
entries down
  - for insert: move the sHeights array entries 'up', and then calculate
the rendered height for the new line
  - and then update the spacebelow for all lines (N..infinity) of the
linenumbers field (i.e. you don't need to recalculate their heights,
just set them)

(And of course the sHeights array should really be a custom prop of the
field so we can generalize it :-)
>
> Secondly, you'll need to trap some events in a frontscript and handle
> things like inserting and deleting text, resizing the field/card, etc.
>
Yeah, well, I did say "If you have a way of determining ...." :-)

But yes, resizing and other events need to be handled - but since we
already have two fields that need to be kept parallel, then any app
using this must be handling resize itself so adding a call to this
function is trivial (and only needs to be done if the width changes, not
the height). It also needs to handle changes to things like margins,
borders (?maybe?), etc. which might be a new requirement.

Not sure why you'd need to do anything in a frontscript - doesn't the
'textchanged' message would cover all cases ?

But in any case - anyone doing a styled text editor, is going to need to
handle all inputs, changes, etc., so they'll have the right
opportunities to do this as needed.


However - it's almost certain that the engine is doing this line-by-line
(i.e. 'paragraph' by 'paragraph') rendering calculation, so it would (at
a guess) not be hard to store that off in the styledText array
structure. Might be a worthwhile enhancement request, if this would be
generally useful.


-- Alex.


_______________________________________________
use-livecode mailing list
[hidden email]
Please visit this url to subscribe, unsubscribe and manage your subscription preferences:
http://lists.runrev.com/mailman/listinfo/use-livecode
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Line numbers for soft-wrapped styled text?

Monte Goulding via use-livecode
In reply to this post by Monte Goulding via use-livecode
Yeah I was thinking the same thing. textChanged triggers a handler that reformats the text every time. In essence, you are doing what a word processor would do.

Bob S


> On Mar 25, 2017, at 09:07 , Mark Wieder via use-livecode <[hidden email]> wrote:
>
> I looked into that for the glx2 script editor and gave up. Soft line wrapping by itself isn't a problem, and line numbering by itself isn't a problem, but there's no message generated that lets you know when wrapping is happening, and no indication in the text fields that a line has been wrapped.
>
> The only ugly solution I could think of was to iterate through each of the lines of text, comparing the line length and character width with the length of the field, and flagging an overflow as a wrapped line. And do this every time the field got resized and text added or deleted. If you're dealing with a field with mixed styles then your problems are even worse.
>
> --
> Mark Wieder
> [hidden email]


_______________________________________________
use-livecode mailing list
[hidden email]
Please visit this url to subscribe, unsubscribe and manage your subscription preferences:
http://lists.runrev.com/mailman/listinfo/use-livecode
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Line numbers for soft-wrapped styled text?

Monte Goulding via use-livecode
Bob Sneidar wrote:

 > Yeah I was thinking the same thing. textChanged triggers a handler
 > that reformats the text every time. In essence, you are doing what
 > a word processor would do.

The textChanged message is only sent when changes are made to the text
of a field.  Changes to styling attributes may also affect line heights
and wrapping (e,g, bold will increase text width, textSize will enlarge
it overall), and those changes are beyond the scope of triggers for the
textChanged message.

That said, I don't believe there are any messages for style changes, so
I agree a frontScript here trapping multiple message should not be
needed/useful.

AFAIK the only way to account for styling changes is either in the
scripts for the UI elements that enact them (which is what I'm using
now) or polling (which I generally try to avoid unless I have no other
way to solve a problem).

--
  Richard Gaskin
  Fourth World Systems
  Software Design and Development for the Desktop, Mobile, and the Web
  ____________________________________________________________________
  [hidden email]                http://www.FourthWorld.com

_______________________________________________
use-livecode mailing list
[hidden email]
Please visit this url to subscribe, unsubscribe and manage your subscription preferences:
http://lists.runrev.com/mailman/listinfo/use-livecode
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Line numbers for soft-wrapped styled text?

Monte Goulding via use-livecode
In reply to this post by Monte Goulding via use-livecode
When I first started down this road I went for getting max values from
the styledText array, similar (though far less efficiently) to how Alex
Tweedly solved this so well in his post the other day:
http://lists.runrev.com/pipermail/use-livecode/2017-March/235688.html

Great work as usual from Alex there, reasonably performant enough for
most needs and very well crafted.

This morning Jim Lambert emailed me a very different solution that I
thought would be worth sharing here.

Here he uses the engine's own metrics for calculating vertical line
spacings, by having the number field placed below the editable text
field, setting its width to that of the editable field + a left margin
in which he uses the engine's support for numeric list styles to draw
the line numbers:

on textchanged
    lock screen
    set the htmltext of fld "nums" to the htmltext of me
    set the liststyle of line 1 to -1 of fld nums to "decimal"
    set the scroll of fld "nums" to the scroll of me
end textchanged

The only downside I can see to this approach is for memory, as it
requires copying the full styled text from the source field into the
line number field.

Very minor drawbacks for my needs are aesthetic:  I prefer a line number
field without trailing decimal points ("1" rather than "1." as LC's
listStyle renders), and that line number be left-aligned by LC renders
its list line numbers left-aligned.

But overall quite nice, and very snappy. Thanks, Jim!

--
  Richard Gaskin
  Fourth World Systems
  Software Design and Development for the Desktop, Mobile, and the Web
  ____________________________________________________________________
  [hidden email]                http://www.FourthWorld.com

_______________________________________________
use-livecode mailing list
[hidden email]
Please visit this url to subscribe, unsubscribe and manage your subscription preferences:
http://lists.runrev.com/mailman/listinfo/use-livecode
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Line numbers for soft-wrapped styled text?

Monte Goulding via use-livecode
What a cool idea !

In fact, could you not simply do
    set the liststyle of line 1 to -1 of fld "mytextfield" to "decimal"
and then unset the liststyle whenever needed (e.g. when the field is
subject to  copy, save, etc.)

-- Alex.

On 27/03/2017 20:32, Richard Gaskin via use-livecode wrote:

>
>
> This morning Jim Lambert emailed me a very different solution that I
> thought would be worth sharing here.
>
> Here he uses the engine's own metrics for calculating vertical line
> spacings, by having the number field placed below the editable text
> field, setting its width to that of the editable field + a left margin
> in which he uses the engine's support for numeric list styles to draw
> the line numbers:
>
> on textchanged
>    lock screen
>    set the htmltext of fld "nums" to the htmltext of me
>    set the liststyle of line 1 to -1 of fld nums to "decimal"
>    set the scroll of fld "nums" to the scroll of me
> end textchanged
>
> The only downside I can see to this approach is for memory, as it
> requires copying the full styled text from the source field into the
> line number field.
>
> Very minor drawbacks for my needs are aesthetic:  I prefer a line
> number field without trailing decimal points ("1" rather than "1." as
> LC's listStyle renders), and that line number be left-aligned by LC
> renders its list line numbers left-aligned.
>
> But overall quite nice, and very snappy. Thanks, Jim!
>


_______________________________________________
use-livecode mailing list
[hidden email]
Please visit this url to subscribe, unsubscribe and manage your subscription preferences:
http://lists.runrev.com/mailman/listinfo/use-livecode
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Line numbers for soft-wrapped styled text?

Monte Goulding via use-livecode
In reply to this post by Monte Goulding via use-livecode
The solution of Alex T. was the first example I saw of a useful
usage of the styledText array. TMHO this is the way to go for the
future of more and more complicated styled text.

As was said elsewhere, there could be a considerable speed up if
first the visible range of lines, say numbers L1 to L2, is determined.

We had once a thread in the forum about that. The fastest method:

Compare the formattedHeight of line 1 to L of fld T to the vscroll v0
of fld T. Not by walking with L up from one, but by using a binary
search for L1 and then starting from there to find L2 by comparing to
v0+the height of fld T. This needs only a few millisecs even for large
chunks.

Then use Alex's method with the styledText array of these lines. Or,
quick and dirty, save the selectedChunk, select before each line L
in the range L1 to L1 and collect the selectedLocs and then restore
the selectedChunk.

Now draw the line numbers each into an own freshly created field or
use Alex's space below method.

p.s. Hopefully you will share your final code.


_______________________________________________
use-livecode mailing list
[hidden email]
Please visit this url to subscribe, unsubscribe and manage your subscription preferences:
http://lists.runrev.com/mailman/listinfo/use-livecode
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Line numbers for soft-wrapped styled text?

Monte Goulding via use-livecode
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 ?


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.


On 28/03/2017 05:30, hh via use-livecode wrote:

> The solution of Alex T. was the first example I saw of a useful
> usage of the styledText array. TMHO this is the way to go for the
> future of more and more complicated styled text.
>
> As was said elsewhere, there could be a considerable speed up if
> first the visible range of lines, say numbers L1 to L2, is determined.
>
> We had once a thread in the forum about that. The fastest method:
>
> Compare the formattedHeight of line 1 to L of fld T to the vscroll v0
> of fld T. Not by walking with L up from one, but by using a binary
> search for L1 and then starting from there to find L2 by comparing to
> v0+the height of fld T. This needs only a few millisecs even for large
> chunks.
>
> Then use Alex's method with the styledText array of these lines. Or,
> quick and dirty, save the selectedChunk, select before each line L
> in the range L1 to L1 and collect the selectedLocs and then restore
> the selectedChunk.
>
> Now draw the line numbers each into an own freshly created field or
> use Alex's space below method.
>
> p.s. Hopefully you will share your final code.
>
>
> _______________________________________________
> use-livecode mailing list
> [hidden email]
> Please visit this url to subscribe, unsubscribe and manage your subscription preferences:
> http://lists.runrev.com/mailman/listinfo/use-livecode


_______________________________________________
use-livecode mailing list
[hidden email]
Please visit this url to subscribe, unsubscribe and manage your subscription preferences:
http://lists.runrev.com/mailman/listinfo/use-livecode
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Line numbers for soft-wrapped styled text?

Monte Goulding via use-livecode
In reply to this post by Monte Goulding via use-livecode
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.

_______________________________________________
use-livecode mailing list
[hidden email]
Please visit this url to subscribe, unsubscribe and manage your subscription preferences:
http://lists.runrev.com/mailman/listinfo/use-livecode
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

RE: Line numbers for soft-wrapped styled text?

Monte Goulding via use-livecode
In reply to this post by Monte Goulding via use-livecode
I remember once had a problem like something like this. I solved it by
including char 1 to -1 or was it adding the effective keyword? Don't
remember and I don't have time to try at this moment. If you do this do you
get the expected results?

the formattedheight of char 1 to -1 of line N of fld
or
the effective formattedheight of char 1 to -1 of line N of fld
or
the effective formattedheight of line N of fld

Ralph DiMola
IT Director
Evergreen Information Services
[hidden email]


-----Original Message-----
From: use-livecode [mailto:[hidden email]] On Behalf
Of Alex Tweedly via use-livecode
Sent: Tuesday, March 28, 2017 4:13 PM
To: [hidden email]
Cc: Alex Tweedly
Subject: Re: Line numbers for soft-wrapped styled text?

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 ?


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.


On 28/03/2017 05:30, hh via use-livecode wrote:

> The solution of Alex T. was the first example I saw of a useful
> usage of the styledText array. TMHO this is the way to go for the
> future of more and more complicated styled text.
>
> As was said elsewhere, there could be a considerable speed up if
> first the visible range of lines, say numbers L1 to L2, is determined.
>
> We had once a thread in the forum about that. The fastest method:
>
> Compare the formattedHeight of line 1 to L of fld T to the vscroll v0
> of fld T. Not by walking with L up from one, but by using a binary
> search for L1 and then starting from there to find L2 by comparing to
> v0+the height of fld T. This needs only a few millisecs even for large
> chunks.
>
> Then use Alex's method with the styledText array of these lines. Or,
> quick and dirty, save the selectedChunk, select before each line L
> in the range L1 to L1 and collect the selectedLocs and then restore
> the selectedChunk.
>
> Now draw the line numbers each into an own freshly created field or
> use Alex's space below method.
>
> p.s. Hopefully you will share your final code.
>
>
> _______________________________________________
> use-livecode mailing list
> [hidden email]
> Please visit this url to subscribe, unsubscribe and manage your
subscription preferences:
> http://lists.runrev.com/mailman/listinfo/use-livecode


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


_______________________________________________
use-livecode mailing list
[hidden email]
Please visit this url to subscribe, unsubscribe and manage your subscription preferences:
http://lists.runrev.com/mailman/listinfo/use-livecode
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Line numbers for soft-wrapped styled text?

Monte Goulding via use-livecode
Thanks Ralph, but no, that doesn't make any difference.

Usually the "char 1 to -1" addition helps where there is an implied
trailing delimiter. In this case, the problem occurs even for the
simplest chunk expression of just a single line (e.g. "line N") where
the delimiter is never included.

-- Alex.


On 28/03/2017 22:48, Ralph DiMola wrote:

> I remember once had a problem like something like this. I solved it by
> including char 1 to -1 or was it adding the effective keyword? Don't
> remember and I don't have time to try at this moment. If you do this do you
> get the expected results?
>
> the formattedheight of char 1 to -1 of line N of fld
> or
> the effective formattedheight of char 1 to -1 of line N of fld
> or
> the effective formattedheight of line N of fld
>
> Ralph DiMola
> IT Director
> Evergreen Information Services
> [hidden email]
>
>
> -----Original Message-----
> From: use-livecode [mailto:[hidden email]] On Behalf
> Of Alex Tweedly via use-livecode
> Sent: Tuesday, March 28, 2017 4:13 PM
> To: [hidden email]
> Cc: Alex Tweedly
> Subject: Re: Line numbers for soft-wrapped styled text?
>
> 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 ?
>
>
> 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.
>
>
> On 28/03/2017 05:30, hh via use-livecode wrote:
>> The solution of Alex T. was the first example I saw of a useful
>> usage of the styledText array. TMHO this is the way to go for the
>> future of more and more complicated styled text.
>>
>> As was said elsewhere, there could be a considerable speed up if
>> first the visible range of lines, say numbers L1 to L2, is determined.
>>
>> We had once a thread in the forum about that. The fastest method:
>>
>> Compare the formattedHeight of line 1 to L of fld T to the vscroll v0
>> of fld T. Not by walking with L up from one, but by using a binary
>> search for L1 and then starting from there to find L2 by comparing to
>> v0+the height of fld T. This needs only a few millisecs even for large
>> chunks.
>>
>> Then use Alex's method with the styledText array of these lines. Or,
>> quick and dirty, save the selectedChunk, select before each line L
>> in the range L1 to L1 and collect the selectedLocs and then restore
>> the selectedChunk.
>>
>> Now draw the line numbers each into an own freshly created field or
>> use Alex's space below method.
>>
>> p.s. Hopefully you will share your final code.
>>
>>
>> _______________________________________________
>> use-livecode mailing list
>> [hidden email]
>> Please visit this url to subscribe, unsubscribe and manage your
> subscription preferences:
>> http://lists.runrev.com/mailman/listinfo/use-livecode
>
> _______________________________________________
> use-livecode mailing list
> [hidden email]
> Please visit this url to subscribe, unsubscribe and manage your subscription
> preferences:
> http://lists.runrev.com/mailman/listinfo/use-livecode
>


_______________________________________________
use-livecode mailing list
[hidden email]
Please visit this url to subscribe, unsubscribe and manage your subscription preferences:
http://lists.runrev.com/mailman/listinfo/use-livecode
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Line numbers for soft-wrapped styled text?

Monte Goulding via use-livecode
In reply to this post by Monte Goulding via use-livecode


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
> [hidden email]
> Please visit this url to subscribe, unsubscribe and manage your subscription preferences:
> http://lists.runrev.com/mailman/listinfo/use-livecode


_______________________________________________
use-livecode mailing list
[hidden email]
Please visit this url to subscribe, unsubscribe and manage your subscription preferences:
http://lists.runrev.com/mailman/listinfo/use-livecode
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Line numbers for soft-wrapped styled text?

Monte Goulding via use-livecode
In reply to this post by Monte Goulding via use-livecode
I see, you are optimizing this. Will become perfect.

The current search is part of a script that has to work also for
non-wrapped text (with possibly horizontal scrollbar) and is a first
step for calculating the visible "chars" (incl. whitespace).

In sum: you are right, the search for the lines can/should be
optimised (you already show a way to go).

From my point of view it has to be a rough estimate only, can be a
full line off, could stop after finding this 'top line' L1, using
then, say, L1-2 to be on the safe side.

*** My approach would then be to start calculating (or collecting, by
using the selectedLoc):
Walk through the string from there, line by line, as one needs the top
of each single 'visible' lines at any rate for the numbers display.
Then compare these found tops with the top and the bottom of the field
and decide when to start and when to stop. ***

Of course, if one would like to know only the line numbers, then a
binary search (optimised in your sense) for the bottomLine could/should
also be done.

This is essentially the same problem starting with a downward shifted
text. This again shows immediately that all your considerations are true
and will lead to an improvement.

So this could then use the same algorithm and adaptive guessing, returning
this time L2+2, to be on the safe side.

By the way:
The problem 'space-below' is probably a general problem of the current
text measurement, because for some fonts with extreme metrics ('Zapfino')
or others with wrong/incomplete metrics we have wrong measurement values.
This leads to the bug which I have seen (and seen reported as bug) that
the insertion cursor is up to a full line "off" (in direction top) and of
wrong height.

I'm looking forward to your complete solution. Perhaps one could even try
to draw a ruler with ticks at the exact line borders for styled text.

> Alex T. wrote:
>

> 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).


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