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