Justifying text
[1/29] from: louisaturk:coxinet at: 12-Dec-2002 13:29
Hi Rebols,
Merry Christmas to you all.
Is there an easy way to justify text using rebol/view?
Louis
[2/29] from: greggirwin:mindspring at: 12-Dec-2002 13:43
Hi Louis,
LAT> Is there an easy way to justify text using rebol/view?
Is this what you're after?
view layout [
text 200 "testing"
text 200 "testing" center
text 200 "testing" right
]
If you want the internal spacing adjusted...I don't know a trick for
that.
-- Gregg
[3/29] from: carl:cybercraft at: 13-Dec-2002 10:25
On 13-Dec-02, Louis A. Turk wrote:
> Hi Rebols,
> Merry Christmas to you all.
Merry Chrristmas Louis!
> Is there an easy way to justify text using rebol/view?
Unfortunately, I don't think there is. You can center and right-align
lines, but that's it as far as I know.
Alignment's stored in the font object...
>> layout [a: area center middle]
>> probe a/font
make object! [
name: "CGTriumvirate"
style: none
size: 12
color: 0.0.0
offset: 2x2
space: 0x0
align: 'center
valign: 'middle
shadow: none
colors: none
]
and the space word there changes the spacing between letters, so that
could possibly be used to give justification. I'd think you'd need
two faces for each line of your text though, which would be possible,
just not easy.
--
Carl Read
[4/29] from: louisaturk:coxinet at: 12-Dec-2002 17:29
Hi Carl,
At 10:25 AM 12/13/2002 +1300, you wrote:
>On 13-Dec-02, Louis A. Turk wrote:
> > Hi Rebols,
<<quoted lines omitted: 3>>
>Unfortunately, I don't think there is. You can center and right-align
>lines, but that's it as far as I know.
To bad. Justification would be a great feature. Oh well, thanks anyway.
Louis
[5/29] from: louisaturk:coxinet at: 12-Dec-2002 17:05
Thanks for answering, Greg,
At 01:43 PM 12/12/2002 -0700, you wrote:
>Hi Louis,
>LAT> Is there an easy way to justify text using rebol/view?
<<quoted lines omitted: 6>>
>If you want the internal spacing adjusted...I don't know a trick for
>that.
Unfortunately, that is what I want---to justify a column of text.
Louis
[6/29] from: ammon:addept:ws at: 12-Dec-2002 19:01
Hi,
You can also try:
field 200x32 "Top aligned" top
field 200x32 "Middle aligned" middle
field 200x32 "Bottom aligned" bottom
HTH
Ammon Johnson --- CIO
Addept ------------------ (www.addept.ws)
435-616-2322 -------- (ammon at addept.ws)
[7/29] from: carl:cybercraft at: 13-Dec-2002 18:33
On 13-Dec-02, Louis A. Turk wrote:
> Hi Carl,
> At 10:25 AM 12/13/2002 +1300, you wrote:
<<quoted lines omitted: 7>>
> To bad. Justification would be a great feature. Oh well, thanks
> anyway.
How were you hoping to display the text? Something specific (as
apposed to general-purpose) mightn't be that hard to put together
using a list (perhaps).
--
Carl Read
[8/29] from: greggirwin:mindspring at: 13-Dec-2002 11:19
Hi Carl,
CR> How were you hoping to display the text? Something specific (as
CR> apposed to general-purpose) mightn't be that hard to put together
CR> 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.
Alternately, on Windows, you could call the DRAWTEXT API to render the
text to a DC and then grab the DC as an image and display it, but that
would be a big pain IMO.
-- Gregg
[9/29] from: louisaturk:coxinet at: 13-Dec-2002 19:32
Hi Carl and Gregg,
Actually, I was just asking out of curiosity this time, as I don't have
time to work on this right now---so I am looking for an easy solution. My
word processor I use has a bug in it that has been known for several years,
and it prevents me from finishing a project. It cannot properly display
and print snaking columns when they contain footnotes. I was just
wondering how hard it would be to do it with rebol. I wonder if pdfmaker
could be used?
Louis
At 11:19 AM 12/13/2002 -0700, you wrote:
[10/29] 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
<<quoted lines omitted: 8>>
> 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
[11/29] from: louisaturk:coxinet at: 14-Dec-2002 3:14
Hi Carl,
Many thanks for your effort and time in doing this. I'll be studying your
code closely. Much of my programming involves formatting text in various
ways. I very much appreciate your help!
Louis
At 08:23 PM 12/14/2002 +1300, you wrote:
[12/29] from: carl:cybercraft at: 15-Dec-2002 1:40
On 14-Dec-02, Louis A. Turk wrote:
> Hi Carl,
> Many thanks for your effort and time in doing this. I'll be studying
> your code closely. Much of my programming involves formatting text
> in various ways. I very much appreciate your help!
Hi Louis,
It's just that I got interested in the problem. (: Text can be spread
out easily enough with View using font/space...
view layout [text "Hello World" font [space: 20x0]]
The hard part is that View (or VID) strips leading and following
spaces from words...
>> layout [x: text " abc "]
>> probe x/text
abc
and so some method to work around that has to be sussed out. The
method I'm using in that example isn't quite right though...
--
Carl Read
[13/29] from: gscottjones:mchsi at: 14-Dec-2002 6:55
From: "Carl Read"
> 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....
That is neat, Carl. I am surprised that it is as quick as it is.
--Scott Jones
[14/29] from: doncox:enterprise at: 14-Dec-2002 12:28
On 14/12/02, Louis A. Turk wrote:
> Actually, I was just asking out of curiosity this time, as I don't
> have time to work on this right now---so I am looking for an easy
<<quoted lines omitted: 3>>
> footnotes. I was just wondering how hard it would be to do it with
> rebol. I wonder if pdfmaker could be used?
For any complex layouts like that, use a DTP program such as Pagemaker,
Quark XPress, Pagestream, or InDesign.
You are trying to use a word processor for doing layout. They are never
very good at it.
Regards
--
Don Cox
[doncox--enterprise--net]
[15/29] from: g:santilli:tiscalinet:it at: 14-Dec-2002 14:54
Hi Carl,
On Saturday, December 14, 2002, 1:40:49 PM, you wrote:
>>> layout [x: text " abc "]
layout [x: text as-is " abc "]
Regards,
Gabriele.
--
Gabriele Santilli <[g--santilli--tiscalinet--it]> -- REBOL Programmer
Amigan -- AGI L'Aquila -- REB: http://web.tiscali.it/rebol/index.r
[16/29] from: rotenca:telvia:it at: 14-Dec-2002 16:04
Hi Carl
> The hard part is that View (or VID) strips leading and following
> spaces from words...
<<quoted lines omitted: 3>>
>> layout [t: text as-is " abc "]
>> t/text
== " abc "
---
Ciao
Romano
[17/29] from: greggirwin:mindspring at: 14-Dec-2002 12:51
Hi Carl,
CR> I've had a quick (yeah, right;) go at it, but my approach is slightly
CR> different. As I said, I thought of using font/space to do the
CR> padding, as this would only require two faces per line, as apposed to
CR> one per word. Anyway, below is (the slightly bugged) result I've
CR> come up with....
Cool! Not sure how to work around the way /space works though. I'm
thinking it maps to SetTextCharacterExtra (under Windows) while what
we really want is something that maps to SetTextJustification that
tells the drawing functions how much space to add to each *break*
character when the text is rendered.
Alternately, we could take a low tech approach if imperfect results
for proportional fonts is acceptable; just add spaces to the text. :)
-- Gregg
[18/29] from: carl:cybercraft at: 15-Dec-2002 13:02
On 15-Dec-02, Gabriele Santilli wrote:
> Hi Carl,
> On Saturday, December 14, 2002, 1:40:49 PM, you wrote:
>>>> layout [x: text " abc "]
> layout [x: text as-is " abc "]
Thanks Gabriele! (And Romano!:)
And that simplified things a lot, as did adding background colors to
the text faces so I could see exactly what was happening.
So, here's the debugged version. (; (Well, at least on Amiga.)
Enjoy...
rebol []
justify: func [
{This accepts a string and an integer and returns a
block containing 5 values, the values being the left
part of the string and the font/space/x value to use
for justifying it, the right part of the string and
its font/space/x value, plus an integer representing
the padding needed between them.
}
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 0]
]
pad: to-integer width - text-width/x / (-1 + length? text)
rem: remainder width - text-width/x (-1 + length? text)
reduce [
copy/part text rem
either rem = 0 [0][pad + 1]
skip text rem
pad
either rem = 0 [0][pad]
]
]
lines: [
"This is an"
"attempt at"
"justifying"
"text using"
"REBOL/View."
""
"It is pretty"
"limited but"
"might be of"
"some use to"
"someone now"
"that it's"
"debugged! (:"
]
build-layout: does [
lo: copy [
backdrop tan
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 'as-is copy blk/1 'black 'gold 'font reduce [
to-set-word 'space to-pair reduce [blk/2 0]
]
]
if not zero? blk/5 [append lo reduce ['pad blk/5]]
append lo reduce [
'txt 'as-is copy blk/3 'black 'wheat '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
[19/29] from: carl:cybercraft at: 15-Dec-2002 18:35
On 15-Dec-02, Carl Read wrote:
> On 15-Dec-02, Gabriele Santilli wrote:
>> Hi Carl,
<<quoted lines omitted: 5>>
> the text faces so I could see exactly what was happening.
> So, here's the debugged version. (; (Well, at least on Amiga.)
Just checked it on Windows and the padded lines are a pixel-width out.
(It's pixel-perfect on Amiga.) Changing the following line in the
justify function...
either rem = 0 [0][pad]
to...
either rem = 0 [0][pad - 1]
fixes it on Windows, but then it mucks up the padded lines by a pixel
on the Amiga version. (: Pretty close either way though!
--
Carl Read
[20/29] from: g:santilli:tiscalinet:it at: 15-Dec-2002 10:49
Hi Carl,
On Sunday, December 15, 2002, 1:02:33 AM, you wrote:
CR> And that simplified things a lot, as did adding background colors to
CR> the text faces so I could see exactly what was happening.
Why are you using two faces per line?
Regards,
Gabriele.
--
Gabriele Santilli <[g--santilli--tiscalinet--it]> -- REBOL Programmer
Amigan -- AGI L'Aquila -- REB: http://web.tiscali.it/rebol/index.r
[21/29] from: carl:cybercraft at: 15-Dec-2002 23:36
On 15-Dec-02, Gabriele Santilli wrote:
> Hi Carl,
> On Sunday, December 15, 2002, 1:02:33 AM, you wrote:
>> And that simplified things a lot, as did adding background
>> the text faces so I could see exactly what was
>> happening.
> Why are you using two faces per line?
Consider a line of 10 characters that's five pixels short of the width
you want the line to be. If you set font/space to 1x0, that'd add
nine pixels to the width of the line, (1 between each character),
which would make it too wide.
What you need to do is add 1 pixel between the first six characters
and leave the following four spaces at 0x0 - hence the need for two
faces. And using two faces means you need padding between them as
well.
Does that make sense? (:
There's a lot of other ways you could do this I guess, such as a face
per word and using the padding between them to get the width right,
but that'd mean much more than two faces per line in most cases.
--
Carl Read
[22/29] from: g:santilli:tiscalinet:it at: 15-Dec-2002 12:36
Hi Carl,
On Sunday, December 15, 2002, 11:36:57 AM, you wrote:
CR> Does that make sense? (:
I see. :-) I wasn't thinking about the fact that we've got
integers there. :-)
Regards,
Gabriele.
--
Gabriele Santilli <[g--santilli--tiscalinet--it]> -- REBOL Programmer
Amigan -- AGI L'Aquila -- REB: http://web.tiscali.it/rebol/index.r
[23/29] from: carl:cybercraft at: 16-Dec-2002 1:25
On 16-Dec-02, Gabriele Santilli wrote:
> Hi Carl,
> On Sunday, December 15, 2002, 11:36:57 AM, you wrote:
>> Does that make sense? (:
> I see. :-) I wasn't thinking about the fact that we've got
> integers there. :-)
There's probably a Nobel prize waiting for the first person who can
split a pixel. (;
--
Carl Read
[24/29] from: nitsch-lists:netcologne at: 15-Dec-2002 13:39
Carl Read wrote:
>On 15-Dec-02, Gabriele Santilli wrote:
>>Hi Carl,
<<quoted lines omitted: 19>>
>per word and using the padding between them to get the width right,
>but that'd mean much more than two faces per line in most cases.
editors shift text with face/para/scroll afaik. /para shared between
faces, remember to clone it
-volker
[25/29] from: nitsch-lists:netcologne at: 15-Dec-2002 14:42
Volker Nitsch wrote:
> Carl Read wrote:
[snip]
>>
>> Consider a line of 10 characters that's five pixels short of the width
<<quoted lines omitted: 15>>
> editors shift text with face/para/scroll afaik. /para shared between
> faces, remember to clone it
Sorry, gave wrong answer, you split text. lazy as usual, i read "move
text" and thought it was usefull.
now tried example, nice :)
[26/29] from: carl:cybercraft at: 16-Dec-2002 14:57
On 15-Dec-02, Gregg Irwin wrote:
> Hi Carl,
>> I've had a quick (yeah, right;) go at it, but my approach is
<<quoted lines omitted: 7>>
> tells the drawing functions how much space to add to each *break*
> character when the text is rendered.
Given the different ways justification could be done across different
platforms, I'd guess View adds that spacing itself, as it wouldn't
surprise me if some OSs don't provide a way to do it. That there's
no justification in View at the moment suggests it's not easy to add
and get right on all the platforms View's running on. What's really
needed is the ability edit a justified text-area, which you can't do
with my hack.
--
Carl Read
[27/29] from: doncox:enterprise at: 16-Dec-2002 10:50
On 15/12/02, Carl Read wrote:
>>> Does that make sense? (:
>
>> I see. :-) I wasn't thinking about the fact that we've got
>> integers there. :-)
>
> There's probably a Nobel prize waiting for the first person who can
> split a pixel. (;
You can position characters between pixel step positions by using
anti-aliasing. For example, create the bitmap 16x the final size (so you
have 16x as many steps), then scale down.
I don't know if that's possible in Rebol.
Regards
--
Don Cox
[doncox--enterprise--net]
[28/29] from: doncox:enterprise at: 15-Dec-2002 15:48
On 14/12/02, Gregg Irwin wrote:
> Alternately, we could take a low tech approach if imperfect results
> for proportional fonts is acceptable; just add spaces to the text. :)
It depends whether Rebol is for use by amateurs or professionals.
When adjusting spacing to make a line of text fit a certain width, it is
best with most fonts to increase the letter spacing (tracking) as well
as the word spacing. The letter spacing must take account of any kerning
pairs in the font.
This problem comes up when text is wrapped around a picture as well as
when it is to be fully justified.
If the font is monospaced (eg Courier) then only extra spaces between
words are needed.
If you look at the Postscript code from a DTP program where text has
been fully justified, you will see coordinates specified for each
character individually.
Regards
--
Don Cox
[doncox--enterprise--net]
[29/29] from: g:santilli:tiscalinet:it at: 16-Dec-2002 12:32
Hi Don,
On Sunday, December 15, 2002, 4:48:18 PM, you wrote:
DC> When adjusting spacing to make a line of text fit a certain width, it is
DC> best with most fonts to increase the letter spacing (tracking) as well
DC> as the word spacing. The letter spacing must take account of any kerning
DC> pairs in the font.
The PDF Maker justifies text this way.
DC> If you look at the Postscript code from a DTP program where text has
DC> been fully justified, you will see coordinates specified for each
DC> character individually.
It looks strange to me, since PDF is considered to be a subset of
PostScript feature-wise, and PDF allows you to just set the char-
and word-spacing.
For example, this is a justified line created by PDF Maker:
0.239095357142857 Tw 0.03347335 Tc
[(Suppor) -40 (t f) 30 (or custom f) 30 (onts w) 10
(ould definitely require w) 10 (or) -15 (k to be added;)
50 ( justification and r) -15 (ight alignment)] TJ
Tw sets the word spacing, Tc the character spacing. The numbers in
the text are for kerning.
Regards,
Gabriele.
--
Gabriele Santilli <[g--santilli--tiscalinet--it]> -- REBOL Programmer
Amigan -- AGI L'Aquila -- REB: http://web.tiscali.it/rebol/index.r
Notes
- Quoted lines have been omitted from some messages.
View the message alone to see the lines that have been omitted