aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid Schweinsberg <[email protected]>2016-01-11 23:22:27 -0800
committerDavid Schweinsberg <[email protected]>2016-01-11 23:22:27 -0800
commit24a44c399342b6a80770c7fc931b62d9900cd5ef (patch)
treed31625ceba4a26d91840c975e1676b8cf04e6dc5
parentc8a6d636e21ef853577ae7abf4a9097894868d26 (diff)
Capturing hstems and vstems. Reoriented coordinate system for GlyphEdit.
-rw-r--r--src/net/java/dev/typecast/cff/T2Interpreter.java53
-rw-r--r--src/net/java/dev/typecast/edit/GlyphEdit.java73
-rw-r--r--src/net/java/dev/typecast/ot/T2Glyph.java29
-rw-r--r--src/net/java/dev/typecast/render/GlyphPathFactory.java36
4 files changed, 163 insertions, 28 deletions
diff --git a/src/net/java/dev/typecast/cff/T2Interpreter.java b/src/net/java/dev/typecast/cff/T2Interpreter.java
index a8cb5a5..ace1fd6 100644
--- a/src/net/java/dev/typecast/cff/T2Interpreter.java
+++ b/src/net/java/dev/typecast/cff/T2Interpreter.java
@@ -52,6 +52,8 @@ public class T2Interpreter {
private final Number[] _transientArray = new Number[TRANSIENT_ARRAY_ELEMENT_COUNT];
private int _stemCount = 0;
+ private ArrayList<Integer> _hstems;
+ private ArrayList<Integer> _vstems;
private ArrayList<Point> _points;
private Index _localSubrIndex;
@@ -65,6 +67,16 @@ public class T2Interpreter {
public T2Interpreter() {
}
+ public Integer[] getHStems() {
+ Integer[] array = new Integer[_hstems.size()];
+ return _hstems.toArray(array);
+ }
+
+ public Integer[] getVStems() {
+ Integer[] array = new Integer[_vstems.size()];
+ return _vstems.toArray(array);
+ }
+
/**
* Moves the current point to a position at the relative coordinates
* (dx1, dy1).
@@ -637,23 +649,53 @@ public class T2Interpreter {
}
private void _hstem() {
+ if (getArgCount() % 2 == 1) {
+
+ // This will be the width value
+ popArg();
+ }
- clearArg();
+ while (getArgCount() > 0) {
+ _hstems.add(popArg().intValue());
+ }
}
private void _vstem() {
+ if (getArgCount() % 2 == 1) {
+
+ // This will be the width value
+ popArg();
+ }
- clearArg();
+ while (getArgCount() > 0) {
+ _vstems.add(popArg().intValue());
+ }
}
private void _hstemhm() {
+ if (getArgCount() % 2 == 1) {
+
+ // This will be the width value
+ popArg();
+ }
+
_stemCount += getArgCount() / 2;
- clearArg();
+ while (getArgCount() > 0) {
+ _hstems.add(popArg().intValue());
+ }
}
private void _vstemhm() {
+ if (getArgCount() % 2 == 1) {
+
+ // This will be the width value
+ popArg();
+ }
+
_stemCount += getArgCount() / 2;
- clearArg();
+ while (getArgCount() > 0) {
+ _vstems.add(popArg().intValue());
+ }
}
private void _hintmask() {
@@ -950,6 +992,9 @@ public class T2Interpreter {
_globalSubrIndex.getDataLength());
_cs = cs;
+ _hstems = new ArrayList<>();
+ _vstems = new ArrayList<>();
+
_points = new ArrayList<>();
_ip = _cs.getFirstIndex();
while (_cs.moreBytes(_ip)) {
diff --git a/src/net/java/dev/typecast/edit/GlyphEdit.java b/src/net/java/dev/typecast/edit/GlyphEdit.java
index 66f76c9..c10ab28 100644
--- a/src/net/java/dev/typecast/edit/GlyphEdit.java
+++ b/src/net/java/dev/typecast/edit/GlyphEdit.java
@@ -35,6 +35,7 @@ import javax.swing.event.MouseInputListener;
import net.java.dev.typecast.ot.Glyph;
import net.java.dev.typecast.ot.OTFont;
import net.java.dev.typecast.ot.Point;
+import net.java.dev.typecast.ot.T2Glyph;
import net.java.dev.typecast.render.GlyphPathFactory;
/**
@@ -68,10 +69,14 @@ public class GlyphEdit extends JPanel implements Scrollable {
_tool = new PointTool(this);
MouseInputListener mil = new MouseInputListener() {
+ @Override
public void mouseClicked(MouseEvent e) {
}
+ @Override
public void mouseEntered(MouseEvent e) { }
+ @Override
public void mouseExited(MouseEvent e) { }
+ @Override
public void mousePressed(MouseEvent e) {
if (_tool != null) {
if (e.isControlDown()) {
@@ -81,22 +86,26 @@ public class GlyphEdit extends JPanel implements Scrollable {
}
}
}
+ @Override
public void mouseReleased(MouseEvent e) {
if (_tool != null) {
_tool.released(e.getPoint());
}
}
+ @Override
public void mouseDragged(MouseEvent e) {
if (_tool != null) {
_tool.dragged(e.getPoint());
}
}
+ @Override
public void mouseMoved(MouseEvent e) { }
};
addMouseListener(mil);
addMouseMotionListener(mil);
}
+ @Override
public void paint(Graphics graphics) {
super.paint(graphics);
@@ -105,7 +114,7 @@ public class GlyphEdit extends JPanel implements Scrollable {
}
Graphics2D g2d = (Graphics2D) graphics;
-
+
int unitsPerEmBy2 = _font.getHeadTable().getUnitsPerEm() / 2;
_translateX = 2 * unitsPerEmBy2;
_translateY = 2 * unitsPerEmBy2;
@@ -114,6 +123,7 @@ public class GlyphEdit extends JPanel implements Scrollable {
AffineTransform atOriginal = new AffineTransform(at);
at.scale(_scaleFactor, _scaleFactor);
at.translate(_translateX, _translateY);
+ at.scale(1.0, -1.0);
g2d.setTransform(at);
// Draw grid
@@ -123,10 +133,64 @@ public class GlyphEdit extends JPanel implements Scrollable {
// Draw guides
g2d.setPaint(Color.lightGray);
- g2d.draw(new Line2D.Float(-unitsPerEmBy2, -_font.getAscent(), unitsPerEmBy2, -_font.getAscent()));
- g2d.draw(new Line2D.Float(-unitsPerEmBy2, -_font.getDescent(), unitsPerEmBy2, -_font.getDescent()));
+ g2d.draw(new Line2D.Float(-unitsPerEmBy2, _font.getAscent(), unitsPerEmBy2, _font.getAscent()));
+ g2d.draw(new Line2D.Float(-unitsPerEmBy2, _font.getDescent(), unitsPerEmBy2, _font.getDescent()));
g2d.draw(new Line2D.Float(_glyph.getLeftSideBearing(), -unitsPerEmBy2, _glyph.getLeftSideBearing(), unitsPerEmBy2));
g2d.draw(new Line2D.Float(_glyph.getAdvanceWidth(), -unitsPerEmBy2, _glyph.getAdvanceWidth(), unitsPerEmBy2));
+
+ if (_glyph instanceof T2Glyph) {
+ T2Glyph t2g = (T2Glyph) _glyph;
+ Rectangle2D bounds = t2g.getBounds();
+
+// g2d.setPaint(Color.PINK);
+// g2d.fill(bounds);
+//
+// g2d.setPaint(Color.RED);
+
+ int y = 0;
+ boolean isWidth = false;
+ for (Integer horiz : t2g.getHStems()) {
+ if (isWidth) {
+ if (horiz == -20) {
+
+ // Top edge
+ y = (int) bounds.getMaxY();
+ } else if (horiz == -21) {
+
+ // Bottom edge
+ y = (int) bounds.getMinY();
+ } else {
+ y += horiz;
+ }
+ } else {
+ y += horiz;
+ }
+// g2d.draw(new Line2D.Float(0, y, 1000, y));
+ isWidth = !isWidth;
+ }
+
+ int x = 0;
+ isWidth = false;
+ for (Integer vert : t2g.getVStems()) {
+ if (isWidth) {
+ if (vert == -20) {
+
+ // Right edge
+ x = (int) bounds.getMaxX();
+ } else if (vert == -21) {
+
+ // Left edge
+ x = (int) bounds.getMinX();
+ } else {
+ x += vert;
+ }
+ } else {
+ x += vert;
+ }
+// g2d.draw(new Line2D.Float(x, 0, x, 1000));
+ isWidth = !isWidth;
+ }
+ }
// Draw contours
g2d.setPaint(Color.black);
@@ -144,7 +208,8 @@ public class GlyphEdit extends JPanel implements Scrollable {
if (_drawControlPoints) {
- g2d.setTransform(atOriginal);
+ AffineTransform at2 = new AffineTransform(atOriginal);
+ g2d.setTransform(at2);
// Draw control points
for (int i = 0; i < _glyph.getPointCount(); i++) {
diff --git a/src/net/java/dev/typecast/ot/T2Glyph.java b/src/net/java/dev/typecast/ot/T2Glyph.java
index be1f573..2b33f3e 100644
--- a/src/net/java/dev/typecast/ot/T2Glyph.java
+++ b/src/net/java/dev/typecast/ot/T2Glyph.java
@@ -1,7 +1,7 @@
/*
* Typecast - The Font Development Environment
*
- * Copyright (c) 2004-2015 David Schweinsberg
+ * Copyright (c) 2004-2016 David Schweinsberg
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -17,6 +17,8 @@
*/
package net.java.dev.typecast.ot;
+import java.awt.Rectangle;
+import java.awt.geom.Rectangle2D;
import net.java.dev.typecast.cff.CharstringType2;
import net.java.dev.typecast.cff.T2Interpreter;
@@ -27,7 +29,9 @@ import net.java.dev.typecast.cff.T2Interpreter;
public class T2Glyph extends Glyph {
protected short _leftSideBearing;
protected int _advanceWidth;
- private Point[] _points;
+ private final Point[] _points;
+ private final Integer[] _hstems;
+ private final Integer[] _vstems;
/**
* Construct a Glyph from a PostScript outline described by a Charstring.
@@ -43,6 +47,8 @@ public class T2Glyph extends Glyph {
_advanceWidth = advance;
T2Interpreter t2i = new T2Interpreter();
_points = t2i.execute(cs);
+ _hstems = t2i.getHStems();
+ _vstems = t2i.getVStems();
}
@Override
@@ -64,4 +70,23 @@ public class T2Glyph extends Glyph {
public int getPointCount() {
return _points.length;
}
+
+ public Integer[] getHStems() {
+ return _hstems;
+ }
+
+ public Integer[] getVStems() {
+ return _vstems;
+ }
+
+ public Rectangle2D getBounds() {
+ Rectangle r = null;
+ for (Point p : _points) {
+ if (r == null) {
+ r = new Rectangle(p.x, p.y, 0, 0);
+ }
+ r.add(new java.awt.Point(p.x, p.y));
+ }
+ return r != null ? r : new Rectangle(0, 0, 0, 0);
+ }
}
diff --git a/src/net/java/dev/typecast/render/GlyphPathFactory.java b/src/net/java/dev/typecast/render/GlyphPathFactory.java
index ff8a1d9..257ba7e 100644
--- a/src/net/java/dev/typecast/render/GlyphPathFactory.java
+++ b/src/net/java/dev/typecast/render/GlyphPathFactory.java
@@ -77,43 +77,43 @@ public class GlyphPathFactory {
Point point_plus1 = glyph.getPoint(startIndex + (offset+1)%count);
Point point_plus2 = glyph.getPoint(startIndex + (offset+2)%count);
if (point.onCurve && point_plus1.onCurve) {
- s = new Line2D.Float(point.x, -point.y, point_plus1.x, -point_plus1.y);
+ s = new Line2D.Float(point.x, point.y, point_plus1.x, point_plus1.y);
offset++;
} else if (point.onCurve && !point_plus1.onCurve && point_plus2.onCurve) {
s = new QuadCurve2D.Float(
point.x,
- -point.y,
+ point.y,
point_plus1.x,
- -point_plus1.y,
+ point_plus1.y,
point_plus2.x,
- -point_plus2.y);
+ point_plus2.y);
offset+=2;
} else if (point.onCurve && !point_plus1.onCurve && !point_plus2.onCurve) {
s = new QuadCurve2D.Float(
point.x,
- -point.y,
+ point.y,
point_plus1.x,
- -point_plus1.y,
+ point_plus1.y,
midValue(point_plus1.x, point_plus2.x),
- -midValue(point_plus1.y, point_plus2.y));
+ midValue(point_plus1.y, point_plus2.y));
offset+=2;
} else if (!point.onCurve && !point_plus1.onCurve) {
s = new QuadCurve2D.Float(
midValue(point_minus1.x, point.x),
- -midValue(point_minus1.y, point.y),
+ midValue(point_minus1.y, point.y),
point.x,
- -point.y,
+ point.y,
midValue(point.x, point_plus1.x),
- -midValue(point.y, point_plus1.y));
+ midValue(point.y, point_plus1.y));
offset++;
} else if (!point.onCurve && point_plus1.onCurve) {
s = new QuadCurve2D.Float(
midValue(point_minus1.x, point.x),
- -midValue(point_minus1.y, point.y),
+ midValue(point_minus1.y, point.y),
point.x,
- -point.y,
+ point.y,
point_plus1.x,
- -point_plus1.y);
+ point_plus1.y);
offset++;
} else {
System.out.println("addContourToPath case not catered for!!");
@@ -134,18 +134,18 @@ public class GlyphPathFactory {
Point point_plus2 = glyph.getPoint(startIndex + (offset+2)%count);
Point point_plus3 = glyph.getPoint(startIndex + (offset+3)%count);
if (point.onCurve && point_plus1.onCurve) {
- s = new Line2D.Float(point.x, -point.y, point_plus1.x, -point_plus1.y);
+ s = new Line2D.Float(point.x, point.y, point_plus1.x, point_plus1.y);
offset++;
} else if (point.onCurve && !point_plus1.onCurve && !point_plus2.onCurve && point_plus3.onCurve) {
s = new CubicCurve2D.Float(
point.x,
- -point.y,
+ point.y,
point_plus1.x,
- -point_plus1.y,
+ point_plus1.y,
point_plus2.x,
- -point_plus2.y,
+ point_plus2.y,
point_plus3.x,
- -point_plus3.y);
+ point_plus3.y);
offset+=3;
} else {
System.out.println("addContourToPath case not catered for!!");