diff options
Diffstat (limited to 'libjava/classpath/gnu/java/awt/font/autofit/GlyphHints.java')
-rw-r--r-- | libjava/classpath/gnu/java/awt/font/autofit/GlyphHints.java | 640 |
1 files changed, 0 insertions, 640 deletions
diff --git a/libjava/classpath/gnu/java/awt/font/autofit/GlyphHints.java b/libjava/classpath/gnu/java/awt/font/autofit/GlyphHints.java deleted file mode 100644 index 033d63fa456..00000000000 --- a/libjava/classpath/gnu/java/awt/font/autofit/GlyphHints.java +++ /dev/null @@ -1,640 +0,0 @@ -/* GlyphHints.java -- Data and methods for actual hinting - Copyright (C) 2006 Free Software Foundation, Inc. - -This file is part of GNU Classpath. - -GNU Classpath is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2, or (at your option) -any later version. - -GNU Classpath is distributed in the hope that it will be useful, but -WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -General Public License for more details. - -You should have received a copy of the GNU General Public License -along with GNU Classpath; see the file COPYING. If not, write to the -Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA -02110-1301 USA. - -Linking this library statically or dynamically with other modules is -making a combined work based on this library. Thus, the terms and -conditions of the GNU General Public License cover the whole -combination. - -As a special exception, the copyright holders of this library give you -permission to link this library with independent modules to produce an -executable, regardless of the license terms of these independent -modules, and to copy and distribute the resulting executable under -terms of your choice, provided that you also meet, for each linked -independent module, the terms and conditions of the license of that -module. An independent module is a module which is not derived from -or based on this library. If you modify this library, you may extend -this exception to your version of the library, but you are not -obligated to do so. If you do not wish to do so, delete this -exception statement from your version. */ - - -package gnu.java.awt.font.autofit; - -import gnu.java.awt.font.FontDelegate; -import gnu.java.awt.font.opentype.truetype.Fixed; -import gnu.java.awt.font.opentype.truetype.Point; -import gnu.java.awt.font.opentype.truetype.Zone; - -/** - * The data and methods used for the actual hinting process. - */ -class GlyphHints - implements Constants -{ - - int xScale; - int xDelta; - int yScale; - int yDelta; - - AxisHints[] axis; - - Point[] points; - int numPoints; - int maxPoints; - - Point[] contours; - int numContours; - int maxContours; - - ScriptMetrics metrics; - - int flags; - - GlyphHints() - { - axis = new AxisHints[Constants.DIMENSION_MAX]; - axis[Constants.DIMENSION_VERT] = new AxisHints(); - axis[Constants.DIMENSION_HORZ] = new AxisHints(); - - xScale = Fixed.ONE; - yScale = Fixed.ONE; - } - - void rescale(ScriptMetrics m) - { - metrics = m; - // TODO: Copy scalerFlags. - } - - void reload(Zone outline) - { - numPoints = 0; - numContours = 0; - axis[0].numSegments = 0; - axis[0].numEdges = 0; - axis[1].numSegments = 0; - axis[1].numEdges = 0; - - // Create/reallocate the contours array. - int newMax = outline.getNumContours(); - if (newMax > maxContours || contours == null) - { - newMax = (newMax + 3) & ~3; // Taken from afhints.c . - Point[] newContours = new Point[newMax]; - if (contours != null) - { - System.arraycopy(contours, 0, newContours, 0, maxContours); - } - contours = newContours; - maxContours = newMax; - } - - // Create/reallocate the points array. - newMax = outline.getSize() + 2; - if (newMax > maxPoints || points == null) - { - newMax = (newMax + 2 + 7) & ~7; // Taken from afhints.c . - Point[] newPoints = new Point[newMax]; - if (points != null) - { - System.arraycopy(points, 0, newPoints, 0, maxPoints); - } - points = newPoints; - maxPoints = newMax; - } - - numPoints = outline.getSize() - 4; // 4 phantom points. - numContours = outline.getNumContours(); - - // Set major direction. We don't handle Type 1 fonts yet. - axis[DIMENSION_HORZ].majorDir = DIR_UP; - axis[DIMENSION_VERT].majorDir = DIR_LEFT; - - // TODO: Freetype seems to scale and translate the glyph at that point. - // I suppose that this is not really needed. - // The scales are scaling from font units to 1/64 device pixels. - xScale = Fixed.valueOf16(outline.scaleX * 64); - yScale = Fixed.valueOf16(outline.scaleY * 64); - - // FIXME: What is that xDelta and yDelta used for? - System.arraycopy(outline.getPoints(), 0, points, 0, numPoints); - - // Setup prev and next and contours array. - // TODO: Probably cache this. - contours = new Point[numContours]; - Point currentContour = points[0]; - for (int i = 0, cIndex = 0; i < numPoints; i++) - { - // Start new contour when the last point has been a contour end. - if (outline.isContourEnd(i)) - { - // Connect the contour end point to the start point. - points[i].setNext(currentContour); - currentContour.setPrev(points[i]); - contours[cIndex] = currentContour; - cIndex++; - currentContour = i < numPoints - 1 ? points[i + 1] : null; - } - else - { - // Connect the current and the previous point. - points[i].setNext(points[i + 1]); - points[i + 1].setPrev(points[i]); - } - } - // Compute directions of in and out vectors of all points as well - // as the weak point flag. - for (int i = 0; i < numPoints; i++) - { - // Compute in and out dir. - Point p = points[i]; - Point prev = p.getPrev(); - int inX = p.getOrigX() - prev.getOrigX(); - int inY = p.getOrigY() - prev.getOrigY(); - p.setInDir(Utils.computeDirection(inX, inY)); - Point next = p.getNext(); - int outX = next.getOrigX() - p.getOrigX(); - int outY = next.getOrigY() - p.getOrigY(); - p.setOutDir(Utils.computeDirection(outX, outY)); - - if (p.isControlPoint()) - { - setWeakPoint(p); - } - else if (p.getOutDir() == p.getInDir()) - { - if (p.getOutDir() != DIR_NONE) - setWeakPoint(p); - else - { - int angleIn = Utils.atan(inY, inX); - int angleOut = Utils.atan(outY, outX); - int delta = Utils.angleDiff(angleIn, angleOut); - if (delta < 2 && delta > -2) - setWeakPoint(p); - } - } - else if (p.getInDir() == - p.getOutDir()) - { - setWeakPoint(p); - } - } - computeInflectionPoints(); - } - - private void setWeakPoint(Point p) - { - p.setFlags((byte) (p.getFlags() | Point.FLAG_WEAK_INTERPOLATION)); - } - - /** - * Computes the inflection points for a glyph. - */ - private void computeInflectionPoints() - { - // Do each contour separately. - contours : for (int c = 0; c < contours.length; c++) - { - Point point = contours[c]; - Point first = point; - Point start = point; - Point end = point; - do - { - end = end.getNext(); - if (end == first) - continue contours; - } while (end.getOrigX() == first.getOrigX() - && end.getOrigY() == first.getOrigY()); - - // Extend segment start whenever possible. - Point before = start; - int angleIn; - int angleSeg = Utils.atan(end.getOrigX() - start.getOrigX(), - end.getOrigY() - start.getOrigY()); - do - { - do - { - start = before; - before = before.getPrev(); - if (before == first) - continue contours; - } while (before.getOrigX() == start.getOrigX() - && before.getOrigY() == start.getOrigY()); - angleIn = Utils.atan(start.getOrigX() - before.getOrigX(), - start.getOrigY() - before.getOrigY()); - } while (angleIn == angleSeg); - - first = start; - int diffIn = Utils.angleDiff(angleIn, angleSeg); - // Now, process all segments in the contour. - Point after; - boolean finished = false; - int angleOut, diffOut; - do - { - // First, extend the current segment's end whenever possible. - after = end; - do - { - do - { - end = after; - after = after.getNext(); - if (after == first) - finished = true; - } while (end.getOrigX() == after.getOrigX() - && end.getOrigY() == after.getOrigY()); - angleOut = Utils.atan(after.getOrigX() - end.getOrigX(), - after.getOrigY() - end.getOrigY()); - } while (angleOut == angleSeg); - diffOut = Utils.angleDiff(angleSeg, angleOut); - if ((diffIn ^ diffOut) < 0) - { - // diffIn and diffOut have different signs, we have - // inflection points here. - do - { - start.addFlags(Point.FLAG_INFLECTION); - start = start.getNext(); - } while (start != end); - start.addFlags(Point.FLAG_INFLECTION); - } - start = end; - end = after; - angleSeg = angleOut; - diffIn = diffOut; - } while (! finished); - } - } - - boolean doHorizontal() - { - return (flags & FontDelegate.FLAG_NO_HINT_HORIZONTAL) == 0; - } - - boolean doVertical() - { - return (flags & FontDelegate.FLAG_NO_HINT_VERTICAL) == 0; - } - - void alignWeakPoints(int dim) - { - short touchFlag; - Point point; - // PASS 1 : Move segments to edge positions. - if (dim == DIMENSION_HORZ) - { - touchFlag = Point.FLAG_DONE_X; - for (int p = 0; p < numPoints; p++) - { - point = points[p]; - point.setU(point.getX()); - point.setV(point.getScaledX()); - } - } - else - { - touchFlag = Point.FLAG_DONE_Y; - for (int p = 0; p < numPoints; p++) - { - point = points[p]; - point.setU(point.getY()); - point.setV(point.getScaledY()); - } - } - point = points[0]; - for (int c = 0; c < numContours; c++) - { - point = contours[c]; - int idx = getPointIndex(point); - Point endPoint = point.getPrev(); - int endIdx = getPointIndex(endPoint); - int firstIdx = idx; - while (idx <= endIdx - && (point.getFlags() & touchFlag) == 0) - { - idx++; - point = points[idx]; - } - if (idx <= endIdx) - { - int firstTouched = idx; - int curTouched = idx; - idx++; - point = points[idx]; - while (idx <= endIdx) - { - if ((point.getFlags() & touchFlag) != 0) - { - // We found two successive touch points. We interpolate - // all contour points between them. - iupInterp(curTouched + 1, idx - 1, curTouched, idx); - curTouched = idx; - } - idx++; - point = points[idx]; - } - if (curTouched == firstTouched) - { - // This is a special case: Only one point was touched in the - // contour. We thus simply shift the whole contour. - iupShift(firstIdx, endIdx, curTouched); - } - else - { - // Now interpolate after the last touched point to the end - // of the contour. - iupInterp(curTouched + 1, endIdx, curTouched, firstTouched); - // If the first contour point isn't touched, interpolate - // from the contour start to the first touched point. - if (firstTouched > 0) - { - iupInterp(firstIdx, firstTouched - 1, curTouched, - firstTouched); - } - } - } - } - // Now store the values back. - if (dim == DIMENSION_HORZ) - { - for (int p = 0; p < numPoints; p++) - { - point = points[p]; - point.setX(point.getU()); - } - } - else - { - for (int p = 0; p < numPoints; p++) - { - point = points[p]; - point.setY(point.getU()); - } - } - } - - private void iupShift(int p1, int p2, int ref) - { - int delta = points[ref].getU() - points[ref].getV(); - for (int p = p1; p < ref; p++) - { - points[p].setU(points[p].getV() + delta); - } - for (int p = ref + 1; p <= p2; p++) - { - points[p].setU(points[p].getV() + delta); - } - } - - private void iupInterp(int p1, int p2, int ref1, int ref2) - { - int v1 = points[ref1].getV(); - int v2 = points[ref2].getV(); - int d1 = points[ref1].getU() - v1; - int d2 = points[ref2].getU() - v2; - if (p1 > p2) - return; - if (v1 == v2) - { - for (int p = p1; p <= p2; p++) - { - int u = points[p].getV(); - if (u <= v1) - u += d1; - else - u += d2; - points[p].setU(u); - } - } - else if (v1 < v2) - { - for (int p = p1; p <= p2; p++) - { - int u = points[p].getV(); - if (u <= v1) - u += d1; - else if (u >= v2) - u += d2; - else - { - u = points[ref1].getU() + Utils.mulDiv(u - v1, - points[ref2].getU() - - points[ref1].getU(), - v2 - v1); - } - points[p].setU(u); - } - } - else - { - for (int p = p1; p <= p2; p++) - { - int u = points[p].getV(); - if (u <= v2) - u += d2; - else if (u >= v1) - u += d1; - else - { - u = points[ref1].getU() + Utils.mulDiv(u - v1, - points[ref2].getU() - - points[ref1].getU(), - v2 - v1); - } - points[p].setU(u); - } - } - } - - void alignStrongPoints(int dim) - { - AxisHints ax = axis[dim]; - Edge[] edges = ax.edges; - int numEdges = ax.numEdges; - short touchFlag; - if (dim == DIMENSION_HORZ) - touchFlag = Point.FLAG_DONE_X; - else - touchFlag = Point.FLAG_DONE_Y; - - if (numEdges > 0) - { - for (int p = 0; p < numPoints; p++) - { - Point point = points[p]; - if ((point.getFlags() & touchFlag) != 0) - continue; - // If this point is a candidate for weak interpolation, we - // interpolate it after all strong points have been processed. - if ((point.getFlags() & Point.FLAG_WEAK_INTERPOLATION) != 0 - && (point.getFlags() & Point.FLAG_INFLECTION) == 0) - continue; - - int u, ou, fu, delta; - if (dim == DIMENSION_VERT) - { - u = point.getOrigY(); - ou = point.getScaledY(); - } - else - { - u = point.getOrigX(); - ou = point.getScaledX(); - } - fu = u; - // Is the point before the first edge? - Edge edge = edges[0]; - // Inversed vertical dimension. - delta = edge.fpos - u; - if (delta >= 0) - { - u = edge.pos - (edge.opos - ou); - storePoint(point, u, dim, touchFlag); - } - else - { - // Is the point after the last edge? - edge = edges[numEdges - 1]; - delta = u - edge.fpos; - if (delta >= 0) - { - u = edge.pos + (ou - edge.opos); - storePoint(point, u, dim, touchFlag); - } - else - { - // Find enclosing edges. - int min = 0; - int max = numEdges; - int mid, fpos; - boolean found = false; - while (min < max) - { - mid = (max + min) / 2; - edge = edges[mid]; - fpos = edge.fpos; - if (u < fpos) - max = mid; - else if (u > fpos) - min = mid + 1; - else - { - // Directly on the edge. - u = edge.pos; - storePoint(point, u, dim, touchFlag); - found = true; - break; - } - } - if (! found) - { - Edge before = edges[min - 1]; - Edge after = edges[min]; - if (before.scale == 0) - { - before.scale = Fixed.div16(after.pos - before.pos, - after.fpos - before.fpos); - } - u = before.pos + Fixed.mul16(fu - before.fpos, - before.scale); - } - storePoint(point, u, dim, touchFlag); - } - } - } - } - } - - private void storePoint(Point p, int u, int dim, short touchFlag) - { - if (dim == DIMENSION_HORZ) - p.setX(u); - else - p.setY(u); - p.addFlags(touchFlag); - } - - void alignEdgePoints(int dim) - { - AxisHints ax = axis[dim]; - Edge[] edges = ax.edges; - int numEdges = ax.numEdges; - for (int e = 0; e < numEdges; e++) - { - Edge edge = edges[e]; - Segment seg = edge.first; - do - { - Point point = seg.first; - while (true) - { - if (dim == DIMENSION_HORZ) - { - point.setX(edge.pos); - point.addFlags(Point.FLAG_DONE_X); - } - else - { - point.setY(edge.pos); - point.addFlags(Point.FLAG_DONE_Y); - } - if (point == seg.last) - break; - point = point.getNext(); - } - seg = seg.edgeNext; - } while (seg != edge.first); - } - } - - private int getPointIndex(Point p) - { - int idx = -1; - for (int i = 0; i < numPoints; i++) - { - if (p == points[i]) - { - idx = i; - break; - } - } - return idx; - } - - public boolean doAlignEdgePoints() - { - return (flags & FontDelegate.FLAG_NO_HINT_EDGE_POINTS) == 0; - } - - public boolean doAlignStrongPoints() - { - return (flags & FontDelegate.FLAG_NO_HINT_STRONG_POINTS) == 0; - } - - public boolean doAlignWeakPoints() - { - return (flags & FontDelegate.FLAG_NO_HINT_WEAK_POINTS) == 0; - } -} |