< prev index next >
src/java.desktop/share/classes/sun/java2d/marlin/Dasher.java
Print this page
@@ -46,10 +46,12 @@
/* huge circle with radius ~ 2E9 only needs 12 subdivision levels */
static final int REC_LIMIT = 16;
static final float CURVE_LEN_ERR = MarlinProperties.getCurveLengthError(); // 0.01
static final float MIN_T_INC = 1.0f / (1 << REC_LIMIT);
+ static final float EPS = 1e-6f;
+
// More than 24 bits of mantissa means we can no longer accurately
// measure the number of times cycled through the dash array so we
// punt and override the phase to just be 0 past that point.
static final float MAX_CYCLES = 16000000.0f;
@@ -268,22 +270,22 @@
}
}
private void emitSeg(float[] buf, int off, int type) {
switch (type) {
+ case 4:
+ out.lineTo(buf[off], buf[off + 1]);
+ return;
case 8:
out.curveTo(buf[off ], buf[off + 1],
buf[off + 2], buf[off + 3],
buf[off + 4], buf[off + 5]);
return;
case 6:
out.quadTo(buf[off ], buf[off + 1],
buf[off + 2], buf[off + 3]);
return;
- case 4:
- out.lineTo(buf[off], buf[off + 1]);
- return;
default:
}
}
private void emitFirstSegments() {
@@ -360,11 +362,11 @@
if (orCode != 0) {
final int sideCode = outcode0 & outcode1;
// basic rejection criteria:
if (sideCode == 0) {
- // ovelap clip:
+ // overlap clip:
if (subdivide) {
// avoid reentrance
subdivide = false;
// subdivide curve => callback with subdivided parts:
boolean ret = curveSplitter.splitLine(cx0, cy0, x1, y1,
@@ -415,45 +417,40 @@
int _idx = idx;
boolean _dashOn = dashOn;
float _phase = phase;
- float leftInThisDashSegment, d;
+ float leftInThisDashSegment, rem;
while (true) {
- d = _dash[_idx];
- leftInThisDashSegment = d - _phase;
+ leftInThisDashSegment = _dash[_idx] - _phase;
+ rem = len - leftInThisDashSegment;
- if (len <= leftInThisDashSegment) {
+ if (rem <= EPS) {
_curCurvepts[0] = x1;
_curCurvepts[1] = y1;
goTo(_curCurvepts, 0, 4, _dashOn);
// Advance phase within current dash segment
_phase += len;
- // TODO: compare float values using epsilon:
- if (len == leftInThisDashSegment) {
+ // compare values using epsilon:
+ if (Math.abs(rem) <= EPS) {
_phase = 0.0f;
_idx = (_idx + 1) % _dashLen;
_dashOn = !_dashOn;
}
break;
}
- if (_phase == 0.0f) {
- _curCurvepts[0] = cx0 + d * cx;
- _curCurvepts[1] = cy0 + d * cy;
- } else {
- _curCurvepts[0] = cx0 + leftInThisDashSegment * cx;
- _curCurvepts[1] = cy0 + leftInThisDashSegment * cy;
- }
+ _curCurvepts[0] = cx0 + leftInThisDashSegment * cx;
+ _curCurvepts[1] = cy0 + leftInThisDashSegment * cy;
goTo(_curCurvepts, 0, 4, _dashOn);
- len -= leftInThisDashSegment;
+ len = rem;
// Advance to next dash segment
_idx = (_idx + 1) % _dashLen;
_dashOn = !_dashOn;
_phase = 0.0f;
}
@@ -505,30 +502,30 @@
final long iterations = fullcycles * _dashLen;
_idx = (int) (iterations + _idx) % _dashLen;
_dashOn = (iterations + (_dashOn ? 1L : 0L) & 1L) == 1L;
}
- float leftInThisDashSegment, d;
+ float leftInThisDashSegment, rem;
while (true) {
- d = _dash[_idx];
- leftInThisDashSegment = d - _phase;
+ leftInThisDashSegment = _dash[_idx] - _phase;
+ rem = len - leftInThisDashSegment;
- if (len <= leftInThisDashSegment) {
+ if (rem <= EPS) {
// Advance phase within current dash segment
_phase += len;
- // TODO: compare float values using epsilon:
- if (len == leftInThisDashSegment) {
+ // compare values using epsilon:
+ if (Math.abs(rem) <= EPS) {
_phase = 0.0f;
_idx = (_idx + 1) % _dashLen;
_dashOn = !_dashOn;
}
break;
}
- len -= leftInThisDashSegment;
+ len = rem;
// Advance to next dash segment
_idx = (_idx + 1) % _dashLen;
_dashOn = !_dashOn;
_phase = 0.0f;
}
@@ -578,11 +575,13 @@
}
goTo(_curCurvepts, curCurveoff + 2, type, _dashOn);
_phase += _li.lastSegLen();
- if (_phase >= _dash[_idx]) {
+
+ // compare values using epsilon:
+ if (_phase + EPS >= _dash[_idx]) {
_phase = 0.0f;
_idx = (_idx + 1) % _dashLen;
_dashOn = !_dashOn;
}
// Save local state:
@@ -937,11 +936,11 @@
if (orCode != 0) {
final int sideCode = outcode0 & outcode1 & outcode2 & outcode3;
// basic rejection criteria:
if (sideCode == 0) {
- // ovelap clip:
+ // overlap clip:
if (subdivide) {
// avoid reentrance
subdivide = false;
// subdivide curve => callback with subdivided parts:
boolean ret = curveSplitter.splitCurve(cx0, cy0, x1, y1, x2, y2, x3, y3,
@@ -1023,11 +1022,11 @@
if (orCode != 0) {
final int sideCode = outcode0 & outcode1 & outcode2;
// basic rejection criteria:
if (sideCode == 0) {
- // ovelap clip:
+ // overlap clip:
if (subdivide) {
// avoid reentrance
subdivide = false;
// subdivide curve => call lineTo() with subdivided curves:
boolean ret = curveSplitter.splitQuad(cx0, cy0, x1, y1,
< prev index next >