tkormann 01/12/13 08:55:02
Modified: sources/org/apache/batik/gvt/font AWTGVTFont.java
AWTGVTGlyphVector.java
sources/org/apache/batik/util CSSConstants.java
Added: sources/org/apache/batik/gvt/font AWTGlyphGeometryCache.java
Log:
- add the font glyph cache
- add missing CSS constants
Revision Changes Path
1.11 +96 -42 xml-batik/sources/org/apache/batik/gvt/font/AWTGVTFont.java
Index: AWTGVTFont.java
===================================================================
RCS file: /home/cvs/xml-batik/sources/org/apache/batik/gvt/font/AWTGVTFont.java,v
retrieving revision 1.10
retrieving revision 1.11
diff -u -r1.10 -r1.11
--- AWTGVTFont.java 2001/12/10 18:30:33 1.10
+++ AWTGVTFont.java 2001/12/13 16:55:02 1.11
@@ -9,13 +9,17 @@
package org.apache.batik.gvt.font;
import java.awt.Font;
+import java.awt.Shape;
import java.awt.font.FontRenderContext;
+import java.awt.font.GlyphMetrics;
import java.awt.font.GlyphVector;
import java.awt.font.LineMetrics;
import java.awt.font.TextAttribute;
import java.awt.geom.AffineTransform;
+import java.awt.geom.Point2D;
+import java.awt.geom.Rectangle2D;
import java.text.CharacterIterator;
@@ -34,24 +38,24 @@
* This is a wrapper class for a java.awt.Font instance.
*
* @author <a href="mailto:[EMAIL PROTECTED]">Bella Robinson</a>
- * @version $Id: AWTGVTFont.java,v 1.10 2001/12/10 18:30:33 deweese Exp $
+ * @version $Id: AWTGVTFont.java,v 1.11 2001/12/13 16:55:02 tkormann Exp $
*/
public class AWTGVTFont implements GVTFont {
- private Font awtFont;
- private float size;
- private float scale;
+ protected Font awtFont;
+ protected float size;
+ protected float scale;
+
/**
* Creates a new AWTGVTFont that wraps the given Font.
*
* @param font The font object to wrap.
*/
public AWTGVTFont(Font font) {
- if (font.getSize2D() < 1f) {
- size = font.getSize2D();
- awtFont = font.deriveFont(10f);
- }
- scale = size/awtFont.getSize2D();
+ this.size = font.getSize2D();
+ this.awtFont = font.deriveFont(FONT_SIZE);
+ this.scale = size/awtFont.getSize2D();
+ initializeFontCache(awtFont);
}
/**
@@ -61,11 +65,10 @@
* @param scale The scale factor to apply to font...
*/
public AWTGVTFont(Font font, float scale) {
- if (font.getSize2D() < 1f) {
- this.size = font.getSize2D()*scale;;
- this.awtFont = font.deriveFont(10f);
- }
+ this.size = font.getSize2D()*scale;;
+ this.awtFont = font.deriveFont(FONT_SIZE);
this.scale = size/awtFont.getSize2D();
+ initializeFontCache(awtFont);
}
/**
@@ -75,16 +78,16 @@
*/
public AWTGVTFont(Map attributes) {
Float sz = (Float)attributes.get(TextAttribute.SIZE);
- if ((sz != null) && (sz.floatValue() < 1f)) {
- size = sz.floatValue();
- attributes.put(TextAttribute.SIZE, new Float(10f));
- awtFont = new Font(attributes);
+ if (sz != null) {
+ this.size = sz.floatValue();
+ attributes.put(TextAttribute.SIZE, new Float(FONT_SIZE));
+ this.awtFont = new Font(attributes);
} else {
- awtFont = new Font(attributes);
- size = awtFont.getSize2D();
+ this.awtFont = new Font(attributes);
+ this.size = awtFont.getSize2D();
}
-
- scale = size/awtFont.getSize2D();
+ this.scale = size/awtFont.getSize2D();
+ initializeFontCache(awtFont);
}
/**
@@ -95,9 +98,10 @@
* @param size The required font size.
*/
public AWTGVTFont(String name, int style, int size) {
- this.awtFont = new Font(name, style, size);
+ this.awtFont = new Font(name, style, (int)FONT_SIZE);
this.size = size;
- this.scale = 1;
+ this.scale = size/awtFont.getSize2D();
+ initializeFontCache(awtFont);
}
/**
@@ -147,8 +151,8 @@
public GVTGlyphVector createGlyphVector(FontRenderContext frc,
char[] chars) {
- StringCharacterIterator sci =
- new StringCharacterIterator(new String(chars));
+ StringCharacterIterator sci =
+ new StringCharacterIterator(new String(chars));
GlyphVector gv = awtFont.createGlyphVector(frc, chars);
return new AWTGVTGlyphVector(gv, this, scale, sci);
}
@@ -177,10 +181,10 @@
* array and the specified FontRenderContext.
*/
public GVTGlyphVector createGlyphVector(FontRenderContext frc,
- int[] glyphCodes,
+ int[] glyphCodes,
CharacterIterator ci) {
return new AWTGVTGlyphVector
- (awtFont.createGlyphVector(frc, glyphCodes),
+ (awtFont.createGlyphVector(frc, glyphCodes),
this, scale, ci);
}
@@ -188,12 +192,13 @@
* Returns a new GlyphVector object created with the specified String and
* the specified FontRenderContext.
*/
- public GVTGlyphVector createGlyphVector(FontRenderContext frc, String str) {
+ public GVTGlyphVector createGlyphVector(FontRenderContext frc, String str)
+ {
StringCharacterIterator sci = new StringCharacterIterator(str);
return new AWTGVTGlyphVector
- (awtFont.createGlyphVector(frc, str), this, scale, sci);
+ (awtFont.createGlyphVector(frc, str), this, scale, sci);
}
/**
@@ -207,8 +212,8 @@
/**
* Returns a LineMetrics object created with the specified arguments.
*/
- public GVTLineMetrics getLineMetrics(char[] chars,
- int beginIndex,
+ public GVTLineMetrics getLineMetrics(char[] chars,
+ int beginIndex,
int limit,
FontRenderContext frc) {
return new GVTLineMetrics
@@ -218,12 +223,12 @@
/**
* Returns a GVTLineMetrics object created with the specified arguments.
*/
- public GVTLineMetrics getLineMetrics(CharacterIterator ci,
+ public GVTLineMetrics getLineMetrics(CharacterIterator ci,
int beginIndex,
- int limit,
+ int limit,
FontRenderContext frc) {
return new GVTLineMetrics
- (awtFont.getLineMetrics(ci, beginIndex, limit, frc), scale);
+ (awtFont.getLineMetrics(ci, beginIndex, limit, frc), scale);
}
/**
@@ -237,12 +242,12 @@
/**
* Returns a GVTLineMetrics object created with the specified arguments.
*/
- public GVTLineMetrics getLineMetrics(String str,
- int beginIndex,
+ public GVTLineMetrics getLineMetrics(String str,
+ int beginIndex,
int limit,
FontRenderContext frc) {
return new GVTLineMetrics
- (awtFont.getLineMetrics(str, beginIndex, limit, frc), scale);
+ (awtFont.getLineMetrics(str, beginIndex, limit, frc), scale);
}
/**
@@ -266,12 +271,61 @@
return 0f;
}
+ /////////////////////////////////////////////////////////////////////////
+
+ public static final float FONT_SIZE = 48f;
+
/**
- * Returns a string representation of this font. This is for debugging
- * purposes only.
- */
- public String toString() {
- return awtFont.getFontName();
+ * Returns the geometry of the specified character. This method also put
+ * the in cache the geometry associated to the specified character if
+ * needed.
+ */
+ public static
+ AWTGlyphGeometryCache.Value getGlyphGeometry(AWTGVTFont font,
+ char c,
+ GlyphVector gv,
+ int glyphIndex,
+ Point2D glyphPos) {
+
+ AWTGlyphGeometryCache glyphCache =
+ (AWTGlyphGeometryCache)fontCache.get(font.awtFont);
+
+ AWTGlyphGeometryCache.Value v = glyphCache.get(c);
+ if (v == null) {
+ Shape outline = gv.getGlyphOutline(glyphIndex);
+ GlyphMetrics metrics = gv.getGlyphMetrics(glyphIndex);
+ Rectangle2D gmB = metrics.getBounds2D();
+ if (AWTGVTGlyphVector.outlinesPositioned()) {
+ AffineTransform tr = AffineTransform.getTranslateInstance
+ (-glyphPos.getX(), -glyphPos.getY());
+ outline = tr.createTransformedShape(outline);
+ }
+ v = new AWTGlyphGeometryCache.Value(outline, gmB);
+ //System.out.println("put "+font.awtFont+" "+c);
+ glyphCache.put(c, v);
+ }
+ return v;
+ }
+
+ //
+ // static cache for AWTGVTFont
+ //
+
+ static Map fontCache = new HashMap(11);
+
+ static void initializeFontCache(Font awtFont) {
+ if (!fontCache.containsKey(awtFont)) {
+ fontCache.put(awtFont, new AWTGlyphGeometryCache());
+ }
+ }
+
+ static void putAWTGVTFont(AWTGVTFont font) {
+ fontCache.put(font.awtFont, font);
}
+
+ static AWTGVTFont getAWTGVTFont(Font awtFont) {
+ return (AWTGVTFont)fontCache.get(awtFont);
+ }
+
}
1.16 +84 -43
xml-batik/sources/org/apache/batik/gvt/font/AWTGVTGlyphVector.java
Index: AWTGVTGlyphVector.java
===================================================================
RCS file:
/home/cvs/xml-batik/sources/org/apache/batik/gvt/font/AWTGVTGlyphVector.java,v
retrieving revision 1.15
retrieving revision 1.16
diff -u -r1.15 -r1.16
--- AWTGVTGlyphVector.java 2001/12/10 22:00:59 1.15
+++ AWTGVTGlyphVector.java 2001/12/13 16:55:02 1.16
@@ -34,19 +34,20 @@
* This is a wrapper class for a java.awt.font.GlyphVector instance.
*
* @author <a href="mailto:[EMAIL PROTECTED]">Bella Robinson</a>
- * @version $Id: AWTGVTGlyphVector.java,v 1.15 2001/12/10 22:00:59 deweese Exp $
+ * @version $Id: AWTGVTGlyphVector.java,v 1.16 2001/12/13 16:55:02 tkormann Exp $
*/
public class AWTGVTGlyphVector implements GVTGlyphVector {
private GlyphVector awtGlyphVector;
private AWTGVTFont gvtFont;
private CharacterIterator ci;
- /** This contains the glyphPostions after doing a performDefaultLayout */
+
+ // This contains the glyphPostions after doing a performDefaultLayout
private Point2D[] defaultGlyphPositions;
private Point2D[] glyphPositions;
- // need to keep track of the glyphTransforms since GlyphVector doesn't seem
- // to
+ // need to keep track of the glyphTransforms since GlyphVector doesn't
+ // seem to
private AffineTransform[] glyphTransforms;
// these are for caching the glyph outlines
@@ -72,11 +73,11 @@
* handle font sizes less than 1 correctly. By using the scale factor we
* can use a GlyphVector created by a larger font and then scale it down to
* the correct size.
- * @param ci The character string that this glyph vector represents.
+ * @param ci The character string that this glyph vector represents.
*/
- public AWTGVTGlyphVector(GlyphVector glyphVector,
+ public AWTGVTGlyphVector(GlyphVector glyphVector,
AWTGVTFont font,
- float scaleFactor,
+ float scaleFactor,
CharacterIterator ci) {
this.awtGlyphVector = glyphVector;
@@ -157,10 +158,10 @@
/**
* Returns the logical bounds of the specified glyph within this
- * GlyphVector.
+ * GlyphVector.
*/
public Shape getGlyphLogicalBounds(int glyphIndex) {
- if (glyphLogicalBounds[glyphIndex] == null &&
+ if (glyphLogicalBounds[glyphIndex] == null &&
glyphVisible[glyphIndex]) {
computeGlyphLogicalBounds();
@@ -171,7 +172,7 @@
/**
* Calculates the logical bounds for each glyph. The logical
* bounds are what is used for highlighting the glyphs when
- * selected.
+ * selected.
*/
private void computeGlyphLogicalBounds() {
@@ -191,19 +192,19 @@
AffineTransform glyphTransform = getGlyphTransform(i);
GVTGlyphMetrics glyphMetrics = getGlyphMetrics(i);
-
+
float glyphX = 0;
float glyphY = -ascent/scaleFactor;
float glyphWidth = (glyphMetrics.getHorizontalAdvance()/
scaleFactor);
float glyphHeight = (glyphMetrics.getVerticalAdvance()/
scaleFactor);
-
- Rectangle2D glyphBounds = new Rectangle2D.Double(glyphX,
+
+ Rectangle2D glyphBounds = new Rectangle2D.Double(glyphX,
glyphY,
- glyphWidth,
+ glyphWidth,
glyphHeight);
-
+
if (glyphBounds.isEmpty()) {
if (i > 0) {
// can't tell if rotated or not, make it the same as
@@ -215,23 +216,23 @@
} else {
// get three corner points so we can determine
// whether the glyph is rotated
- Point2D p1 = new Point2D.Double(glyphBounds.getMinX(),
+ Point2D p1 = new Point2D.Double(glyphBounds.getMinX(),
glyphBounds.getMinY());
- Point2D p2 = new Point2D.Double(glyphBounds.getMaxX(),
+ Point2D p2 = new Point2D.Double(glyphBounds.getMaxX(),
glyphBounds.getMinY());
- Point2D p3 = new Point2D.Double(glyphBounds.getMinX(),
+ Point2D p3 = new Point2D.Double(glyphBounds.getMinX(),
glyphBounds.getMaxY());
-
+
AffineTransform tr = AffineTransform.getTranslateInstance
(getGlyphPosition(i).getX(),
getGlyphPosition(i).getY());
-
+
if (glyphTransform != null)
tr.concatenate(glyphTransform);
tr.scale(scaleFactor, scaleFactor);
tempLogicalBounds[i] = tr.createTransformedShape(glyphBounds);
-
+
Point2D tp1 = new Point2D.Double();
Point2D tp2 = new Point2D.Double();
Point2D tp3 = new Point2D.Double();
@@ -245,15 +246,15 @@
if (((Math.abs(tdx12) < 0.001) && (Math.abs(tdy13) < 0.001)) ||
((Math.abs(tdx13) < 0.001) && (Math.abs(tdy12) < 0.001))) {
- // If either of these are zero then it is axially aligned
+ // If either of these are zero then it is axially aligned
rotated[i] = false;
} else {
rotated [i] = true;
}
-
+
Rectangle2D rectBounds;
rectBounds = tempLogicalBounds[i].getBounds2D();
- if (rectBounds.getWidth() > maxWidth)
+ if (rectBounds.getWidth() > maxWidth)
maxWidth = rectBounds.getWidth();
if (rectBounds.getHeight() > maxHeight)
maxHeight = rectBounds.getHeight();
@@ -283,17 +284,17 @@
double x = glyphBounds.getMinX();
double width = glyphBounds.getWidth();
- if ((i < getNumGlyphs()-1) &&
+ if ((i < getNumGlyphs()-1) &&
(tempLogicalBounds[i+1] != null)) {
// make this glyph extend to the start of the next one
- Rectangle2D nextGlyphBounds =
+ Rectangle2D nextGlyphBounds =
tempLogicalBounds[i+1].getBounds2D();
- if (nextGlyphBounds.getX() > x) {
+ if (nextGlyphBounds.getX() > x) {
// going left to right (this is pretty hoky)
width = nextGlyphBounds.getX() - x;
} else {
- double newGlyphX = (nextGlyphBounds.getX() +
+ double newGlyphX = (nextGlyphBounds.getX() +
nextGlyphBounds.getWidth());
width += (x - newGlyphX);
x = newGlyphX;
@@ -301,7 +302,7 @@
}
tempLogicalBounds[i] = new Rectangle2D.Double
- (x, logicalBounds.getMinY(),
+ (x, logicalBounds.getMinY(),
width, logicalBounds.getHeight());
}
} else if (logicalBounds.getWidth() < maxWidth*1.5) {
@@ -316,15 +317,15 @@
double y = glyphBounds.getMinY();
double height = glyphBounds.getHeight();
- if ((i < getNumGlyphs()-1) &&
+ if ((i < getNumGlyphs()-1) &&
(tempLogicalBounds[i+1] != null)) {
// make this glyph extend to the start of the next one
- Rectangle2D nextGlyphBounds =
+ Rectangle2D nextGlyphBounds =
tempLogicalBounds[i+1].getBounds2D();
if (nextGlyphBounds.getY() > y) { // going top to bottom
height = nextGlyphBounds.getY() - y;
} else {
- double newGlyphY = (nextGlyphBounds.getY() +
+ double newGlyphY = (nextGlyphBounds.getY() +
nextGlyphBounds.getHeight());
height += (y - newGlyphY);
y = newGlyphY;
@@ -332,7 +333,7 @@
}
tempLogicalBounds[i] = new Rectangle2D.Double
- (logicalBounds.getMinX(), y,
+ (logicalBounds.getMinX(), y,
logicalBounds.getWidth(), height);
}
}
@@ -348,19 +349,30 @@
*/
public GVTGlyphMetrics getGlyphMetrics(int glyphIndex) {
if (glyphMetrics[glyphIndex] == null) {
+/*
GlyphMetrics gm = awtGlyphVector.getGlyphMetrics(glyphIndex);
Rectangle2D gmB = gm.getBounds2D();
+*/
+ // -- start glyph cache code --
+ Point2D glyphPos = defaultGlyphPositions[glyphIndex];
+ char c = ci.setIndex(ci.getBeginIndex()+glyphIndex);
+ ci.setIndex(ci.getBeginIndex());
+ AWTGlyphGeometryCache.Value v = AWTGVTFont.getGlyphGeometry
+ (gvtFont, c, awtGlyphVector, glyphIndex, glyphPos);
+ Rectangle2D gmB = v.getBounds2D();
+ // -- end glyph cache code --
+
Rectangle2D bounds = new Rectangle2D.Double
(gmB.getX() * scaleFactor, gmB.getY() * scaleFactor,
gmB.getWidth() * scaleFactor, gmB.getHeight() * scaleFactor);
-
+
// defaultGlyphPositions has one more entry than glyphs
// the last entry stores the total advance for the
// glyphVector.
float adv = (float)(defaultGlyphPositions[glyphIndex+1].getX()-
defaultGlyphPositions[glyphIndex] .getX());
glyphMetrics[glyphIndex] = new GVTGlyphMetrics
- (adv*scaleFactor, (ascent+descent),
+ (adv*scaleFactor, (ascent+descent),
bounds, GlyphMetrics.STANDARD);
}
return glyphMetrics[glyphIndex];
@@ -372,7 +384,17 @@
*/
public Shape getGlyphOutline(int glyphIndex) {
if (glyphOutlines[glyphIndex] == null) {
+/*
Shape glyphOutline = awtGlyphVector.getGlyphOutline(glyphIndex);
+*/
+ // -- start glyph cache code --
+ Point2D glyphPos = defaultGlyphPositions[glyphIndex];
+ char c = ci.setIndex(ci.getBeginIndex()+glyphIndex);
+ ci.setIndex(ci.getBeginIndex());
+ AWTGlyphGeometryCache.Value v = AWTGVTFont.getGlyphGeometry
+ (gvtFont, c, awtGlyphVector, glyphIndex, glyphPos);
+ Shape glyphOutline = v.getOutline();
+ // -- end glyph cache code --
AffineTransform tr = AffineTransform.getTranslateInstance
(getGlyphPosition(glyphIndex).getX(),
@@ -398,12 +420,12 @@
//
// -- Bella
//
-
+/*
if (outlinesPositioned()) {
Point2D glyphPos = defaultGlyphPositions[glyphIndex];
tr.translate(-glyphPos.getX(), -glyphPos.getY());
}
-
+*/
tr.scale(scaleFactor, scaleFactor);
glyphOutlines[glyphIndex]=tr.createTransformedShape(glyphOutline);
}
@@ -424,7 +446,7 @@
}
}
- private static boolean outlinesPositioned() {
+ static boolean outlinesPositioned() {
return outlinesPositioned;
}
@@ -438,7 +460,7 @@
/**
* Returns an array of glyph positions for the specified glyphs
*/
- public float[] getGlyphPositions(int beginGlyphIndex,
+ public float[] getGlyphPositions(int beginGlyphIndex,
int numEntries,
float[] positionReturn) {
@@ -467,8 +489,18 @@
*/
public Shape getGlyphVisualBounds(int glyphIndex) {
if (glyphVisualBounds[glyphIndex] == null) {
+/*
Shape glyphOutline = awtGlyphVector.getGlyphOutline(glyphIndex);
Rectangle2D glyphBounds = glyphOutline.getBounds2D();
+*/
+ // -- start glyph cache code --
+ Point2D glyphPos = defaultGlyphPositions[glyphIndex];
+ char c = ci.setIndex(ci.getBeginIndex()+glyphIndex);
+ ci.setIndex(ci.getBeginIndex());
+ AWTGlyphGeometryCache.Value v = AWTGVTFont.getGlyphGeometry
+ (gvtFont, c, awtGlyphVector, glyphIndex, glyphPos);
+ Rectangle2D glyphBounds = v.getOutlineBounds2D();
+ // -- end glyph cache code --
AffineTransform tr = AffineTransform.getTranslateInstance
(getGlyphPosition(glyphIndex).getX(),
@@ -479,7 +511,7 @@
tr.concatenate(glyphTransform);
}
tr.scale(scaleFactor, scaleFactor);
- glyphVisualBounds[glyphIndex] =
+ glyphVisualBounds[glyphIndex] =
tr.createTransformedShape(glyphBounds);
}
@@ -522,14 +554,19 @@
return outline;
}
+ private Rectangle2D visualBounds;
+
/**
* Returns the visual bounds of this GlyphVector The visual bounds is the
* tightest rectangle enclosing all non-background pixels in the rendered
* representation of this GlyphVector.
*/
public Rectangle2D getVisualBounds() {
- Shape outline = getOutline();
- return outline.getBounds2D();
+ if (visualBounds == null) {
+ Shape outline = getOutline();
+ visualBounds = outline.getBounds2D();
+ }
+ return visualBounds;
}
/**
@@ -544,6 +581,7 @@
}
outline = null;
+ visualBounds = null;
logicalBounds = null;
float shiftLeft = 0;
for (int i = 0; i < getNumGlyphs(); i++) {
@@ -570,10 +608,11 @@
* Sets the position of the specified glyph within this GlyphVector.
*/
public void setGlyphPosition(int glyphIndex, Point2D newPos) {
- glyphPositions[glyphIndex] =
+ glyphPositions[glyphIndex] =
new Point2D.Float((float)newPos.getX(), (float)newPos.getY());
outline = null;
logicalBounds = null;
+ visualBounds = null;
glyphVisualBounds[glyphIndex] = null;
glyphLogicalBounds[glyphIndex] = null;
glyphOutlines[glyphIndex] = null;
@@ -586,6 +625,7 @@
glyphTransforms[glyphIndex] = newTX;
outline = null;
logicalBounds = null;
+ visualBounds = null;
glyphVisualBounds[glyphIndex] = null;
glyphLogicalBounds[glyphIndex] = null;
glyphOutlines[glyphIndex] = null;
@@ -598,6 +638,7 @@
glyphVisible[glyphIndex] = visible;
outline = null;
logicalBounds = null;
+ visualBounds = null;
glyphVisualBounds[glyphIndex] = null;
glyphLogicalBounds[glyphIndex] = null;
glyphOutlines[glyphIndex] = null;
1.1
xml-batik/sources/org/apache/batik/gvt/font/AWTGlyphGeometryCache.java
Index: AWTGlyphGeometryCache.java
===================================================================
/*****************************************************************************
* Copyright (C) The Apache Software Foundation. All rights reserved. *
* ------------------------------------------------------------------------- *
* This software is published under the terms of the Apache Software License *
* version 1.1, a copy of which has been included with this distribution in *
* the LICENSE file. *
*****************************************************************************/
package org.apache.batik.gvt.font;
import java.awt.Shape;
import java.awt.font.GlyphMetrics;
import java.awt.font.GlyphVector;
import java.awt.geom.Rectangle2D;
import java.lang.ref.ReferenceQueue;
import java.lang.ref.SoftReference;
/**
* This class represents a doubly indexed hash table, which holds
* soft references to the contained glyph geometry informations.
*
* @author <a href="mailto:[EMAIL PROTECTED]">Stephane Hillion</a>
* @author <a href="mailto:[EMAIL PROTECTED]">Thierry Kormann</a>
* @version $Id: AWTGlyphGeometryCache.java,v 1.1 2001/12/13 16:55:02 tkormann Exp $
*/
public class AWTGlyphGeometryCache {
/**
* The initial capacity
*/
protected final static int INITIAL_CAPACITY = 71;
/**
* The underlying array
*/
protected Entry[] table;
/**
* The number of entries
*/
protected int count;
/**
* The reference queue.
*/
protected ReferenceQueue referenceQueue = new ReferenceQueue();
/**
* Creates a new AWTGlyphGeometryCache.
*/
public AWTGlyphGeometryCache() {
table = new Entry[INITIAL_CAPACITY];
}
/**
* Creates a new AWTGlyphGeometryCache.
* @param c The inital capacity.
*/
public AWTGlyphGeometryCache(int c) {
table = new Entry[c];
}
/**
* Returns the size of this table.
*/
public int size() {
return count;
}
/**
* Gets the value of a variable
* @return the value or null
*/
public Value get(char c) {
int hash = hashCode(c) & 0x7FFFFFFF;
int index = hash % table.length;
for (Entry e = table[index]; e != null; e = e.next) {
if ((e.hash == hash) && e.match(c)) {
return (Value)e.get();
}
}
return null;
}
/**
* Sets a new value for the given variable
* @return the old value or null
*/
public Value put(char c, Value value) {
removeClearedEntries();
int hash = hashCode(c) & 0x7FFFFFFF;
int index = hash % table.length;
Entry e = table[index];
if (e != null) {
if ((e.hash == hash) && e.match(c)) {
Object old = e.get();
table[index] = new Entry(hash, c, value, e.next);
return (Value)old;
}
Entry o = e;
e = e.next;
while (e != null) {
if ((e.hash == hash) && e.match(c)) {
Object old = e.get();
e = new Entry(hash, c, value, e.next);
o.next = e;
return (Value)old;
}
o = e;
e = e.next;
}
}
// The key is not in the hash table
int len = table.length;
if (count++ >= (len * 3) >>> 2) {
rehash();
index = hash % table.length;
}
table[index] = new Entry(hash, c, value, table[index]);
return null;
}
/**
* Clears the table.
*/
public void clear() {
table = new Entry[INITIAL_CAPACITY];
count = 0;
referenceQueue = new ReferenceQueue();
}
/**
* Rehash the table
*/
protected void rehash () {
Entry[] oldTable = table;
table = new Entry[oldTable.length * 2 + 1];
for (int i = oldTable.length-1; i >= 0; i--) {
for (Entry old = oldTable[i]; old != null;) {
Entry e = old;
old = old.next;
int index = e.hash % table.length;
e.next = table[index];
table[index] = e;
}
}
}
/**
* Computes a hash code corresponding to the given objects.
*/
protected int hashCode(char c) {
return c;
}
/**
* Removes the cleared entries.
*/
protected void removeClearedEntries() {
Entry e;
while ((e = (Entry)referenceQueue.poll()) != null) {
int index = e.hash % table.length;
Entry t = table[index];
if (t == e) {
table[index] = e.next;
} else {
loop: for (;t!=null;) {
Entry c = t.next;
if (c == e) {
t.next = e.next;
break loop;
}
t = c;
}
}
count--;
}
}
/**
* The object that holds glyph geometry.
*/
public static class Value {
protected Shape outline;
protected Rectangle2D gmB;
protected Rectangle2D outlineBounds;
/**
* Constructs a new Value with the specified parameter.
*/
public Value(Shape outline, Rectangle2D gmB) {
this.outline = outline;
this.outlineBounds = outline.getBounds2D();
this.gmB = gmB;
}
/**
* Returns the outline of the glyph.
*/
public Shape getOutline() {
return outline;
}
/**
* Returns the bounds of the glyph according to its glyph metrics.
*/
public Rectangle2D getBounds2D() {
return gmB;
}
/**
* Returns the bounds of the outline.
*/
public Rectangle2D getOutlineBounds2D() {
return outlineBounds;
}
}
/**
* To manage collisions
*/
protected class Entry extends SoftReference {
/**
* The hash code
*/
public int hash;
/**
* The character
*/
public char c;
/**
* The next entry
*/
public Entry next;
/**
* Creates a new entry
*/
public Entry(int hash, char c, Value value, Entry next) {
super(value, referenceQueue);
this.hash = hash;
this.c = c;
this.next = next;
}
/**
* Whether this entry match the given keys.
*/
public boolean match(char o2) {
return (c == o2);
}
}
}
1.16 +6 -2 xml-batik/sources/org/apache/batik/util/CSSConstants.java
Index: CSSConstants.java
===================================================================
RCS file: /home/cvs/xml-batik/sources/org/apache/batik/util/CSSConstants.java,v
retrieving revision 1.15
retrieving revision 1.16
diff -u -r1.15 -r1.16
--- CSSConstants.java 2001/11/21 10:05:57 1.15
+++ CSSConstants.java 2001/12/13 16:55:02 1.16
@@ -13,7 +13,7 @@
* Important: Constants must not contain uppercase characters.
*
* @author <a href="mailto:[EMAIL PROTECTED]">Stephane Hillion</a>
- * @version $Id: CSSConstants.java,v 1.15 2001/11/21 10:05:57 hillion Exp $
+ * @version $Id: CSSConstants.java,v 1.16 2001/12/13 16:55:02 tkormann Exp $
*/
public interface CSSConstants {
@@ -93,10 +93,11 @@
String CSS_ACTIVEBORDER_VALUE = "activeborder";
String CSS_ACTIVECAPTION_VALUE = "activecaption";
String CSS_AFTER_EDGE_VALUE = "after-edge";
+ String CSS_AUTOSENSE_SCRIPT_VALUE = "autosense-script";
+ String CSS_ALPHABETIC_VALUE = "alphabetic";
String CSS_ALL_VALUE = "all";
String CSS_APPWORKSPACE_VALUE = "appworkspace";
String CSS_AUTO_VALUE = "auto";
- String CSS_AUTOSENSE_SCRIPT_VALUE = "autosense-script";
String CSS_BACKGROUND_VALUE = "background";
String CSS_BASELINE_VALUE = "baseline";
String CSS_BEFORE_EDGE_VALUE = "before-edge";
@@ -114,6 +115,7 @@
String CSS_BUTTONTEXT_VALUE = "buttontext";
String CSS_CAPTIONTEXT_VALUE = "captiontext";
String CSS_CENTER_VALUE = "center";
+ String CSS_CENTRAL_VALUE = "central";
String CSS_COLLAPSE_VALUE = "collapse";
String CSS_COMPACT_VALUE = "compact";
String CSS_CONDENSED_VALUE = "condensed";
@@ -184,6 +186,7 @@
String CSS_PAINTED_VALUE = "painted";
String CSS_POINTER_VALUE = "pointer";
String CSS_RESET_VALUE = "reset";
+ String CSS_RESET_SIZE_VALUE = "reset-size";
String CSS_RL_VALUE = "rl";
String CSS_RL_TB_VALUE = "rl-tb";
String CSS_ROUND_VALUE = "round";
@@ -232,6 +235,7 @@
String CSS_ULTRA_CONDENSED_VALUE = "ultra-condensed";
String CSS_ULTRA_EXPANDED_VALUE = "ultra-expanded";
String CSS_UNDERLINE_VALUE = "underline";
+ String CSS_USE_SCRIPT_VALUE = "use-script";
String CSS_VISIBLE_VALUE = "visible";
String CSS_VISIBLEFILL_VALUE = "visiblefill";
String CSS_VISIBLEFILLSTROKE_VALUE = "visiblefillstroke";
---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]