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]

Reply via email to