Friday Dec 04, 2009

Drawing TrueType Fonts Using Java

The various fonts that are displayed in any raster image of a display device or a printer requires a font engine to render them. TrueType fonts are a specific kind of font format that  are widely used by Mac and Windows machines. These are  binary files with the extension .ttf and could be converted to human-readable files using utilities like fonttools (in Ubuntu). A typcal human-readable truetype font file would look like an XML file with data to draw all the characters of a font. The is XML file could be parsed and drawn as an image output using Java's Graphics2D API.

 Any  character (or the glyph in broader  terms) to be rendered is represented as a set of contours . Each contour is a path formed by straight lines and Bezier curves, that are in turn connected by a set of points in the x-y co-ordinate space (read as raster space for the display). In addition to the x and y co-ordinates, the points also have a boolean value indicating if the points are either on-curve or off-curve. An on-curve point is part of the contour while the off curve point is a control point of the Bezier curve. A single control point indicates a quadratic Bezier curve while two control points indicate a cubic Bezier curve.

To draw the glyph using Java, the Graphics 2D API (java.awt.\*) could be used. Each point is represented using java.awt.geom.Point2D.  The contour is represented using java.awt.geom.GeneralPath  and the lines and Bezier curves are drawn using the methods lineTo(), quadTo() and curveTo() to represent straight lines, quadratic and cubic Bezier curves respectively.

 Here are the code snippets for the methods:

private static void drawLine(GeneralPath.Double path, Point2D point1, Point2D point2)   {

      path.moveTo(point1.getX() , point1.getY());          

      path.lineTo(point2.getX(), point2.getY());
    }

    private static void drawBezQuadCurve(GeneralPath.Double path, Point2D point1, Point2D controlPoint, Point2D point2) {

path.moveTo(point1.getX() , point1.getY());  

           path.quadTo(controlPoint.getX() , controlPoint.getY() , point2.getX() , point2.getY() );
    }


    private static void drawBezCubicCurve(GeneralPath.Double path, Point2D point1, Point2D ctrlPt1, Point2D ctrlPt2, Point2D point2) {

         path.moveTo(point1.getX() , point1.getY());   

         path.curveTo(ctrlPt1.getX() , ctrlPt1.getY() , ctrlPt2.getX() , ctrlPt2.getY() , point2.getX() , point2.getY());
    }

A contour is constructed from this path using java.awt.geom.Area  . The different contours of a particular glyph are eXlusive ORed before they are filled to provide an exact replica of the font glyph:

            if (contourArea == null) {
                contourArea = new Area(glyfPath);
            } else {
                contourArea.exclusiveOr(new Area(glyfPath));

            }

The algorithm for drawing the glyph must be able to clearly distinguish the lines, quadratic and cubic Bezier curves and draw them accordingly. 


About

nitkal

Search

Categories
Archives
« July 2014
SunMonTueWedThuFriSat
  
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
  
       
Today
Bookmarks