deweese 01/09/19 11:46:07
Modified: sources/org/apache/batik/bridge SVGPatternElementBridge.java
sources/org/apache/batik/gvt/text GlyphLayout.java
sources/org/apache/batik/swing/gvt TextSelectionManager.java
Log:
1) Now uses a nice semi-transparent light grey field with a black border
to identify selected text.
2) modified how GlyphLayout generates Highlight shape to work much better
with #1. Could still use some work for text on a path...
3) Pattern Paint now uses component transfer rather than color matrix
to apply opacity (should be much faster).
Revision Changes Path
1.20 +11 -11
xml-batik/sources/org/apache/batik/bridge/SVGPatternElementBridge.java
Index: SVGPatternElementBridge.java
===================================================================
RCS file:
/home/cvs/xml-batik/sources/org/apache/batik/bridge/SVGPatternElementBridge.java,v
retrieving revision 1.19
retrieving revision 1.20
diff -u -r1.19 -r1.20
--- SVGPatternElementBridge.java 2001/09/18 21:18:59 1.19
+++ SVGPatternElementBridge.java 2001/09/19 18:46:06 1.20
@@ -21,9 +21,9 @@
import org.apache.batik.dom.util.XLinkSupport;
import org.apache.batik.ext.awt.image.renderable.ClipRable8Bit;
-import org.apache.batik.ext.awt.image.renderable.ColorMatrixRable8Bit;
-import org.apache.batik.ext.awt.image.renderable.ColorMatrixRable;
+import org.apache.batik.ext.awt.image.renderable.ComponentTransferRable8Bit;
import org.apache.batik.ext.awt.image.renderable.Filter;
+import org.apache.batik.ext.awt.image.ConcreteComponentTransferFunction;
import org.apache.batik.gvt.CompositeGraphicsNode;
import org.apache.batik.gvt.GraphicsNode;
@@ -36,7 +36,7 @@
* Bridge class for the <pattern> element.
*
* @author <a href="mailto:[EMAIL PROTECTED]">Thierry Kormann</a>
- * @version $Id: SVGPatternElementBridge.java,v 1.19 2001/09/18 21:18:59 deweese
Exp $
+ * @version $Id: SVGPatternElementBridge.java,v 1.20 2001/09/19 18:46:06 deweese
Exp $
*/
public class SVGPatternElementBridge extends AbstractSVGBridge
implements PaintBridge, ErrorConstants {
@@ -188,14 +188,14 @@
// take the opacity into account. opacity is implemented by a Filter
if (opacity != 1) {
- float[][] matrix = { {1, 0, 0, 0, 0},
- {0, 1, 0, 0, 0},
- {0, 0, 1, 0, 0},
- {0, 0, 0, opacity, 0} };
-
- ColorMatrixRable filter = ColorMatrixRable8Bit.buildMatrix(matrix);
- Filter contentRable = patternContentNode.getGraphicsNodeRable();
- filter.setSource(contentRable);
+ Filter filter = patternContentNode.getGraphicsNodeRable();
+ filter = new ComponentTransferRable8Bit
+ (filter,
+ ConcreteComponentTransferFunction.getLinearTransfer
+ (opacity, 0), //alpha
+ ConcreteComponentTransferFunction.getIdentityTransfer(), //Red
+ ConcreteComponentTransferFunction.getIdentityTransfer(), //Grn
+ ConcreteComponentTransferFunction.getIdentityTransfer());//Blu
patternContentNode.setFilter(filter);
}
1.22 +82 -9 xml-batik/sources/org/apache/batik/gvt/text/GlyphLayout.java
Index: GlyphLayout.java
===================================================================
RCS file: /home/cvs/xml-batik/sources/org/apache/batik/gvt/text/GlyphLayout.java,v
retrieving revision 1.21
retrieving revision 1.22
diff -u -r1.21 -r1.22
--- GlyphLayout.java 2001/09/18 21:19:01 1.21
+++ GlyphLayout.java 2001/09/19 18:46:06 1.22
@@ -15,10 +15,11 @@
import java.awt.Font;
import java.awt.font.TextAttribute;
import java.awt.font.FontRenderContext;
-import java.awt.geom.GeneralPath;
-import java.awt.geom.Rectangle2D;
import java.awt.geom.AffineTransform;
+import java.awt.geom.GeneralPath;
+import java.awt.geom.PathIterator;
import java.awt.geom.Point2D;
+import java.awt.geom.Rectangle2D;
import java.text.AttributedCharacterIterator;
import java.text.CharacterIterator;
@@ -38,7 +39,7 @@
* @see org.apache.batik.gvt.text.TextSpanLayout
*
* @author <a href="[EMAIL PROTECTED]>Bill Haneman</a>
- * @version $Id: GlyphLayout.java,v 1.21 2001/09/18 21:19:01 deweese Exp $
+ * @version $Id: GlyphLayout.java,v 1.22 2001/09/19 18:46:06 deweese Exp $
*/
public class GlyphLayout implements TextSpanLayout {
@@ -253,9 +254,15 @@
beginCharIndex = endCharIndex;
endCharIndex = temp;
}
- Shape shape = null;
+ GeneralPath shape = null;
int currentChar = aci.getBeginIndex();
int numGlyphs = getGlyphCount();
+
+ Point2D.Float [] topPts = new Point2D.Float[2*numGlyphs];
+ Point2D.Float [] botPts = new Point2D.Float[2*numGlyphs];
+
+ int ptIdx = 0;
+
for (int i = 0; i < numGlyphs; i++) {
aci.setIndex(currentChar);
int glyphCharIndex = ((Integer)aci.getAttribute(
@@ -263,17 +270,83 @@
if (glyphCharIndex >= beginCharIndex && glyphCharIndex <= endCharIndex)
{
Shape gbounds = gv.getGlyphLogicalBounds(i);
if (gbounds != null) {
- if (shape == null) {
- shape = new GeneralPath(gbounds);
+ // We got something...
+ if (shape == null)
+ shape = new GeneralPath();
+
+ // We are pretty dumb here we assume that we always
+ // get back polygons with four sides to them if
+ // isn't met we are SOL.
+ float [] pts = new float[6];
+ int count = 0;
+ int type = -1;
+
+ PathIterator pi = gbounds.getPathIterator(null);
+ while (!pi.isDone()) {
+ type = pi.currentSegment(pts);
+ if ((type == PathIterator.SEG_MOVETO) ||
+ (type == PathIterator.SEG_LINETO)) {
+ // LINETO or MOVETO
+ if (count > 4) break; // too many lines...
+ if (count == 4) {
+ // make sure we are just closing it..
+ if ((topPts[ptIdx].x != pts[0]) ||
+ (topPts[ptIdx].y != pts[1]))
+ break;
+ } else {
+ Point2D.Float pt;
+ pt = new Point2D.Float(pts[0], pts[1]);
+ switch (count) {
+ case 0: topPts[ptIdx] = pt; break;
+ case 1: topPts[ptIdx+1] = pt; break;
+ case 2: botPts[ptIdx+1] = pt; break;
+ case 3: botPts[ptIdx] = pt; break;
+ }
+ }
+ } else if (type == PathIterator.SEG_CLOSE) {
+ // Close in the wrong spot?
+ if ((count < 4) || (count > 5)) break;
+ } else {
+ // QUADTO or CUBETO
+ break;
+ }
+
+ count++;
+ pi.next();
+ }
+ if (pi.isDone()) {
+ // Sucessfully Expressed as a quadralateral...
+ if ((topPts[ptIdx].x != topPts[ptIdx+1].x) ||
+ (topPts[ptIdx].y != topPts[ptIdx+1].y))
+ // box isn't empty so use it's points...
+ ptIdx += 2;
} else {
- ((GeneralPath) shape).append(gbounds, false);
+ // System.out.println("Type: " + type +
+ // " count: " + count);
+ shape.moveTo(topPts[0].x, topPts[0].y);
+ for (int j=1; j<ptIdx; j++)
+ shape.lineTo(topPts[j].x, topPts[j].y);
+ for (int j=ptIdx-1; j>=0; j--)
+ shape.lineTo(botPts[j].x, botPts[j].y);
+ shape.closePath();
+ ptIdx = 0;
+ shape.append(gbounds, false);
}
}
}
currentChar += getCharacterCount(i, i);
}
- if (transform != null && shape != null) {
- shape = transform.createTransformedShape(shape);
+ if (ptIdx != 0) {
+ shape.moveTo(topPts[0].x, topPts[0].y);
+ for (int i=1; i<ptIdx; i++)
+ shape.lineTo(topPts[i].x, topPts[i].y);
+ for (int i=ptIdx-1; i>=0; i--)
+ shape.lineTo(botPts[i].x, botPts[i].y);
+ shape.closePath();
+ }
+
+ if (transform != null) {
+ return transform.createTransformedShape(shape);
}
return shape;
}
1.7 +22 -7
xml-batik/sources/org/apache/batik/swing/gvt/TextSelectionManager.java
Index: TextSelectionManager.java
===================================================================
RCS file:
/home/cvs/xml-batik/sources/org/apache/batik/swing/gvt/TextSelectionManager.java,v
retrieving revision 1.6
retrieving revision 1.7
diff -u -r1.6 -r1.7
--- TextSelectionManager.java 2001/09/18 21:19:01 1.6
+++ TextSelectionManager.java 2001/09/19 18:46:07 1.7
@@ -35,7 +35,7 @@
* This class represents an object which manage GVT text nodes selection.
*
* @author <a href="mailto:[EMAIL PROTECTED]">Stephane Hillion</a>
- * @version $Id: TextSelectionManager.java,v 1.6 2001/09/18 21:19:01 deweese Exp $
+ * @version $Id: TextSelectionManager.java,v 1.7 2001/09/19 18:46:07 deweese Exp $
*/
public class TextSelectionManager {
@@ -189,13 +189,13 @@
AffineTransform at = component.getRenderingTransform();
if (selectionHighlight != null) {
r = at.createTransformedShape(selectionHighlight).getBounds();
+ outset(r, 1);
}
selectionHighlight = e.getHighlightShape();
if (selectionHighlight != null) {
if (r != null) {
- Rectangle r2;
- r2 = at.createTransformedShape(selectionHighlight).getBounds();
+ Rectangle r2 = getHighlightBounds();
component.paintImmediately(r.union(r2));
} else {
component.paintImmediately(getHighlightBounds());
@@ -207,15 +207,26 @@
}
+ protected Rectangle outset(Rectangle r, int amount) {
+ r.x -= amount;
+ r.y -= amount;
+ r.width += 2*amount;
+ r.height += 2*amount;
+ return r;
+ }
+
/**
* The highlight bounds.
*/
protected Rectangle getHighlightBounds() {
AffineTransform at = component.getRenderingTransform();
Shape s = at.createTransformedShape(selectionHighlight);
- return s.getBounds();
+ return outset(s.getBounds(), 1);
}
+ static final Color fillColor = new Color(200, 200, 200, 100);
+ static final Color strokeColor = new Color(0, 0, 0, 255);
+
/**
* The selection overlay.
*/
@@ -231,10 +242,14 @@
Graphics2D g2d = (Graphics2D)g;
- g2d.setXORMode(Color.white);
- g2d.setColor(Color.black);
-
+ // g2d.setXORMode(Color.white);
+ // g2d.setColor(Color.black);
+ g2d.setColor(fillColor);
g2d.fill(s);
+
+ g2d.setStroke(new java.awt.BasicStroke(2.0f));
+ g2d.setColor(strokeColor);
+ g2d.draw(s);
}
}
}
---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]