/[classpath]/classpath/gnu/java/awt/peer/gtk/GdkGraphics2D.java
ViewVC logotype

Diff of /classpath/gnu/java/awt/peer/gtk/GdkGraphics2D.java

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 1.15.2.1 by gnu_andrew, Fri Jan 14 10:24:04 2005 UTC revision 1.15.2.2 by gnu_andrew, Sat Jan 15 17:01:40 2005 UTC
# Line 1  Line 1 
1  /* GdkGraphics2D.java  /* GdkGraphics2D.java
2     Copyright (C) 2003, 2004 Free Software Foundation, Inc.     Copyright (C) 2003, 2004  Free Software Foundation, Inc.
3    
4  This file is part of GNU Classpath.  This file is part of GNU Classpath.
5    
# Line 38  exception statement from your version. * Line 38  exception statement from your version. *
38    
39  package gnu.java.awt.peer.gtk;  package gnu.java.awt.peer.gtk;
40    
41  import java.awt.*;  import gnu.classpath.Configuration;
42  import java.awt.geom.*;  import gnu.java.awt.ClasspathToolkit;
43  import java.awt.font.*;  import gnu.java.awt.peer.ClasspathFontPeer;
 import java.awt.color.*;  
 import java.awt.image.*;  
 import java.awt.image.renderable.*;  
 import java.util.HashMap;  
 import java.util.Map;  
44    
45    import java.awt.AlphaComposite;
46    import java.awt.BasicStroke;
47    import java.awt.Color;
48    import java.awt.Composite;
49    import java.awt.Font;
50    import java.awt.FontMetrics;
51    import java.awt.GradientPaint;
52    import java.awt.Graphics;
53    import java.awt.Graphics2D;
54    import java.awt.GraphicsConfiguration;
55    import java.awt.Image;
56    import java.awt.Paint;
57    import java.awt.Rectangle;
58    import java.awt.RenderingHints;
59    import java.awt.Shape;
60    import java.awt.Stroke;
61    import java.awt.TexturePaint;
62    import java.awt.Toolkit;
63    import java.awt.color.ColorSpace;
64    import java.awt.font.FontRenderContext;
65    import java.awt.font.GlyphVector;
66    import java.awt.font.GlyphJustificationInfo;
67    import java.awt.geom.Arc2D;
68    import java.awt.geom.GeneralPath;
69    import java.awt.geom.NoninvertibleTransformException;
70    import java.awt.geom.PathIterator;
71    import java.awt.geom.Point2D;
72    import java.awt.geom.Rectangle2D;
73    import java.awt.geom.AffineTransform;
74    import java.awt.image.AffineTransformOp;
75    import java.awt.image.BufferedImage;
76    import java.awt.image.BufferedImageOp;
77    import java.awt.image.ColorModel;
78    import java.awt.image.CropImageFilter;
79    import java.awt.image.DataBuffer;
80    import java.awt.image.DataBufferInt;
81    import java.awt.image.FilteredImageSource;
82    import java.awt.image.ImageConsumer;
83    import java.awt.image.ImageObserver;
84    import java.awt.image.ImagingOpException;
85    import java.awt.image.SampleModel;
86    import java.awt.image.Raster;
87    import java.awt.image.RenderedImage;
88    import java.awt.image.WritableRaster;
89    import java.awt.image.renderable.RenderableImage;
90    import java.awt.image.renderable.RenderContext;
91  import java.text.AttributedCharacterIterator;  import java.text.AttributedCharacterIterator;
92    import java.util.HashMap;
93    import java.util.Map;
94  import java.util.Stack;  import java.util.Stack;
 import java.lang.Integer;  
 import gnu.java.awt.ClasspathToolkit;  
 import gnu.java.awt.peer.ClasspathFontPeer;  
 import gnu.classpath.Configuration;  
95    
96  public class GdkGraphics2D extends Graphics2D  public class GdkGraphics2D extends Graphics2D
97  {  {
# Line 95  public class GdkGraphics2D extends Graph Line 134  public class GdkGraphics2D extends Graph
134    native public void dispose ();    native public void dispose ();
135    native private int[] getImagePixels();    native private int[] getImagePixels();
136    native private void cairoSurfaceSetFilter(int filter);    native private void cairoSurfaceSetFilter(int filter);
137      native void connectSignals (GtkComponentPeer component);
138    
139    public void finalize ()    public void finalize ()
140    {    {
# Line 115  public class GdkGraphics2D extends Graph Line 155  public class GdkGraphics2D extends Graph
155    {    {
156      paint = g.paint;      paint = g.paint;
157      stroke = g.stroke;      stroke = g.stroke;
158      hints = g.hints;      setRenderingHints (g.hints);
159    
160      if (g.fg.getAlpha() != -1)      if (g.fg.getAlpha() != -1)
161        fg = new Color (g.fg.getRed (), g.fg.getGreen (),        fg = new Color (g.fg.getRed (), g.fg.getGreen (),
# Line 170  public class GdkGraphics2D extends Graph Line 210  public class GdkGraphics2D extends Graph
210    GdkGraphics2D (GtkComponentPeer component)    GdkGraphics2D (GtkComponentPeer component)
211    {    {
212      this.component = component;      this.component = component;
213    
214        setFont (new Font("SansSerif", Font.PLAIN, 12));
215    
216        if (component.isRealized ())
217          initComponentGraphics2D ();
218        else
219          connectSignals (component);
220      }
221    
222      void initComponentGraphics2D ()
223      {
224      initState (component);      initState (component);
225    
226      setColor (component.awtComponent.getForeground ());      setColor (component.awtComponent.getForeground ());
227      setBackground (component.awtComponent.getBackground ());      setBackground (component.awtComponent.getBackground ());
228      setPaint (getColor());      setPaint (getColor());
     setFont (new Font("SansSerif", Font.PLAIN, 12));  
229      setTransform (new AffineTransform ());      setTransform (new AffineTransform ());
230      setStroke (new BasicStroke ());      setStroke (new BasicStroke ());
231      setRenderingHints (getDefaultHints());      setRenderingHints (getDefaultHints());
# Line 226  public class GdkGraphics2D extends Graph Line 276  public class GdkGraphics2D extends Graph
276    private native void cairoSave ();    private native void cairoSave ();
277    private native void cairoRestore ();    private native void cairoRestore ();
278    private native void cairoSetMatrix (double m[]);    private native void cairoSetMatrix (double m[]);
   private native void cairoSetFont (GdkClasspathFontPeer peer);  
   private native void cairoShowGlyphs (int codes[],  
                                        float positions[]);  
279    private native void cairoSetOperator (int cairoOperator);    private native void cairoSetOperator (int cairoOperator);
280    private native void cairoSetRGBColor (double red, double green, double blue);    private native void cairoSetRGBColor (double red, double green, double blue);
281    private native void cairoSetAlpha (double alpha);    private native void cairoSetAlpha (double alpha);
# Line 308  public class GdkGraphics2D extends Graph Line 355  public class GdkGraphics2D extends Graph
355          cairoRestore ();          cairoRestore ();
356      }      }
357    
358      // Some operations (drawing rather than filling) require that their
359      // coords be shifted to land on 0.5-pixel boundaries, in order to land on
360      // "middle of pixel" coordinates and light up complete pixels.
361    
362    double x;    private boolean shiftDrawCalls = false;
363    double y;    private final double shifted(double coord, boolean doShift)
   private void setPos (double nx, double ny)  
364    {    {
365      x = nx;      if (doShift)
366      y = ny;        return Math.floor(coord) + 0.5;
367        else
368          return coord;
369    }    }
370    
371    private void walkPath(PathIterator p)    private final void walkPath(PathIterator p, boolean doShift)
372    {    {
373        double x = 0;
374        double y = 0;
375      double coords[] = new double[6];      double coords[] = new double[6];
376    
377      cairoSetFillRule (p.getWindingRule ());      cairoSetFillRule (p.getWindingRule ());
# Line 329  public class GdkGraphics2D extends Graph Line 382  public class GdkGraphics2D extends Graph
382            {            {
383    
384            case PathIterator.SEG_MOVETO:            case PathIterator.SEG_MOVETO:
385              setPos(coords[0], coords[1]);              x = shifted(coords[0], doShift);
386              cairoMoveTo (coords[0], coords[1]);              y = shifted(coords[1], doShift);
387                cairoMoveTo (x, y);
388              break;              break;
389    
390            case PathIterator.SEG_LINETO:            case PathIterator.SEG_LINETO:
391              setPos(coords[0], coords[1]);              x = shifted(coords[0], doShift);
392              cairoLineTo (coords[0], coords[1]);              y = shifted(coords[1], doShift);
393                cairoLineTo (x, y);
394              break;              break;
395    
396            case PathIterator.SEG_QUADTO:            case PathIterator.SEG_QUADTO:
# Line 343  public class GdkGraphics2D extends Graph Line 398  public class GdkGraphics2D extends Graph
398              // splitting a quadratic bezier into a cubic:              // splitting a quadratic bezier into a cubic:
399              // see: http://pfaedit.sourceforge.net/bezier.html              // see: http://pfaedit.sourceforge.net/bezier.html
400    
401              double x1 = x + (2.0/3.0) * (coords[0] - x);              double x1 = x + (2.0/3.0) * (shifted(coords[0], doShift) - x);
402              double y1 = y + (2.0/3.0) * (coords[1] - y);              double y1 = y + (2.0/3.0) * (shifted(coords[1], doShift) - y);
403                            
404              double x2 = x1 + (1.0/3.0) * (coords[2] - x);              double x2 = x1 + (1.0/3.0) * (shifted(coords[2], doShift) - x);
405              double y2 = y1 + (1.0/3.0) * (coords[3] - y);              double y2 = y1 + (1.0/3.0) * (shifted(coords[3], doShift) - y);
406    
407              setPos(coords[2], coords[3]);              x = shifted(coords[2], doShift);
408                y = shifted(coords[3], doShift);
409              cairoCurveTo (x1, y1,              cairoCurveTo (x1, y1,
410                            x2, y2,                            x2, y2,
411                            coords[2], coords[3]);                            x, y);
412              break;              break;
413    
414            case PathIterator.SEG_CUBICTO:            case PathIterator.SEG_CUBICTO:
415              setPos(coords[4], coords[5]);              x = shifted(coords[4], doShift);
416              cairoCurveTo (coords[0], coords[1],              y = shifted(coords[5], doShift);
417                            coords[2], coords[3],              cairoCurveTo (shifted(coords[0], doShift), shifted(coords[1], doShift),
418                            coords[4], coords[5]);                            shifted(coords[2], doShift), shifted(coords[3], doShift),
419                              x, y);
420              break;              break;
421    
422            case PathIterator.SEG_CLOSE:            case PathIterator.SEG_CLOSE:
# Line 370  public class GdkGraphics2D extends Graph Line 427  public class GdkGraphics2D extends Graph
427    }    }
428    
429    
430    private Map getDefaultHints()    private final Map getDefaultHints()
431    {    {
432      HashMap defaultHints = new HashMap ();      HashMap defaultHints = new HashMap ();
433            
# Line 393  public class GdkGraphics2D extends Graph Line 450  public class GdkGraphics2D extends Graph
450            
451    }    }
452    
453    private void updateBufferedImage()    private final void updateBufferedImage()
454    {    {
455      int[] pixels = getImagePixels();      int[] pixels = getImagePixels();
456      updateImagePixels(pixels);      updateImagePixels(pixels);
457    }    }
458    
459        
460    private boolean isBufferedImageGraphics ()    private final boolean isBufferedImageGraphics ()
461    {    {
462        return bimage != null;
     if (bimage != null)  
       return true;  
     else  
       return false;  
463    }    }
464            
465    private void updateImagePixels (int[] pixels)    private final void updateImagePixels (int[] pixels)
466    {    {
467    
468      // This function can only be used if      // This function can only be used if
# Line 444  public class GdkGraphics2D extends Graph Line 497  public class GdkGraphics2D extends Graph
497    }    }
498    
499    
500    private boolean drawImage(Image img,    private final boolean drawImage(Image img,
501                              AffineTransform xform,                                    AffineTransform xform,
502                              Color bgcolor,                                                              Color bgcolor,                            
503                              ImageObserver obs)                                    ImageObserver obs)
504    {    {
505      if (img instanceof GtkOffScreenImage &&      if (img instanceof GtkOffScreenImage &&
506          img.getGraphics () instanceof GdkGraphics2D &&                      img.getGraphics () instanceof GdkGraphics2D &&            
# Line 480  public class GdkGraphics2D extends Graph Line 533  public class GdkGraphics2D extends Graph
533    
534          try          try
535            {                        {            
536                invertedXform = xform.createInverse();              invertedXform = xform.createInverse();
537               if (img instanceof BufferedImage)               if (img instanceof BufferedImage)
538                 {                 {
539                     // draw an image which has actually been loaded                     // draw an image which has actually been loaded
540                     // into memory fully                     // into memory fully
541                                        
542                       BufferedImage b = (BufferedImage) img;                   BufferedImage b = (BufferedImage) img;
543                     return drawRaster (b.getColorModel (),                   return drawRaster (b.getColorModel (),
544                                        b.getData (),                                      b.getData (),
545                                        invertedXform,                                      invertedXform,
546                                        bgcolor);                                      bgcolor);
547                 }                 }
548               else               else
549                 {                 {
550                     // begin progressive loading in a separate thread                   return this.drawImage(GdkPixbufDecoder.createBufferedImage(img.getSource()),
551                     new PainterThread (this, img, invertedXform, bgcolor);                                         xform, bgcolor,obs);
                    return false;  
552                 }                               }              
553            }            }
554          catch (NoninvertibleTransformException e)          catch (NoninvertibleTransformException e)
# Line 522  public class GdkGraphics2D extends Graph Line 574  public class GdkGraphics2D extends Graph
574          return;          return;
575        }        }
576    
     stateSave ();  
577      cairoNewPath ();      cairoNewPath ();
   
     boolean normalize;  
     normalize = hints.containsValue (RenderingHints.VALUE_STROKE_NORMALIZE)  
                 || hints.containsValue (RenderingHints.VALUE_STROKE_DEFAULT);  
   
     if (normalize)  
       translate (0.5,0.5);        
578            
579      if (s instanceof Rectangle2D)      if (s instanceof Rectangle2D)
580        {        {
581          Rectangle2D r = (Rectangle2D)s;          Rectangle2D r = (Rectangle2D)s;
582          cairoRectangle (r.getX (), r.getY (), r.getWidth (), r.getHeight ());          cairoRectangle (shifted(r.getX (), shiftDrawCalls),
583                            shifted(r.getY (), shiftDrawCalls),
584                            r.getWidth (), r.getHeight ());
585        }        }
586      else            else      
587        walkPath (s.getPathIterator (null));        walkPath (s.getPathIterator (null), shiftDrawCalls);
588      cairoStroke ();      cairoStroke ();
589            
     if (normalize)  
       translate (-0.5,-0.5);  
         
     stateRestore ();  
       
590      if (isBufferedImageGraphics ())      if (isBufferedImageGraphics ())
591        updateBufferedImage();          updateBufferedImage();  
   
592    }    }
593    
594    public void fill (Shape s)    public void fill (Shape s)
595    {    {
     stateSave();  
596      cairoNewPath ();      cairoNewPath ();
597      if (s instanceof Rectangle2D)      if (s instanceof Rectangle2D)
598        {        {
# Line 561  public class GdkGraphics2D extends Graph Line 600  public class GdkGraphics2D extends Graph
600          cairoRectangle (r.getX (), r.getY (), r.getWidth (), r.getHeight ());          cairoRectangle (r.getX (), r.getY (), r.getWidth (), r.getHeight ());
601        }        }
602      else            else      
603        walkPath (s.getPathIterator (null));        walkPath (s.getPathIterator (null), false);
604      cairoFill ();      cairoFill ();
     stateRestore ();  
605            
606     if (isBufferedImageGraphics ())     if (isBufferedImageGraphics ())
607       updateBufferedImage();         updateBufferedImage();  
# Line 597  public class GdkGraphics2D extends Graph Line 635  public class GdkGraphics2D extends Graph
635                                        r.getWidth (), r.getHeight ());                                        r.getWidth (), r.getHeight ());
636                    }                    }
637                else                else
638                    walkPath (clip.getPathIterator (null));                  walkPath (clip.getPathIterator (null), false);
639                cairoClosePath ();                // cairoClosePath ();
640                cairoClip ();                cairoClip ();
641            }            }
642    }    }
# Line 744  public class GdkGraphics2D extends Graph Line 782  public class GdkGraphics2D extends Graph
782        {        {
783          BasicStroke bs = (BasicStroke) stroke;          BasicStroke bs = (BasicStroke) stroke;
784          cairoSetLineCap (bs.getEndCap());          cairoSetLineCap (bs.getEndCap());
785          cairoSetLineWidth (bs.getLineWidth() / 2.0);          cairoSetLineWidth (bs.getLineWidth());
786          cairoSetLineJoin (bs.getLineJoin());          cairoSetLineJoin (bs.getLineJoin());
787          cairoSetMiterLimit (bs.getMiterLimit());          cairoSetMiterLimit (bs.getMiterLimit());
788          float dashes[] = bs.getDashArray();          float dashes[] = bs.getDashArray();
# Line 810  public class GdkGraphics2D extends Graph Line 848  public class GdkGraphics2D extends Graph
848        return clip.getBounds ();        return clip.getBounds ();
849    }    }
850    
851      protected Rectangle2D getClipInDevSpace ()    protected Rectangle2D getClipInDevSpace ()
852      {    {
853          Rectangle2D uclip = clip.getBounds2D ();      Rectangle2D uclip = clip.getBounds2D ();
854          if (transform == null)      if (transform == null)
855              return uclip;        return uclip;
856          else      else
857              {        {
858                  Point2D pos = transform.transform (new Point2D.Double(uclip.getX (),          Point2D pos = transform.transform (new Point2D.Double(uclip.getX (),
859                                                                        uclip.getY ()),                                                                uclip.getY ()),
860                                                     (Point2D)null);                                                           (Point2D)null);              
861                  Point2D extent = transform.deltaTransform (new Point2D.Double(uclip.getWidth (),          Point2D extent = transform.deltaTransform (new Point2D.Double(uclip.getWidth (),
862                                                                                uclip.getHeight ()),                                                                        uclip.getHeight ()),
863                                                             (Point2D)null);                                                     (Point2D)null);
864                  return new Rectangle2D.Double (pos.getX (), pos.getY (),          return new Rectangle2D.Double (pos.getX (), pos.getY (),
865                                                 extent.getX (), extent.getY ());                                               extent.getX (), extent.getY ());      
866              }        }
867      }    }
868    
869    public void setClip (int x, int y, int width, int height)    public void setClip (int x, int y, int width, int height)
870    {    {
# Line 847  public class GdkGraphics2D extends Graph Line 885  public class GdkGraphics2D extends Graph
885                              r.getWidth (), r.getHeight ());                              r.getWidth (), r.getHeight ());
886            }            }
887          else          else
888            walkPath (s.getPathIterator (null));            walkPath (s.getPathIterator (null), false);
889          cairoClosePath ();          // cairoClosePath ();
890          cairoClip ();          cairoClip ();
891        }        }
892    }    }
893        
894      private static BasicStroke draw3DRectStroke = new BasicStroke();
895    
896    public void draw3DRect(int x, int y, int width,    public void draw3DRect(int x, int y, int width,
897                           int height, boolean raised)                           int height, boolean raised)
898    {    {
899      Color std = fg;      Stroke tmp = stroke;
900      Color light = std.brighter();      setStroke(draw3DRectStroke);
901      Color dark = std.darker();      super.draw3DRect(x, y, width, height, raised);
902        setStroke(tmp);    
     if (!raised)  
       {  
         Color t = light;  
         light = dark;  
         dark = t;  
       }  
       
     double x1 = (double) x;  
     double x2 = (double) x + width;  
   
     double y1 = (double) y;  
     double y2 = (double) y + height;  
   
     stateSave ();  
       
     cairoNewPath ();  
       
     boolean normalize;  
     normalize = hints.containsValue (RenderingHints.VALUE_STROKE_NORMALIZE)  
                 || hints.containsValue (RenderingHints.VALUE_STROKE_DEFAULT);  
                   
     if (normalize)  
       {  
         x1 += 0.5;  
         y1 += 0.5;  
         x2 += 0.5;  
         y2 += 0.5;  
       }  
       
     setColor (light);  
     cairoMoveTo (x1, y1);  
     cairoLineTo (x2, y1);  
     cairoLineTo (x2, y2);  
     cairoStroke ();  
       
     cairoNewPath ();  
     setColor (dark);  
     cairoMoveTo (x1, y1);  
     cairoLineTo (x1, y2);  
     cairoLineTo (x2, y2);  
     cairoStroke ();  
       
     stateRestore ();      
       
903      if (isBufferedImageGraphics ())      if (isBufferedImageGraphics ())
904        updateBufferedImage();          updateBufferedImage();  
   
905    }    }
906    
907    public void fill3DRect(int x, int y, int width,    public void fill3DRect(int x, int y, int width,
908                           int height, boolean raised)                           int height, boolean raised)
909    {    {
910      double step = 1.0;      Stroke tmp = stroke;
911      if (stroke != null && stroke instanceof BasicStroke)      setStroke(draw3DRectStroke);
912        {      super.fill3DRect(x, y, width, height, raised);
913          BasicStroke bs = (BasicStroke) stroke;      setStroke(tmp);    
         step = bs.getLineWidth();  
       }  
   
     Color bright = fg.brighter ();  
     Color dark = fg.darker ();  
         
     draw3DRect (x, y, width, height, raised);  
       
     stateSave ();  
     translate (step/2.0, step/2.0);  
     cairoNewPath ();  
     cairoRectangle ((double) x, (double) y,  
                     ((double) width) - step,  
                     ((double) height) - step );  
     cairoClosePath ();  
     cairoFill ();  
     stateRestore ();  
       
914      if (isBufferedImageGraphics ())      if (isBufferedImageGraphics ())
915        updateBufferedImage();          updateBufferedImage();  
   
916    }    }
917    
918    
# Line 947  public class GdkGraphics2D extends Graph Line 923  public class GdkGraphics2D extends Graph
923    
924    public void fillRect (int x, int y, int width, int height)    public void fillRect (int x, int y, int width, int height)
925    {    {
926      fill(new Rectangle (x, y, width, height));      cairoNewPath ();
927        cairoRectangle (x, y, width, height);
928        cairoFill ();
929    }    }
930    
931    public void clearRect (int x, int y, int width, int height)    public void clearRect (int x, int y, int width, int height)
932    {    {
     stateSave ();  
933      cairoSetRGBColor (bg.getRed() / 255.0,      cairoSetRGBColor (bg.getRed() / 255.0,
934                        bg.getGreen() / 255.0,                        bg.getGreen() / 255.0,
935                        bg.getBlue() / 255.0);                        bg.getBlue() / 255.0);
936      cairoSetAlpha (1.0);      cairoSetAlpha (1.0);
937      cairoNewPath ();      cairoNewPath ();
938      cairoRectangle (x, y, width, height);      cairoRectangle (x, y, width, height);
     cairoClosePath ();  
939      cairoFill ();      cairoFill ();
940      stateRestore ();      setColor (fg);
941                
942      if (isBufferedImageGraphics ())      if (isBufferedImageGraphics ())
943        updateBufferedImage();          updateBufferedImage();  
# Line 978  public class GdkGraphics2D extends Graph Line 954  public class GdkGraphics2D extends Graph
954      return bg;      return bg;
955    }    }
956    
957    private void doPolygon(int[] xPoints, int[] yPoints, int nPoints,    private final void doPolygon(int[] xPoints, int[] yPoints, int nPoints,
958                           boolean close, boolean fill)                                 boolean close, boolean fill)
959    {        {    
960      if (nPoints < 1)      if (nPoints < 1)
961        return;        return;
# Line 1034  public class GdkGraphics2D extends Graph Line 1010  public class GdkGraphics2D extends Graph
1010      doPolygon (xPoints, yPoints, nPoints, false, false);      doPolygon (xPoints, yPoints, nPoints, false, false);
1011    }    }
1012    
1013    private boolean drawRaster (ColorModel cm, Raster r,    private final boolean drawRaster (ColorModel cm, Raster r,
1014                                AffineTransform imageToUser,                                      AffineTransform imageToUser,
1015                                Color bgcolor)                                      Color bgcolor)
1016    {    {
1017      if (r == null)      if (r == null)
1018        return false;        return false;
# Line 1095  public class GdkGraphics2D extends Graph Line 1071  public class GdkGraphics2D extends Graph
1071            }            }
1072        }        }
1073    
     stateSave ();  
     translate (x, y);  
1074      drawPixels (pixels, r.getWidth (), r.getHeight (), r.getWidth (), i2u);      drawPixels (pixels, r.getWidth (), r.getHeight (), r.getWidth (), i2u);
     stateRestore ();      
1075            
1076      if (isBufferedImageGraphics ())      if (isBufferedImageGraphics ())
1077        updateBufferedImage();          updateBufferedImage();  
# Line 1141  public class GdkGraphics2D extends Graph Line 1114  public class GdkGraphics2D extends Graph
1114    }    }
1115    
1116    
   ////////////////////////////////////////  
   ////// Supporting Private Classes //////  
   ////////////////////////////////////////  
     
   private class PainterThread implements Runnable, ImageConsumer  
   {  
   
     // this is a helper which is spun off when someone tries to do  
     // Graphics2D.drawImage on an image we cannot determine to be either  
     // one of our own offscreen images or a BufferedImage; that is, when  
     // someone wants to draw an image which is possibly still loading over  
     // a network or something. you run it in a separate thread and it  
     // writes through to the underlying Graphics2D as pixels becomg  
     // available.  
   
     GdkGraphics2D gr;  
     Image image;  
     ColorModel defaultModel;  
     AffineTransform xform;  
     Color bgcolor;  
   
     public PainterThread (GdkGraphics2D g, Image im,  
                           AffineTransform xf, Color bg)  
     {  
       image = im;  
       xform = xf;  
       bgcolor = bg;  
       this.gr = (GdkGraphics2D) g.create ();  
       new Thread (this).start ();  
     }  
       
     public void imageComplete (int status)  
     {  
     }  
       
     public void setColorModel (ColorModel model)  
     {  
       defaultModel = model;  
     }  
       
     public void setDimensions (int width, int height)  
     {  
     }  
       
     public void setHints (int hintflags)  
     {  
     }  
       
     public void setPixels (int x, int y, int w, int h, ColorModel model,  
                            byte[] pixels, int off, int scansize)  
     {  
     }  
       
     public void setPixels (int x, int y, int w, int h, ColorModel model,  
                            int[] pixels, int off, int scansize)  
       {  
         gr.stateSave ();  
         gr.translate (x, y);  
   
         if (model == null)  
           model = defaultModel;  
   
         int pixels2[];  
         if (model != null)  
           {  
             pixels2 = new int[pixels.length];  
             for (int yy = 0; yy < h; yy++)  
               for (int xx = 0; xx < w; xx++)  
                 {  
                   int i = yy * scansize + xx;  
                   pixels2[i] = model.getRGB (pixels[i]);  
                 }  
           }  
         else  
           pixels2 = pixels;  
   
         // change all transparent pixels in the image to the  
         // specified bgcolor  
               
         if (bgcolor != null)  
           {  
             for (int i = 0; i < pixels2.length; i++)  
               {  
                 if (model.getAlpha (pixels2[i]) == 0)  
                 pixels2[i] = bgcolor.getRGB ();      
               }  
           }  
   
         double[] xf = new double[6];  
         xform.getMatrix(xf);          
         gr.drawPixels (pixels2, w, h, scansize, xf);  
         gr.stateRestore ();  
       }  
   
     public void setProperties (java.util.Hashtable props)  
     {  
     }  
       
     public void run ()  
     {  
       image.getSource ().startProduction (this);  
       gr.dispose ();  
     }  
   }  
   
   
   
1117    ///////////////////////////////////////////////    ///////////////////////////////////////////////
1118    ////// Unimplemented Stubs and Overloads //////    ////// Unimplemented Stubs and Overloads //////
1119    ///////////////////////////////////////////////    ///////////////////////////////////////////////
# Line 1307  public class GdkGraphics2D extends Graph Line 1173  public class GdkGraphics2D extends Graph
1173          else if (hintValue.equals(RenderingHints.VALUE_ALPHA_INTERPOLATION_DEFAULT))          else if (hintValue.equals(RenderingHints.VALUE_ALPHA_INTERPOLATION_DEFAULT))
1174             cairoSurfaceSetFilter(4);             cairoSurfaceSetFilter(4);
1175                
1176        }        }
1177    
1178        shiftDrawCalls = hints.containsValue (RenderingHints.VALUE_STROKE_NORMALIZE)
1179          || hints.containsValue (RenderingHints.VALUE_STROKE_DEFAULT);
1180        
1181    }    }
1182    
1183    public Object getRenderingHint(RenderingHints.Key hintKey)    public Object getRenderingHint(RenderingHints.Key hintKey)
# Line 1341  public class GdkGraphics2D extends Graph Line 1210  public class GdkGraphics2D extends Graph
1210           else if(hints.containsValue(RenderingHints.VALUE_ALPHA_INTERPOLATION_DEFAULT))           else if(hints.containsValue(RenderingHints.VALUE_ALPHA_INTERPOLATION_DEFAULT))
1211              cairoSurfaceSetFilter(4);              cairoSurfaceSetFilter(4);
1212        }              }      
1213    
1214        shiftDrawCalls = hints.containsValue (RenderingHints.VALUE_STROKE_NORMALIZE)
1215          || hints.containsValue (RenderingHints.VALUE_STROKE_DEFAULT);
1216    }    }
1217    
1218    public void addRenderingHints(Map hints)    public void addRenderingHints(Map hints)
# Line 1366  public class GdkGraphics2D extends Graph Line 1238  public class GdkGraphics2D extends Graph
1238      return new FontRenderContext (transform, true, true);      return new FontRenderContext (transform, true, true);
1239    }    }
1240    
   public void drawGlyphVector (GlyphVector g, float x, float y)  
   {      
     stateSave ();  
     setFont (g.getFont ());  
     translate ((double)x, (double)y);  
     cairoMoveTo (0, 0);  
     int nglyphs = g.getNumGlyphs ();  
     int codes[] = g.getGlyphCodes (0, nglyphs, (int []) null);  
     float posns[] = g.getGlyphPositions (0, nglyphs, (float []) null);  
     cairoShowGlyphs (codes, posns);  
       
     if (isBufferedImageGraphics ())  
       updateBufferedImage();    
   
     stateRestore ();  
   }  
   
1241    public void copyArea (int x, int y, int width, int height, int dx, int dy)    public void copyArea (int x, int y, int width, int height, int dx, int dy)
1242    {    {
1243      throw new java.lang.UnsupportedOperationException ();      throw new java.lang.UnsupportedOperationException ();
# Line 1514  public class GdkGraphics2D extends Graph Line 1369  public class GdkGraphics2D extends Graph
1369      drawLine (x1, y + height, x2, y + height);      drawLine (x1, y + height, x2, y + height);
1370    }    }
1371    
1372    public void drawString (String str, int x, int y)    // these are the most accelerated painting paths
1373      native void cairoDrawGdkGlyphVector (GdkFontPeer f, GdkGlyphVector gv, float x, float y);
1374      native void cairoDrawGdkTextLayout (GdkFontPeer f, GdkTextLayout gl, float x, float y);
1375      native void cairoDrawString (GdkFontPeer f, String str, float x, float y);
1376    
1377      GdkFontPeer getFontPeer()
1378    {    {
1379      drawString (str, (float)x, (float)y);      return (GdkFontPeer) getFont().getPeer();
1380      }
1381    
1382      public void drawGdkGlyphVector(GdkGlyphVector gv, float x, float y)
1383      {
1384        cairoDrawGdkGlyphVector(getFontPeer(), gv, x, y);
1385        if (isBufferedImageGraphics ())
1386          updateBufferedImage();  
1387      }
1388    
1389      public void drawGdkTextLayout(GdkTextLayout gl, float x, float y)
1390      {
1391        cairoDrawGdkTextLayout(getFontPeer(), gl, x, y);
1392        if (isBufferedImageGraphics ())
1393          updateBufferedImage();  
1394    }    }
1395    
1396    public void drawString (String str, float x, float y)    public void drawString (String str, float x, float y)
1397    {    {
1398      GlyphVector gv = font.createGlyphVector (getFontRenderContext(), str);      cairoDrawString(getFontPeer(), str, x, y);
1399      drawGlyphVector (gv, x, y);      if (isBufferedImageGraphics ())
1400          updateBufferedImage();      
1401      }
1402    
1403      public void drawString (String str, int x, int y)
1404      {
1405        drawString (str, (float)x, (float)y);
1406    }    }
1407    
1408    public void drawString (AttributedCharacterIterator ci, int x, int y)    public void drawString (AttributedCharacterIterator ci, int x, int y)
# Line 1530  public class GdkGraphics2D extends Graph Line 1410  public class GdkGraphics2D extends Graph
1410      drawString (ci, (float)x, (float)y);      drawString (ci, (float)x, (float)y);
1411    }    }
1412    
1413      public void drawGlyphVector (GlyphVector gv, float x, float y)
1414      {
1415        if (gv instanceof GdkGlyphVector)
1416          drawGdkGlyphVector((GdkGlyphVector)gv, x, y);
1417        else
1418          throw new java.lang.UnsupportedOperationException ();
1419      }
1420    
1421    public void drawString (AttributedCharacterIterator ci, float x, float y)    public void drawString (AttributedCharacterIterator ci, float x, float y)
1422    {    {
1423      GlyphVector gv = font.createGlyphVector (getFontRenderContext(), ci);      GlyphVector gv = font.createGlyphVector (getFontRenderContext(), ci);
# Line 1575  public class GdkGraphics2D extends Graph Line 1463  public class GdkGraphics2D extends Graph
1463      return font;      return font;
1464    }    }
1465    
1466      // Until such time as pango is happy to talk directly to cairo, we
1467      // actually need to redirect some calls from the GtkFontPeer and
1468      // GtkFontMetrics into the drawing kit and ask cairo ourselves.
1469    
1470      static native void releasePeerGraphicsResource(GdkFontPeer f);
1471      static native void getPeerTextMetrics (GdkFontPeer f, String str, double [] metrics);
1472      static native void getPeerFontMetrics (GdkFontPeer f, double [] metrics);
1473    
1474    public FontMetrics getFontMetrics ()    public FontMetrics getFontMetrics ()
1475    {    {
1476        // the reason we go via the toolkit here is to try to get
1477        // a cached object. the toolkit keeps such a cache.
1478      return Toolkit.getDefaultToolkit ().getFontMetrics (font);      return Toolkit.getDefaultToolkit ().getFontMetrics (font);
1479    }    }
1480    
1481    public FontMetrics getFontMetrics (Font f)    public FontMetrics getFontMetrics (Font f)
1482    {    {
1483        // the reason we go via the toolkit here is to try to get
1484        // a cached object. the toolkit keeps such a cache.
1485      return Toolkit.getDefaultToolkit ().getFontMetrics (f);      return Toolkit.getDefaultToolkit ().getFontMetrics (f);
1486    }    }
1487    
1488    public void setFont (Font f)    public void setFont (Font f)
1489    {    {
1490      if (f.getPeer() instanceof GdkClasspathFontPeer)      if (f.getPeer() instanceof GdkFontPeer)
1491        font = f;        font = f;
1492      else      else
1493        font =        font =
1494          ((ClasspathToolkit)(Toolkit.getDefaultToolkit ()))          ((ClasspathToolkit)(Toolkit.getDefaultToolkit ()))
1495          .getFont (f.getName(), f.getAttributes ());          .getFont (f.getName(), f.getAttributes ());    
   
     if (f != null &&  
         f.getPeer() instanceof GdkClasspathFontPeer)  
       cairoSetFont ((GdkClasspathFontPeer) f.getPeer());  
1496    }    }
1497      
1498    public String toString()    public String toString()
1499    {    {
1500      return  getClass ().getName () +      return  getClass ().getName () +

Legend:
Removed from v.1.15.2.1  
changed lines
  Added in v.1.15.2.2

savannah-hackers-public@gnu.org
ViewVC Help
Powered by ViewVC 1.1.26