Eutocode graphics.

William Overington

Copyright 2002 and 2003 William Overington

Wednesday 15 January 2003

In December 2002 I started a new thread in the discussion forum at http://forum.mhp.org entitled "eutocode graphics". As it happened, no one else posted to that thread.

I thought that it might be interesting to add a transcript of those postings into this sequence of documents.

The postings are the text that appeared, except that I have made the web addresses referenced into active links and that the layout of Java source code listings in this web page has been altered so as to assist readability and transcription into a text file for use if so desired.

Each transcript consists of the date and time recorded with the posting, followed by the posting itself.


Supplementary note of Tuesday 21 January 2003

One transcript has now been edited to replace a typographical error in the original posting, namely that in the phrase "with each level above level 1 incorporating all of the levels which are below it" there was no space between the figure 1 and the word incorporating in the original posting.

End of supplementary note of Tuesday 21 January 2003



2002/12/13 10:36


I have been thinking about the possibility of running a DVB-MHP channel for distance education and have come to the conclusion that the tightest constraint is on the number of bytes which can be used for files in the object carousel.

Thus, for example, in producing a multimedia presentation, there is an abundance of computational power available in the DVB-MHP terminal for decoding a sequence of commands to produce a graphics display and in a content author's environment there is an abundance of computational power for encoding a graphics display into a compact format, so using extra computation at the content authorship stage and extra computation at the display stage is fine if that means that the number of bytes needed to include the application in the object carousel is reduced. If a number of applications are implemented using just one generic Java class file together with a number of independent text files, one for each application, then the reduction in the number of bytes in each of the text files produced by using a compact encoding format could result in allowing more applications to be placed in an object carousel of a particular size, or maybe even in producing a distance education channel small enough in byte size requirement that it gains the opportunity to become broadcast at all.

Although the DVB-MHP specification provides for bitmap graphics files, it does not appear to provide for a vector graphics file format. Vector graphics can, in appropriate situations, be used to provide large graphics using relatively small numbers of bytes. Thus I feel that a vector graphics format for the DVB-MHP platform would be a good idea. However, there is no need to alter the DVB-MHP specification to do this as such a vector graphics system can be produced using Java programming. I have therefore decided to try to produce and support a vector graphics system for use on the DVB-MHP platform. Whether this vector graphics system will be just a theoretical exercise, or used in just a distance education channel, or becomes a system so widely used that it is almost a broadcasting standard depends upon how this vector graphics system is received by content authors.

I have used Unicode Private Use Area characters for the encoding of the vector graphics system. This is so that the codes may be included in text files, either as stand alone graphics files or mixed in with ordinary text characters. I have not yet worked out the details of doing that yet in relation to anchor points to which graphics data positions would be relative and so on.

For the moment I am experimenting with entering a sequence of graphics codes into an offline web applet using Internet Explorer on a PC. The method of experimentation is to prepare a sequence of Unicode Private Use Area characters in another application and then to copy and paste those characters into the text box of the applet and then click on the draw button of the applet.

Results can be achieved using WordPad to produce the character sequence though that is awkward in the absence of a font to display the various Private Use Area characters distinctly from one another in WordPad. A very easy way to produce the character sequence is to use the SC UniPad program which is available from the http://www.unipad.org website. When using SC UniPad one simply needs to use CTRL Q and to then insert the hexadecimal characters followed by pressing the Enter key on the keyboard. It is best to set up the SC UniPad window using the following sequence from the menu bar and cascading menus.

Options | Character Rendering | Private Use Characters then select Hexadecimal

This has the effect that each Private Use Area code entered then shows in a glyph which displays its character code point value.

I am hoping to add some more graphics codes gradually, including some which combine the effects of two or three of the basic codes, so as to minimize the number of characters needed for graphics. I am hoping to be able to add polygons and filled polygons.

I do not, as yet, have the facilities to try out broadcasts on a DVB-MHP channel and indeed I do not have the knowledge to produce a DVB-MHP application, yet if any content authors who do have such an opportunity would like to try these graphics codes out on the DVB-MHP platform, please feel free to do so.

Here is the source code for a Java applet. It needs to be placed in a file named eutocodegraphics.java and then compiled using a Java compiler.

import java.awt.*;
import java.awt.event.*;
 
public class eutocodegraphics extends java.applet.Applet implements
                                                     ActionListener
 
// Software written by William Overington
// WOverington@ngo.globalnet.co.uk
// 12 December 2002
// Copyright 2002 William Overington
//
// This software is an applet which is for demonstrating the use of
// eutocode graphics
 
  {
    int obeycode=1;
 
    Button go1Button = new Button("draw");
    Button go2Button = new Button("clear");
 
    TextField text1TextField = new TextField(80);
 
    String text1="";
 
    char eutocode='?';
 
// Start of the declarations for the eutocode engine
//
    int eutocode_engine_A=0;
//
    int eutocode_engine_X1L=0;
    int eutocode_engine_Y1L=0;
    int eutocode_engine_X2L=0;
    int eutocode_engine_Y2L=0;
//
    int eutocode_engine_X1H=0;
    int eutocode_engine_Y1H=0;
    int eutocode_engine_X2H=0;
    int eutocode_engine_Y2H=0;
//
    int eutocode_engine_X1=0;
    int eutocode_engine_Y1=0;
    int eutocode_engine_X2=0;
    int eutocode_engine_Y2=0;
//
    int eutocode_engine_COLOUR=0;
//
// End of the declarations for the eutocode engine
 
// Start of the declarations for the additional colours
    Color brown = new Color(255,102,  0);
    Color lavender = new Color(204,153,204);
    Color mint = new Color(204,255,204);
// End of the declarations for the additional colours
 
    public void init()
      {
        setLayout(null);
        setBounds(0,0,720,576);
        go1Button.addActionListener(this);
        go1Button.setLocation(530,200);
        go1Button.setSize(110,30);
        add(go1Button);
        go2Button.addActionListener(this);
        go2Button.setLocation(530,250);
        go2Button.setSize(110,30);
        add(go2Button);
        text1TextField.setLocation(530,150);
        text1TextField.setSize(110,20);
        add(text1TextField);
 
        setBackground(Color.white);
        Font typeface = new Font("Arial", Font.PLAIN, 12);
        setFont(typeface);
 
        text1TextField.setText(" ");
 
        obeycode=1;
      }
 
    public void actionPerformed(ActionEvent event)
      {
        Object source = event.getSource();
 
        if (source == go1Button)
          {
            obeycode=51;
            repaint();
          }
 
        if (source == go2Button)
          {
            obeycode=52;
            repaint();
          }
      }
 
     public void paint(Graphics screen)
      {                                                             
 
        screen.setColor(Color.black); 
       
        if(obeycode == 51)
          {
            text1=text1TextField.getText();
            int length=text1.length();
            if(length > 0)
              {
                for(int i=0;i < length;i++)
                  {
                    char c;
                    c=text1.charAt(i);
                    eutocode=c;
                    process(screen,eutocode);
                  }
              }
 
            text1TextField.setText("*");
          }
        else if(obeycode == 52)
          {
            screen.setColor(Color.white);
            screen.fillRect(0,0,720,576);
          }
      
      }
 
    public void update(Graphics screen)
      {
        paint(screen);
      }
 
    private void process(Graphics screen, char eutocode)
      {
        char c;
        c=eutocode;
//
        if((c >= '\uEC00') & (c <= '\uEFFF'))
          {
            int n;
            n=((int) c) - ((int) '\uEC00');
            eutocode_engine_A=n;
          }
        else if(c == '\uEB00')
          {
            eutocode_engine_X1L=eutocode_engine_A;
            eutocode_engine_X1=1024*eutocode_engine_X1H + eutocode_engine_X1L;
          }
        else if(c == '\uEB01')
          {
            eutocode_engine_Y1L=eutocode_engine_A;
            eutocode_engine_Y1=1024*eutocode_engine_Y1H + eutocode_engine_Y1L;
          }
        else if(c == '\uEB02')
          {
            eutocode_engine_X2L=eutocode_engine_A;
            eutocode_engine_X2=1024*eutocode_engine_X2H + eutocode_engine_X2L;
          }
        else if(c == '\uEB03')
          {
            eutocode_engine_Y2L=eutocode_engine_A;
            eutocode_engine_Y2=1024*eutocode_engine_Y2H + eutocode_engine_Y2L;
          }
        else if(c == '\uEB20')
          {
            eutocode_engine_COLOUR=eutocode_engine_A;
            screen.setColor(Color.yellow);
            switch(eutocode_engine_COLOUR)
              {
                case  0:  screen.setColor(Color.black);      break;
                case  1:  screen.setColor(brown);            break;
                case  2:  screen.setColor(Color.red);        break;
                case  3:  screen.setColor(Color.orange);     break;
                case  4:  screen.setColor(Color.yellow);     break;
                case  5:  screen.setColor(Color.green);      break;
                case  6:  screen.setColor(Color.blue);       break;
                case  7:  screen.setColor(Color.magenta);    break;
                case  8:  screen.setColor(Color.gray);       break;
                case  9:  screen.setColor(Color.white);      break;
                case 10:  screen.setColor(Color.cyan);       break;
                case 11:  screen.setColor(Color.pink);       break;
                case 12:  screen.setColor(Color.darkGray);   break;
                case 13:  screen.setColor(Color.lightGray);  break;
                case 14:  screen.setColor(lavender);         break;
                case 15:  screen.setColor(mint);             break;
                default:  screen.setColor(Color.black); 
              }
          }
        else if(c == '\uEB40')
          {
            screen.drawLine(eutocode_engine_X1,eutocode_engine_Y1,
                            eutocode_engine_X2,eutocode_engine_Y2);
          }
        else if(c == '\uEB41')
          {
            screen.drawRect(eutocode_engine_X1,eutocode_engine_Y1,
                            eutocode_engine_X2,eutocode_engine_Y2);
          }
        else if(c == '\uEB42')
          {
            screen.fillRect(eutocode_engine_X1,eutocode_engine_Y1,
                            eutocode_engine_X2,eutocode_engine_Y2);
          }
        else if(c == '\uEB43')
          {
            screen.drawOval(eutocode_engine_X1,eutocode_engine_Y1,
                            eutocode_engine_X2,eutocode_engine_Y2);
          }
        else if(c == '\uEB44')
          {
            screen.fillOval(eutocode_engine_X1,eutocode_engine_Y1,
                            eutocode_engine_X2,eutocode_engine_Y2);
          }
      }
 
  }

Here is the source code for an HTML file to run the above applet.

<html>
<head>
</head>
<body bgcolor="#000000">
<p align=center>
<applet code="eutocodegraphics.class" width=720 height=576>
</applet>
 
</body>

William Overington

13 December 2002


2002/12/13 10:41


In relation to the above post, a better laid out display of the source code of the applet can be obtained if one looks at the source code of the HTML page which normally displays in this forum.

William Overington

13 December 2002

Note of 15 January 2003: This particular posting refers to the situation in the forum. It is included here as a matter of record. The layout of Java source code listings in this web page has been altered so as to assist readability, as mentioned at the top of the page.


2002/12/14 11:36


I have been having some fun this morning adding facilities for polygons into my demonstration applet. As the additions are in various places within the program I am posting the whole of the source code rather than just the additions. I have tried a few tests and the results are very encouraging.

William Overington

14 December 2002

import java.awt.*;
import java.awt.event.*;
 
public class eutocodegraphics extends java.applet.Applet implements
                                                     ActionListener
 
// Software written by William Overington
// WOverington@ngo.globalnet.co.uk
// 12 December 2002
// Also the additions of 14 December 2002 for polygons
// Copyright 2002 William Overington
//
// This software is an applet which is for demonstrating the use of
// eutocode graphics
 
  {
    int obeycode=1;
 
    Button go1Button = new Button("draw");
    Button go2Button = new Button("clear");
 
    TextField text1TextField = new TextField(80);
 
    String text1="";
 
    char eutocode='?';
 
// Start of the declarations for the eutocode engine
//
    int eutocode_engine_A=0;
//
    int eutocode_engine_X1L=0;
    int eutocode_engine_Y1L=0;
    int eutocode_engine_X2L=0;
    int eutocode_engine_Y2L=0;
//
    int eutocode_engine_X1H=0;
    int eutocode_engine_Y1H=0;
    int eutocode_engine_X2H=0;
    int eutocode_engine_Y2H=0;
//
    int eutocode_engine_X1=0;
    int eutocode_engine_Y1=0;
    int eutocode_engine_X2=0;
    int eutocode_engine_Y2=0;
//
    int eutocode_engine_COLOUR=0;
//
// Start of the additions of 14 December 2002 for polygons
//
    int eutocode_engine_POLYGON_POINTER=0;
    int[] eutocode_engine_POLYGON_XL= new int[101];
    int[] eutocode_engine_POLYGON_YL= new int[101];
    int[] eutocode_engine_POLYGON_XH= new int[101];
    int[] eutocode_engine_POLYGON_YH= new int[101];
    int[] eutocode_engine_POLYGON_X= new int[101];
    int[] eutocode_engine_POLYGON_Y= new int[101];
    int eutocode_engine_POLYGON_SIDES=0;
//
// End of the additions of 14 December 2002 for polygons
//
// End of the declarations for the eutocode engine
 
// Start of the declarations for the additional colours
    Color brown = new Color(255,102,  0);
    Color lavender = new Color(204,153,204);
    Color mint = new Color(204,255,204);
// End of the declarations for the additional colours
 
    public void init()
      {
        setLayout(null);
        setBounds(0,0,720,576);
        go1Button.addActionListener(this);
        go1Button.setLocation(530,200);
        go1Button.setSize(110,30);
        add(go1Button);
        go2Button.addActionListener(this);
        go2Button.setLocation(530,250);
        go2Button.setSize(110,30);
        add(go2Button);
        text1TextField.setLocation(530,150);
        text1TextField.setSize(110,20);
        add(text1TextField);
 
        setBackground(Color.white);
        Font typeface = new Font("Arial", Font.PLAIN, 12);
        setFont(typeface);
 
        text1TextField.setText(" ");
 
        obeycode=1;
 
// Start of the additions of 14 December 2002 for polygons
    for(int i=0;i <= 100;i++)
      {
        eutocode_engine_POLYGON_XL[i]=0;
        eutocode_engine_POLYGON_YL[i]=0;
        eutocode_engine_POLYGON_XH[i]=0;
        eutocode_engine_POLYGON_YH[i]=0;
        eutocode_engine_POLYGON_X[i]=0;
        eutocode_engine_POLYGON_Y[i]=0;
      }
// End of the additions of 14 December 2002 for polygons
      }
 
    public void actionPerformed(ActionEvent event)
      {
        Object source = event.getSource();
 
        if (source == go1Button)
          {
            obeycode=51;
            repaint();
          }
 
        if (source == go2Button)
          {
            obeycode=52;
            repaint();
          }
      }
 
     public void paint(Graphics screen)
      {                                                             
 
        screen.setColor(Color.black); 
       
        if(obeycode == 51)
          {
            text1=text1TextField.getText();
            int length=text1.length();
            if(length > 0)
              {
                for(int i=0;i < length;i++)
                  {
                    char c;
                    c=text1.charAt(i);
                    eutocode=c;
                    process(screen,eutocode);
                  }
              }
 
            text1TextField.setText("*");
          }
        else if(obeycode == 52)
          {
            screen.setColor(Color.white);
            screen.fillRect(0,0,720,576);
          }
      
      }
 
    public void update(Graphics screen)
      {
        paint(screen);
      }
 
    private void process(Graphics screen, char eutocode)
      {
        char c;
        c=eutocode;
//
        if((c >= '\uEC00') & (c <= '\uEFFF'))
          {
            int n;
            n=((int) c) - ((int) '\uEC00');
            eutocode_engine_A=n;
          }
        else if(c == '\uEB00')
          {
            eutocode_engine_X1L=eutocode_engine_A;
            eutocode_engine_X1=1024*eutocode_engine_X1H + eutocode_engine_X1L;
          }
        else if(c == '\uEB01')
          {
            eutocode_engine_Y1L=eutocode_engine_A;
            eutocode_engine_Y1=1024*eutocode_engine_Y1H + eutocode_engine_Y1L;
          }
        else if(c == '\uEB02')
          {
            eutocode_engine_X2L=eutocode_engine_A;
            eutocode_engine_X2=1024*eutocode_engine_X2H + eutocode_engine_X2L;
          }
        else if(c == '\uEB03')
          {
            eutocode_engine_Y2L=eutocode_engine_A;
            eutocode_engine_Y2=1024*eutocode_engine_Y2H + eutocode_engine_Y2L;
          }
        else if(c == '\uEB20')
          {
            eutocode_engine_COLOUR=eutocode_engine_A;
            screen.setColor(Color.yellow);
            switch(eutocode_engine_COLOUR)
              {
                case  0:  screen.setColor(Color.black);      break;
                case  1:  screen.setColor(brown);            break;
                case  2:  screen.setColor(Color.red);        break;
                case  3:  screen.setColor(Color.orange);     break;
                case  4:  screen.setColor(Color.yellow);     break;
                case  5:  screen.setColor(Color.green);      break;
                case  6:  screen.setColor(Color.blue);       break;
                case  7:  screen.setColor(Color.magenta);    break;
                case  8:  screen.setColor(Color.gray);       break;
                case  9:  screen.setColor(Color.white);      break;
                case 10:  screen.setColor(Color.cyan);       break;
                case 11:  screen.setColor(Color.pink);       break;
                case 12:  screen.setColor(Color.darkGray);   break;
                case 13:  screen.setColor(Color.lightGray);  break;
                case 14:  screen.setColor(lavender);         break;
                case 15:  screen.setColor(mint);             break;
                default:  screen.setColor(Color.black); 
              }
          }
        else if(c == '\uEB40')
          {
            screen.drawLine(eutocode_engine_X1,eutocode_engine_Y1,
                            eutocode_engine_X2,eutocode_engine_Y2);
          }
        else if(c == '\uEB41')
          {
            screen.drawRect(eutocode_engine_X1,eutocode_engine_Y1,
                            eutocode_engine_X2,eutocode_engine_Y2);
          }
        else if(c == '\uEB42')
          {
            screen.fillRect(eutocode_engine_X1,eutocode_engine_Y1,
                            eutocode_engine_X2,eutocode_engine_Y2);
          }
        else if(c == '\uEB43')
          {
            screen.drawOval(eutocode_engine_X1,eutocode_engine_Y1,
                            eutocode_engine_X2,eutocode_engine_Y2);
          }
        else if(c == '\uEB44')
          {
            screen.fillOval(eutocode_engine_X1,eutocode_engine_Y1,
                            eutocode_engine_X2,eutocode_engine_Y2);
          }
// Start of the additions of 14 December 2002 for polygons
        else if(c == '\uEB30')
// Set this pointer before entering the data for a polygon.
          {
            eutocode_engine_POLYGON_POINTER=0;
          }
        else if(c == '\uEB31')
// Use this after all of the data for a polygon point has been added, data for the first point
// is entered with the pointer value at 0; the pointer is incremented so as to be
// in a steady state when ready to receive an extra point.
          {
            eutocode_engine_POLYGON_POINTER++;
          }
        else if(c == '\uEB10')
// sets an X data value for a polygon point with a new XL value
          {
            eutocode_engine_POLYGON_XL[eutocode_engine_POLYGON_POINTER]=eutocode_engine_A;
//
            eutocode_engine_POLYGON_X[eutocode_engine_POLYGON_POINTER]=
              1024*eutocode_engine_POLYGON_XH[eutocode_engine_POLYGON_POINTER]+
                eutocode_engine_POLYGON_XL[eutocode_engine_POLYGON_POINTER];
          }
        else if(c == '\uEB11')
// sets a Y data value for a polygon point with a new YL value
          {
            eutocode_engine_POLYGON_YL[eutocode_engine_POLYGON_POINTER]=eutocode_engine_A;
//
            eutocode_engine_POLYGON_Y[eutocode_engine_POLYGON_POINTER]=
              1024*eutocode_engine_POLYGON_YH[eutocode_engine_POLYGON_POINTER]+
                eutocode_engine_POLYGON_YL[eutocode_engine_POLYGON_POINTER];
          }
        else if(c == '\uEB50')
// draws a polygon
          {
            eutocode_engine_POLYGON_SIDES=eutocode_engine_POLYGON_POINTER;
            screen.drawPolygon(eutocode_engine_POLYGON_X,
                                 eutocode_engine_POLYGON_Y,
                                   eutocode_engine_POLYGON_SIDES);
          }
        else if(c == '\uEB51')
// draws a filled polygon
          {
            eutocode_engine_POLYGON_SIDES=eutocode_engine_POLYGON_POINTER;
            screen.fillPolygon(eutocode_engine_POLYGON_X,
                                 eutocode_engine_POLYGON_Y,
                                   eutocode_engine_POLYGON_SIDES);
          }
// End of the additions of 14 December 2002 for polygons
 
      }
 
  } 


2002/12/14 11:50


Here is some test data for the eutocode graphics applet. It represents an orange filled triangle with a red border. This is produced by entering data for a three-sided polygon then setting the drawing colour to orange and drawing a filled polygon and then setting the drawing colour to red and drawing a polygon (that is, an unfilled polygon).

I produced the data sequence using SC UniPad and used it in the applet direct from there.

I am now going to try to post the sequence into this posting and observe what happens and whether the data can be retrieved from the web page which is produced.



The character sequence which I used is as follows.

U+EB30 U+EC60 U+EB10 U+EC60 U+EB11 U+EB31 U+ECC0 U+EB10 U+EC80 U+EB11 U+EB31 U+EC80 U+EB10 U+ECC0 U+EB11 U+EB31 U+EC03 U+EB20 U+EB51 U+EC02 U+EB20 U+EB50

William Overington

14 December 2002


2002/12/14 12:20


I am pleased to report that I found it possible to copy the 22 characters in the previous posting, which show as 22 black rectangles on the display here, onto the clipboard of a PC running Windows 98 and then paste them into the text box of the applet, using CTRL V to effect the pasting operation, and to then click the draw button of the applet and produce a display of an orange triangle with a red border.

So, with the addition of polygons, the eutocode graphics system has reached the stage where it could be used for quite a wide variety of graphics upon the DVB-MHP system. I am thinking in terms of the eutocode graphics characters being in a file which is read by a Java program. Achieving the encoding of a graphic of an orange triangle with a red border in 44 bytes (that is, two bytes for each character) is, I feel, quite a step forward in the capabilities for producing graphics on the DVB-MHP system where the graphics are encoded in separate files.

There is the fact that the Java program needs to be broadcast, so that is going to take up space as well. I do not know how big a Java program for the DVB-MHP platform would be, but in the hope that the figure might be some guide, I mention that the applet class in the demonstration is listed as 6KB in Windows Explorer, which may mean that it is somewhere bewteen 5 kilobytes and 6 kilobytes.

A matter which concerns me in the design process of the eutocode graphics system is that although the more commands that I add into the system the more comprehensive it becomes in terms of what can be drawn, yet the bigger it gets in terms of the size of a Java program. Also, the amount of memory needed by the Java program for data storage increases, though that does not appear to be a problem. The potential problem is in increasing the size of the Java program which is to be broadcast.

I have it in mind to add some facilities for using more than sixteen fixed colours.

However, I am concerned to keep the size of the eutocode graphics system fairly small in the hope that that will help in it being used widely on the DVB-MHP platform.

William Overington

14 December 2002


2002/12/14 16:43


I have now added a few more codes to the eutocode graphics system which, I feel, now produces a plateau upon which experiments can proceed.

These codes are for using a colour named colour16 which can be accessed using the sequence U+EC10 U+EB20, the meaning of the U+EB20 code having had some more software added to it.

The colour16 colour may have its red, green and blue components set using respectively U+EB21, U+EB22 and U+EB23, in each case by first setting the data value to be used into the eutocode_engine_A variable. For example, the sequence U+ECFF U+EB22 sets the green component to be used in colour16, from when colour16 is next selected, to be 255.

I have now added the HTML file to the web at the following place.

http://www.users.globalnet.co.uk/~ngo/eutocodegraphics.htm

The Java class file is at the following place.

http://www.users.globalnet.co.uk/~ngo/eutocodegraphics.class

The Java source code of the applet is at the following place.

http://www.users.globalnet.co.uk/~ngo/eutocodegraphics.java

As the addition of these additional codes relating to colour now produces a plateau upon which experiments can proceed I am also posting a copy of the source code here, so that it becomes archived in the records of this forum.

The eutocode graphics codes detailed in this thread can, I feel, produce a wide range of graphics. Certainly, where pairs or triples of characters are often used in sequence it may well be desirable to define additional eutocode graphics codes which perform all of the sequence of commands using just one character code. Yet, the set thus far defined is capable of producing good quality graphics in a fairly compact manner.

Please feel free to use the eutocode graphics codes and the software in the eutocodegraphics.java file, or pieces of software copied out from that file, in order to help to implement eutocode graphics on the DVB-MHP platform if you so wish.

Hopefully eutocode graphics will become part of the application of the DVB-MHP system around the world.

William Overington

14 December 2002  

import java.awt.*;
import java.awt.event.*;
 
public class eutocodegraphics extends java.applet.Applet implements
                                                     ActionListener
 
// Software written by William Overington
// WOverington@ngo.globalnet.co.uk
// 12 December 2002
// Also the additions of 14 December 2002 for polygons
// Also the additions of 14 December 2002 for colour 16
// Copyright 2002 William Overington
//
// This software is an applet which is for demonstrating the use of
// eutocode graphics
 
  {
    int obeycode=1;
 
    Button go1Button = new Button("draw");
    Button go2Button = new Button("clear");
 
    TextField text1TextField = new TextField(80);
 
    String text1="";
 
    char eutocode='?';
 
// Start of the declarations for the eutocode engine
//
    int eutocode_engine_A=0;
//
    int eutocode_engine_X1L=0;
    int eutocode_engine_Y1L=0;
    int eutocode_engine_X2L=0;
    int eutocode_engine_Y2L=0;
//
    int eutocode_engine_X1H=0;
    int eutocode_engine_Y1H=0;
    int eutocode_engine_X2H=0;
    int eutocode_engine_Y2H=0;
//
    int eutocode_engine_X1=0;
    int eutocode_engine_Y1=0;
    int eutocode_engine_X2=0;
    int eutocode_engine_Y2=0;
//
    int eutocode_engine_COLOUR=0;
//
// Start of the additions of 14 December 2002 for polygons
//
    int eutocode_engine_POLYGON_POINTER=0;
    int[] eutocode_engine_POLYGON_XL= new int[101];
    int[] eutocode_engine_POLYGON_YL= new int[101];
    int[] eutocode_engine_POLYGON_XH= new int[101];
    int[] eutocode_engine_POLYGON_YH= new int[101];
    int[] eutocode_engine_POLYGON_X= new int[101];
    int[] eutocode_engine_POLYGON_Y= new int[101];
    int eutocode_engine_POLYGON_SIDES=0;
//
// End of the additions of 14 December 2002 for polygons
//
// Start of the additions of 14 December 2002 for colour 16
//
    int eutocode_engine_COLOUR16_RED_COMPONENT=0;
    int eutocode_engine_COLOUR16_GREEN_COMPONENT=0;
    int eutocode_engine_COLOUR16_BLUE_COMPONENT=0;
//
// End of the additions of 14 December 2002 for colour 16
//
// End of the declarations for the eutocode engine
 
// Start of the declarations for the additional colours
    Color brown = new Color(255,102,  0);
    Color lavender = new Color(204,153,204);
    Color mint = new Color(204,255,204);
// End of the declarations for the additional colours
 
    public void init()
      {
        setLayout(null);
        setBounds(0,0,720,576);
        go1Button.addActionListener(this);
        go1Button.setLocation(530,200);
        go1Button.setSize(110,30);
        add(go1Button);
        go2Button.addActionListener(this);
        go2Button.setLocation(530,250);
        go2Button.setSize(110,30);
        add(go2Button);
        text1TextField.setLocation(530,150);
        text1TextField.setSize(110,20);
        add(text1TextField);
 
        setBackground(Color.white);
        Font typeface = new Font("Arial", Font.PLAIN, 12);
        setFont(typeface);
 
        text1TextField.setText(" ");
 
        obeycode=1;
 
// Start of the additions of 14 December 2002 for polygons
    for(int i=0;i <= 100;i++)
      {
        eutocode_engine_POLYGON_XL[i]=0;
        eutocode_engine_POLYGON_YL[i]=0;
        eutocode_engine_POLYGON_XH[i]=0;
        eutocode_engine_POLYGON_YH[i]=0;
        eutocode_engine_POLYGON_X[i]=0;
        eutocode_engine_POLYGON_Y[i]=0;
      }
// End of the additions of 14 December 2002 for polygons
      }
 
    public void actionPerformed(ActionEvent event)
      {
        Object source = event.getSource();
 
        if (source == go1Button)
          {
            obeycode=51;
            repaint();
          }
 
        if (source == go2Button)
          {
            obeycode=52;
            repaint();
          }
      }
 
     public void paint(Graphics screen)
      {                                                             
 
        screen.setColor(Color.black); 
       
        if(obeycode == 51)
          {
            text1=text1TextField.getText();
            int length=text1.length();
            if(length > 0)
              {
                for(int i=0;i < length;i++)
                  {
                    char c;
                    c=text1.charAt(i);
                    eutocode=c;
                    process(screen,eutocode);
                  }
              }
 
            text1TextField.setText("*");
          }
        else if(obeycode == 52)
          {
            screen.setColor(Color.white);
            screen.fillRect(0,0,720,576);
          }
      
      }
 
    public void update(Graphics screen)
      {
        paint(screen);
      }
 
    private void process(Graphics screen, char eutocode)
      {
        char c;
        c=eutocode;
//
        if((c >= '\uEC00') & (c <= '\uEFFF'))
          {
            int n;
            n=((int) c) - ((int) '\uEC00');
            eutocode_engine_A=n;
          }
        else if(c == '\uEB00')
          {
            eutocode_engine_X1L=eutocode_engine_A;
            eutocode_engine_X1=1024*eutocode_engine_X1H + eutocode_engine_X1L;
          }
        else if(c == '\uEB01')
          {
            eutocode_engine_Y1L=eutocode_engine_A;
            eutocode_engine_Y1=1024*eutocode_engine_Y1H + eutocode_engine_Y1L;
          }
        else if(c == '\uEB02')
          {
            eutocode_engine_X2L=eutocode_engine_A;
            eutocode_engine_X2=1024*eutocode_engine_X2H + eutocode_engine_X2L;
          }
        else if(c == '\uEB03')
          {
            eutocode_engine_Y2L=eutocode_engine_A;
            eutocode_engine_Y2=1024*eutocode_engine_Y2H + eutocode_engine_Y2L;
          }
        else if(c == '\uEB20')
          {
            eutocode_engine_COLOUR=eutocode_engine_A;
            screen.setColor(Color.yellow);
            switch(eutocode_engine_COLOUR)
              {
                case  0:  screen.setColor(Color.black);      break;
                case  1:  screen.setColor(brown);            break;
                case  2:  screen.setColor(Color.red);        break;
                case  3:  screen.setColor(Color.orange);     break;
                case  4:  screen.setColor(Color.yellow);     break;
                case  5:  screen.setColor(Color.green);      break;
                case  6:  screen.setColor(Color.blue);       break;
                case  7:  screen.setColor(Color.magenta);    break;
                case  8:  screen.setColor(Color.gray);       break;
                case  9:  screen.setColor(Color.white);      break;
                case 10:  screen.setColor(Color.cyan);       break;
                case 11:  screen.setColor(Color.pink);       break;
                case 12:  screen.setColor(Color.darkGray);   break;
                case 13:  screen.setColor(Color.lightGray);  break;
                case 14:  screen.setColor(lavender);         break;
                case 15:  screen.setColor(mint);             break;
                default:  screen.setColor(Color.black); 
              }
// Start of the additions of 14 December 2002 for colour 16
             if(eutocode_engine_COLOUR == 16)
               {
                 Color colour16=new Color(eutocode_engine_COLOUR16_RED_COMPONENT,
                                          eutocode_engine_COLOUR16_GREEN_COMPONENT,
                                          eutocode_engine_COLOUR16_BLUE_COMPONENT);
                 screen.setColor(colour16);
               }
// End of the additions of 14 December 2002 for colour 16
          }
// Start of the additions of 14 December 2002 for colour 16
        else if(c == '\uEB21')
          {
            eutocode_engine_COLOUR16_RED_COMPONENT=eutocode_engine_A;            
          }
        else if(c == '\uEB22')
          {
            eutocode_engine_COLOUR16_GREEN_COMPONENT=eutocode_engine_A;
          }
        else if(c == '\uEB23')
          {
            eutocode_engine_COLOUR16_BLUE_COMPONENT=eutocode_engine_A;
          }
// End of the additions of 14 December 2002 for colour 16
        else if(c == '\uEB40')
          {
            screen.drawLine(eutocode_engine_X1,eutocode_engine_Y1,
                            eutocode_engine_X2,eutocode_engine_Y2);
          }
        else if(c == '\uEB41')
          {
            screen.drawRect(eutocode_engine_X1,eutocode_engine_Y1,
                            eutocode_engine_X2,eutocode_engine_Y2);
          }
        else if(c == '\uEB42')
          {
            screen.fillRect(eutocode_engine_X1,eutocode_engine_Y1,
                            eutocode_engine_X2,eutocode_engine_Y2);
          }
        else if(c == '\uEB43')
          {
            screen.drawOval(eutocode_engine_X1,eutocode_engine_Y1,
                            eutocode_engine_X2,eutocode_engine_Y2);
          }
        else if(c == '\uEB44')
          {
            screen.fillOval(eutocode_engine_X1,eutocode_engine_Y1,
                            eutocode_engine_X2,eutocode_engine_Y2);
          }
// Start of the additions of 14 December 2002 for polygons
        else if(c == '\uEB30')
// Set this pointer before entering the data for a polygon.
          {
            eutocode_engine_POLYGON_POINTER=0;
          }
        else if(c == '\uEB31')
// Use this after all of the data for a polygon point has been added, data for the first point
// is entered with the pointer value at 0; the pointer is incremented so as to be
// in a steady state when ready to receive an extra point.
          {
            eutocode_engine_POLYGON_POINTER++;
          }
        else if(c == '\uEB10')
// sets an X data value for a polygon point with a new XL value
          {
            eutocode_engine_POLYGON_XL[eutocode_engine_POLYGON_POINTER]=eutocode_engine_A;
//
            eutocode_engine_POLYGON_X[eutocode_engine_POLYGON_POINTER]=
              1024*eutocode_engine_POLYGON_XH[eutocode_engine_POLYGON_POINTER]+
                eutocode_engine_POLYGON_XL[eutocode_engine_POLYGON_POINTER];
          }
        else if(c == '\uEB11')
// sets a Y data value for a polygon point with a new YL value
          {
            eutocode_engine_POLYGON_YL[eutocode_engine_POLYGON_POINTER]=eutocode_engine_A;
//
            eutocode_engine_POLYGON_Y[eutocode_engine_POLYGON_POINTER]=
              1024*eutocode_engine_POLYGON_YH[eutocode_engine_POLYGON_POINTER]+
                eutocode_engine_POLYGON_YL[eutocode_engine_POLYGON_POINTER];
          }
        else if(c == '\uEB50')
// draws a polygon
          {
            eutocode_engine_POLYGON_SIDES=eutocode_engine_POLYGON_POINTER;
            screen.drawPolygon(eutocode_engine_POLYGON_X,
                                 eutocode_engine_POLYGON_Y,
                                   eutocode_engine_POLYGON_SIDES);
          }
        else if(c == '\uEB51')
// draws a filled polygon
          {
            eutocode_engine_POLYGON_SIDES=eutocode_engine_POLYGON_POINTER;
            screen.fillPolygon(eutocode_engine_POLYGON_X,
                                 eutocode_engine_POLYGON_Y,
                                   eutocode_engine_POLYGON_SIDES);
          }
// End of the additions of 14 December 2002 for polygons
 
      }
 
  } 


2002/12/21 14:29


I have been looking at the possibility of adding into the eutocode graphics system some codes which produce Bézier curves and have tried some experiments.

I added four codes to a copy of the eutocodegraphics.java program. These were to load data into a control point x register, to load data into a control point y register, to load a number into a "number of steps" register and to specify that the drawing of a quadratic Bézier curve from point (x1,y1) to point (x2,y2) influenced by point (c1x,c1y) should take place drawing the curve using the specified number of steps. Using 4 steps produces 4 straight lines, with only the start point, the end point and the ends of the lines actually on the Bézier curve. Using 64 points produces what looks like a curve. I chose to specify the number of steps so that all implementations would draw an identical picture, so that a content author can make the choice of how to draw a particular curve and so that as well as curves as such the codes may be used to draw graphic effects using straight lines between points along a Bézier curve. I am hoping to extend these experiments to cubic Bézier curves with two control points and to cubic Bézier curves where the two control points are in the same place. These cubic Bézier curves are particularly useful as, I have found, they are the way that the Curve Tool in the Microsoft Paint program on a PC works, so it will be possible to express in eutocode curves which are designed using the Curve Tool of the Microsoft Paint program.

My thinking is that such Bézier curves might be very useful in producing filled shapes, so I am also thinking about how best to use the codes for Bézier curves in conjunction with the arrays for storing the points of a polygon, so that the points on the Bézier curves may be used in producing filled shapes. It is a quite fascinating design process.

However, an important design consideration for eutocode graphics is that it is small in size, so that using eutocode graphics does not automatically necessitate using a large Java program. Accordingly I am thinking of defining eutocode graphics at several levels, with each level above level 1 incorporating all of the levels which are below it. There will then be a code which allows a content author to specify the level of eutocode graphics which is needed for a particular graphic. A eutocode graphics program will be able to know its own level and so can always detect any eutocode graphic which is beyond its abilities to draw. Level 1 eutocode graphics will be very small, containing only a few more codes than the codes published earlier in this thread, so that hopefully level 1 will become widely implemented on the DVB-MHP platform.

William Overington

21 December 2002


 

Astrolabe Channel

Copyright 2002 and 2003 William Overington

This file is accessible as follows.

http://www.users.globalnet.co.uk/~ngo/ast03000.htm