1
2 package org.freehep.graphicsio.font;
3
4 import java.awt.Font;
5 import java.awt.Shape;
6 import java.awt.font.FontRenderContext;
7 import java.awt.font.GlyphMetrics;
8 import java.awt.font.GlyphVector;
9 import java.awt.geom.GeneralPath;
10 import java.awt.geom.Rectangle2D;
11 import java.io.IOException;
12
13 import org.freehep.graphics2d.font.CharTable;
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38 public abstract class FontEmbedder extends FontIncluder {
39
40 public static final String NOTDEF = ".notdef";
41
42
43
44
45
46
47
48
49
50
51
52 protected abstract void writeGlyph(String unicodeName, Shape glyph,
53 GlyphMetrics glyphMetrics) throws IOException;
54
55
56 protected abstract void writeWidths(double[] widths) throws IOException;
57
58
59
60
61
62 protected void openGlyphs() throws IOException {
63 }
64
65
66
67
68
69 protected void closeGlyphs() throws IOException {
70 }
71
72 protected abstract void closeEmbedFont() throws IOException;
73
74 private double[] widths;
75
76 private GlyphVector glyphs;
77
78 private Font font;
79
80 public FontEmbedder(FontRenderContext context) {
81 super(context);
82 }
83
84 protected double[] getAdvanceWidths() {
85 if (widths == null) {
86
87 widths = new double[256];
88 for (int i = 0; i < widths.length; i++) {
89 widths[i] = glyphs.getGlyphMetrics(i).getAdvance();
90
91
92 if (getCharName(i) == null) {
93 widths[i] = getUndefinedWidth();
94 }
95 }
96 }
97 return widths;
98 }
99
100 protected double getAdvanceWidth(int character) {
101 return getAdvanceWidths()[character];
102 }
103
104 protected Shape getGlyph(int i) {
105
106
107
108
109
110
111
112
113 FontRenderContext orig = getContext();
114 FontRenderContext frc = new FontRenderContext(null, orig
115 .isAntiAliased(), orig.usesFractionalMetrics());
116 Shape shape = font.createGlyphVector(frc, new char[] { getUnicode(i) })
117 .getGlyphOutline(0);
118 return orig.getTransform().createTransformedShape(shape);
119 }
120
121 protected GlyphMetrics getGlyphMetrics(int i) {
122 return glyphs.getGlyphMetrics(i);
123 }
124
125 public void includeFont(Font font, CharTable charTable, String name)
126 throws IOException {
127
128 glyphs = null;
129 widths = null;
130
131 this.font = font;
132
133 super.includeFont(font, charTable, name);
134
135 this.glyphs = font.createGlyphVector(getContext(), getUnicode());
136
137 writeWidths(getAdvanceWidths());
138
139 try {
140
141 openGlyphs();
142
143
144 for (int i = 0; i < 256; i++) {
145 if (getCharName(i) != null) {
146 writeGlyph(getCharName(i), getGlyph(i), getGlyphMetrics(i));
147 }
148 }
149 writeGlyph(NOTDEF, createUndefined(), null);
150
151 closeGlyphs();
152 closeEmbedFont();
153
154 } catch (Exception e) {
155 e.printStackTrace();
156 }
157 }
158
159 private Shape createUndefined() {
160 GeneralPath ud = new GeneralPath(GeneralPath.WIND_EVEN_ODD, 10);
161 ud.append(new Rectangle2D.Double(0, 0, FONT_SIZE, FONT_SIZE), false);
162 ud.append(new Rectangle2D.Double(FONT_SIZE / 20, FONT_SIZE / 20,
163 18 * FONT_SIZE / 20, 18 * FONT_SIZE / 20), false);
164 return ud;
165 }
166 }