eXept Software AG Logo

Smalltalk/X Webserver

Documentation of class 'HTMLDocumentPainter':

Home

Documentation
www.exept.de
Everywhere
for:
[back]

Class: HTMLDocumentPainter


Inheritance:

   Object
   |
   +--HTMLDocumentInterpreter
      |
      +--HTMLDocumentPainter

Package:
stx:libhtml
Category:
System-Documentation
Version:
rev: 1.424 date: 2023/10/05 09:25:21
user: stefan
file: HTMLDocumentPainter.st directory: libhtml
module: stx stc-classLibrary: libhtml

Description:


Before you use this, read the caveat below.

This one is responsible to paint a document (a linked list
of HTMLElements) into some drawable.

The major entry points are:
    format:for:resolver:style:
            to scan the list for applets, widgets
            and preformat it.

    reformatDocument
            to reformat the document after a size change of the            
            drawable.

    displayX:y:width:height:on:
            to redraw (part of) the document.

Caveat:
    This was written at a time when machines with 4M of main memory were
    considered as ''big machines''. So the code tries hard to save memory,
    in order to be able to display big documents on such small machines reasonably fast.

    This is done by avoiding an in-memory html dom-tree, but instead reparsing the
    document for redraws, and repeating the layout computations every time we draw. 

    Of course, in order to figure out what to draw when positioning (scrolling),
    we would have to redo all calculations from the start of the document.
    (i.e. parse the whole document for every redraw).
    Which would be a stupid idea, making the thing super slow.
    Therefore, it saves so called sync-points, which contain the captured state 
    (x, y position, font, position in document etc.) after every few pages worth
    of text. 
    So, to update any random page, it has to search for the last sync-point
    before that page, and rerender (parse) from there till the end of the visible page.
    The way to get the state for a sync point is cheap and simple: a shallow copy of myself.

    This scheme worked quite well for simple documents in those small-memory systems,
    but it is complicated, error prone, and has problems with more complex documents
    (involving style, box models, complex tables etc.). 
    So now, as we have gigabytes of memory, noone would do it that way.
    Meaning: 
        it ought to be rewritten, to implement a proper dom tree, and the drawing
        engine to implement a proper box model.

    However: 
        we are not going into the browser business here 
        and there is no return of investment if we tried.

    The HTMPainter was written for, and should only be used to display simple help texts, 
    online documentation and html tooltips.
    It will also not be enhanced and maintained, except for obvious bugs which
    break rendering the above mentioned use cases.
    
    Anyone in need for such a thing should investigate better renderers 
    (which exist - both written in Smalltalk and as plugins, 
     using common rendering engines or embedded frameworks like CEF).

[pending bugs:]
    these should be fixed, to make the documentation viewing nicer.
    - <nobr> must    collect text and determine if a break should be done at the beginning
    - <pre>...</pre> inserts an extra empty line
    - <table>        is almost useless
    - <img>          surrounding text on the same textline must be rendered on the
                     baseline of the image; 
                     currently, text after the image is shifted down   

copyright

COPYRIGHT (c) 1996 by Claus Gittinger All Rights Reserved This software is furnished under a license and may be used only in accordance with the terms of that license and with the inclusion of the above copyright notice. This software may not be provided or otherwise made available to, or used by, any other person. No title to or ownership of the software is hereby transferred.

Class protocol:

contents
o  headerAsString: anArray depht: depth

** This is an obsolete interface - do not use it (it may vanish in future versions) **

o  headerAsString: anArray depth: depth
returns printable header assigned to array

helpers
o  fontFor: aFont onDevice: aDevice

o  romanStringFor: aNumber
aNumber >= 100 ifTrue:[

Usage example(s):

^ 'C' , (self romanStringFor:aNumber - 100)

Usage example(s):

^ 'L' , (self romanStringFor:aNumber - 50)

Usage example(s):

^ 'X' , (self romanStringFor:aNumber - 10)

Usage example(s):

^ 'V' , (self romanStringFor:aNumber - 5)

Usage example(s):

^ 'I' , (self romanStringFor:aNumber - 1)

Usage example(s):

     HTMLDocumentPainter new romanStringFor:110  
     HTMLDocumentPainter new romanStringFor:99  
     HTMLDocumentPainter new romanStringFor:9   
     HTMLDocumentPainter new romanStringFor:4    
     HTMLDocumentPainter new romanStringFor:5   

image specs
o  bullet1
This resource specification was automatically generated
by the ImageEditor of ST/X.

Usage example(s):

     self bullet1 inspect
     ImageEditor openOnClass:self andSelector:#bullet1
     Icon flushCachedIcons

o  bullet2
This resource specification was automatically generated
by the ImageEditor of ST/X.

Usage example(s):

     self bullet2 inspect
     ImageEditor openOnClass:self andSelector:#bullet2
     Icon flushCachedIcons

o  bullet3
This resource specification was automatically generated
by the ImageEditor of ST/X.

Usage example(s):

     self bullet3 inspect
     ImageEditor openOnClass:self andSelector:#bullet3
     Icon flushCachedIcons

o  bullet4
This resource specification was automatically generated
by the ImageEditor of ST/X.

Usage example(s):

     self bullet4 inspect
     ImageEditor openOnClass:self andSelector:#bullet4
     Icon flushCachedIcons

o  bullet5
This resource specification was automatically generated
by the ImageEditor of ST/X.

Usage example(s):

     self bullet5 inspect
     ImageEditor openOnClass:self andSelector:#bullet5
     Icon flushCachedIcons

o  bullet6
This resource specification was automatically generated
by the ImageEditor of ST/X.

Usage example(s):

     self bullet6 inspect
     ImageEditor openOnClass:self andSelector:#bullet6
     Icon flushCachedIcons

o  bullet7
This resource specification was automatically generated
by the ImageEditor of ST/X.

o  bullet8
This resource specification was automatically generated
by the ImageEditor of ST/X.

Usage example(s):

     self bullet8 inspect
     ImageEditor openOnClass:self andSelector:#bullet8
     Icon flushCachedIcons

initialization
o  initialize
self initialize

instance creation
o  new
return an initialized instance


Instance protocol:

accessing
o  applets
return a collection of my applets

o  arrayOfHeaderIndex
returns current header index

o  forms
return a collection of my forms

o  imageResolver: somethingProvidingImagesGivenURL
Modified (format): / 29-06-2018 / 16:35:32 / Claus Gittinger

o  leftMargin

o  leftMargin: something

o  listOfHeaders
returns current list of headers

o  rightMargin

o  rightMargin: something

o  scriptObject
return my scriptObject - if any

o  topMargin

o  topMargin: something

accessing-private
o  currentBGColor

o  currentColIndex

o  currentColor

o  currentElement

o  currentFont

o  currentFontAscent

o  currentFontAvgHeight

o  currentFontHeight

o  currentForm

o  currentIndentOffset

o  currentLeftIndent

o  currentRightIndent

o  currentRowIndex

o  currentTable

o  currentUnderlineColor

o  document: aDocument

o  hBegin

o  haveSpace

o  inBLOCKQUOTE
returns an integer>0 if inside <blockquote>...</blockquote>

o  inCenter

o  inDL
returns an integer>0 if inside <dl>...</dl>

o  inKbd

o  inNoBreak

o  inOL
returns an integer>0 if inside <ol>...</ol>

o  inPre

o  inRightAlign

o  inStrikeout

o  inStyle
returns true if inside <style>...</style>

o  inSup

o  inUnderline

o  needSpace

o  previousIsEmpty

o  styleStack

o  ulLevel

o  xPosition

o  yNextLine

o  yPosition

o  yText

applets
o  createAppletFor: element
create the applet

o  defineAppletParameterFor: element
add it to its environment information

o  destroyApplet: appletElement

o  setupAppletElement: element
already present.

checking
o  checkInitialStateAtEndOfDocument
check for correct closing TAGS.
Although, most HTML viewers can handle this case, its usually an
indication of some error and often leads to badly formatted documents

o  printCheckInfoMessage: msg

contents
o  contentsAddHeader: text
assign text to header and store in list of headers

o  printContents
print contents pages

o  printContents: aList pageNumber: initialPageNumber romanPageNumbers: romanPageNumbers
print contents to destination

displaying
o  displayX: xLeft y: yTop width: w height: h on: aGC
self conditionalBreak.

o  pageBreak
(y > self pageBreakLimit and:[self atLeft and:[destination isView not]]) ifTrue:[

o  pageBreakLimit

o  redrawDocument
find a synchronization point

elements-document
o  body
why not self imageFor:bg now:true. ?

o  bodyEnd
(comment from inherited method)
intentionally left blank - to be redefined by concrete class (if required)

o  head
(comment from inherited method)
intentionally left blank - to be redefined by concrete class (if required)

o  headEnd
(comment from inherited method)
intentionally left blank - to be redefined by concrete class (if required)

o  htmlEnd
(comment from inherited method)
intentionally left blank - to be redefined by concrete class (if required)

o  meta
already handled in parser ...

o  style

o  styleEnd
TODO: extract info

o  title
(comment from inherited method)
intentionally left blank - to be redefined by concrete class (if required)

o  titleEnd
(comment from inherited method)
intentionally left blank - to be redefined by concrete class (if required)

elements-forms
o  anyFormElement: element

o  form
(comment from inherited method)
intentionally left blank - to be redefined by concrete class (if required)

o  formEnd
(comment from inherited method)
intentionally left blank - to be redefined by concrete class (if required)

o  input
(comment from inherited method)
intentionally left blank - to be redefined by concrete class (if required)

o  prescanForm: aFormElement
prescan a form, for its widgets max height.
a kludge - we need the form elements' heights BEFORE
formatting (since the text-elements have no origin knowledge,
which could be backpatched (also, we needed a way to break
MarkupText into multiple individual text items

o  prescanForms
a kludge - we need the form elements' heights BEFORE
formatting - since the text-elements have no origin knowledge,
which could be backpatched (also, we needed a way to break
MarkupText into multiple individual text items)

o  textarea
(comment from inherited method)
intentionally left blank - to be redefined by concrete class (if required)

o  textareaEnd
(comment from inherited method)
intentionally left blank - to be redefined by concrete class (if required)

elements-lists
o  blockquote
(comment from inherited method)
intentionally left blank - to be redefined by concrete class (if required)

o  blockquoteEnd
(comment from inherited method)
intentionally left blank - to be redefined by concrete class (if required)

o  dd
self conditionalBreak.

o  dir
(comment from inherited method)
intentionally left blank - to be redefined by concrete class (if required)

o  dirEnd
(comment from inherited method)
intentionally left blank - to be redefined by concrete class (if required)

o  dl
(comment from inherited method)
intentionally left blank - to be redefined by concrete class (if required)

o  dlEnd
(comment from inherited method)
intentionally left blank - to be redefined by concrete class (if required)

o  dt
(comment from inherited method)
intentionally left blank - to be redefined by concrete class (if required)

o  li
this will ignore a followup BR or P

o  li_ol
this will ignore a followup BR or P

o  li_ul
in <ul> ... </ul> - draw a bullet

o  listTypeOElement: anElement

** This is an obsolete interface - do not use it (it may vanish in future versions) **

o  listTypeOfElement: anElement

o  menu
(comment from inherited method)
intentionally left blank - to be redefined by concrete class (if required)

o  menuEnd
(comment from inherited method)
intentionally left blank - to be redefined by concrete class (if required)

o  ol
need to pass this info to </OL> element, for this to work

o  olEnd
(comment from inherited method)
intentionally left blank - to be redefined by concrete class (if required)

o  ul
need to pass this info to </UL> element, for this to work

Usage example(s):

indent := element numericParameterFor:'INDENT' default:ULindent.

o  ulEnd
(comment from inherited method)
intentionally left blank - to be redefined by concrete class (if required)

elements-pseudo tags
o  internalMathFont
(comment from inherited method)
intentionally left blank - to be redefined by concrete class (if required)

o  internalMathFontEnd
(comment from inherited method)
intentionally left blank - to be redefined by concrete class (if required)

elements-special
o  a
needSpace := true.

Usage example(s):

haveSpace := true.

o  aEnd
(comment from inherited method)
intentionally left blank - to be redefined by concrete class (if required)

o  app
backward compatible (now obsolete) applet tag

o  appEnd
backward compatible (now obsolete) applet end-tag

o  applet
(comment from inherited method)
intentionally left blank - to be redefined by concrete class (if required)

o  appletEnd
(comment from inherited method)
intentionally left blank - to be redefined by concrete class (if required)

o  area
self halt.

o  imageFor: urlString now: now
now:true.

o  img
<IMG
SRC='image-url'
ALT='alternative-text'
WIDTH=w
HEIGHT=h
HSPACE=hSpc
VSPACE=vSpc
BORDER=bw
NOPRINT // deprecated
PRINT=yesOrNo // deprecated
LOWSRC='lowRes-image-url' // not implemented
STYLE='width:w; height:h'
>

o  map
(comment from inherited method)
intentionally left blank - to be redefined by concrete class (if required)

o  mapEnd
(comment from inherited method)
intentionally left blank - to be redefined by concrete class (if required)

o  param
done in preparse - see #defineAppletParameterFor: ...

o  script
the script is now loaded and evaluated by the parser
(to allow it to generate the HTML text ...)
However, we need to remember it, for startup & cleanup message
sends.

o  specialMarkup
called for text

elements-structure
o  br
(comment from inherited method)
intentionally left blank - to be redefined by concrete class (if required)

o  center
(comment from inherited method)
intentionally left blank - to be redefined by concrete class (if required)

o  centerEnd
(comment from inherited method)
intentionally left blank - to be redefined by concrete class (if required)

o  div
w := element numericParameterFor:#'WIDTH' default:nil.

o  h1
headline level1

o  h1End
headline end

o  h2
headline level2

o  h2End
headline end

o  h3
headline

o  h3End
headline end

o  h4
headline

o  h4End
headline end

o  h5
headline

o  h5End
headline end

o  h6
headline

o  h6End
headline end

o  h7
headline

o  h7End
headline end

o  h8
headline

o  h8End
headline end

o  h9
headline

o  h9End
headline end

o  hr
should come from a config or classVar

o  nobr
(comment from inherited method)
intentionally left blank - to be redefined by concrete class (if required)

o  nobrEnd
(comment from inherited method)
intentionally left blank - to be redefined by concrete class (if required)

o  p
cg: no, a P is a P

Usage example(s):

self empty.

o  pEnd
(comment from inherited method)
intentionally left blank - to be redefined by concrete class (if required)

o  pre
conditionalHalfEmpty.

o  preEnd
if the last element was a newLine, remove it

o  span
<span style="padding: 0 2px;border: 1px solid black;border-radius: 3px;">Connect</span>

o  spanEnd
(comment from inherited method)
intentionally left blank - to be redefined by concrete class (if required)

o  tab
(comment from inherited method)
intentionally left blank - to be redefined by concrete class (if required)

o  wbr
(comment from inherited method)
intentionally left blank - to be redefined by concrete class (if required)

o  xmp
(comment from inherited method)
intentionally left blank - to be redefined by concrete class (if required)

o  xmpEnd
(comment from inherited method)
intentionally left blank - to be redefined by concrete class (if required)

elements-style
o  acronym
(comment from inherited method)
intentionally left blank - to be redefined by concrete class (if required)

o  acronymEnd
(comment from inherited method)
intentionally left blank - to be redefined by concrete class (if required)

o  address
(comment from inherited method)
intentionally left blank - to be redefined by concrete class (if required)

o  addressEnd
(comment from inherited method)
intentionally left blank - to be redefined by concrete class (if required)

o  b
(comment from inherited method)
intentionally left blank - to be redefined by concrete class (if required)

o  bEnd
inPre ~~ 0 ifTrue:[

o  cite
(comment from inherited method)
intentionally left blank - to be redefined by concrete class (if required)

o  citeEnd
(comment from inherited method)
intentionally left blank - to be redefined by concrete class (if required)

o  code
(comment from inherited method)
intentionally left blank - to be redefined by concrete class (if required)

o  codeEnd
(comment from inherited method)
intentionally left blank - to be redefined by concrete class (if required)

o  dfn
(comment from inherited method)
intentionally left blank - to be redefined by concrete class (if required)

o  dfnEnd
self handlePendingSpaceNeed.

o  em
(comment from inherited method)
intentionally left blank - to be redefined by concrete class (if required)

o  emEnd
(comment from inherited method)
intentionally left blank - to be redefined by concrete class (if required)

o  font
a font element can also specifies bgColor, color etc.

o  fontEnd
inPre ~~ 0 ifTrue:[

o  i
(comment from inherited method)
intentionally left blank - to be redefined by concrete class (if required)

o  iEnd
inPre ~~ 0 ifTrue:[

o  kbd
(comment from inherited method)
intentionally left blank - to be redefined by concrete class (if required)

o  kbdEnd
inPre ~~ 0 ifTrue:[

o  s
(comment from inherited method)
intentionally left blank - to be redefined by concrete class (if required)

o  sEnd
(comment from inherited method)
intentionally left blank - to be redefined by concrete class (if required)

o  samp
(comment from inherited method)
intentionally left blank - to be redefined by concrete class (if required)

o  sampEnd
(comment from inherited method)
intentionally left blank - to be redefined by concrete class (if required)

o  small
(comment from inherited method)
intentionally left blank - to be redefined by concrete class (if required)

o  smallEnd
(comment from inherited method)
intentionally left blank - to be redefined by concrete class (if required)

o  strike
(comment from inherited method)
intentionally left blank - to be redefined by concrete class (if required)

o  strikeEnd
(comment from inherited method)
intentionally left blank - to be redefined by concrete class (if required)

o  strong
(comment from inherited method)
intentionally left blank - to be redefined by concrete class (if required)

o  strongEnd
(comment from inherited method)
intentionally left blank - to be redefined by concrete class (if required)

o  sub
(comment from inherited method)
intentionally left blank - to be redefined by concrete class (if required)

o  subEnd
(comment from inherited method)
intentionally left blank - to be redefined by concrete class (if required)

o  sup
(comment from inherited method)
intentionally left blank - to be redefined by concrete class (if required)

o  supEnd
(comment from inherited method)
intentionally left blank - to be redefined by concrete class (if required)

o  tt
(comment from inherited method)
intentionally left blank - to be redefined by concrete class (if required)

o  ttEnd
(comment from inherited method)
intentionally left blank - to be redefined by concrete class (if required)

o  u
(comment from inherited method)
intentionally left blank - to be redefined by concrete class (if required)

o  uEnd
self handlePendingSpaceNeed.

o  var
(comment from inherited method)
intentionally left blank - to be redefined by concrete class (if required)

o  varEnd
(comment from inherited method)
intentionally left blank - to be redefined by concrete class (if required)

elements-tables
o  caption
(comment from inherited method)
intentionally left blank - to be redefined by concrete class (if required)

o  drawTable

o  drawTableRow: row
draw one row

o  finishPreviousTableColumn
'HTML [info]: empty table row' infoPrintCR.

o  finishPreviousTableRow: final

o  table
=fontDescent

Usage example(s):

allow space for tables border

o  tableEnd
true.

o  tbody
(comment from inherited method)
intentionally left blank - to be redefined by concrete class (if required)

o  tbodyEnd
(comment from inherited method)
intentionally left blank - to be redefined by concrete class (if required)

o  td
(comment from inherited method)
intentionally left blank - to be redefined by concrete class (if required)

o  th
(comment from inherited method)
intentionally left blank - to be redefined by concrete class (if required)

o  th_td_common
'pass1 col: ' print. currentColIndex print. ' x:' print. col x print. ' xT:' print. col xText printCR.

o  tr
allow space for tables leftborder

elements-text
o  addText: txtIn fromElement: elementArg
Transcript show:'T: '; show:needSpace; show:' '; showCR:txtIn.

o  drawDelayedStringsWithDelta: deltaYForDelayedText

o  futureDrawString: aString atX: xS y: yS yt: yT to: xE
hack: the y-offset of strings is not known, until we finish the line
(graphics may be embedded, which shift the baseLine down)
Thus, we collect the drawing calls until the line is flushed,
then call them, passing a y-offset as additional arg

o  possiblyAddSpaceAfter: lastAddedText
hack: if text ends with a letter,

o  privateDrawString2: aString atX: xS y: yS yt: yt to: xE underline: underlineArg strikeout: strikeoutArg

o  privateDrawString2: aString atX: xS y: yS yt: yt to: xE underline: underlineArg strikeout: strikeoutArg spanStyle: spanStyleArg

o  privateDrawString: aString atX: xS y: yS to: xE

formatting
o  flushAnchorColors
anchors notNil ifTrue:[

o  format: docAnchor for: aGC resolver: aResolver style: aStyle
loadedAppletClasses := nil.

o  process: aDocumentAnchor
skip upto applet end

o  reformatDocument
destination width == docWidth ifTrue:[

helpers
o  atLeft

o  atOrLeftOfLeft

o  atTop

o  break
yText is nonNil, if there was an image or widget; we have to shift the collected text then

o  conditionalBreak
break line if not already at the beginning

o  conditionalEmpty
add vertical space, but only if there is not already some

o  conditionalHalfEmpty
add vertical space, but only if there is not already some

o  currentElementHasHREF

o  do_needAndNewPage
handle any NEWPAGE and NEED= attributes of the current element,
put only if painting to paper (i.e. ignore if displaying)

o  do_starOfficeStyleBefore
handle
STYLE='page-break-before: always'

o  empty

o  empty: height

o  getFontsFor: aGC

o  halfEmpty

o  handlePendingSpaceNeed

o  header: index font: aFont space: space
don't break for headers within a list

o  headerEnd
self empty.

o  initialHeaderNumbers

o  needVerticalSpace: nVerticalPixel

o  relativeValueFrom: aString with: aNumericValue

initialization & release
o  initialize
(comment from inherited method)
just to ignore initialize to objects which do not need it

o  release
sent from docView, to release stuff

o  terminateMetaCommands
sent from docView, to release stuff

o  whenAboutToRender: tag call: aCallbackBlock
register a block to e invoked on the element to be draw.
This allows for just-in-time manipulation of eg. anchor colors.
This has been added especially for the help wizard, which wants to draw
invalid anchors (refs) in red.

meta commands
o  processMetaCommands
Transcript showCR:metaCmd , ' -> ' , metaArg.

o  refreshDocument: url

private
o  addSyncPoint

o  clearLastTextX
lastTextX is only used for PS-printing:
it remembers where the previous text ended,
in order to optimize the output (no new coordinates needed between words).
ClearlastTextX forgets any remembered position, so that the next textOut
will generate a drawString with coordinates.

o  displayImagesOn: destinationDevice usingPlayers: players
removeLast.

o  forkImageSequencePlayerFor: entry

o  handleColorAttribute
font and th/td elements can also specify bgColor, color etc.

o  handleColorChange

o  playImageSequence: entry
get device images first ..

o  rememberLastTextX
lastTextX is only used for PS-printing:
it remembers where the previous text ended,
in order to optimize the output (no new coordinates needed between words).
ClearlastTextX forgets any remembered position, so that the next textOut
will generate a drawString with coordinates.

o  resyncFrom: syncPoint
fetch the state found there

o  saveExcursion: aBlock
save the current state, perform aBlock and restore the state afterwards

o  saveExcursionFrom: firstElement while: testBlock
remember the current state, process elements starting with firstElement,
while testBlock returns true, finally restore the state

o  setupInitialState
setup some initial state, such as margins, indents,
colors, fonts etc.

o  startImageDisplayProcess
handle two queues in the background; the first
contains images which are to be loaded (i.e. which are
contained in the current document) and have to be
rendered for the device.
The second contains those which are to be displayed.
The displayList is always served first.

o  syncPoint
save my state in a sync point

queries
o  anchorAt: aPoint
given a (click-) point, search for and return the corresponding
anchorElement. Return nil, if there is none

o  elementAt: aPoint
given a (click-) point, search for and return the corresponding
element. Return nil, if there is none

o  elementAt: aPoint type: typeOrNil
given a (click-) point, search for and return the corresponding
element. Return nil, if there is none

o  height

o  imageAt: aPoint
given a (click-) point, search for and return the corresponding
imageElement. Return nil, if there is none

o  positionOfAnchor: aLocalAnchor

o  width

style changes
o  currentStyle

o  defaultStyle

o  getFontParameters
extra spacing.

o  normalStyle

o  popStyle
should not happen

o  pushStyle

o  setBGColor: aColor

o  setColor: aColor

o  setFont: aFont
self halt.

o  setStyle: aStyle

o  setUnderlineColor: aColor

widget-actions
o  buttonWidgetPressed: aWidgetElement
"/ pass it to the script object - if any.

o  formResetted: aFormElement from: aWidgetElement
reset forms contents to their original values

o  formSubmitted: aFormElement from: aWidgetElement
submit-button may still have an onClick... (nil if submitted via RETURN)

o  mouseOverAnchor: anElement
pass it to the script object - if any.

widgets
o  createWidgetFor: element inForm: aForm
widget backgroundColor:(destination viewBackground).

o  destroyWidgets

o  fixupForm: aForm
fixup the form: if there is a single inputField,

o  hideAllWidgets
hide any widget

o  hideWidgets
hide any widget which became invisible

o  prescanForm: aForm atIndex: startIndex
prescan a form, for its widgets max height.
a kludge - we need the form elements' heights BEFORE
formatting (since the text-elements have no origin knowledge,
which could be backpatched (also, we needed a way to break
MarkupText into multiple individual text items

o  showWidgets
show any widget which became visible


Private classes:

    BorderStyle
    Padding
    PainterState
    SpanStyle
    TextStyle
    WidgetQuery


ST/X 7.7.0.0; WebServer 1.702 at 20f6060372b9.unknown:8081; Mon, 18 Nov 2024 06:56:27 GMT