1 /* Zone.java -- A collection of points with some additional information.
2    Copyright (C) 2006 Free Software Foundation, Inc.
3 
4 This file is part of GNU Classpath.
5 
6 GNU Classpath is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2, or (at your option)
9 any later version.
10 
11 GNU Classpath is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 General Public License for more details.
15 
16 You should have received a copy of the GNU General Public License
17 along with GNU Classpath; see the file COPYING.  If not, write to the
18 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
19 02110-1301 USA.
20 
21 Linking this library statically or dynamically with other modules is
22 making a combined work based on this library.  Thus, the terms and
23 conditions of the GNU General Public License cover the whole
24 combination.
25 
26 As a special exception, the copyright holders of this library give you
27 permission to link this library with independent modules to produce an
28 executable, regardless of the license terms of these independent
29 modules, and to copy and distribute the resulting executable under
30 terms of your choice, provided that you also meet, for each linked
31 independent module, the terms and conditions of the license of that
32 module.  An independent module is a module which is not derived from
33 or based on this library.  If you modify this library, you may extend
34 this exception to your version of the library, but you are not
35 obligated to do so.  If you do not wish to do so, delete this
36 exception statement from your version. */
37 
38 package gnu.java.awt.font.opentype.truetype;
39 
40 import gnu.java.awt.font.FontDelegate;
41 
42 import java.awt.geom.AffineTransform;
43 import java.awt.geom.GeneralPath;
44 import java.awt.geom.PathIterator;
45 
46 
47 /**
48  * A collection of points with some additional information.
49  */
50 public final class Zone
51 {
52   private Point[] points;
53   private int numPoints;
54 
55   public double scaleX, scaleY, shearX, shearY;
56 
Zone(int maxNumPoints)57   public Zone(int maxNumPoints)
58   {
59     points = new Point[maxNumPoints];
60   }
61 
getCapacity()62   public int getCapacity()
63   {
64     return points.length;
65   }
66 
67 
getSize()68   public int getSize()
69   {
70     return numPoints;
71   }
72 
73 
getX(int point)74   public int getX(int point)
75   {
76     return getX(point, FontDelegate.FLAG_FITTED);
77   }
78 
getX(int point, int flags)79   public int getX(int point, int flags)
80   {
81     int x;
82     if ((flags & FontDelegate.FLAG_FITTED) != 0)
83       x = points[point].x;
84     else
85       x = points[point].scaledX;
86     return x;
87   }
88 
89 
setX(int point, int value, boolean touch)90   public void setX(int point, int value, boolean touch)
91   {
92     points[point].scaledX = value;
93     points[point].x = value;
94     if (touch)
95       points[point].flags |= Point.FLAG_TOUCHED_X;
96   }
97 
98 
setY(int point, int value, boolean touch)99   public void setY(int point, int value, boolean touch)
100   {
101     points[point].scaledY = value;
102     points[point].y = value;
103     if (touch)
104       points[point].flags |= Point.FLAG_TOUCHED_Y;
105   }
106 
getY(int point)107   public int getY(int point)
108   {
109     return getY(point, FontDelegate.FLAG_FITTED);
110   }
111 
getY(int point, int flags)112   public int getY(int point, int flags)
113   {
114     int y;
115     if ((flags & FontDelegate.FLAG_FITTED) != 0)
116       y = points[point].y;
117     else
118       y = points[point].scaledY;
119     return y;
120   }
121 
122 
getOriginalX(int point)123   public int getOriginalX(int point)
124   {
125     return points[point].origX;
126   }
127 
128 
getOriginalY(int point)129   public int getOriginalY(int point)
130   {
131     return points[point].origY;
132   }
133 
134 
setOriginalX(int point, int x)135   public void setOriginalX(int point, int x)
136   {
137     points[point].origX = x;
138   }
139 
setOriginalY(int point, int y)140   public void setOriginalY(int point, int y)
141   {
142     points[point].origY = y;
143   }
144 
setNumPoints(int numPoints)145   public void setNumPoints(int numPoints)
146   {
147     for (int i = 0; i < numPoints; i++)
148       points[i] = new Point();
149     this.numPoints = numPoints;
150   }
151 
152 
isOnCurve(int point)153   public boolean isOnCurve(int point)
154   {
155     return (points[point].flags & Point.FLAG_ON_CURVE) != 0;
156   }
157 
158 
setOnCurve(int point, boolean onCurve)159   public void setOnCurve(int point, boolean onCurve)
160   {
161     if (onCurve)
162       points[point].flags |= Point.FLAG_ON_CURVE;
163     else
164       points[point].flags &= ~Point.FLAG_ON_CURVE;
165   }
166 
167 
isContourEnd(int point)168   public boolean isContourEnd(int point)
169   {
170     return (points[point].flags & Point.FLAG_CONTOUR_END) != 0;
171   }
172 
173 
setContourEnd(int point, boolean segEnd)174   public void setContourEnd(int point, boolean segEnd)
175   {
176     if (segEnd)
177       points[point].flags |= Point.FLAG_CONTOUR_END;
178     else
179       points[point].flags &= ~Point.FLAG_CONTOUR_END;
180   }
181 
182 
183 
184 
transform(double pointSize, AffineTransform deviceTransform, int unitsPerEm, int preTranslateX, int preTranslateY)185   void transform(double pointSize, AffineTransform deviceTransform,
186                  int unitsPerEm, int preTranslateX, int preTranslateY)
187   {
188     double factor;
189 
190     factor = pointSize / (double) unitsPerEm;
191     scaleX = deviceTransform.getScaleX() * factor;
192     scaleY = deviceTransform.getScaleY() * factor;
193     shearX = deviceTransform.getShearX() * factor;
194     shearY = deviceTransform.getShearY() * factor;
195 
196     for (int i = 0; i < numPoints; i++)
197     {
198       int x = points[i].origX + preTranslateX;
199       int y = points[i].origY + preTranslateY;
200 
201       points[i].scaledX = points[i].x = Fixed.valueOf(scaleX * x
202                                                       + shearX * y);
203       points[i].scaledY = points[i].y = Fixed.valueOf(shearY * x
204                                                       + scaleY * y);
205     }
206   }
207 
208 
209 
combineWithSubGlyph(Zone zone, int numPhantomPoints)210   void combineWithSubGlyph(Zone zone, int numPhantomPoints)
211   {
212     int offset = this.numPoints - numPhantomPoints;
213     int count = zone.numPoints;
214     System.arraycopy(zone.points, 0, this.points, offset, count);
215     this.numPoints += count - numPhantomPoints;
216   }
217 
218 
dump()219   private void dump()
220   {
221     for (int i = 0; i < numPoints; i++)
222     {
223       System.out.print(" " + i + ": ");
224       System.out.print(Fixed.toString(points[i].scaledX, points[i].scaledY));
225       System.out.print(' ');
226       System.out.print(Fixed.toString(points[i].origX, points[i].origY));
227       System.out.print(' ');
228       if (isOnCurve(i))
229         System.out.print('.');
230       else
231         System.out.print('c');
232       if (isContourEnd(i))
233         System.out.print('E');
234       System.out.println();
235       if (isContourEnd(i))
236         System.out.println();
237     }
238   }
239 
240 
getPathIterator(int type)241   public PathIterator getPathIterator(int type)
242   {
243     return new ZonePathIterator(this, type);
244   }
245 
246 
getPath(int type)247   public GeneralPath getPath(int type)
248   {
249     GeneralPath p = new GeneralPath(GeneralPath.WIND_NON_ZERO, numPoints);
250     p.append(getPathIterator(type), /* connect */ false);
251     return p;
252   }
253 
254   /**
255    * Returns the number of contours in this outline.
256    *
257    * @return the number of contours in this outline
258    */
getNumContours()259   public int getNumContours()
260   {
261     int num = 0;
262     for (int i = 0; i < numPoints; i++)
263       {
264         if (isContourEnd(i))
265           num++;
266       }
267     return num;
268   }
269 
getContourEnd(int n)270   public int getContourEnd(int n)
271   {
272     int idx = -1;
273     int num = 0;
274     for (int i = 0; i < numPoints; i++)
275       {
276         if (isContourEnd(i))
277           {
278             idx = i;
279             if (num == n)
280               break;
281             num++;
282           }
283       }
284     return idx;
285   }
286 
getPoints()287   public Point[] getPoints()
288   {
289     return points;
290   }
291 }
292