deweese 01/10/29 13:13:41
Modified: sources/org/apache/batik/ext/awt/image/codec
PNGEncodeParam.java
sources/org/apache/batik/gvt/font AWTFontFamily.java
AWTGVTFont.java
sources/org/apache/batik/gvt/renderer
StrokingTextPainter.java
sources/org/apache/batik/gvt/text ArabicTextHandler.java
AttributedCharacterSpanIterator.java
BidiAttributedCharacterIterator.java
Log:
1) 7-10x improvement in PNG encoding time.
2) Improved arabic text handling interface to avoid needing
to construct AttributedString.
3) Reindented some of the GVT Text stuff.
Revision Changes Path
1.2 +103 -81
xml-batik/sources/org/apache/batik/ext/awt/image/codec/PNGEncodeParam.java
Index: PNGEncodeParam.java
===================================================================
RCS file:
/home/cvs/xml-batik/sources/org/apache/batik/ext/awt/image/codec/PNGEncodeParam.java,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- PNGEncodeParam.java 2001/01/23 17:07:13 1.1
+++ PNGEncodeParam.java 2001/10/29 21:13:41 1.2
@@ -1362,96 +1362,118 @@
byte[][] scratchRows,
int bytesPerRow,
int bytesPerPixel) {
- int[] filterBadness = new int[5];
- for (int i = 0; i < 5; i++) {
- filterBadness[i] = Integer.MAX_VALUE;
- }
-
- {
- int badness = 0;
-
- for (int i = bytesPerPixel; i < bytesPerRow + bytesPerPixel; i++) {
- int curr = currRow[i] & 0xff;
- badness += curr;
- }
-
- filterBadness[0] = badness;
- }
-
- {
- byte[] subFilteredRow = scratchRows[1];
- int badness = 0;
-
- for (int i = bytesPerPixel; i < bytesPerRow + bytesPerPixel; i++) {
- int curr = currRow[i] & 0xff;
- int left = currRow[i - bytesPerPixel] & 0xff;
- int difference = curr - left;
- subFilteredRow[i] = (byte)difference;
-
- badness += abs(difference);
- }
-
- filterBadness[1] = badness;
- }
-
- {
- byte[] upFilteredRow = scratchRows[2];
- int badness = 0;
-
- for (int i = bytesPerPixel; i < bytesPerRow + bytesPerPixel; i++) {
- int curr = currRow[i] & 0xff;
- int up = prevRow[i] & 0xff;
- int difference = curr - up;
- upFilteredRow[i] = (byte)difference;
+
+ int [] badness = {0, 0, 0, 0, 0};
+ int curr, left, up, upleft, diff;
+ int pa, pb, pc;
+ for (int i = bytesPerPixel; i < bytesPerRow + bytesPerPixel; i++) {
+ curr = currRow[i] & 0xff;
+ left = currRow[i - bytesPerPixel] & 0xff;
+ up = prevRow[i] & 0xff;
+ upleft = prevRow[i - bytesPerPixel] & 0xff;
- badness += abs(difference);
- }
-
- filterBadness[2] = badness;
- }
-
- {
- byte[] averageFilteredRow = scratchRows[3];
- int badness = 0;
+ // no filter
+ badness[0] += curr;
- for (int i = bytesPerPixel; i < bytesPerRow + bytesPerPixel; i++) {
- int curr = currRow[i] & 0xff;
- int left = currRow[i - bytesPerPixel] & 0xff;
- int up = prevRow[i] & 0xff;
- int difference = curr - (left + up)/2;;
- averageFilteredRow[i] = (byte)difference;
+ // sub filter
+ diff = curr - left;
+ scratchRows[1][i] = (byte)diff;
+ badness [1] += (diff>0)?diff:-diff;
+
+ // up filter
+ diff = curr - up;
+ scratchRows[2][i] = (byte)diff;
+ badness [2] += (diff>=0)?diff:-diff;
- badness += abs(difference);
- }
-
- filterBadness[3] = badness;
- }
-
- {
- byte[] paethFilteredRow = scratchRows[4];
- int badness = 0;
-
- for (int i = bytesPerPixel; i < bytesPerRow + bytesPerPixel; i++) {
- int curr = currRow[i] & 0xff;
- int left = currRow[i - bytesPerPixel] & 0xff;
- int up = prevRow[i] & 0xff;
- int upleft = prevRow[i - bytesPerPixel] & 0xff;
- int predictor = paethPredictor(left, up, upleft);
- int difference = curr - predictor;
- paethFilteredRow[i] = (byte)difference;
+ // average filter
+ diff = curr - ((left+up)>>1);
+ scratchRows[3][i] = (byte)diff;
+ badness [3] += (diff>=0)?diff:-diff;
- badness += abs(difference);
+ // paeth filter
+
+ // Original code much simplier but doesn't take full
+ // advantage of relationship between pa/b/c and
+ // information gleaned in abs operations.
+ /// pa = up -upleft;
+ /// pb = left-upleft;
+ /// pc = pa+pb;
+ /// pa = abs(pa);
+ /// pb = abs(pb);
+ /// pc = abs(pc);
+ /// if ((pa <= pb) && (pa <= pc))
+ /// diff = curr-left;
+ /// else if (pb <= pc)
+ /// diff = curr-up;
+ /// else
+ /// diff = curr-upleft;
+
+ pa = up -upleft;
+ pb = left-upleft;
+ if (pa<0) {
+ if (pb<0) {
+ // both pa & pb neg so pc is always greater than or
+ // equal to pa or pb;
+ if (pa >= pb) // since pa & pb neg check sense is reversed.
+ diff = curr-left;
+ else
+ diff = curr-up;
+ } else {
+ // pa neg pb pos so we must compute pc...
+ pc = pa+pb;
+ pa=-pa;
+ if (pa <= pb) // pc is positive and less than pb
+ if (pa <= pc)
+ diff = curr-left;
+ else
+ diff = curr-upleft;
+ else
+ // pc is negative and less than or equal to pa,
+ // but since pa is greater than pb this isn't an issue...
+ if (pb <= -pc)
+ diff = curr-up;
+ else
+ diff = curr-upleft;
+ }
+ } else {
+ if (pb<0) {
+ pb =-pb; // make it positive...
+ if (pa <= pb) {
+ // pc would be negative and less than or equal to pb
+ pc = pb-pa;
+ if (pa <= pc)
+ diff = curr-left;
+ else if (pb == pc)
+ // if pa is zero then pc==pb otherwise
+ // pc must be less than pb.
+ diff = curr-up;
+ else
+ diff = curr-upleft;
+ } else {
+ // pc would be positive and less than pa.
+ pc = pa-pb;
+ if (pb <= pc)
+ diff = curr-up;
+ else
+ diff = curr-upleft;
+ }
+ } else {
+ // both pos so pa+pb is always greater than pa/pb
+ if (pa <= pb)
+ diff = curr-left;
+ else
+ diff = curr-up;
+ }
}
-
- filterBadness[4] = badness;
+ scratchRows[4][i] = (byte)diff;
+ badness [4] += (diff>=0)?diff:-diff;
}
-
int filterType = 0;
- int minBadness = filterBadness[0];
+ int minBadness = badness[0];
for (int i = 1; i < 5; i++) {
- if (filterBadness[i] < minBadness) {
- minBadness = filterBadness[i];
+ if (badness[i] < minBadness) {
+ minBadness = badness[i];
filterType = i;
}
}
1.2 +3 -3 xml-batik/sources/org/apache/batik/gvt/font/AWTFontFamily.java
Index: AWTFontFamily.java
===================================================================
RCS file: /home/cvs/xml-batik/sources/org/apache/batik/gvt/font/AWTFontFamily.java,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- AWTFontFamily.java 2001/04/29 08:22:54 1.1
+++ AWTFontFamily.java 2001/10/29 21:13:41 1.2
@@ -18,7 +18,7 @@
* A font family class for AWT fonts.
*
* @author <a href="mailto:[EMAIL PROTECTED]">Bella Robinson</a>
- * @version $Id: AWTFontFamily.java,v 1.1 2001/04/29 08:22:54 dino Exp $
+ * @version $Id: AWTFontFamily.java,v 1.2 2001/10/29 21:13:41 deweese Exp $
*/
public class AWTFontFamily implements GVTFontFamily {
@@ -46,8 +46,8 @@
* Derives a GVTFont object of the correct size.
*
* @param size The required size of the derived font.
- * @param aci The character iterator that will be rendered using the derived
- * font.
+ * @param aci The character iterator that will be rendered using
+ * the derived font.
*/
public GVTFont deriveFont(float size, AttributedCharacterIterator aci) {
HashMap fontAttributes = new HashMap(aci.getAttributes());
1.8 +3 -4 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.7
retrieving revision 1.8
diff -u -r1.7 -r1.8
--- AWTGVTFont.java 2001/09/17 16:28:27 1.7
+++ AWTGVTFont.java 2001/10/29 21:13:41 1.8
@@ -34,7 +34,7 @@
* 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.7 2001/09/17 16:28:27 tkormann Exp $
+ * @version $Id: AWTGVTFont.java,v 1.8 2001/10/29 21:13:41 deweese Exp $
*/
public class AWTGVTFont implements GVTFont {
@@ -160,10 +160,9 @@
if (ci instanceof AttributedCharacterIterator) {
AttributedCharacterIterator aci = (AttributedCharacterIterator)ci;
- AttributedString as = new AttributedString(aci);
- if (ArabicTextHandler.containsArabic(as)) {
+ if (ArabicTextHandler.containsArabic(aci)) {
String substString =
- ArabicTextHandler.createSubstituteString(aci);
+ ArabicTextHandler.createSubstituteString(aci);
return createGlyphVector(frc, substString);
}
1.19 +23 -16
xml-batik/sources/org/apache/batik/gvt/renderer/StrokingTextPainter.java
Index: StrokingTextPainter.java
===================================================================
RCS file:
/home/cvs/xml-batik/sources/org/apache/batik/gvt/renderer/StrokingTextPainter.java,v
retrieving revision 1.18
retrieving revision 1.19
diff -u -r1.18 -r1.19
--- StrokingTextPainter.java 2001/10/23 13:42:29 1.18
+++ StrokingTextPainter.java 2001/10/29 21:13:41 1.19
@@ -60,7 +60,7 @@
* @see org.apache.batik.gvt.text.GVTAttributedCharacterIterator
*
* @author <a href="[EMAIL PROTECTED]>Bill Haneman</a>
- * @version $Id: StrokingTextPainter.java,v 1.18 2001/10/23 13:42:29 deweese Exp $
+ * @version $Id: StrokingTextPainter.java,v 1.19 2001/10/29 21:13:41 deweese Exp $
*/
public class StrokingTextPainter extends BasicTextPainter {
@@ -362,14 +362,17 @@
private AttributedCharacterIterator createModifiedACIForFontMatching
(TextNode node, AttributedCharacterIterator aci) {
+ // This looks like vestigial code, but perhaps it works around
+ // a bug...
+ // aci.first();
+ // AttributedCharacterSpanIterator acsi =
+ // new AttributedCharacterSpanIterator(aci, aci.getBeginIndex(),
+ // aci.getEndIndex());
+ //
+ // AttributedString as = new AttributedString(acsi);
+ AttributedString as = new AttributedString(aci);
aci.first();
- AttributedCharacterSpanIterator acsi =
- new AttributedCharacterSpanIterator(aci, aci.getBeginIndex(),
- aci.getEndIndex());
- AttributedString as = new AttributedString(acsi);
- aci.first();
-
boolean moreChunks = true;
while (moreChunks) {
int start = aci.getRunStart
@@ -380,8 +383,8 @@
AttributedCharacterSpanIterator runaci
= new AttributedCharacterSpanIterator(aci, start, end);
- Vector fontFamilies = (Vector)runaci.getAttributes().get(
- GVTAttributedCharacterIterator.TextAttribute.GVT_FONT_FAMILIES);
+ Vector fontFamilies = (Vector)runaci.getAttributes().get
+ (GVTAttributedCharacterIterator.TextAttribute.GVT_FONT_FAMILIES);
if (fontFamilies == null) {
// no font families set, just return the same aci
@@ -404,8 +407,9 @@
resolvedFontFamilies.add(fontFamily);
}
}
+
// if could not resolve at least one of the fontFamilies then use
- // the default faont
+ // the default font
if (resolvedFontFamilies.size() == 0) {
resolvedFontFamilies.add(FontFamilyResolver.defaultFont);
}
@@ -440,7 +444,8 @@
int currentRunIndex = runaci.getBeginIndex();
while (currentRunIndex < runaci.getEndIndex()) {
- int displayUpToIndex = font.canDisplayUpTo(runaci,
currentRunIndex, end);
+ int displayUpToIndex =
+ font.canDisplayUpTo(runaci, currentRunIndex, end);
if (displayUpToIndex == -1) {
// for each char, if not already assigned a font,
@@ -454,9 +459,9 @@
currentRunIndex = runaci.getEndIndex();
} else if (displayUpToIndex > currentRunIndex) {
- // could display some but not all
- // for each char it can display,
- // if not already assigned a font, assign this font to it
+ // could display some but not all, so for each
+ // char it can display, if char not already
+ // assigned a font, assign this font to it
for (int j = currentRunIndex; j < displayUpToIndex; j++) {
if (!fontAssigned[j - start]) {
as.addAttribute(GVTAttributedCharacterIterator.TextAttribute.GVT_FONT, font, j, j+1);
@@ -471,11 +476,13 @@
}
}
}
+
// assign the first font to any chars haven't alreay been assigned
for (int i = 0; i < runaciLength; i++) {
if (!fontAssigned[i]) {
- GVTFontFamily fontFamily
- =
FontFamilyResolver.getFamilyThatCanDisplay(runaci.setIndex(start+i));
+ GVTFontFamily fontFamily
+ = FontFamilyResolver.getFamilyThatCanDisplay
+ (runaci.setIndex(start+i));
if (fontFamily != null) {
GVTFont font = fontFamily.deriveFont(fontSize, runaci);
as.addAttribute(GVTAttributedCharacterIterator.TextAttribute.GVT_FONT,
1.2 +16 -6
xml-batik/sources/org/apache/batik/gvt/text/ArabicTextHandler.java
Index: ArabicTextHandler.java
===================================================================
RCS file:
/home/cvs/xml-batik/sources/org/apache/batik/gvt/text/ArabicTextHandler.java,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- ArabicTextHandler.java 2001/07/05 06:26:22 1.1
+++ ArabicTextHandler.java 2001/10/29 21:13:41 1.2
@@ -21,7 +21,7 @@
* text is rendered using an AWT font.
*
* @author <a href="mailto:[EMAIL PROTECTED]">Bella Robinson</a>
- * @version $Id: ArabicTextHandler.java,v 1.1 2001/07/05 06:26:22 bella Exp $
+ * @version $Id: ArabicTextHandler.java,v 1.2 2001/10/29 21:13:41 deweese Exp $
*/
public class ArabicTextHandler {
@@ -31,11 +31,12 @@
private final static Map charMap = new HashMap(54);
/**
- * If the AttributedString contains any arabic chars, assigns an arabic form
- * attribute, ie. initial|medial|terminal|isolated, to each arabic char.
+ * If the AttributedString contains any arabic chars, assigns an
+ * arabic form attribute, ie. initial|medial|terminal|isolated, to
+ * each arabic char.
*
* @param as The string to attach the arabic form attributes to.
- * @return An attributed string with arabic form attributes.
+ * @return An attributed string with arabic form attributes.
*/
public static AttributedString assignArabicForms(AttributedString as) {
@@ -227,8 +228,17 @@
* @return True if at least one char is arabic, false otherwise.
*/
public static boolean containsArabic(AttributedString as) {
+ return containsArabic(as.getIterator());
+ }
+
+ /**
+ * Returns true if the ACI contains any arabic characters.
+ *
+ * @param aci The AttributedCharacterIterator to test.
+ * @return True if at least one char is arabic, false otherwise.
+ */
+ public static boolean containsArabic(AttributedCharacterIterator aci) {
char c;
- AttributedCharacterIterator aci = as.getIterator();
for (int i = aci.getBeginIndex(); i < aci.getEndIndex(); i++) {
c = aci.setIndex(i);
if (arabicChar(c)) {
@@ -655,4 +665,4 @@
}
-}
\ No newline at end of file
+}
1.5 +9 -7
xml-batik/sources/org/apache/batik/gvt/text/AttributedCharacterSpanIterator.java
Index: AttributedCharacterSpanIterator.java
===================================================================
RCS file:
/home/cvs/xml-batik/sources/org/apache/batik/gvt/text/AttributedCharacterSpanIterator.java,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -r1.4 -r1.5
--- AttributedCharacterSpanIterator.java 2001/05/14 16:46:44 1.4
+++ AttributedCharacterSpanIterator.java 2001/10/29 21:13:41 1.5
@@ -26,7 +26,7 @@
* AttributedString.
*
* @author <a href="mailto:[EMAIL PROTECTED]">Bill Haneman</a>
- * @version $Id: AttributedCharacterSpanIterator.java,v 1.4 2001/05/14 16:46:44
tkormann Exp $
+ * @version $Id: AttributedCharacterSpanIterator.java,v 1.5 2001/10/29 21:13:41
deweese Exp $
*/
public class AttributedCharacterSpanIterator implements
@@ -43,8 +43,9 @@
* @param start the first index of the subinterval
* @param stop the index of the first character after the subinterval
*/
- public AttributedCharacterSpanIterator(AttributedCharacterIterator aci, int
start, int stop) {
- this.aci = aci;
+ public AttributedCharacterSpanIterator(AttributedCharacterIterator aci,
+ int start, int stop) {
+ this.aci = aci;
end = Math.min(aci.getEndIndex(), stop);
begin = Math.max(aci.getBeginIndex(), start);
this.aci.setIndex(begin);
@@ -64,7 +65,7 @@
* Get the value of the named attribute for the current
* character.
*/
- public Object getAttribute(AttributedCharacterIterator.Attribute attribute) {
+ public Object getAttribute(Attribute attribute) {
return aci.getAttribute(attribute);
}
@@ -122,9 +123,10 @@
}
/**
- * Get the index of the first character of the run with
- * respect to the given attributes containing the current character.
- * @param attributes the Set of attributes which begins at the returned index.
+ * Get the index of the first character of the run with respect to
+ * the given attributes containing the current character.
+ * @param attributes the Set of attributes which begins at the
+ * returned index.
*/
public int getRunStart(Set attributes) {
return Math.max(aci.getRunStart(attributes), begin);
1.3 +7 -5
xml-batik/sources/org/apache/batik/gvt/text/BidiAttributedCharacterIterator.java
Index: BidiAttributedCharacterIterator.java
===================================================================
RCS file:
/home/cvs/xml-batik/sources/org/apache/batik/gvt/text/BidiAttributedCharacterIterator.java,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -r1.2 -r1.3
--- BidiAttributedCharacterIterator.java 2001/07/05 06:29:21 1.2
+++ BidiAttributedCharacterIterator.java 2001/10/29 21:13:41 1.3
@@ -25,7 +25,7 @@
* in a text run will all have the same bidi level.
*
* @author <a href="mailto:[EMAIL PROTECTED]">Bella Robinson</a>
- * @version $Id: BidiAttributedCharacterIterator.java,v 1.2 2001/07/05 06:29:21
bella Exp $
+ * @version $Id: BidiAttributedCharacterIterator.java,v 1.3 2001/10/29 21:13:41
deweese Exp $
*/
public class BidiAttributedCharacterIterator implements AttributedCharacterIterator
{
@@ -44,7 +44,8 @@
* order.
* @param frc The current font render context
*/
- public BidiAttributedCharacterIterator(AttributedCharacterIterator aci,
FontRenderContext frc) {
+ public BidiAttributedCharacterIterator(AttributedCharacterIterator aci,
+ FontRenderContext frc) {
this.frc = frc;
aci.first();
@@ -54,8 +55,9 @@
int numChars = tl.getCharacterCount();
AttributedString as = new AttributedString(aci);
for (int i = 0; i < numChars; i++) {
- as.addAttribute(GVTAttributedCharacterIterator.TextAttribute.BIDI_LEVEL,
- new Integer(tl.getCharacterLevel(i)), i, i+1);
+ as.addAttribute
+ (GVTAttributedCharacterIterator.TextAttribute.BIDI_LEVEL,
+ new Integer(tl.getCharacterLevel(i)), i, i+1);
}
this.aci = as.getIterator();
@@ -481,4 +483,4 @@
}
-}
\ No newline at end of file
+}
---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]