[comp.sys.mac.programmer] Text Spacing on Laser & Fractional Font Sizes?

a_dent@fennel.cc.uwa.oz.au (10/28/90)

I'm working on a newspaper printing application where I have to fully justify
text (actually it's kind of fun, taking the text and codes previously sent to
a traditional printer & handling them on the Mac - Think Pascal's OOP library is
GREAT!).

So far I've come to terms with SetFractEnable and SpaceExtra and am using the
PicComment to tell the laserprint to fully justify the text.

The books/Technotes say that the Laserwriter takes the text endpoints set by
Quickdraw and justifies the text between those points.  As far as I can see, 
the only way to set these "Endpoints" is to draw the text in Quickdraw as
accurately as possible - ie: using fractional widths and SpaceExtra.  Am I
missing something here?

Secondly, how do you specify fractional font sizes?  The text I am trying to
emulate looks like about a 5.9 point Helvetica.

It is sure MESSY tracking down all the info on these bits and pieces.  (Thank
Phil for the Technote stack!).

(By the way, the comment on the "univ" parameter type for my pointer unit was 
appreciated, but I did them as they were for orthogonality - I had a need for
procedures in some places and functions in others).

Thanks in Advance

Andy Dent                     A.D. Software phone 09 249 2719
Mac & VAX programmer          94 Bermuda Dve, Ballajura
a_dent@fennel.cc.uwa.oz       Western Australia  6066     
a_dent@fennel.cc.uwa.oz.AU (international)

kaufman@Neon.Stanford.EDU (Marc T. Kaufman) (10/29/90)

In article <1990Oct28.235805.2481@fennel.cc.uwa.oz.au> a_dent@fennel.cc.uwa.oz.au writes:

>The books/Technotes say that the Laserwriter takes the text endpoints set by
>Quickdraw and justifies the text between those points.  As far as I can see, 
>the only way to set these "Endpoints" is to draw the text in Quickdraw as
>accurately as possible - ie: using fractional widths and SpaceExtra.  Am I
>missing something here?

That is correct.  The LW driver will do a MeasureText using your settings
for FractEnable and SpaceExtra (and CharExtra), and use the results as the
endpoints for the line.  Actual spacing, character-to-character, will be
different on the Laserwriter.

>Secondly, how do you specify fractional font sizes?  The text I am trying to
>emulate looks like about a 5.9 point Helvetica.

Use the StdText procedure to draw the text.  You can specify fine scaling via
the numer and denom parameters.  Try, e.g. 59/100, with 10 point type.
Note that this will change the measured width, (above), and you will have
to compensate for that.  Within a TextBegin-TextEnd comment, ALL calls to
StdText must have the SAME numer/denom, or you will get funny results.

Marc Kaufman (kaufman@Neon.stanford.edu)

neil@odin.ucsd.edu (Neil Rhodes) (10/29/90)

In article <1990Oct28.235805.2481@fennel.cc.uwa.oz.au> a_dent@fennel.cc.uwa.oz.au writes:
>I'm working on a newspaper printing application where I have to fully justify
>text
>So far I've come to terms with SetFractEnable and SpaceExtra and am using the
>PicComment to tell the laserprint to fully justify the text.
>
>The books/Technotes say that the Laserwriter takes the text endpoints set by
>Quickdraw and justifies the text between those points.  As far as I can see, 
>the only way to set these "Endpoints" is to draw the text in Quickdraw as
>accurately as possible - ie: using fractional widths and SpaceExtra.  Am I
>missing something here?

I worked on the HP PaintJet and PaintWriter drivers and am familiar with how
other printer drivers handle text.

	The best way to set text for printing is indeed to make sure that
the QuickDraw calls you make cause the endpoints of the text to be where
you want it.  Note that most printer drivers do NOT set each string
(call to DrawString, DrawText, or StdText) individually, but rather look at
a whole line, and cause the endpoints of the whole line to remain the same.
Therefore, a word in bold in the middle of a line of normal text is justified
along with the normal text.  Using fractional widths is certainly your best
bet.  If your goal is to justify your text, fractional widths along with 
SpaceExtra will work just fine.  Note that the printed page will most likely
have different amounts of space for the space character than you requested;
however, the endpoints will remain constant.  There is no need to use the
LaserWriter picture comment to do full justification.

>
>Secondly, how do you specify fractional font sizes?  The text I am trying to
>emulate looks like about a 5.9 point Helvetica.
>

	There is a QuickDraw call StdText which takes as parameters a
numerator and denominator (both points) which specify the horizontal and
vertical scaling. To obtain 5.9 point text, you could specify 59 point text
with TextSize, and then call StdText with numer.h=numer.v=10, and 
denom.h=denom.v=10.  You can make sure this is doing what you want by drawing
to the screen first (you should see six point on the screen).

>Andy Dent                     A.D. Software phone 09 249 2719
>Mac & VAX programmer          94 Bermuda Dve, Ballajura
>a_dent@fennel.cc.uwa.oz       Western Australia  6066     
>a_dent@fennel.cc.uwa.oz.AU (international)




-- 
Neil Rhodes    Calliope Enterprises, Inc.  neil@odin.ucsd.edu

lippin@wish-bone.berkeley.edu (The Apathist) (10/30/90)

Rather than using SpaceExtra to do full justification, I suggest using
DrawJust, or its younger sibling, NDrawJust.  Both take a slop
parameter that controls just how much to stretch the line.  NDrawJust
also takes scaling parameters (like StdText does) which will help you
achieve fractional font sizes.

The only catch lies in finding the documentation for these routines --
they're not listed in IM.  DrawJust is described in the Script Manager
2.0 interim chapter of IM (strangely, this isn't part of IM VI).
NDrawJust is listed in a document titled roughly "Guide to Worldwide
Software Development" which is part of IM VI.  Both documents are also
available from APDA, and, I think, on the Developer CD.

					--Tom Lippincott
					  lippin@math.berkeley.edu

 "Ask a fish head anything you want to.  It won't answer you; they can't talk."

a_dent@fennel.cc.uwa.oz.au (11/21/90)

In article <1990Oct30.054006.22697@agate.berkeley.edu>, lippin@wish-bone.berkeley.edu (The Apathist) writes:
> 
> Rather than using SpaceExtra to do full justification, I suggest using
> DrawJust, or its younger sibling, NDrawJust.  Both take a slop
> parameter that controls just how much to stretch the line.  NDrawJust
> also takes scaling parameters (like StdText does) which will help you
> achieve fractional font sizes.
> 
> The only catch lies in finding the documentation for these routines --
> they're not listed in IM.  DrawJust is described in the Script Manager
> 2.0 interim chapter of IM (strangely, this isn't part of IM VI).
But it IS part of IM vol FIVE!!!!! (although I didn't get any better results
than the methods I've been using).

On a different but related note, I ran into an interesting problem with fully
justified text being copied to the clipboard.  Although properly justified
when looked at with Clipboard Magician (GREAT tool) the text failed to justify
when pasted into MacDraw II.  MacDraw II has a definition of "justification"
which doesn't allow single lines to be "spread" out to the length of the
text box - it only justifies multiple line objects.

In case anyone else is wondering how to get around a similar problem, I 
finally solved it by sending each word as a separate text object, the last one
being Right justified.  The definition of the Text record and some sample code
are shown below, the main point being the use of the (IM vol 5 Script Manager)
call Char2Pixel to get the start of the words.

type
 laserJust = (leftJust, centreJust, rightJust, fullJust);


 someJustText = record
   pos: ptr;
   len, x, y, width, numSpaces, pointsShort: integer;    { NOTE numSpaces & pointsShort only used if we're going to Fully justify field }
   just: laserJust;
   moveUpALine: boolean;
  end;

{**** sample code for drawing fully justified text so it works with MacDraw II ***}
{ text is an array of someJustText, the locations "x" & "y" being calculated }
{ in a parsing stage earlier.  "Pos" points to the text & the "just" and }
{ "moveUpALine" fields aren't used in this procedure. }

   textStyle.setStyle;
   i := 1;
   while (i < textLines) & (text[i + 1].len > 0) do
    with text[i] do begin
     lastCharInLineOffset := len - 1;
     charOffsetInLine := 0;
     startOfWord := 0;
     lengthOfWord := 1;
     charDrawingOffset := Char2Pixel(pos, len, pointsShort, charOffsetInLine, smHilite);
     charPtr := Plus1P(pos);
     charOffsetInLine := 1;
     while charOffsetInLine < lastCharInLineOffset do begin  { remember offset's 0-based, start at 2nd char }
{ if get a space then end of a word so draw the word }
      if charAt(charPtr) = space then begin
       charX := x + charDrawingOffset;
       MoveTo(charX, y);
       DrawText(pos, startOfWord, lengthOfWord);
       repeat  { skip one or more spaces after word }
       incI(charOffsetInLine);
       incP(charPtr);
       until (charAt(charPtr) <> space) | (charOffsetInLine = lastCharInLineOffset);
{ now set the start of the next word - what char it starts at and where on screen }
       charDrawingOffset := Char2Pixel(pos, len, pointsShort, charOffsetInLine, smHilite);
       startOfWord := charOffsetInLine;
       lengthOfWord := 1;
      end
      else begin  { just a normal character }
       incI(lengthOfWord);
       incI(charOffsetInLine);
       incP(charPtr);
      end;
     end; { loop through single line }
{ last word is Right aligned except on last line }
     PicComment(TextBegin, rightJustPicCommentSize, handle(rightJustPicCommentHandle));
     charX := x + charDrawingOffset;
     MoveTo(charX, y);
     DrawText(pos, startOfWord, lengthOfWord);
     PicComment(TextEnd, 0, nil);
     incI(i);
    end;  { loop through lines }
   with text[i] do begin
    MoveTo(x, y);
    DrawText(pos, 0, len);
   end;
  end; { some lines to process }


Andy Dent                     A.D. Software phone 09 249 2719
Mac & VAX programmer          94 Bermuda Dve, Ballajura
a_dent@fennel.cc.uwa.oz       Western Australia  6066     
a_dent@fennel.cc.uwa.oz.AU (international)

kaufman@Neon.Stanford.EDU (Marc T. Kaufman) (11/22/90)

In article <1990Nov21.234954.2636@fennel.cc.uwa.oz.au> a_dent@fennel.cc.uwa.oz.au writes:

>On a different but related note, I ran into an interesting problem with fully
>justified text being copied to the clipboard.  Although properly justified
>when looked at with Clipboard Magician (GREAT tool) the text failed to justify
>when pasted into MacDraw II.  MacDraw II has a definition of "justification"
>which doesn't allow single lines to be "spread" out to the length of the
>text box - it only justifies multiple line objects.

Well, actually, this is how full justification is supposed to work.  Go into
your favorite text editor (say, MacWrite or Word), select Full Justification,
and type away.  You will find that every line in the paragaph, EXCEPT THE LAST,
is fully justified.  The last line will be left justified only.  Or look at
a newspaper.

Marc Kaufman (kaufman@Neon.stanford.edu)