summaryrefslogtreecommitdiff
path: root/libjava/classpath/gnu/java/awt/font/autofit/GlyphHints.java
diff options
context:
space:
mode:
Diffstat (limited to 'libjava/classpath/gnu/java/awt/font/autofit/GlyphHints.java')
-rw-r--r--libjava/classpath/gnu/java/awt/font/autofit/GlyphHints.java640
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;
- }
-}