Design: 06.01.02/P17

This is an abstract, language-independent design. Grim details may be found in the corresponding source code. You may return to the documentation for the module containing this program design, or to the entire hierarchical table of topics covered by the PVT.


PROGRAM 17: Modelling clipping for text and annotation text

CHARACTERISTICS: ynny

OPERATOR SCRIPT:

MODELLING CLIPPING OF STROKE TEXT: There should be six windows,
each containing some clipped text.  The visible text should be
accurately outlined by a dotted polyline. Identify the window in
which this is NOT the case.

MODELLING CLIPPING OF CHAR TEXT: The screen should display a
single text string.  Count and report the number of visible
characters in the string.  Even if a character is partially
clipped, it should be included in the count.

MODELLING CLIPPING OF ENTIRE ANNOTATION TEXT: There should be six
windows, some containing at least partially visible annotation
text, others empty.  List all empty the windows (in any order).

PARTIAL MODELLING CLIPPING OF ANNOTATION TEXT: There should be eight
numbered lines of text, each containing some visible annotation text.
In all but one, a dotted polyline is used to outline that part of the
annotation text which must be visible (because it is within the
transformed modelling clipping volume).  Identify the window in which
the outline is at least partially empty.  In all the windows, ignore
any additional annotation text that may appear outside the outline.

DESIGN:

throughout, represent a line segment as a point P and vector V,
  where endpoints = P and P+V

*** *** *** ***   text   *** *** *** ***

TEST: #SR 40 41 42 43 53 57 58
      "Exactly those parts of a text primitive in STROKE
       precision that lie outside the current modelling clipping
       volume should be clipped."

txstr = text string with ASCII characters that fill character box
      = ZHMENKX

*** *** ***  set up expected horizontal text extent:

using text alignment = center,half:
nomhl = nominal x-location of left border of horizontal string
nomhr = nominal x-location of right border of horizontal string
nomhb = nominal y-location of baseline of horizontal string
nomhc = nominal y-location of capline of horizontal string
chxph = horizontal-path expansion factor = 0.3
nomhl = nomhl*chxph
nomhr = nomhr*chxph
chhth = horizontal-path character height = 1.8 / (nomhr-nomhl)

*** *** ***  set up expected vertical text extent:

assuming text alignment = center,half:
nomvl = nominal x-location of left border of vertical string
nomvr = nominal x-location of right border of vertical string
nomvb = nominal y-location of baseline of vertical string
nomvc = nominal y-location of capline of vertical string
chxpv = vertical-path expansion factor = 3.0
nomvl = nomvl*chxpv
nomvr = nomvr*chxpv
chhtv = vertical-path character height = 1.8 / (nomvc-nomvb)

set up 6 numbered windows on screen
set text alignment      = center,half
set text precision      = stroke

ngwin = incorrectly drawn window = random from 1 to 6
for thiswn = 1 to 6
   xf = modelling transformation to map double-unit MC cube (-1 to 1)
        into window #thiswn in xy-dimensions, and into (0 to 1)
        in z-dimension
   set local transformation = xf
   set clipping ON

   compute expected text position:
get_vecs:
   td(1) = random 3D vector chosen from -1 to 1 in each dimension
   td(2) = random 3D vector chosen from -1 to 1 in each dimension
   nvec = normal vector to text plane = cross-product of vec1 x vec2

   ensure text-plane not edge-on to operator:
   if (nvec too oblique) then
      goto get_vecs
   endif

   tdrot = 3D rotation transformation resulting from application
           of text direction vectors

   compute text rectangle corners:
   if (thiswn < 4) then
      set up for horizontal path:
      set character height    = chhth
      set character expansion = chxph
      set text path           = RIGHT
      scxf = transformation to scale by chhth
      corxf = transformation for corners of text rectangle induced
              by text direction vectors and char-height: TLC to MC
            = scxf x tdrot
      compute expected corners of text rectangle in MC:
      corlb = (nomhl,nomhb,0) transformed by corxf
      corlc = (nomhl,nomhc,0) transformed by corxf
      corrb = (nomhr,nomhb,0) transformed by corxf
      corrc = (nomhr,nomhc,0) transformed by corxf
   else
      set up for vertical path:
      set character height    = chhtv
      set character expansion = chxpv
      set text path           = DOWN
      scxf = transformation to scale by chhtv
      corxf = transformation for corners of text rectangle induced
              by text direction vectors and char-height: TLC to MC
            = scxf x tdrot
      compute expected corners of text rectangle in MC:
      corlb = (nomvl,nomvb,0) transformed by corxf
      corlc = (nomvl,nomvc,0) transformed by corxf
      corrb = (nomvr,nomvb,0) transformed by corxf
      corrc = (nomvr,nomvc,0) transformed by corxf
   endif

   4 corners form a scaled, rotated rectangle in 3D MC,
      and a parallelogram when projected to xy-plane.
   cent = center point = (corlb + corlc + corrb + corrc) / 4
   hvec  = horizontal vector   = corrb-corlb
   vvec  = vertical vector     = corlc-corlb
   d1vec = 1st diagonal vector = corrc-corlb
   d2vec = 2nd diagonal vector = corlc-corrb

   compute values for clipping planes and for expected vertices:

   if (thiswn = 1 or 4) then
      clip off all but one corner:
      plpt(1) = (corlb + 2*cent) / 3
      vec(1)  = cross-product of nvec x d2vec
      numhp = number of half-planes = 1
      expnum = expected number of vertices = 3
      expv(1) = corlb
      expv(2) = (2*corlc + corlb) / 3
      expv(3) = (2*corrb + corlb) / 3

   elseif (thiswn = 2 or 5) then
      clip off 4 corners:
      plpt(1) = (2*corlb + cent) / 3
      plpt(2) = (2*corlc + cent) / 3
      plpt(3) = (2*corrb + cent) / 3
      plpt(4) = (2*corrc + cent) / 3
      vec(1)  = cross-product of d2vec x nvec
      vec(2)  = cross-product of d1vec x nvec
      vec(3)  = -vec(2)
      vec(4)  = -vec(1)
      numhp = number of half-planes = 4

      expnum = expected number of vertices = 8
      expv(1) = (2*corlc + corlb) / 3
      expv(2) = (2*corlc + corrc) / 3
      expv(3) = (2*corrc + corlc) / 3
      expv(4) = (2*corrc + corrb) / 3
      expv(5) = (2*corrb + corrc) / 3
      expv(6) = (2*corrb + corlb) / 3
      expv(7) = (2*corlb + corrb) / 3
      expv(8) = (2*corlb + corlc) / 3

   elseif (thiswn = 3 or 6) then
      clip down the middle:
      numhp = number of half-planes = 1
      plpt(1) = cent
      expnum = expected number of vertices = 4

      if (thiswn = 3) then
         clip horizontally - clip away top half
         vec(1) = cross-product of hvec x nvec
         expv(1) = corlb
         expv(2) = corrb
         expv(3) = (corrb + corrc) / 2
         expv(4) = (corlb + corlc) / 2
      else
         clip vertically - clip away left side
         vec(1) = cross-product of vvec x nvec
         expv(1) = corrc
         expv(2) = corrb
         expv(3) = (corrb + corlb) / 2
         expv(4) = (corrc + corlc) / 2
      endif

   endif

   set MCV (with REPLACE operator) with numhp half-planes =
      points: plpt; vectors: vec

   draw 3D text using:
      text position     = (0,0,0)
      direction vectors = td(1), td(2)
      character string  = txstr

   if (thiswn = ngwin) then
      3rd expected vertex = cent
   endif

   compute expected vertices in WC
   for ix = 1, expnum+1
      iy = mod(ix, expnum) + 1
      plloc(ix) = expv(iy) as transformed by xf
   next ix

   set clipping OFF
   set modelling transformation to identity
   draw 2D polyline for plloc(1 to expnum+1)
next thiswn

OPQA/MODELLING CLIPPING OF STROKE TEXT: In which window is the
  clipped text NOT accurately outlined?
pass/fail depending on (operator identifies ngwin)

clear screen

TEST: #SR 40 41 42 43 53 57 58 60
      "Characters in a text primitive drawn in CHAR precision
       that lie completely outside the current modelling clipping
       volume should be clipped, and those completely inside
       should not be clipped."

set text font           = 1
set text precision      = char
set text alignment      = center,half
set text path           = RIGHT

chstr  = "EEEEEEEEEEEEE"
numvis = random integer from 2 to 6
txlen  = number of characters drawn = 2*numvis + 1

set 2D MCV (with REPLACE operator) with 1 half-plane =
   point: (.5,.5); vector: (1,0)
set clipping on

draw 2D text using:
   text position     = (.5,.5)
   character string  = 1st txlen characters of chstr

OPQA/MODELLING CLIPPING OF CHAR TEXT: How many characters are at
  least partially visible?
pass/fail depending on (operator response = numvis or numvis+1)

*** *** *** ***   annotation text   *** *** *** ***

TEST: #SR 40 41 42 43 53 57 58 61 62
      "If its reference point is inside the current MCV, then
       those parts of an annotation text primitive that also lie
       inside should be visible, but if its reference point is
       outside the current MCV, then the entire annotation text
       primitive should be model-clipped."

set up 6 windows

npcpwc = NPC units per WC units

winsiz = window-size in NPC = window-size in WC * npcpwc

set text font                 = 1
set text precision            = stroke
set character spacing         = 0
set character expansion       = 1
set annotation char-height    = 0.2 * winsiz
set annotation text alignment = center,half
set annotation text path      = RIGHT
set annotation style          = 2

ranwin = list of 6 integers chosen from 1-8
vislis = list of windows with invisible annotation text = empty
set clipping ON

vecx = 0
for thiswn = 1 to 6
   wntype = ranwin(thiswn)
   plpt = center of window #thiswn (with z=0.5)

   point MCV vector to 4 quadrants around the y-axis:
   if (mod(wntype,4) < 2) then
      vecy = -1
   else
      vecy =  1
   endif
   vecz = 2 * mod(wntype,2) - 1

   set MCV (with REPLACE operator) with 1 half-plane =
   point: plpt; vector: vec

   if (wntype < 5) then
      should be partially visible:
      delta = 0.01
   else
      should be invisible:
      add thiswn to vislis
      delta = -0.01
   endif

   d1vec = vector pointing into or out of MCV = delta * vec

   set up reference point and annotation point on opposite sides of
   clipping plane:
      refpt = reference point (MC) = plpt + d1vec
      offst = annotation offset (NPC) = -2 * d1vec * npcpwc
   draw annotation text "ABC" at refpt with offst
next thiswn

OPQA/MODELLING CLIPPING OF ENTIRE ANNOTATION TEXT: List all the
  empty windows.
pass/fail depending on (operator response = vislis)

*** *** *** *** *** *** *** *** *** *** *** *** *** ***

TEST: #SR 40 41 42 43 53 57 58 62
      "If its reference point is inside the current MCV, then
       at least those parts of an annotation text primitive that
       also lie inside should be visible."

txstr = text string with ASCII characters that fill character box
      = "EXAM"

using text alignment = center,half:
nomhl = nominal x-location of left border of horizontal string
nomhr = nominal x-location of right border of horizontal string
nomhb = nominal y-location of baseline of horizontal string
nomhc = nominal y-location of capline of horizontal string

numlin = number of lines to display = 8
yincr = 1 / (numlin + 1.0)
ytop = 1-yincr
yloc = ytop
set achht to scale ann-text so as to fit on line:
achht = WC character height = 0.5 * yincr

nomhl = nomhl * achht
nomhr = nomhr * achht
nomhb = nomhb * achht
nomhc = nomhc * achht

set text font                 = 1
set text precision            = stroke
set character spacing         = 0
set character expansion       = 1
set annotation char-height    = achht * npcpwc
set annotation text alignment = center,half
set annotation text path      = RIGHT
set text color                = 1
set polyline color            = 2
set line style                = dotted
set line width                = minimum available

draw labels for numlin lines
ngline = incorrect line = random from 1 to numlin
xcent = reference point for annotation text = 0.6
expnum = expected number of vertices = 5

for thisln = 1 to numlin
   set clipping ON

   compute values for clipping planes and for expected vertices:
   clip down the middle:
   plpt(1) = xcent,yloc,0.5
   vecx = nomhc
   if (random integer from 0 to 1 = 1) then
      vecx = -vecx
   endif
   vecy = nomhl * random real between -.7 and .7
   vecz = 0.1

   set MCV (with REPLACE operator) with 1 half-plane =
      points: plpt; vectors: vec

   compute expected annotation text position:
   chxp = character expansion factor = random from 0.6 to 1.0

   xleft = xcent + nomhl*chxp
   xrite = xcent + nomhr*chxp
   ybas  = yloc  + nomhb*chxp
   ycap  = yloc  + nomhc*chxp

   draw 3D annotation text:
      make sure reference point inside MCV:
      reference point   = plpt(1) + 0.1*vec
      annotation offset = -0.1 * vec * npcpwc
      character string  = txstr

   compute expected vertices in WC:
   expvy(1) = ycap
   expvy(2) = ybas
   expvy(3) = ybas
   expvy(4) = ycap
   expvy(5) = ycap

   if (thisln = ngline) then
      distort vertices:
      rtval = xrite + 0.1
      lfval = xleft - 0.1
   else
      rtval = xrite
      lfval = xleft
   endif

   if (vecx > 0) then
      expvx(1) = rtval
      expvx(2) = rtval
      expvx(5) = rtval
   else
      expvx(1) = lfval
      expvx(2) = lfval
      expvx(5) = lfval
   endif

   expvx(3) = xcent + (ybas-yloc) * vecy/vecx
   expvx(4) = xcent + (yloc-ytop) * vecy/vecx

   set clipping OFF
   draw 2D polyline for expv(1 to expnum)

   yloc = yloc-yincr
next thisln

OPQA/PARTIAL MODELLING CLIPPING OF ANNOTATION TEXT: On which
  line is the dotted boundary NOT filled with annotation text
  (additional annotation text outside boundary is permitted)?
pass/fail depending on (operator identifies ngline)

END PROGRAM 17