Mailing List Archive: 49091 messages
  • Home
  • Script library
  • AltME Archive
  • Mailing list
  • Articles Index
  • Site search
 

[REBOL] Re: Justifying text

From: carl:cybercraft at: 14-Dec-2002 20:23

On 14-Dec-02, Gregg Irwin wrote:
> Hi Carl, >> How were you hoping to display the text? Something specific (as >> apposed to general-purpose) mightn't be that hard to put >> using a list (perhaps). > I was thinking, that you could do it yourself, though it would > probably be hideously slow one way, and complex the other way. > If you could get the lines, as wrapped, for a face (but I don't know > that you can as line-list doesn't always seem to be set), then you > could iterate over them, find the actual width for each line, take > that from the width you want, giving you a width delta, then count > words and add (delta/word-count) to each offset, using either draw > commands or faces. Faces would be bad unless you only need a few.
I've had a quick (yeah, right;) go at it, but my approach is slightly different. As I said, I thought of using font/space to do the padding, as this would only require two faces per line, as apposed to one per word. Anyway, below is (the slightly bugged) result I've come up with.... rebol [] justify: func [ {This accepts a string and an integer and returns a block containing 4 values, the values being the left part of the string and the font/space/x value to use for justifying it, and the right part of the string and its font/space/x value. } text [string!] "Text to be justified." width [integer!] "Width to justify in pixels." /local text-width pad rem ][ face/text: text if none? text-width: size-text face [text-width: 0x0] if any [width <= text-width/x text = ""][ return reduce [text 0 "" 0] ] pad: to-integer width - text-width/x / length? text rem: remainder width - text-width/x length? text reduce [ copy/part text rem either rem = 0 [0][pad + 1] skip text rem pad ] ] lines: [ "This is an" "attempt at" "justifying" "text using" "REBOL/View." "" "It is pretty" "limited but" "might be of" "some use to" "someone if" "they can" "debug it..." ] build-layout: does [ lo: copy [ style txt text para [origin: 0x0 margin: 0x0] across space 0x0 ] face/text: " " space-size: size-text face foreach line lines [ blk: justify line width append lo reduce [ 'txt copy blk/1 'font reduce [ to-set-word 'space to-pair reduce [blk/2 0] ] ] ; This bit is supposed to pad out spaces and the join ; between the two text faces, but it ain't working ; quite right... (: (The justify function should ; probably work out the padding anyway...) ; ------ padding: 0 if not any [empty? blk/1 empty? blk/3][padding: blk/4] if " " = back tail blk/1 [ padding: padding + space-size/x + blk/2 ] if " " = blk/3/1 [ padding: padding + space-size/x + blk/4 ] if padding > 0 [append lo reduce ['pad padding]] ; ------ append lo reduce [ 'txt copy blk/3 'font reduce [ to-set-word 'space to-pair reduce [blk/4 0] ] 'return ] ] append lo [button 60 "Close" [unview]] ] ; Get longest line ;------------------ width: 0 foreach line lines [ if line-length: size-text make face [text: line][ width: max width line-length/x ] ] ; Tests ;------- build-layout view layout lo width: width + 20 build-layout view layout lo width: width + 40 build-layout view layout lo -- Carl Read