< prev index next >

src/java.desktop/share/classes/sun/java2d/marlin/Dasher.java

Print this page

        

@@ -136,11 +136,11 @@
                     }
                     phase += dash[sidx];
                     dashOn = !dashOn;
                 }
             }
-        } else if (phase > 0) {
+        } else if (phase > 0.0f) {
             if (cycles >= MAX_CYCLES) {
                 phase = 0.0f;
             } else {
                 int fullcycles = FloatMath.floor_int(cycles);
                 if ((fullcycles & dash.length & 1) != 0) {

@@ -156,16 +156,17 @@
             }
         }
 
         this.dash = dash;
         this.dashLen = dashLen;
-        this.startPhase = this.phase = phase;
+        this.phase = phase;
+        this.startPhase = phase;
         this.startDashOn = dashOn;
         this.startIdx = sidx;
         this.starting = true;
-        needsMoveTo = false;
-        firstSegidx = 0;
+        this.needsMoveTo = false;
+        this.firstSegidx = 0;
 
         this.recycleDashes = recycleDashes;
 
         return this; // fluent API
     }

@@ -201,20 +202,22 @@
         return newDashes;
     }
 
     @Override
     public void moveTo(float x0, float y0) {
-        if (firstSegidx > 0) {
+        if (firstSegidx != 0) {
             out.moveTo(sx, sy);
             emitFirstSegments();
         }
         needsMoveTo = true;
         this.idx = startIdx;
         this.dashOn = this.startDashOn;
         this.phase = this.startPhase;
-        this.sx = this.x0 = x0;
-        this.sy = this.y0 = y0;
+        this.sx = x0;
+        this.sy = y0;
+        this.x0 = x0;
+        this.y0 = y0;
         this.starting = true;
     }
 
     private void emitSeg(float[] buf, int off, int type) {
         switch (type) {

@@ -235,11 +238,11 @@
     }
 
     private void emitFirstSegments() {
         final float[] fSegBuf = firstSegmentsBuffer;
 
-        for (int i = 0; i < firstSegidx; ) {
+        for (int i = 0, len = firstSegidx; i < len; ) {
             int type = (int)fSegBuf[i];
             emitSeg(fSegBuf, i + 1, type);
             i += (type - 1);
         }
         firstSegidx = 0;

@@ -250,52 +253,61 @@
     // buffer below.
     private float[] firstSegmentsBuffer; // dynamic array
     private int firstSegidx;
 
     // precondition: pts must be in relative coordinates (relative to x0,y0)
-    private void goTo(float[] pts, int off, final int type) {
-        float x = pts[off + type - 4];
-        float y = pts[off + type - 3];
-        if (dashOn) {
+    private void goTo(final float[] pts, final int off, final int type, final boolean on) {
+        final int index = off + type;
+        final float x = pts[index - 4];
+        final float y = pts[index - 3];
+
+        if (on) {
             if (starting) {
-                int len = type - 1; // - 2 + 1
-                int segIdx = firstSegidx;
-                float[] buf = firstSegmentsBuffer;
-                if (segIdx + len  > buf.length) {
-                    if (DO_STATS) {
-                        rdrCtx.stats.stat_array_dasher_firstSegmentsBuffer
-                            .add(segIdx + len);
-                    }
-                    firstSegmentsBuffer = buf
-                        = firstSegmentsBuffer_ref.widenArray(buf, segIdx,
-                                                             segIdx + len);
-                }
-                buf[segIdx++] = type;
-                len--;
-                // small arraycopy (2, 4 or 6) but with offset:
-                System.arraycopy(pts, off, buf, segIdx, len);
-                segIdx += len;
-                firstSegidx = segIdx;
+                goTo_starting(pts, off, type);
             } else {
                 if (needsMoveTo) {
-                    out.moveTo(x0, y0);
                     needsMoveTo = false;
+                    out.moveTo(x0, y0);
                 }
                 emitSeg(pts, off, type);
             }
         } else {
-            starting = false;
+            if (starting) {
+                // low probability test (hotspot)
+                starting = false;
+            }
             needsMoveTo = true;
         }
         this.x0 = x;
         this.y0 = y;
     }
 
+    private void goTo_starting(final float[] pts, final int off, final int type) {
+        int len = type - 1; // - 2 + 1
+        int segIdx = firstSegidx;
+        float[] buf = firstSegmentsBuffer;
+
+        if (segIdx + len  > buf.length) {
+            if (DO_STATS) {
+                rdrCtx.stats.stat_array_dasher_firstSegmentsBuffer
+                    .add(segIdx + len);
+            }
+            firstSegmentsBuffer = buf
+                = firstSegmentsBuffer_ref.widenArray(buf, segIdx,
+                                                     segIdx + len);
+        }
+        buf[segIdx++] = type;
+        len--;
+        // small arraycopy (2, 4 or 6) but with offset:
+        System.arraycopy(pts, off, buf, segIdx, len);
+        firstSegidx = segIdx + len;
+    }
+
     @Override
     public void lineTo(float x1, float y1) {
-        float dx = x1 - x0;
-        float dy = y1 - y0;
+        final float dx = x1 - x0;
+        final float dy = y1 - y0;
 
         float len = dx*dx + dy*dy;
         if (len == 0.0f) {
             return;
         }

@@ -306,52 +318,65 @@
         final float cx = dx / len;
         final float cy = dy / len;
 
         final float[] _curCurvepts = curCurvepts;
         final float[] _dash = dash;
+        final int _dashLen = this.dashLen;
+
+        int _idx = idx;
+        boolean _dashOn = dashOn;
+        float _phase = phase;
 
         float leftInThisDashSegment;
-        float dashdx, dashdy, p;
+        float d, dashdx, dashdy, p;
 
         while (true) {
-            leftInThisDashSegment = _dash[idx] - phase;
+            d = _dash[_idx];
+            leftInThisDashSegment = d - _phase;
 
             if (len <= leftInThisDashSegment) {
                 _curCurvepts[0] = x1;
                 _curCurvepts[1] = y1;
-                goTo(_curCurvepts, 0, 4);
+
+                goTo(_curCurvepts, 0, 4, _dashOn);
 
                 // Advance phase within current dash segment
-                phase += len;
+                _phase += len;
+
                 // TODO: compare float values using epsilon:
                 if (len == leftInThisDashSegment) {
-                    phase = 0.0f;
-                    idx = (idx + 1) % dashLen;
-                    dashOn = !dashOn;
+                    _phase = 0.0f;
+                    _idx = (_idx + 1) % _dashLen;
+                    _dashOn = !_dashOn;
                 }
+
+                // Save local state:
+                idx = _idx;
+                dashOn = _dashOn;
+                phase = _phase;
                 return;
             }
 
-            dashdx = _dash[idx] * cx;
-            dashdy = _dash[idx] * cy;
+            dashdx = d * cx;
+            dashdy = d * cy;
 
-            if (phase == 0.0f) {
+            if (_phase == 0.0f) {
                 _curCurvepts[0] = x0 + dashdx;
                 _curCurvepts[1] = y0 + dashdy;
             } else {
-                p = leftInThisDashSegment / _dash[idx];
+                p = leftInThisDashSegment / d;
                 _curCurvepts[0] = x0 + p * dashdx;
                 _curCurvepts[1] = y0 + p * dashdy;
             }
 
-            goTo(_curCurvepts, 0, 4);
+            goTo(_curCurvepts, 0, 4, _dashOn);
 
             len -= leftInThisDashSegment;
             // Advance to next dash segment
-            idx = (idx + 1) % dashLen;
-            dashOn = !dashOn;
-            phase = 0.0f;
+            _idx = (_idx + 1) % _dashLen;
+            _dashOn = !_dashOn;
+            _phase = 0.0f;
         }
     }
 
     // shared instance in Dasher
     private final LengthIterator li = new LengthIterator();

@@ -360,43 +385,56 @@
     // that contains the curve we want to dash in the first type elements
     private void somethingTo(int type) {
         if (pointCurve(curCurvepts, type)) {
             return;
         }
-        li.initializeIterationOnCurve(curCurvepts, type);
+        final LengthIterator _li = li;
+        final float[] _curCurvepts = curCurvepts;
+        final float[] _dash = dash;
+        final int _dashLen = this.dashLen;
+
+        _li.initializeIterationOnCurve(_curCurvepts, type);
+
+        int _idx = idx;
+        boolean _dashOn = dashOn;
+        float _phase = phase;
 
         // initially the current curve is at curCurvepts[0...type]
         int curCurveoff = 0;
         float lastSplitT = 0.0f;
         float t;
-        float leftInThisDashSegment = dash[idx] - phase;
+        float leftInThisDashSegment = _dash[_idx] - _phase;
 
-        while ((t = li.next(leftInThisDashSegment)) < 1.0f) {
+        while ((t = _li.next(leftInThisDashSegment)) < 1.0f) {
             if (t != 0.0f) {
                 Helpers.subdivideAt((t - lastSplitT) / (1.0f - lastSplitT),
-                                    curCurvepts, curCurveoff,
-                                    curCurvepts, 0,
-                                    curCurvepts, type, type);
+                                    _curCurvepts, curCurveoff,
+                                    _curCurvepts, 0,
+                                    _curCurvepts, type, type);
                 lastSplitT = t;
-                goTo(curCurvepts, 2, type);
+                goTo(_curCurvepts, 2, type, _dashOn);
                 curCurveoff = type;
             }
             // Advance to next dash segment
-            idx = (idx + 1) % dashLen;
-            dashOn = !dashOn;
-            phase = 0.0f;
-            leftInThisDashSegment = dash[idx];
-        }
-        goTo(curCurvepts, curCurveoff+2, type);
-        phase += li.lastSegLen();
-        if (phase >= dash[idx]) {
-            phase = 0.0f;
-            idx = (idx + 1) % dashLen;
-            dashOn = !dashOn;
-        }
+            _idx = (_idx + 1) % _dashLen;
+            _dashOn = !_dashOn;
+            _phase = 0.0f;
+            leftInThisDashSegment = _dash[_idx];
+        }
+        goTo(_curCurvepts, curCurveoff + 2, type, _dashOn);
+        _phase += _li.lastSegLen();
+        if (_phase >= _dash[_idx]) {
+            _phase = 0.0f;
+            _idx = (_idx + 1) % _dashLen;
+            _dashOn = !_dashOn;
+        }
+        // Save local state:
+        idx = _idx;
+        dashOn = _dashOn;
+        phase = _phase;
         // reset LengthIterator:
-        li.reset();
+        _li.reset();
     }
 
     private static boolean pointCurve(float[] curve, int type) {
         for (int i = 2; i < type; i++) {
             if (curve[i] != curve[i-2]) {

@@ -668,26 +706,27 @@
         }
 
         // this is a bit of a hack. It returns -1 if we're not on a leaf, and
         // the length of the leaf if we are on a leaf.
         private float onLeaf() {
-            float[] curve = recCurveStack[recLevel];
+            final float[] curve = recCurveStack[recLevel];
+            final int _curveType = curveType;
             float polyLen = 0.0f;
 
             float x0 = curve[0], y0 = curve[1];
-            for (int i = 2; i < curveType; i += 2) {
+            for (int i = 2; i < _curveType; i += 2) {
                 final float x1 = curve[i], y1 = curve[i+1];
                 final float len = Helpers.linelen(x0, y0, x1, y1);
                 polyLen += len;
                 curLeafCtrlPolyLengths[i/2 - 1] = len;
                 x0 = x1;
                 y0 = y1;
             }
 
             final float lineLen = Helpers.linelen(curve[0], curve[1],
-                                                  curve[curveType-2],
-                                                  curve[curveType-1]);
+                                                  curve[_curveType-2],
+                                                  curve[_curveType-1]);
             if ((polyLen - lineLen) < ERR || recLevel == REC_LIMIT) {
                 return (polyLen + lineLen) / 2.0f;
             }
             return -1.0f;
         }

@@ -716,22 +755,22 @@
     }
 
     @Override
     public void closePath() {
         lineTo(sx, sy);
-        if (firstSegidx > 0) {
+        if (firstSegidx != 0) {
             if (!dashOn || needsMoveTo) {
                 out.moveTo(sx, sy);
             }
             emitFirstSegments();
         }
         moveTo(sx, sy);
     }
 
     @Override
     public void pathDone() {
-        if (firstSegidx > 0) {
+        if (firstSegidx != 0) {
             out.moveTo(sx, sy);
             emitFirstSegments();
         }
         out.pathDone();
 
< prev index next >