Dasherpublic class Dasher extends LineSink The Dasher class takes a series of linear commands
(moveTo , lineTo , close and
end ) and breaks them into smaller segments according to a
dash pattern array and a starting dash phase.
Issues: in J2Se, a zero length dash segment as drawn as a very
short dash, whereas Pisces does not draw anything. The PostScript
semantics are unclear. |
Fields Summary |
---|
LineSink | output | int[] | dash | int | startPhase | int | startIdx | int | idx | int | phase | int | sx | int | sy | int | x0 | int | y0 | int | m00 | int | m01 | int | m10 | int | m11 | Transform4 | transform | boolean | symmetric | long | ldet | boolean | firstDashOn | boolean | starting | int | sx1 | int | sy1 |
Constructors Summary |
---|
public Dasher()Empty constructor. setOutput and
setParameters must be called prior to calling any
other methods.
| public Dasher(LineSink output, int[] dash, int phase, Transform4 transform)Constructs a Dasher .
setOutput(output);
setParameters(dash, phase, transform);
|
Methods Summary |
---|
public void | close()
lineTo(sx, sy);
if (firstDashOn) {
output.lineTo(sx1, sy1);
}
| public void | end()
output.end();
| private void | goTo(int x1, int y1)
if ((idx % 2) == 0) {
if (starting) {
this.sx1 = x1;
this.sy1 = y1;
firstDashOn = true;
starting = false;
}
output.lineTo(x1, y1);
} else {
if (starting) {
firstDashOn = false;
starting = false;
}
output.moveTo(x1, y1);
}
this.x0 = x1;
this.y0 = y1;
| public void | lineJoin()
output.lineJoin();
| public void | lineTo(int x1, int y1)
while (true) {
int d = dash[idx] - phase;
int lx = x1 - x0;
int ly = y1 - y0;
// Compute segment length in the untransformed
// coordinate system
// IMPL NOTE - use fixed point
int l;
if (symmetric) {
l = (int)((PiscesMath.hypot(lx, ly)*65536L)/ldet);
} else{
long la = ((long)ly*m00 - (long)lx*m10)/ldet;
long lb = ((long)ly*m01 - (long)lx*m11)/ldet;
l = (int)PiscesMath.hypot(la, lb);
}
if (l < d) {
goTo(x1, y1);
// Advance phase within current dash segment
phase += l;
return;
}
long t;
int xsplit, ysplit;
// // For zero length dashses, SE appears to move 1/8 unit
// // in device space
// if (d == 0) {
// double dlx = lx/65536.0;
// double dly = ly/65536.0;
// len = PiscesMath.hypot(dlx, dly);
// double dt = 1.0/(8*len);
// double dxsplit = (x0/65536.0) + dt*dlx;
// double dysplit = (y0/65536.0) + dt*dly;
// xsplit = (int)(dxsplit*65536.0);
// ysplit = (int)(dysplit*65536.0);
// } else {
t = ((long)d << 16)/l;
xsplit = x0 + (int)(t*(x1 - x0) >> 16);
ysplit = y0 + (int)(t*(y1 - y0) >> 16);
// }
goTo(xsplit, ysplit);
// Advance to next dash segment
idx = (idx + 1) % dash.length;
phase = 0;
}
| public void | moveTo(int x0, int y0)
output.moveTo(x0, y0);
this.idx = startIdx;
this.phase = this.startPhase;
this.sx = this.x0 = x0;
this.sy = this.y0 = y0;
this.starting = true;
| public void | setOutput(LineSink output)Sets the output LineSink of this
Dasher .
this.output = output;
| public void | setParameters(int[] dash, int phase, Transform4 transform)Sets the parameters of this Dasher .
if (phase < 0) {
throw new IllegalArgumentException("phase < 0 !");
}
// Normalize so 0 <= phase < dash[0]
int idx = 0;
int d;
while (phase >= (d = dash[idx])) {
phase -= d;
idx = (idx + 1) % dash.length;
}
this.dash = new int[dash.length];
for (int i = 0; i < dash.length; i++) {
this.dash[i] = dash[i];
}
this.startPhase = this.phase = phase;
this.startIdx = idx;
this.transform = transform;
this.m00 = transform.m00;
this.m01 = transform.m01;
this.m10 = transform.m10;
this.m11 = transform.m11;
this.ldet = ((long)m00*m11 - (long)m01*m10) >> 16;
this.symmetric = (m00 == m11 && m10 == -m01);
|
|