Contents
Articles
Behaviors
Books
Director News
Director Web Sites
FAQ
Games
Mailing Lists
News Groups
Project Examples
Reviews
Software
Tools
Useful Web Sites
Utilities
Xtras

Don't miss these
TRAX
Mile High Table O'Products
Quiz engine
StuntRacer
Button - De-Xploding behaviour
Resolution Xtra
Lingo Paradise Smartgroups
Generic behavior to set Wallpaper
Sortem
DirectControl Xtra
 

 

 

Behavior PDF Class

Added on 3/25/2004

 

Compatibilities:
D6_5 D7 D8 D8_5 D9 Mac Parent PC

This item has not yet been rated

Author: fluxus

Parent Script for creating PDF files with Director

Download PC Source
--****************************************************************************
-- Software: PDF CLASS
-- Version:  1.03, based on FPDF 1.51 by Olivier Plathey (respect!)
-- Date:     2004/01/30
-- Author:   Valentin Schmidt (original PHP Script by Olivier Plathey, inspiration by Daniel Nelson)
-- Contact:  valentin@dasdeck.de
-- License:  Freeware
--
-- Requirements/Dependencies: needs fileIO Xtra
--
-- You may use and modify this software as you wish.
--****************************************************************************
property pPDF_CLASS_VERSION
property pPDF_FONTPATH

property pPage               --current page number
property pN                  --current object number
property pOffsets            --array of object offsets
property pBuffer             --buffer holding in-memory PDF
property pPages              --array containing pages
property pState              --current document state
property pCompress           --compression flag
property pDefOrientation     --default orientation
property pCurOrientation     --current orientation
property pOrientationChanges --array indicating orientation changes
property pFwPt,pFhPt         --dimensions of page format in points
property pFw,pFh             --dimensions of page format in user unit
property pWPt,pHPt           --current dimensions of page in points
property pK                  --scale factor (number of points in user unit)
property pW,pH               --current dimensions of page in user unit
property pLMargin            --left margin
property pTMargin            --top margin
property pRMargin            --right margin
property pBMargin            --page break margin
property pCMargin            --cell margin
property pX,pY               --current position in user unit for cell positionning
property pLasth              --height of last cell printed
property pLineWidth          --line width in user unit
property pCoreFonts          --array of standard font names
property pFonts              --array of used fonts
property pFontFiles          --array of font files
property pDiffs              --array of encoding differences
property pImages             --array of used images
property pPageLinks          --array of links in pages
property pLinks              --array of internal links
property pFontFamily         --current font family
property pFontStyle          --current font style
property pUnderline          --underlining flag
property pCurrentFont        --current font info
property pFontSizePt         --current font size in points
property pFontSize           --current font size in user unit
property pDrawColor          --commands for drawing color
property pFillColor          --commands for filling color
property pTextColor          --commands for text color
property pColorFlag          --indicates whether fill and text colors are different
property pWs                 --word spacing
property pAutoPageBreak      --automatic page breaking
property pPageBreakTrigger   --threshold used to trigger page breaks
property pInFooter           --flag set when processing footer
property pZoomMode           --zoom display mode
property pLayoutMode         --layout display mode
property pTitle              --title
property pSubject            --subject
property pAuthor             --author
property pKeywords           --keywords
property pCreator            --creator
property pAliasNbPages       --alias for total number of pages

property pLF,pCR
property pMacAnsiVec
property pIsMac

property pCharWidths


--****************************************************************************
--                                                                           *
--                              Public methods                               *
--                                                                           *
--****************************************************************************

on new me,orientation,unit,format
  if (voidP(orientation)) then orientation="P"
  if (voidP(unit)) then unit="mm"
  if (voidP(format)) then format="A4"
  
  pPDF_CLASS_VERSION = "1.00"
  pPDF_FONTPATH = the moviepath
  pCharWidths=[:]
  
  --Initialization of properties
  pPage=0
  pN=2
  pBuffer=""
  pOffsets=[]
  pPages=[]
  pPageLinks=[]
  pOrientationChanges=[]
  pState=0
  pFonts=[:]
  pFontFiles=[:]
  pDiffs=[]
  pImages=[:]
  pLinks=[]
  pInFooter=false
  pFontFamily=""
  pFontStyle=""
  pFontSizePt=12
  pUnderline=false
  pDrawColor="0 G"
  pFillColor="0 g"
  pTextColor="0 g"
  pColorFlag=false
  pWs=0
  
  pLF=NumToChar(10)
  pCR=NumToChar(13)
  pMacAnsiVec=[196,197,199,201,209,214,220,225,224,226,228,227,229,231,233,232,234,235,237,236,238,239,241,243,242,244,246,245,250,249,251,252,134,176,162,163,167,149,182,223,174,169,153,180,168,32,198,216,218,177,32,32,165,181,32,32,32,32,32,170,186,32,198,216,191,161,172,32,131,152,32,171,187,133,160,192,195,213,140,156,150,151,147,148,145,146,215,32,255,159,32,128,139,155,32,32,135,183,130,132,137,194,202,193,203,200,205,206,207,204,211,212,32,210,218,219,217,32,136,152,175,32,32,176,184,32,32,32]
  pIsMac=(the platform contains "mac")
  
  --Standard fonts
  pCoreFonts=[:]
  pCoreFonts["courier"]="Courier"
  pCoreFonts["courierB"]="Courier-Bold"
  pCoreFonts["courierI"]="Courier-Oblique"
  pCoreFonts["courierBI"]="Courier-BoldOblique"
  pCoreFonts["helvetica"]="Helvetica"
  pCoreFonts["helveticaB"]="Helvetica-Bold"
  pCoreFonts["helveticaI"]="Helvetica-Oblique"
  pCoreFonts["helveticaBI"]="Helvetica-BoldOblique"
  pCoreFonts["times"]="Times-Roman"
  pCoreFonts["timesB"]="Times-Bold"
  pCoreFonts["timesI"]="Times-Italic"
  pCoreFonts["timesBI"]="Times-BoldItalic"
  pCoreFonts["symbol"]="Symbol"
  pCoreFonts["zapfdingbats"]="ZapfDingbats"
  --Scale factor
  if (unit="pt") then
    pK=1.0
  else if (unit="mm") then
    pK=72/25.4
  else if (unit="cm") then
    pK=72/2.54
  else if(unit="in") then
    pK=72.0
  else
    me._Error("Incorrect unit: "&unit)
  end if
  
  --Page format
  if (stringP(format)) then    
    format=strtolower(format)
    if (format="a3") then
      format=[841.89,1190.55]
    else if (format="a4") then
      format=[595.28,841.89]
    else if (format="a5") then
      format=[420.94,595.28]
    else if (format="letter") then
      format=[612.0,792.0]
    else if (format="legal") then
      format=[612.0,1008.0]
    else
      me._Error("Unknown page format: "&format)
    end if
    pFwPt=format[1]
    pFhPt=format[2]
  else
    pFwPt=format[1]*pK
    pFhPt=format[2]*pK
  end if
  
  pFw=pFwPt/pK
  pFh=pFhPt/pK
  
  --Page orientation
  orientation=strtolower(orientation)
  if (orientation="p" or orientation="portrait") then
    pDefOrientation="P"
    pWPt=pFwPt
    pHPt=pFhPt
  else if (orientation="l" or orientation="landscape") then
    pDefOrientation="L"
    pWPt=pFhPt
    pHPt=pFwPt
  else
    me._Error("Incorrect orientation: "&orientation)
  end if
  
  pCurOrientation=pDefOrientation
  pW=pWPt/pK
  pH=pHPt/pK
  --Page margins (1 cm)
  marg=28.35/pK
  me.SetMargins(marg,marg)
  --Interior cell margin (1 mm)
  pCMargin=marg/10.0
  --Line width (0.2 mm)
  pLineWidth=.567/pK
  --Automatic page break
  me.SetAutoPageBreak(true,2*marg)
  --Full width display mode
  me.SetDisplayMode("fullwidth")
  --Compression
  pCompress=0 --me.handler(#gzcompress)
  
  return me
end

----------------------------------------
-- Set the path to font folder for non-standard fonts
----------------------------------------
on SetFontpath me, fp
  pd=the last char of the moviepath
  if the last char of fp<>pd then fp=fp& pd
  pPDF_FONTPATH=fp
end

----------------------------------------
-- Set left, top and right margins
----------------------------------------
on SetMargins me, l,t,r
  if voidP(r) then r=-1
  pLMargin=l
  pTMargin=t
  if (r=-1) then r=l
  pRMargin=r
end

----------------------------------------
-- Set left margin
----------------------------------------
on SetLeftMargin me, marg
  pLMargin=marg
  if (pPage>0 and pXend

----------------------------------------
-- Set top margin
----------------------------------------
on SetTopMargin me, marg
  pTMargin=marg
end

----------------------------------------
-- Set right margin
----------------------------------------
on SetRightMargin me, marg
  pRMargin=marg
end

----------------------------------------
-- Set inner cell margin
----------------------------------------
on SetCellMargin me, marg
  pCMargin = marg
end

----------------------------------------
-- Set auto page break mode and triggering margin
----------------------------------------
on SetAutoPageBreak me, auto,marg
  if voidP(marg) then marg=0
  pAutoPageBreak=auto
  pBMargin=marg
  pPageBreakTrigger=pH-marg
end

----------------------------------------
-- Set display mode in viewer
----------------------------------------
on SetDisplayMode me, zoom,layout
  if voidP(layout) then layout="continuous"
  if (zoom="fullpage" or zoom="fullwidth" or zoom="real" or zoom="default" or NOT stringP(zoom)) then
    pZoomMode=zoom
  else if (zoom="zoom") then
    pZoomMode=layout
  else
    me._Error("Incorrect zoom display mode: "&zoom)
  end if
  if (layout="single" or layout="continuous" or layout="two" or layout="default") then
    pLayoutMode=layout
  else if (zoom<>"zoom") then
    me._Error("Incorrect layout display mode: "&layout)
  end if
end

----------------------------------------
-- Set page compression
----------------------------------------
on SetCompression me, compressionFlag
  if (me.handlerP(#gzcompress)) then
    pCompress=compressionFlag
  else
    pCompress=false
  end if
end

----------------------------------------
-- Set Title of document
----------------------------------------
on SetTitle me, aTitle
  pTitle = aTitle
end

----------------------------------------
-- Set Subject of document
----------------------------------------
on SetSubject me, aSubject
  pSubject = aSubject
end

----------------------------------------
-- Set Author of document
----------------------------------------
on SetAuthor me, aAuthor
  pAuthor = aAuthor
end

----------------------------------------
-- Set Keywords of document
----------------------------------------
on SetKeywords me, aKeywords
  pKeywords = aKeywords
end

----------------------------------------
-- Set Creator of document
----------------------------------------
on SetCreator me, aCreator
  pCreator = aCreator
end

----------------------------------------
-- Define an alias for total number of pages
----------------------------------------
on AliasNbPages me, aAlias
  if voidP(aAlias) then aAlias = "{nb}"
  pAliasNbPages = aAlias
end

----------------------------------------
-- Fatal error
----------------------------------------
on _Error me, msg
  alert("PDF CLASS error: " & msg)
  halt
end

----------------------------------------
-- Begin document
----------------------------------------
on Open me
  me._begindoc()
end

----------------------------------------
-- Terminate document
----------------------------------------
on Close me
  if (pPage=0) then me.AddPage()
  --Page footer
  pInFooter = true
  if me.handlerP(#Footer) then me.Footer()
  pInFooter = false
  --Close page
  me._endpage()
  --Close document
  me._enddoc()
end

----------------------------------------
-- Start a new page
----------------------------------------
on AddPage me, orientation
  if voidP(orientation) then orientation=""
  family=pFontFamily
  style=pFontStyle
  if (pUnderline) then style=style& "U"
  
  size=pFontSizePt
  lw=pLineWidth
  dc=pDrawColor
  fc=pFillColor
  tc=pTextColor
  cf=pColorFlag
  if (pPage>0) then
    --Page footer
    pInFooter=true
    if me.handlerP(#Footer) then me.Footer()
    pInFooter=false
    --Close page
    me._endpage()
  end if
  
  --Start new page
  _beginpage(orientation)
  --Set line cap style to square
  me._out("2 J")
  --Set line width
  pLineWidth=lw
  the floatprecision=2
  me._out(float(lw*pK)&" w")
  --Set font
  if (family<>"") then SetFont(me,family,style,size)
  --Set colors
  pDrawColor=dc
  if (dc<>"0 G") then me._out(dc)
  pFillColor=fc
  if (fc<>"0 g") then me._out(fc)
  pTextColor=tc
  pColorFlag=cf
  --Page header
  if me.handlerP(#Header) then me.Header()
  --Restore line width
  if (pLineWidth<>lw) then
    pLineWidth=lw
    the floatprecision=2
    me._out(float(lw*pK)&" w")
  end if
  
  --Restore font
  if (family<>"") then SetFont(me,family,style,size)
  --Restore colors
  if (pDrawColor<>dc) then
    pDrawColor=dc
    me._out(dc)
  end if
  
  if (pFillColor<>fc) then
    pFillColor=fc
    me._out(fc)
  end if
  pTextColor=tc
  pColorFlag=cf
end

----------------------------------------
-- Get current page number
----------------------------------------
on PageNo me
  return pPage
end

----------------------------------------
-- Set color for all stroking operations
----------------------------------------
on SetDrawColor me, r,g,b
  if voidP(g) then g=-1
  if voidP(b) then b=-1
  the floatprecision=3
  if ((r=0 and g=0 and b=0) or g=-1) then
    pDrawColor=r/255.0 & " G"
  else
    pDrawColor=r/255.0 && g/255.0 && b/255.0 && "RG"
  end if
  if (pPage>0) then me._out(pDrawColor)
end

----------------------------------------
-- Set color for all filling operations
----------------------------------------
on SetFillColor me, r,g,b
  if voidP(g) then g=-1
  if voidP(b) then b=-1
  the floatprecision=3
  if ((r=0 and g=0 and b=0) or g=-1) then
    pFillColor=r/255.0 & " g"
  else
    pFillColor=r/255.0 && g/255.0 && b/255.0 && "rg"
  end if
  pColorFlag=(pFillColor<>pTextColor)
  if(pPage>0) then me._out(pFillColor)
end

----------------------------------------
-- Set color for text
----------------------------------------
on SetTextColor me, r,g,b
  if voidP(g) then g=-1
  if voidP(b) then b=-1
  the floatprecision=3
  if ((r=0 and g=0 and b=0) or g=-1) then
    pTextColor=r/255.0 & " g"
  else
    pTextColor=r/255.0 && g/255.0 && b/255.0 && "rg"
  end if
  pColorFlag=(pFillColor<>pTextColor)
end

----------------------------------------
-- Get width of a string in the current font
----------------------------------------
on GetStringWidth me, s
  s=string(s)
  cw=pCurrentFont["cw"] -- ???
  w=0
  l=s.length
  repeat with i = 1 to l
    w=w+cw[ord(s.char[i])+1]--???
  end repeat
  return w*pFontSize/1000.0
end

----------------------------------------
-- Set line width
----------------------------------------
on SetLineWidth me, aWidth
  pLineWidth = aWidth
  the floatprecision=2
  if (pPage>0) then me._out(float(aWidth*pK) & " w")
end

----------------------------------------
-- Draw a line
----------------------------------------
on DrawLine me, x1,y1,x2,y2
  the floatprecision=2
  me._out(float(x1*pK) && float((pH-y1)*pK) && "m" && float(x2*pK) && float((pH-y2)*pK) && "l S" )
end

----------------------------------------
-- Draw a rectangle
----------------------------------------
on DrawRect me, x,y,w,h,aStyle
  if voidP(aStyle) then g=-1
  if (aStyle="F") then
    op="f"
  else if (aStyle="FD" or aStyle="DF") then
    op="B"
  else
    op="S"
  end if
  the floatprecision=2
  me._out(float(x*pK) && float((pH-y)*pK) && float(w*pK) && float(-h*pK) &&"re" && op)
end

----------------------------------------
-- Add a TrueType or Type1 font
----------------------------------------
on AddFont me, family,aStyle
  aStyle=strtoupper(string(aStyle))
  family=strtolower(family)
  if (family="arial") then family="helvetica"
  if (aStyle="IB") then aStyle="BI"
  if (NOT voidP(pFonts[family & aStyle])) then me._Error("Font already added: " & family && aStyle)
  fontMem=member(family,"fonts")
  if (fontMem.memberNum<1) then me._Error("Could not find font definition")
  fnt=value(fontMem.text)
  if (ilk(fnt)<>#propList) then me._Error("font definition is corrupted")
  i=count(pFonts)+1
  fnt["i"]=i
  pFonts[family & aStyle]=fnt --["i":i,"type":type,"name":name,"desc":desc,"up":up,"ut":ut,"cw":cw,"enc":enc,"file":file]
  diff=fnt["diff"]
  if (diff<>"") then
    --Search existing encodings
    d=0
    nb=count(pDiffs)
    repeat with i = 1 to nb
      if (pDiffs[i]=diff) then
        d=i
        exit repeat
      end if
    end repeat
    if (d=0) then
      d=nb+1
      pDiffs[d]=diff
    end if
    pFonts[family&aStyle]["diff"]=d
  end if
  
  if (fnt["type"]="TrueType") then
    pFontFiles[fnt["file"]]=["length1":fnt["originalsize"]] --fontMem
  else
    pFontFiles[fnt["file"]]=["length1":fnt["size1"],"length2":fnt["size2"]] --fontMem
  end if
end

----------------------------------------
-- Select a font; size given in points
----------------------------------------
on SetFont me, family,style,size
  style=string(style)
  if voidP(size) then size=0
  family=strtolower(family)
  if (family="") then family=pFontFamily
  if (family="arial") then
    family="helvetica"
  else if(family="symbol" or family="zapfdingbats") then
    style=""
  end if
  style=strtoupper(style)
  if (style contains "U") then
    pUnderline=true
    style=str_replace("U","",style)
  else
    pUnderline=false
  end if
  if (style="IB") then style="BI"
  if (size=0) then size=pFontSizePt
  --Test if font is already selected
  if (pFontFamily=family and pFontStyle=style and pFontSizePt=size) then return
  --Test if used for the first time
  fontkey=family & style

  if (voidP(pFonts[fontkey])) then
    --Check if one of the standard fonts
    if (NOT voidP(pCoreFonts[fontkey])) then
      if (member(fontkey,"fonts").membernum<1) then me._Error("Can't find charwidths for font"&&fontkey) --family
      pCharWidths[fontkey] = value(member(fontkey,"fonts").text) --family
      i=count(pFonts)+1
      pFonts[fontkey]=["i":i,"type":"core","name":pCoreFonts[fontkey],"up":-100,"ut":50,"cw":pCharWidths[fontkey]]
    else
      me._Error("Undefined font: " & fontkey)
    end if
  end if
  
  --Select it
  pFontFamily=family
  pFontStyle=style
  pFontSizePt=size
  pFontSize=size/pK
  pCurrentFont=pFonts[fontkey]
  the floatprecision=2
  if (pPage>0) then me._out("BT /F" & integer(pCurrentFont["i"]) && float(pFontSizePt) && "Tf ET")
end

----------------------------------------
-- Set font size in points
----------------------------------------
on SetFontSize me, size
  if (pFontSizePt=size) then return
  pFontSizePt=size
  pFontSize=size/pK
  floatprecision=2
  if (pPage>0) then me._out("BT /F"&integer(pCurrentFont["i"])&& float(pFontSizePt) && "Tf ET")
end

----------------------------------------
-- Create a new internal link
----------------------------------------
on AddLink me
  n=count(pLinks)+1
  pLinks[n]=[0,0]
  return n
end

----------------------------------------
-- Set destination of internal link
----------------------------------------
on SetLink me, link,y,page
  if voidP(y) then y=0
  if voidP(page) then page=-1
  if (y=-1) then y=pY
  if (page=-1) then page=pPage
  pLinks[link]=[page,y]
end

----------------------------------------
-- Put a link on the page
----------------------------------------
on Link me, x,y,w,h,link
  pPageLinks[pPage].add([x*pK,pHPt-y*pK,w*pK,h*pK,link])
end

----------------------------------------
-- Output a string
----------------------------------------
on Text me, x,y,txt
  txt=str_replace(")",")",str_replace("(","(",str_replace("","\",txt)))
  the floatprecision=2
  s="BT" && float(x*pK) && float((pH-y)*pK) && "Td ("&txt&") Tj ET"
  if (pUnderline and txt<>"") then s = s && me._dounderline(x,y,txt)
  if (pColorFlag) then s="q " & pTextColor && s && "Q"
  me._out(s)
end

----------------------------------------
-- Accept automatic page break or not
----------------------------------------
on AcceptPageBreak
  return pAutoPageBreak
end

----------------------------------------
-- Output a cell
----------------------------------------
on Cell me, w,h,txt,border,ln,align,fill,link
  if voidP(h) then h=0
  txt=string(txt)
  if voidP(border) then border=0
  if voidP(ln) then ln=0
  align=string(align)
  if voidP(fill) then fill=0
  --link=string(link)
  if voidP(link) then link=""
  
  if pIsMac then txt=me.mac2ansi(txt)
  
  k=pK
  if (pY+h>pPageBreakTrigger and NOT pInFooter and AcceptPageBreak()) then
    x=pX
    ws=pWs
    if (ws>0) then
      pWs=0
      me._out("0 Tw")
    end if
    me.AddPage(pCurOrientation)
    pX=x
    if (ws>0) then
      pWs=ws
      the floatprecision=3
      me._out(float(ws*k) && "Tw")
    end if
  end if
  if (w=0) then w=pW-pRMargin-pX
  s=""
  if (fill=1 or border=1) then
    if (fill=1) then
      if (border=1) then op="B"
      else op="f"
    else op="S"
    the floatprecision=2
    s=float(pX*k) && float((pH-pY)*k) && float(w*k) && float(-h*k) && "re" && op & " "
  end if
  
  if (stringP(border)) then
    x=pX
    y=pY
    the floatprecision=2
    if (border contains "L") then s=s& float(x*k) && float((pH-y)*k) && "m" && float(x*k) && float((pH-(y+h))*k) && "l S "
    if (border contains "T") then s=s& float(x*k) && float((pH-y)*k) && "m" && float((x+w)*k) && float((pH-y)*k) && "l S "
    if (border contains "R") then s=s& float((x+w)*k) && float((pH-y)*k) && "m" && float((x+w)*k) && float((pH-(y+h))*k) && "l S "
    if (border contains "B") then s=s& float(x*k) && float((pH-(y+h))*k) && "m" && float((x+w)*k) && float((pH-(y+h))*k) && "l S "
  end if
  if(txt<>"") then
    if (align="R") then dx=w-pCMargin-me.GetStringWidth(txt)
    else if(align="C") then dx=(w-me.GetStringWidth(txt))/2
    else
      dx=pCMargin
    end if
    txt=str_replace(")",")",str_replace("(","(",str_replace("","\",txt)))
    if (pColorFlag) then s=s& "q" && pTextColor &" "
    the floatprecision=2
    s=s& "BT" && float((pX+dx)*k) && float((pH-(pY+.5*h+.3*pFontSize))*k) && "Td ("&txt&") Tj ET"
    if (pUnderline) then s=s&& me._dounderline(pX+dx,pY+.5*h+.3*pFontSize,txt)
    if (pColorFlag) then s=s&& "Q"
    if (link<>"") then me.Link(pX+dx,pY+.5*h-.5*pFontSize,me.GetStringWidth(txt),pFontSize,link)
  end if
  
  if (s<>"") then me._out(s)
  pLasth=h
  if(ln>0) then
    --Go to next line
    pY=pY+h
    if(ln=1) then
      pX=pLMargin
    end if
  else pX=pX+w
end


----------------------------------------
-- Output text with automatic or explicit line breaks
----------------------------------------
on MultiCell me, w,h,txt,border,align,fill
  if voidP(border) then border=0
  if voidP(align) then align="J"
  if voidP(fill) then fill=0
  cw=pCurrentFont["cw"] -- ???
  if (w=0) then w=pW-pRMargin-pX
  wmax=(w-2*pCMargin)*1000.0/pFontSize
  --s=str_replace(pCR,"",txt)
  s=str_replace(pCR,pLF,txt)
  nb=length(s)
  if (nb>0 and s.char[nb]=pLF) then nb=nb-1
  b=0
  if (NOT voidP(border)) then
    if (border=1) then
      border="LTRB"
      b="LRT"
      b2="LR"
    else
      b2=""
      if (border contains "L") then b2=b2& "L"
      if (border contains "R") then b2=b2& "R"
      
      if (border contains "T") then b=b2 & "T"
      else b=b2
    end if
  end if
  sep=-1
  i=1 --0
  j=0
  l=0
  ns=0
  nl=1
  repeat while (i    --Get next character
    c=s.char[i]
    
    if (c=pLF) then
      --Explicit line break
      if(pWs>0) then
        pWs=0
        me._out("0 Tw")
      end if
      me.Cell(w,h, s.char[j+1..i-1],b,2,align,fill) --j+1..i
      i=i+1
      sep=-1
      j=i  -1
      l=0
      ns=0
      nl=nl+1
      if (border and nl=2) then b=b2
      next repeat
    end if
    
    if (c=" ") then
      sep=i -- -1--???
      ls=l
      ns=ns+1
    end if
    l=l+cw[ord(c)+1] --???
    if (l>wmax) then
      --Automatic line break
      if (sep=-1) then
        if (i=j) then i=i+1
        if (pWs>0) then
          pWs=0
          me._out("0 Tw")
        end if
        me.Cell(w,h,s.char[j+1..i],b,2,align,fill)
      else
        if (align="J") then
          if (ns>1) then pWs=(wmax-ls)/1000.0*pFontSize/(ns-1.0)
          else pWs=0
          the floatprecision=3
          me._out(float(pWs*pK) && "Tw")
        end if
        me.Cell(w,h,s.char[j+1..sep-1],b,2,align,fill) --j+1
        i=sep+1
      end if
      sep=-1
      j=i   -1
      l=0
      ns=0
      nl=nl+1
      if (border and nl=2) then
        b=b2
      end if
    else
      i=i+1
    end if
  end repeat
  --Last chunk
  if (pWs>0) then
    pWs=0
    me._out("0 Tw")
  end if
  if (border and (border contains "B")) then b=b& "B"
  me.Cell(w,h,s.char[j+1..j+i],b,2,align,fill) --j+1
  pX=pLMargin
end

----------------------------------------
-- Output text in flowing mode
----------------------------------------
on Write me, h,txt,link
  if voidP(link) then link=""
  cw=pCurrentFont["cw"]
  w=pW-pRMargin-pX
  wmax=(w-2*pCMargin)*1000.0/pFontSize
  --s=str_replace(pCR,"",txt)
  s=str_replace(pCR,pLF,txt)
  nb=length(s)
  sep=-1
  i=1
  j=0
  l=0
  nl=1
  repeat while (i    --Get next character
    c=s.char[i]
    if(c=pLF) then
      --Explicit line break
      me.Cell(w,h,s.char[j+1..i-1],0,2,"",0,link)
      i=i+1
      sep=-1
      j=i
      l=0
      if (nl=1) then
        pX=pLMargin
        w=pW-pRMargin-pX
        wmax=(w-2*pCMargin)*1000.0/pFontSize
      end if
      nl=nl+1
      next repeat
    end if
    if (c=" ") then
      sep=i
      ls=l
    end if
    l=l+cw[ord(c)+1]--???
    if (l>wmax) then
      --Automatic line break
      if (sep=-1) then
        if (pX>pLMargin) then
          --Move to next line
          pX=pLMargin
          pY=pY+h
          w=pW-pRMargin-pX
          wmax=(w-2*pCMargin)*1000.0/pFontSize
          i=i+1
          nl=nl+1
          next repeat
        end if
        if (i=j) then i=i+1
        me.Cell(w,h,s.char[j+1..i],0,2,"",0,link)
      else
        me.Cell(w,h,s.char[j+1..sep-1],0,2,"",0,link)
        i=sep+1
      end if
      sep=-1
      j=i
      l=0
      if (nl=1) then
        pX=pLMargin
        w=pW-pRMargin-pX
        wmax=(w-2*pCMargin)*1000.0/pFontSize
      end if
      nl=nl+1
    else i=i+1
  end repeat
  --Last chunk
  if (i<>j) then me.Cell(l/1000.0*pFontSize,h,s.char[j+1..j+i],0,0,"",0,link)
end

----------------------------------------
-- Put an PNG image on the page
----------------------------------------
on addPng me, file,x,y,w,h,link
  if voidP(h) then h=0
  if (voidP(pImages[file])) then
    --First use of image, get info
    info=me._parsepng(file)
    info["i"]=count(pImages)+1
    pImages[file]=info
  else
    info=pImages[file]
  end if
  --Automatic width or height calculation
  if (w=0) then w=h*info["w"]/info["h"]
  if (h=0) then h=w*info["h"]/info["w"]
  the floatprecision=2
  me._out("q" && float(w*pK) &&"0 0" && float(h*pK) && float(x*pK) && float((pH-(y+h))*pK) && "cm /I" & integer(info["i"]) && "Do Q")
  if (NOT voidP(link)) then me.Link(x,y,w,h,link)
end

----------------------------------------
-- Put an JPG image on the page
----------------------------------------
on addJpg me, file,depth,x,y,w,h,link
  if voidP(h) then h=0
  if (voidP(pImages[file])) then
    --First use of image, get info
    info=me._parsejpg(file, depth)
    info["i"]=count(pImages)+1
    pImages[file]=info
  else
    info=pImages[file]
  end if
  --Automatic width or height calculation
  if (w=0) then w=h*info["w"]/info["h"]
  if (h=0) then h=w*info["h"]/info["w"]
  the floatprecision=2
  me._out("q" && float(w*pK) &&"0 0" && float(h*pK) && float(x*pK) && float((pH-(y+h))*pK) && "cm /I" & integer(info["i"]) && "Do Q") --sprintf("q %.2f 0 0 %.2f %.2f %.2f cm /I%d Do Q",w*pK,h*pK,x*pK,(pH-(y+h))*pK,info["i"]))
  if (NOT voidP(link)) then me.Link(x,y,w,h,link)
end

----------------------------------------
-- Put an image on the page
----------------------------------------
on addImg me, img,x,y,w,h,link
  wi=img.width
  hi=img.height
  depth=img.depth
  
  if (NOT integerP(w) OR w=0) then w=wi/pK -- original size at 72 dpi
  if (NOT integerP(h) OR h=0) then h=w*hi/wi
  
  imgStr=string(img)
  
  if (voidP(pImages[imgStr])) then
    --First use of image, get info
    if (depth=8 AND img.paletteRef=#grayscale) then
      colspace="DeviceGray"
    else
      colspace="DeviceRGB"
    end if
    bpc=8
    --Get Image Data
    data=""
    if (colspace="DeviceGray") then
      --Grayscale
      repeat with i=0 to hi-1
        repeat with j=0 to wi-1
          data=data& chr(255-img.getpixel(j,i,#integer))
        end repeat
      end repeat
    else
      --RGB
      repeat with i=0 to hi-1
        repeat with j=0 to wi-1
          col=img.getpixel(j,i)
          data=data& chr(col.red) & chr(col.green) & chr(col.blue)
        end repeat
      end repeat
    end if
    
    info = ["w":wi,"h":hi,"cs":colspace,"bpc":bpc]
  
    if pCompress then
      --put "before" && count(data)
      info["f"] = "FlateDecode"
      data = me.gzcompress(data)
      --put "after" && count(data)
    end if
    
    info["data"] = data
    info["i"]=count(pImages)+1
    pImages[imgStr]=info
  else
    info=pImages[imgStr]
  end if
  
  the floatprecision=2
  me._out("q" && float(w*pK) &&"0 0" && float(h*pK) && float(x*pK) && float((pH-(y+h))*pK) && "cm /I" & integer(info["i"]) && "Do Q")
  if (NOT voidP(link)) then me.Link(x,y,w,h,link)
end

----------------------------------------
-- Line feed; default value is last cell height
----------------------------------------
on Ln me, h
  if voidP(h) then h=""
  pX=pLMargin
  if (stringP(h)) then pY=pY+pLasth
  else pY=pY+h
end

----------------------------------------
-- Get x position
----------------------------------------
on GetX me
  return pX
end

----------------------------------------
-- Set x position
----------------------------------------
on SetX me, x
  if (x>=0) then pX=x
  else pX=pW+x
end

----------------------------------------
-- Get y position
----------------------------------------
on GetY me
  return pY
end

----------------------------------------
-- Set y position and reset x
----------------------------------------
on SetY me, y
  pX=pLMargin
  if (y>=0) then pY=y
  else pY=pH+y
end

----------------------------------------
-- Set x and y positions
----------------------------------------
on SetXY me, x,y
  me.SetY(y)
  me.SetX(x)
end

----------------------------------------
-- Output PDF to file (or msg window)
----------------------------------------
on Output me, file
  if (pState<3) then me.Close()
  if (voidP(file)) then
    return pBuffer
  else
    writeFile(pBuffer,file)
  end if
end


--****************************************************************************
--                                                                           *
--                              Private methods                              *
--                                                                           *
--****************************************************************************

----------------------------------------
-- Start document
----------------------------------------
on _begindoc me
  pState=1
  me._out("%PDF-1.3")
end

----------------------------------------
--
----------------------------------------
on _putpages me
  nb=pPage
  if (NOT voidP(pAliasNbPages)) then
    --Replace number of pages
    repeat with n=1 to nb
      pPages[n]=str_replace(pAliasNbPages,nb,pPages[n])
    end repeat
  end if
  if (pDefOrientation="p") then
    wPt=pFwPt
    hPt=pFhPt
  else
    wPt=pFhPt
    hPt=pFwPt
  end if
  
  if (pCompress) then filter = "/Filter /FlateDecode "
  else filter = ""
  repeat with n=1 to nb
    --Page
    me._newobj()
    me._out("<    me._out("/Parent 1 0 R")
    the floatprecision=2
    
    if (count(pOrientationChanges)>=n) then
      if pOrientationChanges[n] then me._out("/MediaBox [0 0 "&float(hPt)&&float(wPt)&"]")
    end if
    me._out("/Resources 2 0 R")
    if (pPageLinks[n]<>[]) then
      --Links
      annots="/Annots ["
      
      repeat with pl in pPageLinks[n]
        the floatprecision=2
        rect=float(pl[1]) && float(pl[2]) && float(pl[1]+pl[3]) && float(pl[2]-pl[4])
        annots=annots& "<        if (stringP(pl[5])) then annots=annots& "/A <>>>"
        else
          l=pLinks[pl[5]]    
          if (count(pOrientationChanges)>=l[1]) then h=wPt
          else h=hPt
          the floatprecision=2
          annots=annots& "/Dest [" & integer(1+2*l[1]) && "0 R /XYZ 0" & float(h-l[2]*pK) && "null]>>"
        end if
      end repeat
      me._out(annots & "]")
    end if
    me._out("/Contents " & (pN+1) & " 0 R>>")
    me._out("endobj")
    --Page content
    p=pPages[n]
    if (pCompress) then p=me.gzcompress(p)
    me._newobj()
    me._out("<<" & filter & "/Length " & length(p) & ">>")
    me._putstream(p)
    me._out("endobj")
  end repeat
  --Pages root
  pOffsets[1]=length(pBuffer)
  me._out("1 0 obj")
  me._out("<  kids="/Kids ["
  repeat with i = 0 to nb-1
    kids=kids& (3+2*i) & " 0 R "
  end repeat
  me._out(kids&"]")
  me._out("/Count " & nb)
  the floatprecision=2
  me._out("/MediaBox [0 0" && float(wPt) && float(hPt) &"]")
  me._out(">>")
  me._out("endobj")
end

----------------------------------------
--
----------------------------------------
on _putfonts me
  nf=pN
  repeat with diff in pDiffs
    --Encodings
    me._newobj()
    me._out("<>")
    me._out("endobj")
  end repeat
  repeat with i = 1 to count(pFontFiles)
    file = pPDF_FONTPATH&pFontFiles.getPropAt(i)
    info = pFontFiles[i]
    
    --Font file embedding
    me._newobj()
    pFontFiles[i]["n"]=pN
    size=filesize(file)
    if (NOT size) then me._Error("Font file not found: "&file)
    me._out("<    the itemdelimiter="."
    if (the last item of file="z") then me._out("/Filter /FlateDecode")
    me._out("/Length1 " & info["length1"])
    if (NOT voidP(info["length2"])) then me._out("/Length2 " & info["length2"] & " /Length3 0")
    me._out(">>")
    
    str=readBinFile(file)
    me._putstream(str)
    
    me._out("endobj")
  end repeat
  repeat with i = 1 to count(pFonts)
    font=pFonts[i]
    k=pFonts.getPropAt(i)
    --Font objects
    me._newobj()
    pFonts[k]["n"]=pN
    name=font["name"]
    me._out("<    me._out("/BaseFont /" & name)
    
    if (font["type"]="core") then
      --Standard font
      me._out("/Subtype /Type1")
      if(name<>"Symbol" and name<>"ZapfDingbats") then
        me._out("/Encoding /WinAnsiEncoding")
      end if
    else
      --Additional font
      me._out("/Subtype /"& font["type"])
      me._out("/FirstChar 32")
      me._out("/LastChar 255")
      me._out("/Widths " & (pN+1) & " 0 R")
      me._out("/FontDescriptor " & (pN+2) & " 0 R")
      if (font["enc"]<>"") then
        if(font["diff"]<>"") then me._out("/Encoding " & (nf+font["diff"]) & " 0 R")
        else me._out("/Encoding /WinAnsiEncoding")
      end if
    end if
    me._out(">>")
    me._out("endobj")
    if (font["type"]<>"core") then
      --Widths
      me._newobj()
      cw=font["cw"]-- ???
      s="["  
      repeat with j = 32 to 255
        s=s& cw[j+1] & " "
      end repeat
      me._out(s & "]")
      me._out("endobj")
      --Descriptor
      me._newobj()
      s="<      repeat with j = 1 to count(font["desc"])
        s=s& " /"&font["desc"].getPropAt(j)&" "&font["desc"][j]
      end repeat
      file=font["file"]
      if (file<>"") then
        s=s& " /FontFile"
        if (font["type"]<>"Type1") then s=s& "2"
        s=s& " " & pFontFiles[file]["n"] & " 0 R"
      end if
      me._out(s & ">>")
      me._out("endobj")
    end if
  end repeat
end

----------------------------------------
--
----------------------------------------
on _putimages me
  if (pCompress) then filter = "/Filter /FlateDecode "
  else filter = ""
  
  repeat with i = 1 to count(pImages)
    info=pImages[i]
    file=pImages.getPropAt(i)
    me._newobj()
    pImages[file]["n"]=pN
    me._out("<    me._out("/Subtype /Image")
    me._out("/Width "&info["w"])
    me._out("/Height "&info["h"])
    if (info["cs"]="Indexed") then
      me._out("/ColorSpace [/Indexed /DeviceRGB "&(length(info["pal"])/3-1)&&(pN+1)&&"0 R]")
    else
      me._out("/ColorSpace /"&info["cs"])
      if(info["cs"]="DeviceCMYK") then me._out("/Decode [1 0 1 0 1 0 1 0]")
    end if
    me._out("/BitsPerComponent "&info["bpc"])
    if (NOT voidP(info["f"])) then me._out("/Filter /"&info["f"])
    if (NOT voidP(info["parms"])) then me._out(info["parms"])
    if (NOT voidP(info["trns"]) and listP(info["trns"])) then
      trns=""
      repeat with j = 1 to count(info["trns"])  -- -1
        trns=trns& info["trns"][j]&" "&info["trns"][j]&" "
      end repeat
      me._out("/Mask ["&trns&"]")
    end if
    
    me._out("/Length "&length(info["data"])&">>")
    
    me._putstream(info["data"])
    me._out("endobj")
    --Palette
    if (info["cs"]="Indexed") then
      me._newobj()
      pal = info["pal"]
      if (pCompress) then pal = me.gzcompress(pal)
      me._out("<<"&filter&"/Length "&length(pal)&">>")
      me._putstream(pal)
      me._out("endobj")
    end if
  end repeat
end

----------------------------------------
--
----------------------------------------
on _putresources me
  me._putfonts()
  me._putimages()
  --Resource dictionary
  pOffsets[2]=length(pBuffer)
  me._out("2 0 obj")
  me._out("<  me._out("/Font <<")
  repeat with aFont in pFonts
    me._out("/F"&aFont["i"]&" "&aFont["n"]&" 0 R")
  end repeat
  me._out(">>")
  if (count(pImages)>0) then
    me._out("/XObject <<")
    repeat with aImage in pImages
      me._out("/I"&aImage["i"]&" "&aImage["n"]&" 0 R")
    end repeat
    me._out(">>")
  end if
  me._out(">>")
  me._out("endobj")
end

----------------------------------------
--
----------------------------------------
on _putinfo me
  me._out("/Producer " & textstring("PDF CLASS "&pPDF_CLASS_VERSION))
  if (string(pTitle)<>"") then me._out("/Title " & textstring(pTitle))
  if (string(pSubject)<>"") then me._out("/Subject " & textstring(pSubject))
  if (string(pAuthor)<>"") then me._out("/Author " & textstring(pAuthor))
  if (string(pKeywords)<>"") then me._out("/Keywords " & textstring(pKeywords))
  if (string(pCreator)<>"") then me._out("/Creator " & textstring(pCreator))
  -- 20031118002711
  
  d = the systemDate
  t = d.seconds
  hr = t/3600
  mins = (t/60) - (hr*60)
  sec = t mod 60
  dat = d.year & _lz(d.month) & _lz(d.day) & _lz(hr) & _lz(mins) & _lz(sec)
  me._out("/CreationDate " & textstring("D:"&dat))
end

on _lz n
  if n<10 then n="0"&n
  return n
end

----------------------------------------
--
----------------------------------------
on _putcatalog me
  me._out("/Type /Catalog")
  me._out("/Pages 1 0 R")
  if (pZoomMode="fullpage") then me._out("/OpenAction [3 0 R /Fit]")
  else if(pZoomMode="fullwidth") then me._out("/OpenAction [3 0 R /FitH null]")
  else if(pZoomMode="real") then me._out("/OpenAction [3 0 R /XYZ null null 1]")
  else if(NOT stringP(pZoomMode)) then me._out("/OpenAction [3 0 R /XYZ null null "&(pZoomMode/100)&"]")
  if (pLayoutMode="single") then me._out("/PageLayout /SinglePage")
  else if(pLayoutMode="continuous") then me._out("/PageLayout /OneColumn")
  else if(pLayoutMode="two") then me._out("/PageLayout /TwoColumnLeft")
end

----------------------------------------
--
----------------------------------------
on _puttrailer me
  me._out("/Size "&(pN+1))
  me._out("/Root "&pN&" 0 R")
  me._out("/Info "&(pN-1)&" 0 R")
end

----------------------------------------
--
----------------------------------------
on _enddoc me
  me._putpages()
  me._putresources()
  --Info
  me._newobj()
  me._out("<<")
  me._putinfo()
  me._out(">>")
  me._out("endobj")
  --Catalog
  me._newobj()
  me._out("<<")
  me._putcatalog()
  me._out(">>")
  me._out("endobj")
  --Cross-ref
  o=length(pBuffer)
  me._out("xref")
  me._out("0 "&(pN+1))
  me._out("0000000000 65535 f ")
  repeat with i = 1 to pN
    s=string(integer(pOffsets[i]))
    s="0000000000".char[1..10-length(s)]&s
    me._out(s && "00000 n ")
  end repeat
  --Trailer
  me._out("trailer")
  me._out("<<")
  me._puttrailer()
  me._out(">>")
  me._out("startxref")
  me._out(o)
  me._out("%%EOF")
  pState=3
end

----------------------------------------
--
----------------------------------------
on _beginpage me, orientation
  pPage=pPage+1
  pPages[pPage]=""
  
  pPageLinks[pPage]=[]--???
  
  pState=2
  pX=pLMargin
  pY=pTMargin
  pLasth=0
  pFontFamily=""
  --Page orientation
  if (string(orientation)="") then
    orientation=pDefOrientation
  else
    orientation=strtoupper(orientation.char[0])
    if (orientation<>pDefOrientation) then pOrientationChanges[pPage]=true
  end if
  if (orientation<>pCurOrientation) then
    --Change orientation
    if (orientation="P") then
      pWPt=pFwPt
      pHPt=pFhPt
      pW=pFw
      pH=pFh
    else
      pWPt=pFhPt
      pHPt=pFwPt
      pW=pFh
      pH=pFw
    end if
    pPageBreakTrigger=pH-pBMargin
    pCurOrientation=orientation
  end if
end

----------------------------------------
-- End of page contents
----------------------------------------
on _endpage me
  pState=1
end

----------------------------------------
-- Begin a new object
----------------------------------------
on _newobj me
  pN=pN+1
  pOffsets[pN]=length(pBuffer)
  me._out(pN&" 0 obj")
end

----------------------------------------
-- Underline text
----------------------------------------
on _dounderline me, x,y,txt
  up=pCurrentFont["up"]
  ut=pCurrentFont["ut"]
  w=me.GetStringWidth(txt)+pWs*substr_count(txt," ")
  the floatprecision=2
  return float(x*pK) && float((pH-(y-up/1000.0*pFontSize))*pK) && float(w*pK) && float(-ut/1000.0*pFontSizePt) && "re f"
end

----------------------------------------
-- Extract info from a JPEG file
----------------------------------------
on _parsejpg me, file, depth
  m=new(#bitmap)
  m.filename=file
  w=m.width
  h=m.height
  --put m.depth
  m.erase()
  
  if (depth=8) then colspace="DeviceGray"
  else if (depth=24) then colspace="DeviceRGB"
  else if (depth=32) then colspace="DeviceCMYK"
  else me._error("unknown depth")
  
  bpc=8
  data=ReadBinFile(file)
  return ["w":w,"h":h,"cs":colspace,"bpc":bpc,"f":"DCTDecode","data":data]
end

----------------------------------------
-- Extract info from a PNG file
----------------------------------------
on _parsepng me, file
  f=ReadBinFile(file)
  
  --Check signature
  if (f.char[1..8]<>chr(137)&"PNG"&chr(13)&chr(10)&chr(26)&chr(10)) then me._Error("Not a PNG file: "&file)
  
  --Read header chunk
  if (f.char[13..16]<>"IHDR") then me._Error("Incorrect PNG file: "&file)
  w=str2int(f.char[17..20])
  h=str2int(f.char[21..24])
  bpc=ord(f.char[25])
  if (bpc>8) then me._Error("16-bit depth not supported: "&file)
  ct=ord(f.char[26])
  if (ct=0) then
    colspace="DeviceGray"
  else if(ct=2) then
    colspace="DeviceRGB"
  else if(ct=3) then
    colspace="Indexed"
  else me._Error("Alpha channel not supported: "&file)
  if (ord(f.char[27])<>0) then me._Error("Unknown compression method: "&file)
  if (ord(f.char[28])<>0) then me._Error("Unknown filter method: "&file)
  if (ord(f.char[29])<>0) then me._Error("Interlacing not supported: "&file)
  
  if (ct=2) then cols=3
  else cols=1
  parms="/DecodeParms <>"
  
  --Scan chunks looking for palette, transparency and image data
  pal=""
  trns=""
  data=""
  
  num=34
  
  repeat while true
    n=str2int(f.char[num..num+3])
    num=num+4
    type=f.char[num..num+3]
    num=num+4
    if (type="PLTE") then
      --Read palette
      pal=f.char[num..num+n-1]
      num=num+n+4
    else if (type="tRNS") then
      --Read transparency info
      t=f.char[num..num+n-1]
      if (ct=0) then
        trns=[ord(t.char[2])]
      else if (ct=2) then
        trns=[ord(t.char[2]),ord(t.char[4]),ord(t.char[6])]
      else
        pos=offset(chr(0),t)-1
      end if
      if (integerP(pos)&pos>=0) then trns=[pos]
      num=num+n+4
    else if (type="IDAT") then
      repeat with i = 0 to n-1
        data=data& f.char[num+i]
      end repeat
      num=num+n+4
    else if (type="IEND") then
      nothing
    else
      num=num+n+4
    end if
    if (n=0) then exit repeat
  end repeat
  if (colspace="Indexed" and pal="") then me._Error("Missing palette in "&file)
  return ["w":w,"h":h,"cs":colspace,"bpc":bpc,"f":"FlateDecode","parms":parms,"pal":pal,"trns":trns,"data":data]
end

----------------------------------------
--
----------------------------------------
on _putstream me, s
  me._out("stream")
  me._out(s)
  me._out("endstream")
end

----------------------------------------
-- Add a line to the document
----------------------------------------
on _out me, s
  if (pState=2) then
    pPages[pPage]=pPages[pPage]& s&pLF
  else
    pBuffer=pBuffer& s&pLF
  end if
end

----------------------------------------
-- Format a text string
----------------------------------------
on textstring s
  return "("&escape(s)&")"
end

----------------------------------------
-- Add  before , ( and )
----------------------------------------
on escape s
  return str_replace(")",")",str_replace("(","(",str_replace("","\",s)))
end

----------------------------------------
-- convert mac string to ansi string
----------------------------------------
on mac2ansi me, str
  out=""
  l=str.length
  repeat with i = 1 to l
    c=str.char[i]
    n=ord(c)
    if n>127 then
      out=out&chr(pMacAnsiVec[n-127])
    else
      out=out&c
    end if
  end repeat
  return out
end

----------------------------------------
-- returns true if specified handler exists in object or any of its ancestor
----------------------------------------
on handlerP me, aHandler
  if me.ilk = #Instance then
    a = me.getAProp(#ancestor)
    if a.ilk = #Instance then
      fnd = handlerP(a, aHandler)
      if fnd then
        return 1
      else
        return me.handler(aHandler)
      end if
    end if
  end if
  return 0
end

 


Contact

MMI
36 South Court Sq
Suite 300
Newnan, GA 30263
USA

Send e-mail