home *** CD-ROM | disk | FTP | other *** search
/ C/C++ Interactive Guide / c-cplusplus-interactive-guide.iso / c_ref / csource4 / 287_01 / gradprog.doc < prev    next >
Encoding:
Text File  |  1989-05-25  |  31.1 KB  |  1,233 lines

  1.  
  2.  
  3.  
  4.  
  5.        
  6.                        GRAD Programmers' Reference Manual
  7.                                         
  8.                                 Table Of Content
  9.        
  10.        
  11.        1   Introduction . . . . . . . . . . . . . . . . . . . . . .    1
  12.        2   Basic Philosophy . . . . . . . . . . . . . . . . . . . .    2
  13.        3   calcaddr and plottype  . . . . . . . . . . . . . . . . .    3
  14.           3.1  calcaddr . . . . . . . . . . . . . . . . . . . . . .    3
  15.           3.2  plottype . . . . . . . . . . . . . . . . . . . . . .    3
  16.        4   Frame Table  . . . . . . . . . . . . . . . . . . . . . .    4
  17.        5   Font Table . . . . . . . . . . . . . . . . . . . . . . .    5
  18.        6   HorzLine, VertLine and Line  . . . . . . . . . . . . . .    6
  19.           6.1  HorzLine . . . . . . . . . . . . . . . . . . . . . .    6
  20.           6.2  VertLine . . . . . . . . . . . . . . . . . . . . . .    6
  21.           6.3  Line . . . . . . . . . . . . . . . . . . . . . . . .    7
  22.        7   Circle, Ellipse and Arc  . . . . . . . . . . . . . . . .    9
  23.           7.1  Circle . . . . . . . . . . . . . . . . . . . . . . .    9
  24.           7.2  Ellipse  . . . . . . . . . . . . . . . . . . . . . .   10
  25.           7.3  Arc  . . . . . . . . . . . . . . . . . . . . . . . .   11
  26.        8   Text Writing . . . . . . . . . . . . . . . . . . . . . .   12
  27.        9   Region Filling . . . . . . . . . . . . . . . . . . . . .   13
  28.        10  Block Copy, Save and Load  . . . . . . . . . . . . . . .   15
  29.        11  Writing Graphics Display Adapter Driver  . . . . . . . .   16
  30.        12  Writing Printer Driver . . . . . . . . . . . . . . . . .   17
  31.        13  Hints on Porting to Other C Compiler or Other Machine  .   18
  32.        
  33.  
  34.  
  35.  
  36.  
  37.  
  38.  
  39.  
  40.  
  41.  
  42.  
  43.  
  44.  
  45.  
  46.  
  47.  
  48.  
  49.  
  50.  
  51.  
  52.  
  53.  
  54.  
  55.  
  56.  
  57.  
  58.  
  59.  
  60.  
  61.  
  62.  
  63.  
  64.  
  65.  
  66.  
  67.  
  68.  
  69.  
  70.                        GRAD Programmers' Reference Manual
  71.  
  72.        1   Introduction
  73.        
  74.             The source code of the GRAD library are coyrighted. However
  75.        you  are  free  to modify and re-distribute the source files for
  76.        non-commerical  use  and  you indiciate the files are originated 
  77.        from the GRAD library.
  78.             
  79.             If you find and bugs in the GRAD routines, please inform me.
  80.        Your help will be appreciated.
  81.  
  82.  
  83.  
  84.  
  85.  
  86.  
  87.  
  88.  
  89.  
  90.  
  91.  
  92.  
  93.  
  94.  
  95.  
  96.  
  97.  
  98.  
  99.  
  100.  
  101.  
  102.  
  103.  
  104.  
  105.  
  106.  
  107.  
  108.  
  109.  
  110.  
  111.  
  112.  
  113.  
  114.  
  115.  
  116.  
  117.  
  118.  
  119.  
  120.  
  121.  
  122.  
  123.  
  124.  
  125.  
  126.  
  127.                                                                         1
  128.  
  129.  
  130.  
  131.  
  132.  
  133.                        GRAD Programmers' Reference Manual
  134.  
  135.        2   Basic Philosophy
  136.        
  137.             The idea of GRAD  system come to  me about 1  year ago (1986
  138.        summer). At that time, I want to write a program that can produce
  139.        high quality,  high speed full page  text and  graphics print out
  140.        suitable for report on a dot matrix printer.
  141.             
  142.             In order to  produce high  quality text  output,  bit mapped
  143.        character must be able to be loaded and included in the print out
  144.        as  graphics  data.  However printing a full  page  of bit mapped
  145.        graphics data on a dot matrix printer may take  5  to 15 minutes.
  146.        So  all normal  text  should be printed in  NLQ text  mode of the
  147.        printer instead of in graphics mode.
  148.             
  149.             Furthermore 2  types of graphics data may be included in the
  150.        print out.  First type is that the graphics  data  are already in
  151.        bit mapped format.  Another type is that the graphics data are in
  152.        high level command format  such  as circles,  lines and dots. The
  153.        advantages of second type are that the graphics data file size is
  154.        relatively small unless the drawing is very complicated. Further-
  155.        more and the drawings may be changed easily.
  156.             
  157.             Very  quickly,  I realized  that  this  program is  not that
  158.        simple.  As the first phase of implementation, a graphics library
  159.        is written which is the GRAD system. The sample program MPrint is
  160.        a simplified version of my original idea.
  161.             
  162.             
  163.             In GRAD,  you may divide the routines into different layers.
  164.        Layer  0  contains routines that directly deal with  the hardware
  165.        (including  memory).   Hence  layer   0   routines  are  hardware
  166.        dependent.  The  number  of routines in  this layer is kept  to a
  167.        minimum.   Layer  1  routines  accepts  physical  coordinates  as
  168.        parameters. No external GRAD functions are in this layer. Most of
  169.        this routines  are written in  assembly  language. GRAD functions
  170.        usually  spend most  of  them  in  this  layer of  codes. Layer 2
  171.        routines handles translation of  logical coordinates  to physical
  172.        coordinates and also clipping  of drawings under  current defined
  173.        window.  Most  of  these routines are  written in C.  Most of the
  174.        layer  2  routines call layer  1  routines to do actual drawings.
  175.        However there are some exception cases that layer 2 routines call
  176.        layer 0  routines directly.  But none of the routines  in layer 1
  177.        and layer 2 access hardware directly.
  178.             
  179.             There are also  some  functions  that  do  not  requires any
  180.        coordinates in the parameter  such as PlotType and ResetWin. They
  181.        are called system functions and do not belong  to any  one of the
  182.        above layers.
  183.  
  184.  
  185.  
  186.  
  187.  
  188.  
  189.  
  190.  
  191.  
  192.  
  193.  
  194.                                                                         2
  195.  
  196.  
  197.  
  198.  
  199.  
  200.                        GRAD Programmers' Reference Manual
  201.  
  202.        3   calcaddr and plottype
  203.        
  204.        3.1  calcaddr
  205.        
  206.             $calc and downln  are the two main  routines  in  the module
  207.        calcaddr. There are also some hardware dependent routines such as
  208.        settext  and setgraph  but they  would  not be discussed  in this
  209.        manual.
  210.             
  211.             $calc accepts x and y coordinates  in  register  AX  and BX.
  212.        Segment and offset values are returned in AX and BX respectively.
  213.        The  return  address a far address that  means the  segment value
  214.        should not be changed because the segment value may  be a logical
  215.        number only  and not a actual  segment number.  The  offset value
  216.        must be a even number and it must  be set  up in such  a way that
  217.        the  whole line  containing  the point  x,y  can  be  accessed by
  218.        changing the offset value only.
  219.             
  220.             downln accepts  the address of  a frame in  ES:BX and return
  221.        the address of the next line with  the same number of  words from
  222.        the beginning  of the line.  This is used to speed up drawings in
  223.        vertical direction such as VertLine.
  224.        
  225.        
  226.        3.2  plottype
  227.        
  228.             The module plottype contain routines  that  access the frame
  229.        memory using the address returned  by $calc and  downln. There is
  230.        nothing fancy so the comment in the module should be sufficient.
  231.  
  232.  
  233.  
  234.  
  235.  
  236.  
  237.  
  238.  
  239.  
  240.  
  241.  
  242.  
  243.  
  244.  
  245.  
  246.  
  247.  
  248.  
  249.  
  250.  
  251.  
  252.  
  253.  
  254.  
  255.  
  256.  
  257.  
  258.  
  259.  
  260.  
  261.                                                                         3
  262.  
  263.  
  264.  
  265.  
  266.  
  267.                        GRAD Programmers' Reference Manual
  268.  
  269.        4   Frame Table
  270.        
  271.             In  the frame table,  it  contains  all information  about a
  272.        frame.  Information include starting address of  the frame, frame
  273.        width in byte,  horizontal and vertical size,  logical origin and
  274.        the window defined in  that frame.
  275.             
  276.             The  number of entries in  frame table controls  the maximum
  277.        number of frame that can be existed in GRAD system. The number of
  278.        entry in the  frame table is  control by the  value NFRAME during
  279.        compilation time. The default value of NFRAME is 10.
  280.             
  281.             The structure of  the frame table may be  changed  in future
  282.        version.  So do not make any assumption about  the relative order
  283.        of the variables inside the structure in your routines.
  284.  
  285.  
  286.  
  287.  
  288.  
  289.  
  290.  
  291.  
  292.  
  293.  
  294.  
  295.  
  296.  
  297.  
  298.  
  299.  
  300.  
  301.  
  302.  
  303.  
  304.  
  305.  
  306.  
  307.  
  308.  
  309.  
  310.  
  311.  
  312.  
  313.  
  314.  
  315.  
  316.  
  317.  
  318.  
  319.  
  320.  
  321.  
  322.  
  323.  
  324.  
  325.  
  326.  
  327.  
  328.                                                                         4
  329.  
  330.  
  331.  
  332.  
  333.  
  334.                        GRAD Programmers' Reference Manual
  335.  
  336.        5   Font Table
  337.        
  338.             Font  table contains  information  about  each  font loaded.
  339.        Information  include the font  type (fix size  or variable size),
  340.        lowest code and highest  code number,  the default character code
  341.        and  also  pointers  to  the  pattern  and  individual  character
  342.        information.
  343.             
  344.             Individual  character  information  include  width,  height,
  345.        inkwidth,  cellheight,  leftmargin and topline. This is one entry
  346.        for fix size font and one entry per character  for  variable size
  347.        font.
  348.             
  349.             There  is also an  additional array of pointers  pointing to
  350.        pattern of individual characters for variable size font. The font
  351.        table contains the pointer to the array of pointers.
  352.  
  353.  
  354.  
  355.  
  356.  
  357.  
  358.  
  359.  
  360.  
  361.  
  362.  
  363.  
  364.  
  365.  
  366.  
  367.  
  368.  
  369.  
  370.  
  371.  
  372.  
  373.  
  374.  
  375.  
  376.  
  377.  
  378.  
  379.  
  380.  
  381.  
  382.  
  383.  
  384.  
  385.  
  386.  
  387.  
  388.  
  389.  
  390.  
  391.  
  392.  
  393.  
  394.  
  395.                                                                         5
  396.  
  397.  
  398.  
  399.  
  400.  
  401.                        GRAD Programmers' Reference Manual
  402.  
  403.        6   HorzLine, VertLine and Line
  404.        
  405.        6.1  HorzLine
  406.        
  407.             The C code  can be  used  to  replace  the  assembly routine
  408.        horzl. It uses the same algorithm as horzl.
  409.        
  410.            horzl(x,y,length)
  411.            int x,y,length;
  412.            {
  413.              int far *addr;
  414.              unsigned int pword;
  415.              int len,loop;
  416.            
  417.              addr=calcaddr(x,y);
  418.              len = (x & 0x0f) + length;
  419.              if (len <= 16) {
  420.                pword=LEFTWORD[x & 0x0f] ^ LEFTWORD[len];
  421.                fr_write(addr,pword);
  422.                return;
  423.                }
  424.              fr_write(addr,LEFTWORD[x & 0x0f]);
  425.              addr++;
  426.              for (loop=len >> 4; loop > 1; loop--,addr++)
  427.                fr_write(addr,0xffff);
  428.              fr_write(addr,RIGHTWORD[len & 0x0f]);
  429.            }
  430.        
  431.             The program should not be difficult to understand.
  432.        
  433.        
  434.        6.2  VertLine
  435.        
  436.             The C routine below is  functional equivalent to  vert1l. It
  437.        only draws a line 1 pixel wide.
  438.        
  439.            vertline(x,y,length)
  440.            int x,y,length;
  441.            {
  442.              int far *addr, far *downline();
  443.              unsigned int pword;
  444.              int loop;
  445.            
  446.              addr=calcaddr(x,y);
  447.              LASTY=y;
  448.              pword=DOTVALUE[x & 0x0f];
  449.              while (length-- > 0) {
  450.                fr_write(addr,pword);
  451.                addr=downline(addr);
  452.                }
  453.            }
  454.            
  455.             To draw a vertical line of 1 pixel wide is quite simple. But
  456.        when the width can be  any number  then  the routine  become much
  457.        more complicated.  The  routine  vertl  combines  both  horzl and
  458.        vert1l together.  The  downline  routine is not  included in GRAD
  459.        library so the code is listed below.
  460.            
  461.  
  462.                                                                         6
  463.  
  464.  
  465.  
  466.  
  467.  
  468.                        GRAD Programmers' Reference Manual
  469.  
  470.            _downline proc  near
  471.                    push    bp
  472.                    mov     bp,sp
  473.                    push    si
  474.                    les     bx,[bp+smo]
  475.                    call    downln
  476.                    mov     dx,es           ; result return in DX:AX
  477.                    mov     ax,bx
  478.                    pop     si
  479.                    pop     bp
  480.                    ret
  481.            _downline endp
  482.             
  483.        
  484.        
  485.        6.3  Line
  486.        
  487.             The algorithm used in drawing line is explained in  the book
  488.        "Fundamental of Interactive  Computer Graphics"  by Foley and Van
  489.        Dam p.433-436.  The C routine below can draw a line but there are
  490.        a lot of difference between this routine and the routine  in GRAD
  491.        library. So the one below is for reference only.
  492.             
  493.            line(x1,y1,x2,y2)
  494.            int x1,y1,x2,y2;
  495.            {
  496.              int dx,dy,d,x,y,xend,yend,len,incr1,incr2,xdir,ydir,dir;
  497.            
  498.              xdir=ydir=0;
  499.              if ((dx=x2-x1) < 0) { dx = -dx; xdir=(-1); }
  500.              if ((dy=y2-y1) < 0) { dy = -dy; ydir=(-1); }
  501.              if (dx == 0) {
  502.                if (xdir)
  503.                  vertline(x1,y2,++dy);
  504.                else
  505.                  vertline(x1,y1,++dy);
  506.                }
  507.              if (dy == 0) {
  508.                if (ydir)
  509.                  horzline(x1,y2,++dx);
  510.                else
  511.                  horzline(x1,y1,++dx);
  512.                }
  513.              if ((xdir==(-1)) && (ydir==(-1)))
  514.                dir=1;
  515.              else if (xdir || ydir)
  516.                dir=xdir+ydir;
  517.              else
  518.                dir=1;
  519.              if (dy <= dx) {
  520.                d = (dy << 1) - dx;
  521.                incr1 = dy << 1;
  522.                incr2 = (dy - dx) << 1;
  523.                if (xdir) {
  524.                  x=x2; y=y2; xend=x1;
  525.                  }
  526.                else {
  527.                  x=x1; y=y1; xend=x2;
  528.  
  529.                                                                         7
  530.  
  531.  
  532.  
  533.  
  534.  
  535.                        GRAD Programmers' Reference Manual
  536.  
  537.                  }
  538.                len=1;
  539.                while (x++<xend) {
  540.                  if (d<0) {
  541.                    d+=incr1;
  542.                    len++;
  543.                    }
  544.                  else {
  545.                    horzline(x-len,y,len);
  546.                    len=1;
  547.                    d+=incr2;
  548.                    y+=dir;
  549.                    }
  550.                  }
  551.                horzline(x-len,y,len);
  552.                }
  553.              else {
  554.                d = (dx << 1) - dy;
  555.                incr1 = dx << 1;
  556.                incr2 = (dx - dy) << 1;
  557.                if (ydir) {
  558.                  x=x2; y=y2; yend=y1;
  559.                  }
  560.                else {
  561.                  x=x1; y=y1; yend=y2;
  562.                  }
  563.                len=1;
  564.                while (y++<yend) {
  565.                  if (d<0) {
  566.                    d+=incr1;
  567.                    len++;
  568.                    }
  569.                  else {
  570.                    vertline(x,y-len,len);
  571.                    len=1;
  572.                    d+=incr2;
  573.                    x+=dir;
  574.                    }
  575.                  }
  576.                vertline(x,y-len,len);
  577.                }
  578.            }
  579.             
  580.  
  581.  
  582.  
  583.  
  584.  
  585.  
  586.  
  587.  
  588.  
  589.  
  590.  
  591.  
  592.  
  593.  
  594.  
  595.  
  596.                                                                         8
  597.  
  598.  
  599.  
  600.  
  601.  
  602.                        GRAD Programmers' Reference Manual
  603.  
  604.        7   Circle, Ellipse and Arc
  605.        
  606.        7.1  Circle
  607.        
  608.             Because a circle is symmetrical so we only need to calculate
  609.        the  value  for  one-eight  of  a  circle  and  by  making simple
  610.        transformation of  the value  calculated,  we  may  draw  a whole
  611.        circle.  The program for drawing circle  is  very  simple but the
  612.        deriving process is not simple. You may find the algorithm in the
  613.        book "Fundamentals of Interactive Computer Graphics"  by Foley on
  614.        page 442-446.
  615.            
  616.            circle_pt(ctrx,ctry,x,y)
  617.            int ctrx,ctry,x,y;
  618.            {
  619.              dot(x+ctrx,y+ctry);
  620.              dot(y+ctrx,x+ctry);
  621.              dot(y+ctrx,-x+ctry);
  622.              dot(x+ctrx,-y+ctry);
  623.              dot(-x+ctrx,-y+ctry);
  624.              dot(-y+ctrx,-x+ctry);
  625.              dot(-y+ctrx,x+ctry);
  626.              dot(-x+ctrx,y+ctry);
  627.            }
  628.            
  629.            circle(centerx,centery,radius)
  630.            int centerx,centery,radius;
  631.            { 
  632.              register int x, d;
  633.              int y, incr1, incr2;
  634.            
  635.              x=0;
  636.              y=radius;
  637.              incr1=6;
  638.              incr2=10-(radius<<2);
  639.              d=3-(radius<<1);
  640.              while (x < y) {
  641.                circle_pt(centerx,centery,x++,y);
  642.                if (d<0) {
  643.                    d+=incr1;
  644.                    incr2+=4;
  645.                } else {
  646.                    d+=incr2;
  647.                    incr2+=8;
  648.                    y--;
  649.                }
  650.                incr1+=4;
  651.              }
  652.              if (x==y) circle_pt(centerx,centery,x,y);
  653.            }
  654.            
  655.             The program below is  equivalent to the circle  above except
  656.        it is shorter but slower.
  657.            
  658.            circle(centerx,centery,radius)
  659.            int centerx,centery,radius;
  660.            { 
  661.              int x,y,d;
  662.  
  663.                                                                         9
  664.  
  665.  
  666.  
  667.  
  668.  
  669.                        GRAD Programmers' Reference Manual
  670.  
  671.            
  672.              x=0;
  673.              y=radius;
  674.              d=3-(radius<<1);
  675.              while     (x < y) {
  676.                circle_pt(centerx,centery,x++,y);
  677.                d += (d < 0) ? (x << 2) + 6     : ((x - y--) << 2) + 10;
  678.                }
  679.              if (x==y) circle_pt(centerx,centery,x,y);
  680.            }
  681.        
  682.        
  683.        7.2  Ellipse
  684.        
  685.             The algorithm for ellipse is the much more  complicated than
  686.        circle. The equation is derived by myself using method similar to
  687.        that of the circle. The program below is a simplified version.
  688.             
  689.            ellipse_pt(ctrx,ctry,x,y)
  690.            int ctrx,ctry,x,y;
  691.            {
  692.              dot(x+ctrx,y+ctry);
  693.              dot(x+ctrx,-y+ctry);
  694.              dot(-x+ctrx,-y+ctry);
  695.              dot(-x+ctrx,y+ctry);
  696.            }
  697.            
  698.            ellipse(ctrx,ctry,a,b)
  699.            int ctrx,ctry,a,b;
  700.            {
  701.              long incr1,incr2,a2,b2,d,step1,step2,ptx,pty;
  702.              int x,y;
  703.            
  704.              x=0;
  705.              y=b;
  706.              a2= (long) a * a;
  707.              b2= (long) b * b;
  708.              step1 = a2 << 2;
  709.              step2 = b2 << 2;
  710.              d= ((b2 - (a2 * b)) << 1) + a2;
  711.              incr1= step2 + (b2 << 1);
  712.              incr2= step1 + step2 + (b2 << 1) - ((a2 * b) << 2);
  713.              ptx=0;
  714.              pty=a2 * y;
  715.              while (ptx < pty) {
  716.                ellipse_pt(ctrx,ctry,x++,y);
  717.                if (d<0)
  718.                  d+=incr1;
  719.                else {
  720.                  d+=incr2;
  721.                  incr2+=step1;
  722.                  y--;
  723.                  pty-=a2;
  724.                  }
  725.                ptx+=b2;
  726.                incr1+=step2;
  727.                incr2+=step2;
  728.                }
  729.  
  730.                                                                        10
  731.  
  732.  
  733.  
  734.  
  735.  
  736.                        GRAD Programmers' Reference Manual
  737.  
  738.              if (ptx == pty) ellipse_pt(ctrx,ctry,x,y);
  739.              y=0;
  740.              x=a;
  741.              d= ((a2 - (b2 * a)) << 1) + b2;
  742.              incr1= step1 + (a2 << 1);
  743.              incr2= step2 + step1 + (a2 << 1) - ((b2 * a) << 2);
  744.              pty=0;
  745.              ptx=b2 * x;
  746.              while (pty < ptx) {
  747.                ellipse_pt(ctrx,ctry,x,y++);
  748.                if (d<0)
  749.                  d+=incr1;
  750.                else {
  751.                  d+=incr2;
  752.                  incr2+=step2;
  753.                  x--;
  754.                  ptx-=b2;
  755.                  }
  756.                pty+=a2;
  757.                incr1+=step1;
  758.                incr2+=step1;
  759.                }
  760.              if (ptx==pty) ellipse_pt(ctrx,ctry,x,y);
  761.            }
  762.        
  763.        
  764.        7.3  Arc
  765.        
  766.             Program for Arc1  and Earc1 can be obtained by making simple
  767.        modification of the program  circle and ellipse  in the preceding
  768.        sections.  Arc2  and Earc2 are much more complicated. I use table
  769.        instead of using the sine and tangent function in  order to avoid
  770.        using  floating  arithmetic.  Moreover the  situation  is further
  771.        complicated by the fact that I do  not know  the exact coordinate
  772.        of the starting  and ending  point.  There are a  lot  of special
  773.        cases in the processing.  The consequence is that I use  a lot of
  774.        time to debug  the routines.  Therefore do not try to  modify the
  775.        Arc2 and Earc2 routines unless you know what you are doing.
  776.  
  777.  
  778.  
  779.  
  780.  
  781.  
  782.  
  783.  
  784.  
  785.  
  786.  
  787.  
  788.  
  789.  
  790.  
  791.  
  792.  
  793.  
  794.  
  795.  
  796.  
  797.                                                                        11
  798.  
  799.  
  800.  
  801.  
  802.  
  803.                        GRAD Programmers' Reference Manual
  804.  
  805.        8   Text Writing
  806.        
  807.             WriteStr  is  quite simple  so I will concentrate  on writec
  808.        here.
  809.             
  810.             In GRAD system,  there are two types of font  can be loaded.
  811.        They are fix size  character and  variable  size  characters. The
  812.        font table and the program  are  structure  in  such  a  way that
  813.        differences in processing are kept to a minimum. This is achieved
  814.        by using pointers to pointer to the desire information instead of
  815.        direct referencing.
  816.             
  817.             I am  not going to  describe  the  clipping  and  copying of
  818.        patterns to  the frame because  I  have  already  written  a more
  819.        efficient routine to do both of them at the same time. It will be
  820.        included in the next release in the near future.
  821.  
  822.  
  823.  
  824.  
  825.  
  826.  
  827.  
  828.  
  829.  
  830.  
  831.  
  832.  
  833.  
  834.  
  835.  
  836.  
  837.  
  838.  
  839.  
  840.  
  841.  
  842.  
  843.  
  844.  
  845.  
  846.  
  847.  
  848.  
  849.  
  850.  
  851.  
  852.  
  853.  
  854.  
  855.  
  856.  
  857.  
  858.  
  859.  
  860.  
  861.  
  862.  
  863.  
  864.                                                                        12
  865.  
  866.  
  867.  
  868.  
  869.  
  870.                        GRAD Programmers' Reference Manual
  871.  
  872.        9   Region Filling
  873.        
  874.             The routine below will  extend  from the given  point to the
  875.        left until it  encounters  a pixel  which  value  is  opposite to
  876.        blankv or left edge  of the frame  is reached.  The line is drawn
  877.        using  the style given in  pattern.  blankv  can either  be  0 or
  878.        0xffff but not any other value.
  879.            
  880.            xleft(x,y,blankv,pattern)
  881.            int x,y,blankv,pattern;
  882.            {
  883.              int *xyloc;
  884.              int loop;
  885.              unsigned int word, word2, temp, tempdot;
  886.            
  887.              unsigned int fr_read();
  888.            
  889.              xyloc=calcaddr(x,y);
  890.              word2=(word=fr_read(xyloc)) ^ blankv;
  891.              if (word2 & DOTVALUE[x & 0x0f]) return;
  892.            
  893.              word2=word2 & RIGHTWORD[(x & 0x0f) + 1];
  894.              if (word2) {
  895.                tempdot=exchange(DOTVALUE[x & 0x0f]);
  896.                word2=exchange(word2);
  897.                for (loop=(x & 0x0f)+1; !(word2 & tempdot);
  898.                    loop--, word2>>=1) ;
  899.                temp=LEFTWORD[loop] & RIGHTWORD[(x & 0x0f) + 1];
  900.                word2=(pattern & temp) & (word & (~temp));
  901.                fr_write(xyloc,word2);
  902.                return;
  903.              }
  904.              word2=(pattern & RIGHTWORD[(x & 0x0f)+1]) |
  905.                            (word & LEFTWORD[(x & 0x0f)+1]);
  906.              fr_write(xyloc,word2);
  907.              xyloc--; x-=16;
  908.              while(!((word=fr_read(xyloc))^blankv) && (x >= 0)) {
  909.                fr_write(xyloc,pattern);
  910.                x-=16;
  911.                xyloc--;
  912.              }
  913.              if (x>=0) {
  914.                word2=exchange(word ^ blankv);
  915.                for(loop=16; !(word2 & 0x01); loop--, word2>>=1) ;
  916.                word2=(pattern & LEFTWORD[loop]) |
  917.                              (word & RIGHTWORD[loop]);
  918.                fr_write(xyloc,word2);
  919.              }
  920.            }
  921.        
  922.             The XHLine in GRAD system will extend in both  direction and
  923.        the coordinates of  the end points  are returned.  XHLine  is the
  924.        basis for region filling. The algorithm for SolidFill is:
  925.             
  926.            1. execute XHLine using the starting coordinate.
  927.            2. if nothing can be drawn, return
  928.            3. otherwise put the left most coordinate and length on the
  929.               queue
  930.  
  931.                                                                        13
  932.  
  933.  
  934.  
  935.  
  936.  
  937.                        GRAD Programmers' Reference Manual
  938.  
  939.            4. fetch the first item on queue. the coordinates fetched is
  940.               the current location and the line starting from current
  941.               location is called the current line
  942.            5. go up 1 line (decrement y coordinate) and search in the
  943.               left direction
  944.            6. if a pixel in background state is found, XHLine is
  945.               executed and the left most coordinate and the length is
  946.               put on queue
  947.            7. the search continue until it is above the right most point
  948.               of current line.
  949.            8. go down 1 line from current location (increment y
  950.               coordinate by 1) and search to the left.
  951.            9. if a pixel in background state is found, XHLine is
  952.               executed and the left most coordinate and the length is
  953.               put on queue
  954.            10. the search continue until it is below the right most
  955.               point of current line.
  956.            11. if there is any item on queue, repeat process 4 to 11
  957.            
  958.             
  959.             Note that I use queue instead of  stack so  that  the region
  960.        filling routine gives a illusion of  filling in  all direction at
  961.        the  same time.  The memory for  the queue is  allocated from the
  962.        stack so it won't 'waste'  any memory when filling  functions are
  963.        not executed.
  964.  
  965.  
  966.  
  967.  
  968.  
  969.  
  970.  
  971.  
  972.  
  973.  
  974.  
  975.  
  976.  
  977.  
  978.  
  979.  
  980.  
  981.  
  982.  
  983.  
  984.  
  985.  
  986.  
  987.  
  988.  
  989.  
  990.  
  991.  
  992.  
  993.  
  994.  
  995.  
  996.  
  997.  
  998.                                                                        14
  999.  
  1000.  
  1001.  
  1002.  
  1003.  
  1004.                        GRAD Programmers' Reference Manual
  1005.  
  1006.        10  Block Copy, Save and Load
  1007.        
  1008.             Block file  structure is  already  explained  in  the Users'
  1009.        manual so  it  would not  be  repeated  here.  A  new  version of
  1010.        BlockCopy, BlockSave and BlockLoad is written such that block can
  1011.        be copied or loaded  to any  location.  They would be included in
  1012.        the next release in the near future.
  1013.  
  1014.  
  1015.  
  1016.  
  1017.  
  1018.  
  1019.  
  1020.  
  1021.  
  1022.  
  1023.  
  1024.  
  1025.  
  1026.  
  1027.  
  1028.  
  1029.  
  1030.  
  1031.  
  1032.  
  1033.  
  1034.  
  1035.  
  1036.  
  1037.  
  1038.  
  1039.  
  1040.  
  1041.  
  1042.  
  1043.  
  1044.  
  1045.  
  1046.  
  1047.  
  1048.  
  1049.  
  1050.  
  1051.  
  1052.  
  1053.  
  1054.  
  1055.  
  1056.  
  1057.  
  1058.  
  1059.  
  1060.  
  1061.  
  1062.  
  1063.  
  1064.  
  1065.                                                                        15
  1066.  
  1067.  
  1068.  
  1069.  
  1070.  
  1071.                        GRAD Programmers' Reference Manual
  1072.  
  1073.        11  Writing Graphics Display Adapter Driver
  1074.        
  1075.             One basic requirement for a graphics adapter  in GRAD system
  1076.        is that the memory for each line must be in consecutive locations
  1077.        and the most significant bit of each byte is the left  most pixel
  1078.        of that  byte  when displayed.  The byte with lower  address in a
  1079.        line is  displayed on the  left.  Furthermore, the number of byte
  1080.        for each line must be even and the memory  in the  same line must
  1081.        be in  the same  bank if the graphics  display memory  is divided
  1082.        into banks.
  1083.             
  1084.             I shall discuss the writing of graphics adapter according to
  1085.        different cases.
  1086.             
  1087.        Case I:   All  graphics  display memory  can be  accessed without
  1088.                  changing any page  register  or  toggling  any software
  1089.                  switch.
  1090.             
  1091.             The modification  required  is quite  simple. Firstly change
  1092.        the  location  defined for _SCREEN in  calcaddr.asm.  Then change
  1093.        $calc  and downln  for  your  graphics  display  card.  Since the
  1094.        address  return  by  $calc is a  far address so  the offset value
  1095.        should be small enough such  that every  byte in the line  can be
  1096.        accessed without changing the segment value.
  1097.        
  1098.        Case II:  Graphics memory  is  divided into banks  but memory for
  1099.                  each line is in the same bank.
  1100.             
  1101.             Same as Case I and then change $or,  $and and $xor such that
  1102.        they  can change  to  appropriate bank  using information  in the
  1103.        segment value. phyaddr routine has to be written too. JLASER is a
  1104.        example for this case.
  1105.             
  1106.             
  1107.             
  1108.             Then you may need to  rewrite some  supporting routines such
  1109.        as settext and setgraph.
  1110.        
  1111.  
  1112.  
  1113.  
  1114.  
  1115.  
  1116.  
  1117.  
  1118.  
  1119.  
  1120.  
  1121.  
  1122.  
  1123.  
  1124.  
  1125.  
  1126.  
  1127.  
  1128.  
  1129.  
  1130.  
  1131.  
  1132.                                                                        16
  1133.  
  1134.  
  1135.  
  1136.  
  1137.  
  1138.                        GRAD Programmers' Reference Manual
  1139.  
  1140.        12  Writing Printer Driver
  1141.        
  1142.             Information given in the users'  manual should be sufficient
  1143.        for  writing printer drivers  for  all  printer  providing  8 bit
  1144.        graphics mode.  In the section below, I shall describe the way to
  1145.        write drivers for 7 bit and 24 bit graphics mode printer.
  1146.             
  1147.             Firstly,   you  should  define  the  control   sequences  in
  1148.        prtcntl.c as described in the users' manual.
  1149.             
  1150.             For 7 bit graphics mode, change ndot in pframe.c from 8 to 7
  1151.        and then change prt in prtgc.asm so that the data can be send out
  1152.        properly.
  1153.             
  1154.             If you use a  24-pin  printer,  you  need  to  do  some more
  1155.        things. Firstly, change ndot to 24. You need to change the prt in
  1156.        prtgc such that 3  bytes in a row are generated. Inside prt,  you
  1157.        may use any registers except si and di unless you save them first
  1158.        and then restore them  before return.  Furthermore, if the length
  1159.        of data  graphics  are required  to  be  included  in the control
  1160.        sequence,  you may have  to  modify prtpc and  optprt in pframe.c
  1161.        and rmv0  in  prt.asm.  It is because the length  in  the control
  1162.        sequence should be the number of columns of graphics data instead
  1163.        of  the number  of  bytes.  You cannot divide the number  of data
  1164.        byte by  a factor  using the standard  features.  Furthermore the
  1165.        rmv0 only look for the last non-zero byte in the output data. You
  1166.        need to change either  rmv0  or optprt to ensure the length  is a
  1167.        multiple of 3.
  1168.             
  1169.             After making the changes, recompile all modified files.
  1170.  
  1171.  
  1172.  
  1173.  
  1174.  
  1175.  
  1176.  
  1177.  
  1178.  
  1179.  
  1180.  
  1181.  
  1182.  
  1183.  
  1184.  
  1185.  
  1186.  
  1187.  
  1188.  
  1189.  
  1190.  
  1191.  
  1192.  
  1193.  
  1194.  
  1195.  
  1196.  
  1197.  
  1198.  
  1199.                                                                        17
  1200.  
  1201.  
  1202.  
  1203.  
  1204.  
  1205.                        GRAD Programmers' Reference Manual
  1206.  
  1207.        13  Hints on Porting to Other C Compiler or Other Machine
  1208.        
  1209.             To port GRAD  to other C  compiler or other system,  I think
  1210.        the most difficult part is the use far and huge  pointers and the
  1211.        large number of assembly routines.
  1212.             
  1213.             If the C compiler does not have  the far or  huge pointer or
  1214.        the architecture  of  the object  machine does  not need  to have
  1215.        different kinds of pointer,  the first thing you need to do is do
  1216.        eliminate  all those far and huge key words and the none standard
  1217.        function calls halloc and hfree.
  1218.             
  1219.             After that  rewrite calcaddr.asm  and plottype.asm  and then
  1220.        use the C routines supplied  in the documentation  to implement a
  1221.        simple system first.
  1222.             
  1223.             Rewriting  the assemble  routines will be  difficult but not
  1224.        impossible.  But in the initial implementation,  you should avoid
  1225.        the following functions:  Arc2, Earc2 and related portion in circ
  1226.        and Ell, SolidFill, PatternFill and XHLine, Line (use the version
  1227.        given in this manual instead), writec and WriteStr.
  1228.             
  1229.             Good Luck !
  1230.  
  1231.  
  1232.  
  1233.  
  1234.  
  1235.  
  1236.  
  1237.  
  1238.  
  1239.  
  1240.  
  1241.  
  1242.  
  1243.  
  1244.  
  1245.  
  1246.  
  1247.  
  1248.  
  1249.  
  1250.  
  1251.  
  1252.  
  1253.  
  1254.  
  1255.  
  1256.  
  1257.  
  1258.  
  1259.  
  1260.  
  1261.  
  1262.  
  1263.  
  1264.  
  1265.  
  1266.                                                                        18
  1267.  
  1268.  
  1269.  
  1270.  
  1271.