1:
37:
38:
39: package ;
40:
41: import ;
42: import ;
43: import ;
44: import ;
45: import ;
46: import ;
47: import ;
48: import ;
49: import ;
50: import ;
51: import ;
52: import ;
53: import ;
54: import ;
55: import ;
56: import ;
57: import ;
58:
59:
65: public class BufferedImageGraphics extends CairoGraphics2D
66: {
67:
70: private BufferedImage image;
71:
72:
75: private int imageWidth, imageHeight;
76:
77:
80: CairoSurface surface;
81:
82:
85: static WeakHashMap bufferedImages = new WeakHashMap();
86:
87:
90: private long cairo_t;
91:
92:
95: static ColorModel rgb32 = new DirectColorModel(32, 0xFF0000, 0xFF00, 0xFF);
96: static ColorModel argb32 = new DirectColorModel(32, 0xFF0000, 0xFF00, 0xFF,
97: 0xFF000000);
98: private boolean hasFastCM;
99: private boolean hasAlpha;
100:
101:
102: public BufferedImageGraphics(BufferedImage bi)
103: {
104: this.image = bi;
105: imageWidth = bi.getWidth();
106: imageHeight = bi.getHeight();
107: if(bi.getColorModel().equals(rgb32))
108: {
109: hasFastCM = true;
110: hasAlpha = false;
111: }
112: else if(bi.getColorModel().equals(argb32))
113: {
114: hasFastCM = true;
115: hasAlpha = false;
116: }
117: else
118: hasFastCM = false;
119:
120:
121: if( bufferedImages.get( bi ) != null )
122: surface = (CairoSurface)bufferedImages.get( bi );
123: else
124: {
125: surface = new CairoSurface( imageWidth, imageHeight );
126: bufferedImages.put(bi, surface);
127: }
128:
129: cairo_t = surface.newCairoContext();
130:
131: DataBuffer db = bi.getRaster().getDataBuffer();
132: int[] pixels;
133:
134:
135: if(db instanceof CairoSurface)
136: pixels = ((CairoSurface)db).getPixels(imageWidth * imageHeight);
137: else
138: {
139: if( hasFastCM )
140: {
141: pixels = ((DataBufferInt)db).getData();
142: if( !hasAlpha )
143: for(int i = 0; i < pixels.length; i++)
144: pixels[i] &= 0xFFFFFFFF;
145: }
146: else
147: {
148: pixels = CairoGraphics2D.findSimpleIntegerArray
149: (image.getColorModel(),image.getData());
150: }
151: }
152: surface.setPixels( pixels );
153:
154: setup( cairo_t );
155: setClip(0, 0, imageWidth, imageHeight);
156: }
157:
158: BufferedImageGraphics(BufferedImageGraphics copyFrom)
159: {
160: surface = copyFrom.surface;
161: cairo_t = surface.newCairoContext();
162: imageWidth = copyFrom.imageWidth;
163: imageHeight = copyFrom.imageHeight;
164: copy( copyFrom, cairo_t );
165: setClip(0, 0, surface.width, surface.height);
166: }
167:
168:
171: private void updateBufferedImage(int x, int y, int width, int height)
172: {
173: int[] pixels = surface.getPixels(imageWidth * imageHeight);
174:
175: if( x > imageWidth || y > imageHeight )
176: return;
177:
178: if( x < 0 ){ width = width + x; x = 0; }
179: if( y < 0 ){ height = height + y; y = 0; }
180: if( x + width > imageWidth )
181: width = imageWidth - x;
182: if( y + height > imageHeight )
183: height = imageHeight - y;
184:
185: if( !hasFastCM )
186: image.setRGB(x, y, width, height, pixels,
187: x + y * imageWidth, imageWidth);
188: else
189: System.arraycopy(pixels, y * imageWidth,
190: ((DataBufferInt)image.getRaster().getDataBuffer()).
191: getData(), y * imageWidth, height * imageWidth);
192: }
193:
194:
197: public Graphics create()
198: {
199: return new BufferedImageGraphics(this);
200: }
201:
202: public GraphicsConfiguration getDeviceConfiguration()
203: {
204: return null;
205: }
206:
207: protected Rectangle2D getRealBounds()
208: {
209: return new Rectangle2D.Double(0.0, 0.0, imageWidth, imageHeight);
210: }
211:
212: public void copyAreaImpl(int x, int y, int width, int height, int dx, int dy)
213: {
214: surface.copyAreaNative(x, y, width, height, dx, dy, surface.width);
215: updateBufferedImage(x + dx, y + dy, width, height);
216: }
217:
218:
222: public void draw(Shape s)
223: {
224: super.draw(s);
225: Rectangle r = s.getBounds();
226: updateBufferedImage(r.x, r.y, r.width, r.height);
227: }
228:
229: public void fill(Shape s)
230: {
231: super.fill(s);
232: Rectangle r = s.getBounds();
233: updateBufferedImage(r.x, r.y, r.width, r.height);
234: }
235:
236: public void drawRenderedImage(RenderedImage image, AffineTransform xform)
237: {
238: super.drawRenderedImage(image, xform);
239: updateBufferedImage(0, 0, imageWidth, imageHeight);
240: }
241:
242: protected boolean drawImage(Image img, AffineTransform xform,
243: Color bgcolor, ImageObserver obs)
244: {
245: boolean rv = super.drawImage(img, xform, bgcolor, obs);
246: updateBufferedImage(0, 0, imageWidth, imageHeight);
247: return rv;
248: }
249:
250: public void drawGlyphVector(GlyphVector gv, float x, float y)
251: {
252: super.drawGlyphVector(gv, x, y);
253: updateBufferedImage(0, 0, imageWidth, imageHeight);
254: }
255: }