Job compilerTM
© S. Sverdlov, 1998    

(* Applet Ticker
   Written by C3C 1998

   <APPLET code="Ticker_App" width=481 height=49>
      <PARAM name = "text" value =
         "80AFABA5E2202281A5A3E3E9A0EF20E1E2E0AEAAA0222E
          204170706C657420225469636B6572222E
          2020202020202020202020202020202020202020
          80AFABA5E220ADA0AFA8E1A0AD20ADA0208EA1A5E0AEADA52D322E
          204170706C6574206973207772697474656E20696E204F6265726F6E2D322E
          2020202020202020202020202020202020202020
          8EE2AAAEACAFA8ABA8E0AEA2A0AD20AAAEACAFA8ABEFE2AEE0AEAC204A4F422E
          20436F6D70696C6564206279204A4F4220636F6D70696C65722E
          2020202020202020202020202020202020202020
          7777772E756E692D766F6C6F6764612E61632E72752F4A6F62
          202020202063336340756E692D766F6C6F6764612E61632E7275
          2020202020202020202020202020202020202020"
      >
   </APPLET>
*)

MODULE Ticker;

IMPORT 
   SYSTEM, Timers,
   J  :=javalang,
   app:=javaapplet,
   awt:=javaawt,
   img:=javaawtimage,
   col:=javaawtColor;

CONST
   Pause = 25;
   SBLen = 20;
   DotSize = 2;
   DotStep = DotSize+1;
   FontFile = 'font16.gif';
   CharH = LONG(16);
   CharW = LONG(8);
   SBw = DotStep*CharW*SBLen+1;
   SBh = DotStep*CharH+1;
   FontImgW = 16*CharW;
   FontImgH = 16*CharH;
   SBCol = SBLen*CharW;

TYPE
   PCharArray = POINTER TO ARRAY OF CHAR;
   PApp = POINTER TO App;
   App* = RECORD (app.Applet)
      buf      : awt.PImage;
      g        : awt.PGraphics;
      scr      : awt.PGraphics;
      im       : awt.PImage;
      timer    : Timers.Timer;
      text     : PCharArray;
      CharNum  : INTEGER;
      ColNum   : INTEGER;
      pixels   : ARRAY FontImgW*FontImgH OF INTEGER;
      grabber  : img.PPixelGrabber;
      tflag    : BOOLEAN;
      tlen     : INTEGER;
      bg       : awt.PColor;
      net      : awt.PColor;
      bulb     : awt.PColor;
   END;

PROCEDURE Str( c : ARRAY OF CHAR ) : J.PString;
VAR
   s     : J.PString;
   len   : INTEGER;
BEGIN
   SYSTEM.NEW( s, c );
   len := s.length();
   IF (len>0) & (s.charAt(len-1)=0X) THEN
      RETURN s.substring(0,len-1);
   END;
   RETURN s;
END Str;

PROCEDURE ( a : PApp ) InitTicker();
VAR
   i, j : INTEGER;
BEGIN
   a.g.setColor( a.bg );
   a.g.fillRect( 0, 0, SBw, SBh );
   a.g.setColor( a.net );
   FOR i := 0 TO CharH DO
      FOR j := 0 TO SBLen*CharW DO
         a.g.fillRect( j*DotStep, i*DotStep, 1, 1 );
      END;
   END;
END InitTicker;

PROCEDURE ( a : PApp ) LoadFont();
VAR
   URL   : net.PURL;
BEGIN
   URL := a.getCodeBase();
   a.im := a.getImage( URL, Str(FontFile) );
   SYSTEM.NEW( a.grabber, a.im, LONG(0), LONG(0), FontImgW, FontImgH, a.pixels, LONG(0), FontImgW );
   IF a.grabber.grabPixels() THEN END;
END LoadFont;

PROCEDURE ( a : PApp ) OneStep();
VAR
   i, k     : INTEGER;
   x, y     : INTEGER;
   ord      : INTEGER;
   Ok       : BOOLEAN;
BEGIN
   ord := ORD(a.text[a.CharNum]);
   y := ord DIV 16 * CharH + CharH;
   x := ord MOD 16 * CharW + a.ColNum;
   i := CharH;
   a.g.copyArea( DotStep, 0, SBw-DotStep, SBh, -DotStep, 0 );
   REPEAT
      DEC(i); DEC(y);
      IF a.pixels[y*FontImgW + x] > -1000000 THEN
         a.g.setColor( a.bulb );
      ELSE
         a.g.setColor( a.bg );
      END;
      a.g.fillRect( SBw-DotStep, i*DotStep+1, DotSize, DotSize );
   UNTIL i=0;
   Ok := a.scr.drawImage( a.buf, 0, 0, NIL );
   a.ColNum := ( a.ColNum + 1 ) MOD CharW;
   IF a.ColNum = 0 THEN a.CharNum := ( a.CharNum + 1 ) MOD a.tlen END;
END OneStep;

PROCEDURE ( a : PApp ) GetText();
VAR
   i, j  : INTEGER;
   h     : INTEGER;
   ord   : INTEGER;
   Ch    : CHAR;
   len   : INTEGER;
   Hi    : BOOLEAN;
   s     : J.PString;

   PROCEDURE Digit;
   BEGIN
      IF Hi THEN
         ord := h
      ELSE
         a.text[j] := CHR(16*ord + h);
         INC(j);
      END;
      Hi := ~Hi;
   END Digit;

BEGIN
   ord := 0;
   s := a.getParameter( Str("text") );
   IF s=NIL THEN
      a.tlen := 24;
      NEW(a.text, a.tlen+1);
      COPY(" *** Text not found *** ", a.text^);
   ELSE
      len := s.length();
      NEW( a.text, len DIV 2 );
      i := 0; j := 0; Hi := TRUE;
      WHILE i<len DO
         Ch := s.charAt(i);
         IF ( '0' <= Ch ) & ( Ch <= '9' ) THEN
            h := ORD(Ch) - ORD('0');
            Digit;
         ELSIF ( 'A' <= Ch ) & ( Ch <= 'F' ) THEN
            h := 10 + ORD(Ch) - ORD('A');
            Digit;
         END;
         INC(i);
      END;
      a.tlen := j;
   END;
END GetText;

PROCEDURE ( a : PApp ) handleEvent*( e : awt.PEvent ) : BOOLEAN;
BEGIN
   IF e.id = Timers.TimerEVENT THEN
      IF ~a.tflag THEN
         a.tflag := TRUE;
         a.OneStep();
         a.tflag := FALSE;
      END;
      RETURN TRUE;
   END;
   RETURN a.handleEvent^(e);
END handleEvent;

PROCEDURE ( a : PApp ) init*();
VAR
   c : awt.PColor;
BEGIN
   a.bg := col.black;
   a.net := col.gray;
   a.bulb := col.green;
   a.buf := a.createImage( SBw, SBh );
   a.g := a.buf.getGraphics();
   a.scr := a.getGraphics();
   a.LoadFont();
   a.GetText();
   a.CharNum := 0;
   a.ColNum := 0;
   a.InitTicker();
   a.timer.Start( a, Pause );
END init;

PROCEDURE ( a : PApp ) destroy*();
BEGIN
   a.timer.Stop();
END destroy;

END Ticker.