[comp.sys.mac.programmer] LDEF with multiple fonts

volaski@acsu.buffalo.edu (11/22/89)

I am trying to implement a list with text that has multiple fonts. The standard
listDefProc allows for text, but it uses the current grafport's font. As a result
only one font, face, and style is allowed.

One solution to this is to write an LDEF that uses the new textedit routines in
IM vol 5. Another is to write an LDEF that draws to an offscreen bitmap and uses
copybits to copy to the list.

I have tried both with only some success.

First, I wrote an LDEF that puts a edit record (with TEStyleNew) into the list's 
userhandle. Then in the draw routine I am setting the text to what it is set to by
LSetCell in the DA. (oh yes the LDEF is being called from a DA) Finally I call TEUpdate to draw the text. The problem
is that it works for the first cell only. Sucessive cells do not draw. I have used
drawstring and have determined that my LDEF is carrying out LSetCell. 

Why would this only work for the first cell drawn and then just stop?

Second, I tried something simple like calling TextFont to change grafport characteristics
each time a drawMessage is sent to my LDEF. This doesn't work and I figure it is because my LDEF cannot accesss the DA's grafport.
I then tried making a new grafport and changing its font with TextFont and using CopyBits to draw into a cell. This works! But it is very slow. I wanted to make the grafport
in response to an initialization message, but it appears that the list manager will
only allow private storage in the list record's userhandle. 

Is there a way to allocate storage for a grafport in the list record's userhandle?

Finally, is there some other method I haven't thought of using?

Any help will be appreciated.

Maurice Volaski

oster@dewey.soe.berkeley.edu (David Phillip Oster) (11/23/89)

To write an LDEF that uses multiple fonts,
1.) you can have your LDEF's draw routine save the GrafPort's current font,
draw the text in the new font, and restore the font. Since this requires
all the fonts you use to be in memory, this takes a lot of RAM, and a lot
of time for the initial disk reads.
2.) You can use bitmaps. See the tech note on drawing SICNs for tips on
drawing arbitrary offscreen bitmaps.

Both of the above techniques have one problem: the List manager does not
support variable sized items. 12 point Geneva is not the same height as 14
point Symbol. What I did was: I wrote a menu definition procedure, an MDEF,
that handled variable sized, scrollable units. Then I wrote a package to
simulate a list manager list to the user, but it was actually calling my
MDEF to do the drawing.

tim@hoptoad.uucp (Tim Maroney) (11/24/89)

In article <13687@eerie.acsu.Buffalo.EDU> volaski@acsu.buffalo.edu () writes:
>I am trying to implement a list with text that has multiple fonts. The standard
>listDefProc allows for text, but it uses the current grafport's font. As a
>result only one font, face, and style is allowed.
>
>I tried something simple like calling TextFont to change grafport characteristics
>each time a drawMessage is sent to my LDEF. This doesn't work and I figure it is because my LDEF cannot accesss the DA's grafport.

First of all, *please* try to restrict your messages to 79 characters
per line.  Thank you.

I use TextFont, TextSize, and TextFace routinely in LDEFs, and I've
never had any problem with them.  You can in fact access and modify
your owning window's grafPort, though of course you should do so with
caution.  So whatever problem you had while doing this must have been a
product of some hidden bug in your code that made it appear to you that
the TextFont call was not working.  If you still have the code, you
should pull it out and try again, and perhaps placing debugging
breakpoints on TextFont and DrawText (or whatever you are using to draw
text).  This implementation of font changes seems like by far the
easiest of the three approaches you mentioned.
-- 
Tim Maroney, Mac Software Consultant, sun!hoptoad!tim, tim@toad.com

"Every year, thousands of new Randoids join the ranks.  Most tend to be either
 too-rich self-made tycoons or picked-on computer nerds (the romantic, heroic
 individualism of Rand's novels flatters the former and fuels the latter's
 revenge fantasies)." -- Bob Mack, SPY, July 1989

volaski@acsu.buffalo.edu (11/26/89)

I got what I needed done without an LDEF (by using a PICT for display-only
info). 

However, I'm still curious as to why my TextFont doesn't work. Here's my code:

procedure DrawList;
  begin
   with lhandle^^ do
    begin
     theChar := cells^^[lDataOffset];
     aStr := theChar;
     Textfont(6);	{this line is ignored; everything appears in Geneva}
     with lRect do
     moveTo(left, bottom);
     drawstring(aStr);
    end;
  end;

Maurice

tim@hoptoad.uucp (Tim Maroney) (11/29/89)

In article <13748@eerie.acsu.Buffalo.EDU> volaski@acsu.buffalo.edu () writes:
>I'm still curious as to why my TextFont doesn't work. Here's my code:
>
>procedure DrawList;
>  begin
>   with lhandle^^ do
>    begin
>     theChar := cells^^[lDataOffset];
>     aStr := theChar;
>     Textfont(6);	{this line is ignored; everything appears in Geneva}
>     with lRect do
>     moveTo(left, bottom);
>     drawstring(aStr);
>    end;
>  end;

I'm curious too.  Is it possible you don't have London font (font 6)
installed?  Also, why aren't you doing a TextSize, since London doesn't
come in the default 12 point size?  This omission makes me wonder, is
this your real and complete code?  It also makes me wonder if, on
getting the bad font size, the system would use Geneva instead of
scaling the font down, but I don't see why it would.  Here's an example
of some code in an LDEF of mine that draws in a nonstandard font.

	TextFont(newYork); TextSize(9); TextFace(0); GetFontInfo(&info);
	w1 = TextWidth(p->humanName + 1, 0, p->humanName[0]) + 2;
	MoveTo(r.left + 4, r.bottom - (1 + info.leading + info.descent));
	DrawText(p->humanName + 1, 0, p->humanName[0]);

Since it works, so should yours.

One more note.  You are using unsafe "with" statements.  It is unsafe
to use a with statement involving a relocatable handle if anything
within the with statement could cause memory to be moved.  TextFont can
cause memory to be moved, so it could cause the previous dereference of
lhandle to become invalid, and so you would be reading from invalid
memory.  This wouldn't cause your problem, but it could cause a problem
in various conditions.  You should just bite the bullet and say
"lhandle^^" before every field reference.  (Actually, looking at
your code, it probably won't cause a problem, but it would be easy
to forget and add a new statement after TextFont that uses the implicit
reference to lHandle -- it's fragile code, in other words.)
-- 
Tim Maroney, Mac Software Consultant, sun!hoptoad!tim, tim@toad.com

"Next prefers its X and T capitalized.  We'd prefer our name in lights in
 Vegas."  -- Louis Trager, San Francisco Examiner

volaski@acsu.buffalo.edu (11/29/89)

From: volaski@acsu.buffalo.edu ()
Path: acsu.buffalo.edu!volaski
Newsgroups: comp.sys.mac.programmers
Subject: LDEF with styled textedit
Expires: 
References: 
Sender: 
Reply-To: volaski@acsu.buffalo.edu ()
Followup-To: 
Distribution: y
Organization: Suny at Buffalo
Keywords: 

From: volaski@acsu.buffalo.edu ()
Path: acsu.buffalo.edu!volaski
Newsgroups: comp.sys.mac.programmer
Subject: LDEF with multiple fonts-more
Expires: 
References: 
Sender: 
Reply-To: volaski@acsu.buffalo.edu ()
Followup-To: 
Distribution: world
Organization: Suny at Buffalo
Keywords: 

Newsgroups: comp.sys.mac.programmer
Subject: Re: LDEF with multiple fonts
Summary: 
Expires: 
References: <13748@eerie.acsu.Buffalo.EDU> <9104@hoptoad.uucp>
Sender: 
Reply-To: volaski@autarch.acsu.buffalo.edu (maurice volaski)
Followup-To: 
Distribution: 
Organization: Suny at Buffalo
Keywords: 

In article <9104@hoptoad.uucp> tim@hoptoad.UUCP (Tim Maroney) writes:
>In article <13748@eerie.acsu.Buffalo.EDU> volaski@acsu.buffalo.edu () writes:
>>I'm still curious as to why my TextFont doesn't work. Here's my code:
>>
>>procedure DrawList;
>>  begin
>>   with lhandle^^ do
>>    begin
>>     theChar := cells^^[lDataOffset];
>>     aStr := theChar;
>>     Textfont(6);	{this line is ignored; everything appears in Geneva}
>>     with lRect do
>>     moveTo(left, bottom);
>>     drawstring(aStr);
>>    end;
>>  end;
>
>I'm curious too.  Is it possible you don't have London font (font 6)
>installed?  Also, why aren't you doing a TextSize, since London doesn't
>come in the default 12 point size?  This omission makes me wonder, is
>this your real and complete code?  It also makes me wonder if, on
>getting the bad font size, the system would use Geneva instead of
>scaling the font down, but I don't see why it would.  Here's an example
>of some code in an LDEF of mine that draws in a nonstandard font.
>
>	TextFont(newYork); TextSize(9); TextFace(0); GetFontInfo(&info);
>	w1 = TextWidth(p->humanName + 1, 0, p->humanName[0]) + 2;
>	MoveTo(r.left + 4, r.bottom - (1 + info.leading + info.descent));
>	DrawText(p->humanName + 1, 0, p->humanName[0]);
>
>Since it works, so should yours.

I'll definitely have to try it with other fonts. I know I don't have London
installed. I wanted to get it to work, so I put in 6 as an arbitrary
number. Obviously, 6 isn't a good idea. I'll add a TextSize to make it 
more complete. The code has changed somewhat since I first started with it. It may
or may not have been the code I originally had. I did over again for the posting.

>One more note.  You are using unsafe "with" statements.  It is unsafe
>to use a with statement involving a relocatable handle if anything
>within the with statement could cause memory to be moved.  TextFont can
>cause memory to be moved, so it could cause the previous dereference of
>lhandle to become invalid, and so you would be reading from invalid
>memory.  This wouldn't cause your problem, but it could cause a problem
>in various conditions.  You should just bite the bullet and say
>"lhandle^^" before every field reference.  (Actually, looking at
>your code, it probably won't cause a problem, but it would be easy
>to forget and add a new statement after TextFont that uses the implicit
>reference to lHandle -- it's fragile code, in other words.)

Now that you mention this, how does one know if a handle is relocatable,
and how does one know when to lock handles down? For example, can the list
handle be locked down, and if not, then why? For example, I believe I once
tried locking down a pichandle and this resulted in a crash. 

Maurice Volaski
Dept. of Physiology
University at Buffalo