Here's some routines to draw the print shop fonts (on the original disk)

[Linked Image from i.imgur.com][Linked Image from i.imgur.com]
[Linked Image from i.imgur.com][Linked Image from i.imgur.com]

Code

-- printshop_drawfont7.lua

function applemem() 
  if applememobject == nil then applememobject = manager:machine().devices[":maincpu"].spaces["program"] end
  return applememobject
end

function calc(line,page) if line<0 then line = 0 end if line > 191 then line=191 end page=page or 0 return line % 8 * 1024 + math.floor(line / 64) * 40 + math.floor((line%64) / 8) * 128 + 8192* (page + 1) end

function calcyaddr(line,page) return calc(line,page) end
function readswitch(a)
local cpu = manager:machine().devices[":maincpu"]  local mem = cpu.spaces["program"]
mem:read_u8(a)
end

function hgrfull(page)
page = page or 1
readswitch(0xC050) -- graphics
readswitch(0xC052) -- full screen
readswitch(0xC054+page-1) -- page 1
readswitch(0xC057) -- hi res
end

function hgr(page)
page = page or 1
readswitch(0xC050) -- graphics
readswitch(0xC053) -- full mixed
readswitch(0xC054+page-1) -- page 1
readswitch(0xC057) -- hi res
end

function textmode()
readswitch(0xC051) -- text
readswitch(0xC054) -- page 1
end

function text()
readswitch(0xC051) -- text
readswitch(0xC054) -- page 1
end

function hgrclr(page) 
local cpu = manager:machine().devices[":maincpu"]  local mem = cpu.spaces["program"]
for y=0,191 do for x=0,39 do mem:write_u8(calc(y)+x,0) end end end

function hgrwhite(page) for x=0,39 do for y=0,191 do applemem():write_u8(calcyaddr(y,page)+x,127) end end end

function getbits(a,lobit,hibit) local retval=0 for bit=lobit,hibit do retval=retval|((1<<bit)&a) end return retval end

function getbitsshift(a,lobit,hibit) return getbits(a,lobit,hibit)>>lobit end


function getfilenamepart(s)
local curpos=1
repeat
local newpos=s:find("/",curpos,true)
if newpos then curpos = newpos+1 end  -- if you don't add the +1, keeps getting same match, infinite loop
until newpos == nil
return s:sub(curpos)
end

function trim2(s) return s:match "^%s*(.-)%s*$" end  -- from lua users wiki

-- plot function, haven't got all the operations working yet but or,xor,store,and inverse seem to be ok

function plot(x,y,page,bit,operation) page=page or 0 x = math.max(0,x) x = math.min(x,279) y = math.max(0,y) y = math.min(y,191) mem=applemem() 
local memloc=calcyaddr(y,page)+math.floor(x/7)
local readval=mem:read_u8(memloc) local bitpos=x%7
local mask=~(1<<bitpos)
local invertmask=(1<<bitpos)
local bitshifted = bit<<bitpos 
local notbitshifted=(iif(bit==0,1,0) << bitpos)
if operation == nil or operation == "or" then mem:write_u8(memloc,readval | (bit<<bitpos)) 
elseif operation == "erase"     then mem:write_u8(memloc,readval & (bit<<bitpos)) 
elseif operation == "color"     then mem:write_u8(memloc,readval & (bit<<bitpos))  -- erase = color black
elseif operation == "xor"     then mem:write_u8(memloc,readval ~ (bit<<bitpos)) 
elseif operation == "store"   then mem:write_u8(memloc,(readval & mask) | bitshifted)
elseif operation == "inverse" then mem:write_u8(memloc,(readval & mask) | notbitshifted)
else error("PLOT OPERATION "..operation.." not recognized") end
end



function revbits(a) if a==nil then print("REV NIL") return nil end local r=0 for i=0,7 do r=(r<<1)+a%2 a=a>>1 end return r end

-- 0x3b = 59 so we can have 59 characters per font
-- 
-- byte offset  0x3b * 0 + c = width of character
-- byte offset  0x3b * 1 + c = height of character
-- byte offset  0x3b * 2 + c = offset of character data low byte
-- byte offset  0x3b * 3 + c = offset of character data high byte as well as some flags so AND it with 0x1f

-- fonts on the Print Shop disk are named F0 through F9, in a "hidden" directory (start at t,s=17,2)
-- fonts on Print Shop Companion have additional 12 bytes at the beginning, we're just interested
--   in drawing the bitmap so we can just "ignore" these 12 bytes by using a:sub(13) which means take
--    all the bytes to the end of the string starting at character position 13 (numbered from 1).

function getcharwidth(a,c)  return a:byte((0x3b*0)+c+1) end
function getcharheight(a,c) return a:byte((0x3b*1)+c+1) end
function getcharoffset(a,c) return a:byte((0x3b*2)+c+1)+(a:byte((0x3b*3)+c+1)&0x1f)*256 end

--if we draw as bytes then we lose the high bit of the byte and we are on byte boundaries so it looks strange
-- drawing as pixels the fonts look much better

function drawpsfont(a,c0,c1,offset,doprint,xpos,ypos,lineheight,bytesorpixels,drawmode)
-- draw font characters from c0 to c1
c0 = c0 or 0
c1 = c1 or 58
offset=offset or 0
xpos,ypos=xpos or 0,ypos or 0
for c=c0,c1 do 
if getcharwidth(a,c) < 128 then 
local charwidth=getcharwidth(a,c)
local charheight=getcharheight(a,c)
local charoffset=getcharoffset(a,c)
local charbytewidth=math.floor((charwidth-1)/8)+1
drawmode = drawmode or "or"
if doprint then print("char="..c,"width="..getcharwidth(a,c),"height="..getcharheight(a,c),"offset="..hex(getcharoffset(a,c)))  end
if charoffset>#a then print("INVALID CHAR OFFSET") 
else
if charheight~=0 then 
if c~=32 then
--drawblock loop by bytes
if bytesorpixels=="bytes" then
  drawblockloop({"y",charheight,"x",charbytewidth},function(x,y,index) applemem():write_u8(calc(y+ypos)+x+xpos,revbits(a:sub(getcharoffset(a,c)+1):byte(index+offset+1))) end,32)
--drawblock loop by pixels
else
  drawblockloop({"y",charheight,"x",charbytewidth},function(x,y,index) local bytetoplot=revbits((a:sub(charoffset+1):byte(index+offset+1))) local numpixels=math.min(8,charwidth-8*x) x=xpos+x*8 for i=0,numpixels-1 do plot(x+i,y+ypos,0,getbitsshift(bytetoplot,i,i),drawmode) end end,32)
end
else  -- draw the space
      -- leave space blank for now
end
-- draw the gap between characters
  if bytesorpixels~="bytes" then for y=0,charheight-1 do plot(xpos+charwidth,y+ypos,0,0,drawmode) end end
end
if bytesorpixels=="bytes" then xpos = xpos+charbytewidth  -- by bytes
                          else xpos = xpos+charwidth+1    -- by pixels
end
end
if bytesorpixels=="bytes" then if xpos>36  then xpos=0 ypos=ypos+lineheight end -- by bytes
                          else if xpos>240 then xpos=0 ypos=ypos+lineheight end -- by pixels
end
end
end
print("returning xpos="..xpos.." ypos="..ypos)
return xpos,ypos
end

function writepsfonttext(a,s,x,y,offset,charoffset,lineheight,drawmode) charoffset=charoffset or (65-33) for i=1,#s do x,y=drawpsfont(a,s:byte(i)-charoffset,s:byte(i)-charoffset,offset,false,x,y,lineheight,nil,drawmode) print(x) if x>255 then x=0 y=y+16 end end end

-- translate function for combo lower case/uppercase fonts

function translateps(c) -- c passed as a char number
local replacedchars=""
local translate0=             "!\"#$%&'()*+,-./0123456789:;<=>?"
local translate1=string.upper("!wmnop`rsqt,k.zjabcdefghivuxly?")
for i=1,#translate0 do
  if translate0:sub(i,i)~= translate1:sub(i,i) then replacedchars=replacedchars..translate0:sub(i,i)
end
end
print("REPLACED="..replacedchars)
if c>=string.byte("A") and c<=string.byte("Z") then  
  local cpos=string.find(translate1,string.char(c),1,true)
  if cpos==nil then c=string.byte(c) end
  c=string.byte(translate0:sub(cpos,cpos))
elseif c>=string.byte("a") and c<=string.byte("z") then c=c-32
elseif string.find(replacedchars,string.char(c),1,true)  then c=string.byte("!")
elseif c>128 or c<32 then c=string.byte(".")
elseif c>90 or c<32 then c=string.byte(".")
end
return c
end

--for i=string.byte("a"),string.byte("z") do c=string.char(i) print(c,translateps(c)) end

--[[

loaddisk("../../PrintShop.dsk")
catalog()
getcatalog(17,2,nil,true)

-- snippet to render font f1

hgrclr() filename="F1" filelist,t,s=getcatalog(17,2,filename,nil) a=getfilefromtslist(gettslist(t,s)) print(#a.." bytes") a=stripfileheaderandextra(a) hgrclr() drawpsfont(a,32,58,0,false,0,0,38,"pixels","xor") writepsfonttext(a,filename.." 32-58",0,160)

--]]


--[[
-- snippet will loop through the namelist and render each one, but not taking any snaps

namelist={"SYSTEM","RSVP","ALEXIA","NEWS","TECH","PARTY","BLOCK","TYPEWRITER","STENCIL"}
filelist={"F0","F1","F2","F3","F4","F5","F6","F7","F8"}loaddisk("../../Print_Shop_The_1984_Broderbund_a.dsk")hgr() hgrfull() hgrclr() for i=1,#filelist do filename=filelist[i] aafilelist,t,s=getcatalog(17,2,filename,nil) a=getfilefromtslist(gettslist(t,s)) print(#a.." bytes") a=stripfileheaderandextra(a) hgrclr() drawpsfont(a,1,58,0,false,0,0,38,"pixels","xor") writepsfonttext(a,filename.." "..namelist[i],0,160) 
end


-- this snippet will create snaps of all the fonts on the print shop disk


co1=coroutine.create( function()
namelist={"SYSTEM","RSVP","ALEXIA","NEWS","TECH","PARTY","BLOCK","TYPEWRITER","STENCIL"}
filelist={"F0","F1","F2","F3","F4","F5","F6","F7","F8"}
diskname="../../Print_Shop_The_1984_Broderbund_a.dsk"  -- has good f5 block font, bad  f1 rsvp
diskname="../../PrintShop.dsk"                         -- has bad  f5 block font, good f1 rsvp
loaddisk(diskname)hgr() hgrfull() hgrclr() for i=1,#filelist do filename=filelist[i] aafilelist,t,s=getcatalog(17,2,filename,nil) a=getfilefromtslist(gettslist(t,s)) print(#a.." bytes") a=stripfileheaderandextra(a) hgrclr() drawpsfont(a,iif(filename=="F1",32,1),58,0,false,0,0,iif(filename=="F1",38,32),"pixels","xor") writepsfonttext(a,filename.." "..namelist[i],0,160) 
emu.wait(2/60)
manager:machine():debugger():command("snap \"" .. sanefilename(getfilenamepart(diskname).."_"..trim2(filelist[i]).."_"..namelist[i])..".png\"")
end
end)
ok,error=coroutine.resume(co1)
print(ok,error)

--]]

A couple of things to note about the print shop disk, the catalog is truncated, so if you start at track 17, sector 2 you can see the rest of the files. Also font F1 or F5 is corrupted depending on the disk you use.

Now the PS Companion fonts seem to have 12 extra bytes at the beginning, so if you pass them as a:sub(13) instead of a those 12 bytes will be ignored.



Code
-- just a quick test on the PS Companion disk.
loaddisk("../../PrintShop.Companion.dsk") catalog()
filename="FONT.BALLOON" hgr() hgrclr() hgrwhite() a=getfile(filename) drawpsfont(a:sub(13),iif(filename=="BALLOON",32,1),58,0,false,0,0,32,"pixels","xor") writepsfonttext(a:sub(13),filename,0,140,0,nil,20,"xor")

[Linked Image from i.imgur.com]