Gnu Unifont WOFF

Today I discovered Gnu Unifont. It’s a really cool unicode bitmap font, with a high level of unicode coverage. There was no WOFF version available so I made one using fontforge. The version of fontforge in debian stable doesn’t have WOFF support so it was a build from source job, it’s worth noting that you need libpng-dev and libz-dev installed for WOFF support to be compiled in (otherwise it’s greyed out in the “generate fonts” menu).

You can download my WOFF here. And see it in action:


UNIFONT DEMO


However, it only seems to work in Safari… which is a shame. 🙁

Pretty terminal fonts and WOFF woes

This evening I’ve been playing with fonts on the web, specifically fixed width terminal fonts. Years ago I was a big fan of Profont and Terminus on Linux, however since moving to a mac I’ve stuck with it’s standard terminal font. I wanted to see if these fonts could be rendered on the web, my first thought was that I could build my own tools to render them to a html5 canvas, that would be a fun project. However with a little further investigation I discovered WOFF. WOFF is a W3C standard which allows browsers to download and render ttf fonts. This isn’t perfect, as Terminus and Profont are generally used as bitmap fonts. However it may mean I can mix those character sets with other, unicode renderings (one of the things I love about OSX is how well the terminal renders Kanji).

So… I found TTF versions of Terminus and Profont on the web. Unfortunately the Terminus TTF renderings seem to be quite bad. In any case I used this tool to convert the ttf files to WOFF files. And then created a couple of simple webpages to test the fonts:

Terminus

Profont

The Profont version looks a lot better to my mind. In firefox/chrome the Kanji gets pulled in from some other font automatically. I think Kanji fonts are fixed width, I think exactly double standard latin characters, at least that’s how it appears on the mac terminal:

You can see the latin characters don’t get pulled out of alignment after the Japanese characters are inserted. The same seems to be stuff of the fixed width fonts in the WOFF webpages above in Firefox and Chrome, however in Safari the hiragana does seem to pull the other characters out of alignment. I’ll have to look in to ways of specifying a fixed width alternative Unicode font…

So, those are my experiments so far. Rendering Profont nicely in the browser seems relatively straight forward, and allows unicode character sets. Next questions is what to do with it!

Another Pretty HTML5 thing

I remember writing ARM assembler code to make these pretty things about 15 years ago. Anyway, now in html5!

Click Here to open in new window.

And here’s the JS for reference:


<script type="text/javascript">

  var ittr=10;
  var delta=-0.05;

  function draw_thing(ctx,ox,oy,sx,sy,ds,ex,ey,de) {

      var mins=0;
      var maxs=0;
      if(ds < 0) {mins=-200; maxs=0;} else {mins=200; maxs=0;}

      for(sy=maxs;Math.abs(sy) < Math.abs(mins);sy=sy+ds) {
        ctx.beginPath();
        ctx.moveTo(ox+sx,oy+sy);
        ctx.lineTo(ox+ex,oy+ey);
        ctx.closePath();
        ctx.stroke();
        ex=ex+de;
      }

      ctx.beginPath();
      ctx.moveTo(ox,oy);
      ctx.lineTo(ox,oy+mins);
      ctx.closePath();
      ctx.stroke();

  }

  function draw_frame() {
    var canvas = document.getElementById("m_canvas");
    if(canvas.getContext) {

      var ctx = canvas.getContext("2d");
      ctx.clearRect(0, 0, canvas.width, canvas.height);
      ctx.lineWidth  = 1;

      ctx.fillStyle = "rgb(0,0,0)";
      var size=1;
      var offset=0;

      draw_thing(ctx,200,200,0,0,  ittr, 200,0,0-ittr);
      draw_thing(ctx,200,200,0,0,0-ittr, 200,0,0-ittr);
      draw_thing(ctx,200,200,0,0,  ittr,-200,0,  ittr);
      draw_thing(ctx,200,200,0,0,0-ittr,-200,0,  ittr);

      ittr = ittr + delta;
      if(ittr<2 ) {delta = 0-delta; ittr=2;}
      if(ittr>10) {delta = 0-delta;}
    }
  }

</script>

Pretty HTML Canvas thing from a 30 year old magazine

I was looking through an old copy of Beebug from 1982 and came across a review for “Practical Programs for the BBC Computer and Acorn Atom”:

The review contains a code listing from the book to draw a “very nice 3D object”. I decided it might be fun to port the program to HTML5 using a canvas. I also modified it slightly to animate the rendering. It’s a direct port, I just ported it line for line and then added code to vary YS to animate the object. Click below to take a look:


CLICK TO OPEN ANIMATION

opens in new window

The basic html5 implementation was pretty straightforward, however getting it to animate without a horrible amount of flickering was harder. It doesn’t look like canvas has support for double buffering, the only option being to use 2 canvas objects and hide one while you’re drawing to it. Blanking the whole canvas resulted in a horrible flicker for me, so instead I opted to black vertical lines during the rendering of each frame, this seems to work pretty well.

If you liked this thing, there’s another one here.

Notes

Here’s the full text of the article:

Title: Practical Programs for the BBC Computer and Acorn Atom
By: David Johnson-Davis Price £5.95
Reviewer: David Graham

As its title suggests, this book is not concerned with teaching you to program, or with teaching you to use the computer, but with the presentation of a number of programs. The range of programs offered is good, and includes games, graphics, number and word handling, and rather surprisingly an SPL compiler. With each program there is a discussion of the objects and principles involved (though nothing on the programming principles). The program listings are also broken down into useful subsections with boxed functional headings. This makes them relatively easy to follow.

The final section of the book, chapter 5, introduces the subject of compilers, and gives a listing for an experimental Simple Programming Language compiler for the BBC machine, plus a number of SPL programs that may be run on it. This all looks very interesting, and well worth some closer study. But if you are not interested in compilers, you are left with only 65 pages of the book; and since some of that space is taken up with the Acorn Atom version of each program presented, the book becomes a little expensive per useable page. It does, however, contain some good ideas, such as the brief program given below which plots the very nice 3D object in the photograph.

 10 REM FROM:
 20 REM PRACTICAL PROGRAMS FOR THE
 30 REM BBC COMPUTER AND ACORN ATOM
 40 REM BY DAVID JOHNSON-DAVIS
 50 MODE4:VDU29,640,512;:XS=4:YS=4
 60 A=640:B=A*A:C=512
 70 FORX=0TOA STEPXS:S=X*X:P=SQR(B-S)
 80   FORI=-P TO P STEP 6*YS
 90     R=SQR(S+I*I)/A
100     Q=(R-1)*SIN(24*R)
110     Y=I/3+Q*C
120     IFI=-P THEN M=Y:GOTO150
130     IFY>M M=Y: GOTO160
140     IFY>=N GOTO170
150     N=Y
160     PLOT69,-X,Y:PLOT69,X,Y
170     NEXT:NEXT
180 END

The Javascript:

  function draw_frame() {
    var canvas = document.getElementById("m_canvas");
    if(canvas.getContext) {
      var ctx = canvas.getContext("2d");
      ctx.lineWidth  = 0;

      ctx.fillStyle = "rgb(0,0,0)";
      var size=1;
      var offset=0;

      ctx.scale(1,-1);

      var xs=2;
      var ys=ittr;
      var a=640;
      var b=a*a;
      var c=512;

      for(var x=0;x<=a;x=x+xs) {
        s = x*x;
        p = Math.sqrt(b-s);

        ctx.clearRect(((  x+640)/2)+offset,0,2,canvas.height);
        ctx.clearRect(((0-x+640)/2)+offset-1,0,2,canvas.height);

        // size=0.5; offset=0;
        for(var i=0-p;i<=p;i+=6*ys) {
          var r = Math.sqrt(s+i*i)/a;
          var q = (r-1)*Math.sin(24*r);
          y = i/3 + q*c;
          if(i==0-p) {m=y; n=y; ctx.fillRect(((0-x+640)/2)+offset,(512-(y+512)/2)+offset,size,size); ctx.fillRect(((x+640)/2)+offset,(512-(y+512)/2)+offset,size,size); }
          if(y>m)    {m=y;      ctx.fillRect(((0-x+640)/2)+offset,(512-(y+512)/2)+offset,size,size); ctx.fillRect(((x+640)/2)+offset,(512-(y+512)/2)+offset,size,size); }
          if(!(y>=n)){n=y;      ctx.fillRect(((0-x+640)/2)+offset,(512-(y+512)/2)+offset,size,size); ctx.fillRect(((x+640)/2)+offset,(512-(y+512)/2)+offset,size,size); }
        }
      }
      ittr = ittr + delta;
      if(ittr < 0.6) delta = 0-delta;
      if(ittr > 100) delta = 0-delta;
    }
  }

The function is then triggered by a setInterval on the page load as follows:

<body  onload="setInterval(draw_frame,10);" >