View Javadoc

1   // Copyright 2001 freehep
2   package org.freehep.graphicsio.font;
3   
4   import java.awt.Shape;
5   import java.io.IOException;
6   import java.io.OutputStream;
7   
8   import org.freehep.graphicsio.QuadToCubicPathConstructor;
9   
10  /**
11   * Encoder to encode "CharStrings" used in PostScript and Type 1 Fonts.
12   * 
13   * @author Simon Fischer
14   * @version $Id: CharstringEncoder.java 8584 2006-08-10 23:06:37Z duns $
15   */
16  public class CharstringEncoder extends QuadToCubicPathConstructor {
17  
18      private static final int LAST_POINT = 0;
19  
20      private static final int HORIZONTAL = 1;
21  
22      private static final int VERTICAL = 2;
23  
24      private static final int BOTH = 3;
25  
26      private OutputStream out;
27  
28      private int currentX, currentY;
29  
30      public CharstringEncoder(OutputStream out) {
31          this.out = out;
32          currentX = currentY = 0;
33      }
34  
35      private int writeNumber(double v) throws IOException {
36          int round = (int) Math.round(v);
37          writeNumber(round);
38          return round;
39      }
40  
41      private void writeNumber(int v) throws IOException {
42          if ((v >= -107) && (v <= 107)) {
43              out.write(v + 139);
44          } else if ((v >= 108) && (v <= 1131)) {
45              int highByte = (v - 108) / 256;
46              out.write(highByte + 247);
47              out.write(v - 108 - 256 * highByte);
48          } else if ((v >= -1131) && (v <= -108)) {
49              int highByte = (v + 108) / 256;
50              out.write(-highByte + 251);
51              out.write(-(v + 108 - 256 * highByte));
52          } else {
53              out.write(255);
54              // copied from DataOutputStream correct? '>>>'?
55              out.write((v >>> 24) & 0xFF);
56              out.write((v >>> 16) & 0xFF);
57              out.write((v >>> 8) & 0xFF);
58              out.write((v >>> 0) & 0xFF);
59          }
60      }
61  
62      protected void writeCommand(int com) throws IOException {
63          if (com >= 31)
64              throw new IOException("Charstring command out of range: " + com);
65          out.write(com);
66      }
67  
68      protected void writeExtCommand(int com) throws IOException {
69          out.write(12);
70          out.write(com);
71      }
72  
73      // -------------------- PATH CONSTRUCTION --------------------
74  
75      private void writePoint(double x, double y) throws IOException {
76          currentX += writeNumber(x - currentX);
77          currentY += writeNumber(y - currentY);
78      }
79  
80      private void writeX(double x) throws IOException {
81          currentX += writeNumber(x - currentX);
82      }
83  
84      private void writeY(double y) throws IOException {
85          currentY += writeNumber(y - currentY);
86      }
87  
88      // -------------------- start/end --------------------
89  
90      public void startChar(double sidebearing, double width) throws IOException {
91          currentX = writeNumber(sidebearing);
92          writeNumber(width);
93          writeCommand(13);
94      }
95  
96      public void endchar() throws IOException {
97          writeCommand(14);
98      }
99  
100     // -------------------- path construction --------------------
101 
102     private int to(double x, double y) throws IOException {
103         // writePoint(x, y);
104         // return BOTH;
105 
106         int rx = (int) Math.round(x);
107         int ry = (int) Math.round(y);
108 
109         if (rx == currentX) {
110             if (ry == currentY) {
111                 return LAST_POINT;
112             } else {
113                 writeY(y);
114                 return VERTICAL;
115             }
116         } else if (ry == currentY) {
117             writeX(x);
118             return HORIZONTAL;
119         } else {
120             writePoint(x, y);
121             return BOTH;
122         }
123     }
124 
125     public void move(double x, double y) throws IOException {
126         switch (to(x, y)) {
127         case BOTH:
128             writeCommand(21);
129             break;
130         case HORIZONTAL:
131             writeCommand(22);
132             break;
133         case VERTICAL:
134             writeCommand(4);
135             break;
136         case LAST_POINT:
137             break;
138         }
139         super.move(x, y);
140     }
141 
142     public void line(double x, double y) throws IOException {
143         switch (to(x, y)) {
144         case BOTH:
145             writeCommand(5);
146             break;
147         case HORIZONTAL:
148             writeCommand(6);
149             break;
150         case VERTICAL:
151             writeCommand(7);
152             break;
153         case LAST_POINT:
154             break;
155         }
156         super.line(x, y);
157     }
158 
159     public void cubic(double x1, double y1, double x2, double y2, double x3,
160             double y3) throws IOException {
161         writePoint(x1, y1);
162         writePoint(x2, y2);
163         writePoint(x3, y3);
164         writeCommand(8);
165         super.cubic(x1, y1, x2, y2, x3, y3);
166     }
167 
168     public void closePath(double x0, double y0) throws IOException {
169         writeCommand(9);
170         super.closePath(x0, y0);
171     }
172 
173     public void drawPath(Shape s) throws IOException {
174         addPath(s);
175     }
176 
177 }