deweese 2004/10/29 07:40:54 Modified: sources/org/apache/batik/bridge UpdateManager.java sources/org/apache/batik/ext/awt/geom ExtendedGeneralPath.java sources/org/apache/batik/util RunnableQueue.java test-references/samples/tests/spec/painting markersExt.png Log: 1) Fixed some files that didn't get the 2.0 license. 2) Tweaked UpdateManager repaint scheduling alg. It now tracks when the rendering goes 'out of date' with the document and runs runnables until it is out of them or MIN_REPAINT_TIME is exceeded. NOTE: This adds a new method the the RunnableQueue.RunHandler Interface. I have added an adapter class to minimize the impact of any future changes that might be needed here. 3) Tweaked the way we generate paths to avoid a bug in the Mac OS X Java implemention where a close followed by a moveto didn't join the path properly. PR: 30948, 31603 Revision Changes Path 1.34 +19 -5 xml-batik/sources/org/apache/batik/bridge/UpdateManager.java Index: UpdateManager.java =================================================================== RCS file: /home/cvs/xml-batik/sources/org/apache/batik/bridge/UpdateManager.java,v retrieving revision 1.33 retrieving revision 1.34 diff -u -r1.33 -r1.34 --- UpdateManager.java 23 Oct 2004 17:11:03 -0000 1.33 +++ UpdateManager.java 29 Oct 2004 14:40:54 -0000 1.34 @@ -402,7 +402,11 @@ } } - long lastRepaint=0; + /** + * This tracks when the rendering first got 'out of date' + * with respect to the document. + */ + long outOfDateTime=0; /** * Repaints the dirty areas, if needed. @@ -411,7 +415,7 @@ if (!updateTracker.hasChanged()) return; long ctime = System.currentTimeMillis(); - if (ctime-lastRepaint < MIN_REPAINT_TIME) { + if (ctime-outOfDateTime < MIN_REPAINT_TIME) { // We very recently did a repaint check if other // repaint runnables are pending. synchronized (updateRunnableQueue.getIteratorLock()) { @@ -431,7 +435,7 @@ if (dirtyAreas != null) { updateRendering(dirtyAreas, false); } - lastRepaint = System.currentTimeMillis(); + outOfDateTime = 0; } @@ -546,7 +550,17 @@ } protected class UpdateManagerRunHander - implements RunnableQueue.RunHandler { + extends RunnableQueue.RunHandlerAdapter { + + public void runnableStart(RunnableQueue rq, Runnable r) { + if (running && !(r instanceof NoRepaintRunnable)) { + // Mark the document as updated when the + // runnable starts. + if (outOfDateTime == 0) + outOfDateTime = System.currentTimeMillis(); + } + } + /** * Called when the given Runnable has just been invoked and 1.8 +74 -35 xml-batik/sources/org/apache/batik/ext/awt/geom/ExtendedGeneralPath.java Index: ExtendedGeneralPath.java =================================================================== RCS file: /home/cvs/xml-batik/sources/org/apache/batik/ext/awt/geom/ExtendedGeneralPath.java,v retrieving revision 1.7 retrieving revision 1.8 diff -u -r1.7 -r1.8 --- ExtendedGeneralPath.java 18 Aug 2004 07:13:47 -0000 1.7 +++ ExtendedGeneralPath.java 29 Oct 2004 14:40:54 -0000 1.8 @@ -43,10 +43,12 @@ /** The enclosed general path. */ protected GeneralPath path; - int numVals = 0; - int numSeg = 0; - double [] values = null; - int [] types = null; + int numVals = 0; + int numSeg = 0; + float [] values = null; + int [] types = null; + + float mx, my, cx, cy; /** * Constructs a new <code>ExtendedGeneralPath</code>. @@ -104,11 +106,11 @@ * @param x, y the absolute coordinates of the final point of * the arc. */ - public synchronized void arcTo(double rx, double ry, - double angle, + public synchronized void arcTo(float rx, float ry, + float angle, boolean largeArcFlag, boolean sweepFlag, - double x, double y) { + float x, float y) { // Ensure radii are valid if (rx == 0 || ry == 0) { @@ -116,10 +118,11 @@ return; } + checkMoveTo(); // check if prev command was moveto + // Get the current (x, y) coordinates of the path - Point2D p2d = path.getCurrentPoint(); - double x0 = p2d.getX(); - double y0 = p2d.getY(); + double x0 = cx; + double y0 = cy; if (x0 == x && y0 == y) { // If the endpoints (x, y) and (x0, y0) are identical, then this // is equivalent to omitting the elliptical arc segment entirely. @@ -142,8 +145,8 @@ values[numVals++] = angle; values[numVals++] = largeArcFlag?1:0; values[numVals++] = sweepFlag?1:0; - values[numVals++] = x; - values[numVals++] = y; + cx = values[numVals++] = x; + cy = values[numVals++] = y; } @@ -257,38 +260,40 @@ * Delegates to the enclosed <code>GeneralPath</code>. */ public synchronized void moveTo(float x, float y) { - path.moveTo(x, y); - + // Don't add moveto to general path unless there is a reason. makeRoom(2); types [numSeg++] = PathIterator.SEG_MOVETO; - values[numVals++] = x; - values[numVals++] = y; + cx = mx = values[numVals++] = x; + cy = my = values[numVals++] = y; + } /** * Delegates to the enclosed <code>GeneralPath</code>. */ public synchronized void lineTo(float x, float y) { + checkMoveTo(); // check if prev command was moveto path.lineTo(x, y); makeRoom(2); types [numSeg++] = PathIterator.SEG_LINETO; - values[numVals++] = x; - values[numVals++] = y; + cx = values[numVals++] = x; + cy = values[numVals++] = y; } /** * Delegates to the enclosed <code>GeneralPath</code>. */ public synchronized void quadTo(float x1, float y1, float x2, float y2) { + checkMoveTo(); // check if prev command was moveto path.quadTo(x1, y1, x2, y2); makeRoom(4); types [numSeg++] = PathIterator.SEG_QUADTO; values[numVals++] = x1; values[numVals++] = y1; - values[numVals++] = x2; - values[numVals++] = y2; + cx = values[numVals++] = x2; + cy = values[numVals++] = y2; } /** @@ -297,6 +302,7 @@ public synchronized void curveTo(float x1, float y1, float x2, float y2, float x3, float y3) { + checkMoveTo(); // check if prev command was moveto path.curveTo(x1, y1, x2, y2, x3, y3); makeRoom(6); @@ -305,18 +311,50 @@ values[numVals++] = y1; values[numVals++] = x2; values[numVals++] = y2; - values[numVals++] = x3; - values[numVals++] = y3; + cx = values[numVals++] = x3; + cy = values[numVals++] = y3; } /** * Delegates to the enclosed <code>GeneralPath</code>. */ public synchronized void closePath() { - path.closePath(); + // Don't double close path. + if ((numSeg != 0) && (types[numSeg-1] == PathIterator.SEG_CLOSE)) + return; + + // Only close path if the previous command wasn't a moveto + if ((numSeg != 0) && (types[numSeg-1] != PathIterator.SEG_MOVETO)) + path.closePath(); makeRoom(0); types [numSeg++] = PathIterator.SEG_CLOSE; + cx = mx; + cy = my; + } + + /** + * Checks if previous command was a moveto command, + * skipping a close command (if present). + */ + protected void checkMoveTo() { + if (numSeg == 0) return; + + switch(types[numSeg-1]) { + + case PathIterator.SEG_MOVETO: + path.moveTo(values[numVals-2], values[numVals-1]); + break; + + case PathIterator.SEG_CLOSE: + if (numSeg == 1) return; + if (types[numSeg-2] == PathIterator.SEG_MOVETO) + path.moveTo(values[numVals-2], values[numVals-1]); + break; + + default: + break; + } } /** @@ -339,8 +377,8 @@ if (type == PathIterator.SEG_MOVETO) { double x = vals[0]; double y = vals[1]; - if ((x != values[numVals-2]) || - (y != values[numVals-1])) { + if ((x != cx) || + (y != cy)) { // Change MOVETO to LINETO. type = PathIterator.SEG_LINETO; } else { @@ -375,15 +413,15 @@ */ public void append(ExtendedPathIterator epi, boolean connect) { while (!epi.isDone()) { - double [] vals = new double[7]; + float [] vals = new float[7]; int type = epi.currentSegment(vals); epi.next(); if (connect && (numVals != 0)) { if (type == PathIterator.SEG_MOVETO) { - double x = vals[0]; - double y = vals[1]; - if ((x != values[numVals-2]) || - (y != values[numVals-1])) { + float x = vals[0]; + float y = vals[1]; + if ((x != cx) || + (y != cy)) { // Change MOVETO to LINETO. type = PathIterator.SEG_LINETO; } else { @@ -435,7 +473,8 @@ * Delegates to the enclosed <code>GeneralPath</code>. */ public synchronized Point2D getCurrentPoint() { - return path.getCurrentPoint(); + if (numVals == 0) return null; + return new Point2D.Double(cx, cy); } /** @@ -647,7 +686,7 @@ ExtendedGeneralPath result = (ExtendedGeneralPath) super.clone(); result.path = (GeneralPath) path.clone(); - result.values = new double[values.length]; + result.values = new float[values.length]; System.arraycopy(result.values, 0, values, 0, values.length); result.numVals = numVals; @@ -662,7 +701,7 @@ private void makeRoom(int numValues) { if (values == null) { - values = new double[2*numValues]; + values = new float[2*numValues]; types = new int[2]; numVals = 0; numSeg = 0; @@ -674,7 +713,7 @@ if (nlen < (numVals + numValues)) nlen = numVals + numValues; - double [] nvals = new double[nlen]; + float [] nvals = new float[nlen]; System.arraycopy(values, 0, nvals, 0, numVals); values = nvals; } 1.19 +47 -1 xml-batik/sources/org/apache/batik/util/RunnableQueue.java Index: RunnableQueue.java =================================================================== RCS file: /home/cvs/xml-batik/sources/org/apache/batik/util/RunnableQueue.java,v retrieving revision 1.18 retrieving revision 1.19 diff -u -r1.18 -r1.19 --- RunnableQueue.java 23 Oct 2004 17:11:04 -0000 1.18 +++ RunnableQueue.java 29 Oct 2004 14:40:54 -0000 1.19 @@ -171,6 +171,8 @@ rable = l.runnable; } + runnableStart(rable); + try { rable.run(); } catch (ThreadDeath td) { @@ -435,6 +437,17 @@ } /** + * Called just prior to executing a Runnable. + * Currently just notifies runHandler + * @param rable The runnable that is about to start + */ + protected synchronized void runnableStart(Runnable rable ) { + if (runHandler != null) { + runHandler.runnableStart(this, rable); + } + } + + /** * Called when a Runnable completes. * Currently just notifies runHandler * @param rable The runnable that just completed. @@ -452,6 +465,11 @@ public interface RunHandler { /** + * Called just prior to invoking the runnable + */ + void runnableStart(RunnableQueue rq, Runnable r); + + /** * Called when the given Runnable has just been invoked and * has returned. */ @@ -466,6 +484,34 @@ * Called when the execution of the queue has been resumed. */ void executionResumed(RunnableQueue rq); + } + + /** + * This is an adapter class that implements the RunHandler interface. + * It simply does nothing in response to the calls. + */ + public static class RunHandlerAdapter implements RunHandler { + + /** + * Called just prior to invoking the runnable + */ + public void runnableStart(RunnableQueue rq, Runnable r) { } + + /** + * Called when the given Runnable has just been invoked and + * has returned. + */ + public void runnableInvoked(RunnableQueue rq, Runnable r) { } + + /** + * Called when the execution of the queue has been suspended. + */ + public void executionSuspended(RunnableQueue rq) { } + + /** + * Called when the execution of the queue has been resumed. + */ + public void executionResumed(RunnableQueue rq) { } } /** 1.4 +183 -158 xml-batik/test-references/samples/tests/spec/painting/markersExt.png <<Binary file>>
--------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]