KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > batik > ext > awt > image > rendered > TileRed


1 /*
2
3    Copyright 2001,2003 The Apache Software Foundation
4
5    Licensed under the Apache License, Version 2.0 (the "License");
6    you may not use this file except in compliance with the License.
7    You may obtain a copy of the License at
8
9        http://www.apache.org/licenses/LICENSE-2.0
10
11    Unless required by applicable law or agreed to in writing, software
12    distributed under the License is distributed on an "AS IS" BASIS,
13    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14    See the License for the specific language governing permissions and
15    limitations under the License.
16
17  */

18 package org.apache.batik.ext.awt.image.rendered;
19
20 import java.awt.AlphaComposite JavaDoc;
21 import java.awt.Color JavaDoc;
22 import java.awt.Graphics2D JavaDoc;
23 import java.awt.Point JavaDoc;
24 import java.awt.Rectangle JavaDoc;
25 import java.awt.RenderingHints JavaDoc;
26 import java.awt.geom.AffineTransform JavaDoc;
27 import java.awt.image.BufferedImage JavaDoc;
28 import java.awt.image.ColorModel JavaDoc;
29 import java.awt.image.DataBufferInt JavaDoc;
30 import java.awt.image.Raster JavaDoc;
31 import java.awt.image.RenderedImage JavaDoc;
32 import java.awt.image.SampleModel JavaDoc;
33 import java.awt.image.SinglePixelPackedSampleModel JavaDoc;
34 import java.awt.image.WritableRaster JavaDoc;
35
36 import org.apache.batik.ext.awt.image.GraphicsUtil;
37 import org.apache.batik.util.HaltingThread;
38
39 /**
40  * This filter simply tiles its tile starting from the upper
41  * left corner of the tiled region.
42  *
43  * @author <a HREF="mailto:vincent.hardy@eng.sun.com">Vincent Hardy</a>
44  * @version $Id: TileRed.java,v 1.15 2004/10/23 17:11:03 deweese Exp $
45  */

46 public class TileRed extends AbstractRed implements TileGenerator {
47     static final AffineTransform JavaDoc IDENTITY = new AffineTransform JavaDoc();
48
49     /**
50      * Area tiled by this filter.
51      */

52     Rectangle JavaDoc tiledRegion;
53
54     int xStep;
55     int yStep;
56
57     TileStore tiles;
58
59     private RenderingHints JavaDoc hints;
60
61     final boolean is_INT_PACK;
62     final boolean alphaPremult;
63
64     /**
65      * Tile
66      */

67     RenderedImage JavaDoc tile = null;
68     WritableRaster JavaDoc raster = null;
69
70
71     public TileRed(RenderedImage JavaDoc tile,
72                    Rectangle JavaDoc tiledRegion) {
73         this(tile, tiledRegion, tile.getWidth(), tile.getHeight(), null);
74     }
75
76     public TileRed(RenderedImage JavaDoc tile,
77                    Rectangle JavaDoc tiledRegion,
78                    RenderingHints JavaDoc hints) {
79         this(tile, tiledRegion, tile.getWidth(), tile.getHeight(), hints);
80     }
81
82     public TileRed(RenderedImage JavaDoc tile,
83                    Rectangle JavaDoc tiledRegion,
84                    int xStep, int yStep) {
85         this(tile, tiledRegion, xStep, yStep, null);
86     }
87
88     public TileRed(RenderedImage JavaDoc tile,
89                    Rectangle JavaDoc tiledRegion,
90                    int xStep, int yStep,
91                    RenderingHints JavaDoc hints) {
92         if(tiledRegion == null){
93             throw new IllegalArgumentException JavaDoc();
94         }
95
96         if(tile == null){
97             throw new IllegalArgumentException JavaDoc();
98         }
99
100         // org.apache.batik.test.gvt.ImageDisplay.showImage("Tile: ", tile);
101
this.tiledRegion = tiledRegion;
102         this.xStep = xStep;
103         this.yStep = yStep;
104         this.hints = hints;
105         this.alphaPremult = false;
106
107         SampleModel JavaDoc sm = fixSampleModel(tile, xStep, yStep,
108                                         tiledRegion.width,
109                                         tiledRegion.height);
110         ColorModel JavaDoc cm = fixColorModel(tile, alphaPremult);
111
112         double smSz = AbstractTiledRed.getDefaultTileSize();
113         smSz = smSz*smSz;
114
115         double stepSz = (xStep*(double)yStep);
116         // be prepaired to grow the default tile size quite a bit if
117
// it means the image tile will fit in it...
118
if (16.1*smSz > stepSz) {
119             int xSz = xStep;
120             int ySz = yStep;
121
122             // If the pattern size is small then have multiple copies
123
// in our tile.
124
if (4*stepSz <= smSz) {
125                 int mult = (int)Math.ceil(Math.sqrt(smSz/stepSz));
126                 xSz *= mult;
127                 ySz *= mult;
128             }
129             // System.out.println("Using Raster for pattern");
130
sm = sm.createCompatibleSampleModel(xSz, ySz);
131             raster = Raster.createWritableRaster
132                 (sm, new Point JavaDoc(tile.getMinX(), tile.getMinY()));
133         }
134         
135         is_INT_PACK = GraphicsUtil.is_INT_PACK_Data(sm, false);
136         // System.out.println("Is INT PACK: " + is_INT_PACK);
137

138         // Initialize our base class We set our bounds be we will
139
// respond with data for any area we cover. This is needed
140
// because the userRegion passed into PatterPaintContext
141
// doesn't account for stroke So we use that as a basis but
142
// when the context asks us for stuff outside that region we
143
// complie.
144
init((CachableRed)null, tiledRegion, cm, sm,
145              tile.getMinX(), tile.getMinY(), null);
146
147         if (raster != null) {
148             WritableRaster JavaDoc fromRaster = raster.createWritableChild
149                 (tile.getMinX(), tile.getMinY(),
150                  xStep, yStep, tile.getMinX(), tile.getMinY(), null);
151
152             // Fill one 'tile' of the input....
153
fillRasterFrom(fromRaster, tile);
154             fillOutRaster(raster);
155         }
156         else {
157             this.tile = new TileCacheRed(GraphicsUtil.wrap(tile));
158         }
159     }
160
161     public WritableRaster JavaDoc copyData(WritableRaster JavaDoc wr) {
162         int xOff = ((int)Math.floor(wr.getMinX()/xStep))*xStep;
163         int yOff = ((int)Math.floor(wr.getMinY()/yStep))*yStep;
164         int x0 = wr.getMinX()-xOff;
165         int y0 = wr.getMinY()-yOff;
166         int tx0 = getXTile(x0);
167         int ty0 = getYTile(y0);
168         int tx1 = getXTile(x0+wr.getWidth() -1);
169         int ty1 = getYTile(y0+wr.getHeight()-1);
170
171         for (int y=ty0; y<=ty1; y++)
172             for (int x=tx0; x<=tx1; x++) {
173                 Raster JavaDoc r = getTile(x, y);
174                 r = r.createChild(r.getMinX(), r.getMinY(),
175                                   r.getWidth(), r.getHeight(),
176                                   r.getMinX()+xOff, r.getMinY()+yOff, null);
177                 if (is_INT_PACK)
178                     GraphicsUtil.copyData_INT_PACK(r, wr);
179                 else
180                     GraphicsUtil.copyData_FALLBACK(r, wr);
181             }
182         return wr;
183     }
184
185
186     public Raster JavaDoc getTile(int x, int y) {
187         
188         if (raster!=null) {
189             // We have a Single raster that we translate where needed
190
// position. So just offest appropriately.
191
int tx = tileGridXOff+x*tileWidth;
192             int ty = tileGridYOff+y*tileHeight;
193             return raster.createTranslatedChild(tx, ty);
194         }
195
196         // System.out.println("Checking Cache [" + x + "," + y + "]");
197
return genTile(x,y);
198     }
199
200     public Raster JavaDoc genTile(int x, int y) {
201       // System.out.println("Cache Miss [" + x + "," + y + "]");
202
int tx = tileGridXOff+x*tileWidth;
203         int ty = tileGridYOff+y*tileHeight;
204         
205         if (raster!=null) {
206             // We have a Single raster that we translate where needed
207
// position. So just offest appropriately.
208
return raster.createTranslatedChild(tx, ty);
209         }
210
211         Point JavaDoc pt = new Point JavaDoc(tx, ty);
212         WritableRaster JavaDoc wr = Raster.createWritableRaster(sm, pt);
213         fillRasterFrom(wr, tile);
214         return wr;
215     }
216
217     public WritableRaster JavaDoc fillRasterFrom(WritableRaster JavaDoc wr, RenderedImage JavaDoc src){
218         // System.out.println("Getting Raster : " + count + " " + wr.getMinX() + "/" + wr.getMinY() + "/" + wr.getWidth() + "/" + wr.getHeight());
219
// System.out.println("Tile : " + tile.getMinX() + "/" + tile.getMinY() + "/" + tile.getWidth() + "/" + tile.getHeight());
220

221         ColorModel JavaDoc cm = getColorModel();
222         BufferedImage JavaDoc bi
223             = new BufferedImage JavaDoc(cm,
224                                 wr.createWritableTranslatedChild(0, 0),
225                                 cm.isAlphaPremultiplied(), null);
226
227         Graphics2D JavaDoc g = GraphicsUtil.createGraphics(bi, hints);
228
229         int minX = wr.getMinX();
230         int minY = wr.getMinY();
231         int maxX = wr.getWidth();
232         int maxY = wr.getHeight();
233
234
235         g.setComposite(AlphaComposite.Clear);
236         g.setColor(new Color JavaDoc(0, 0, 0, 0));
237         g.fillRect(0, 0, maxX, maxY);
238         g.setComposite(AlphaComposite.SrcOver);
239
240         g.translate(-minX, -minY);
241
242         // Process initial translate so that tile is
243
// painted to the left of the raster top-left
244
// corner on the first drawRenderedImage
245
int x1 = src.getMinX()+src.getWidth()-1;
246         int y1 = src.getMinY()+src.getHeight()-1;
247
248         int tileTx = (int)Math.ceil(((minX-x1)/xStep))*xStep;
249         int tileTy = (int)Math.ceil(((minY-y1)/yStep))*yStep;
250
251         g.translate(tileTx, tileTy);
252
253         int curX = tileTx - wr.getMinX() + src.getMinX();
254         int curY = tileTy - wr.getMinY() + src.getMinY();
255
256         // System.out.println("Wr: " + wr.getBounds());
257
// System.out.println("Src : [" + src.getMinX() + ", " +
258
// src.getMinY() + ", " +
259
// src.getWidth() + ", " +
260
// src.getHeight() + "]");
261
// System.out.println("tileTx/tileTy : " + tileTx + " / " + tileTy);
262
minX = curX;
263         while(curY < maxY) {
264             if (HaltingThread.hasBeenHalted())
265                 return wr;
266
267             while (curX < maxX) {
268                 // System.out.println("curX/curY : " + curX + " / " + curY);
269
// System.out.println("transform : " +
270
// g.getTransform().getTranslateX() +
271
// " / " +
272
// g.getTransform().getTranslateY());
273
GraphicsUtil.drawImage(g, src);
274                 curX += xStep;
275                 g.translate(xStep, 0);
276             }
277             curY += yStep;
278             g.translate(minX-curX, yStep);
279             curX = minX;
280         }
281         
282         /*g.setTransform(new AffineTransform());
283         g.setPaint(colors[count++]);
284         count %= colors.length;
285
286         g.fillRect(0, 0, maxX, maxY);*/

287         GraphicsUtil.coerceData(wr, src.getColorModel(), alphaPremult);
288         return wr;
289     }
290
291     protected void fillOutRaster(WritableRaster JavaDoc wr) {
292         if (is_INT_PACK)
293             fillOutRaster_INT_PACK(wr);
294         else
295             fillOutRaster_FALLBACK(wr);
296         
297     }
298
299     protected void fillOutRaster_INT_PACK(WritableRaster JavaDoc wr) {
300         // System.out.println("Fast copyData");
301
int x0 = wr.getMinX();
302         int y0 = wr.getMinY();
303         int width = wr.getWidth();
304         int height = wr.getHeight();
305
306         SinglePixelPackedSampleModel JavaDoc sppsm;
307         sppsm = (SinglePixelPackedSampleModel JavaDoc)wr.getSampleModel();
308
309         final int scanStride = sppsm.getScanlineStride();
310         DataBufferInt JavaDoc db = (DataBufferInt JavaDoc)wr.getDataBuffer();
311         final int [] pixels = db.getBankData()[0];
312         final int base =
313             (db.getOffset() +
314              sppsm.getOffset(x0-wr.getSampleModelTranslateX(),
315                              y0-wr.getSampleModelTranslateY()));
316         int step = xStep;
317         for (int x=xStep; x<width; x+=step, step*=2) {
318             int w = step;
319             if (x+w > width) w = width-x;
320             if (w >= 128) {
321                 int srcSP = base;
322                 int dstSP = base+x;
323                 for(int y=0; y<yStep; y++) {
324                     System.arraycopy(pixels, srcSP, pixels, dstSP, w);
325                     srcSP += scanStride;
326                     dstSP += scanStride;
327                 }
328             } else {
329                 int srcSP = base;
330                 int dstSP = base+x;
331                 for(int y=0; y<yStep; y++) {
332                     int end = srcSP;
333                     srcSP += w-1;
334                     dstSP += w-1;
335                     while(srcSP>=end)
336                         pixels[dstSP--] = pixels[srcSP--];
337                     srcSP+=scanStride+1;
338                     dstSP+=scanStride+1;
339                 }
340             }
341         }
342
343         step = yStep;
344         for (int y=yStep; y<height; y+=step, step*=2) {
345             int h = step;
346             if (y+h > height) h = height-y;
347             int dstSP = base+y*scanStride;
348             System.arraycopy(pixels, base, pixels, dstSP, h*scanStride);
349         }
350     }
351
352     protected void fillOutRaster_FALLBACK(WritableRaster JavaDoc wr) {
353         // System.out.println("Fast copyData");
354
int width = wr.getWidth();
355         int height = wr.getHeight();
356
357         Object JavaDoc data = null;
358
359         int step = xStep;
360         for (int x=xStep; x<width; x+=step, step*=4) {
361             int w = step;
362             if (x+w > width) w = width-x;
363             data = wr.getDataElements(0, 0, w, yStep, data);
364             wr.setDataElements(x, 0, w, yStep, data);
365             x+=w;
366
367             if (x >= width) break;
368             if (x+w > width) w = width-x;
369             wr.setDataElements(x, 0, w, yStep, data);
370             x+=w;
371
372             if (x >= width) break;
373             if (x+w > width) w = width-x;
374             wr.setDataElements(x, 0, w, yStep, data);
375         }
376
377         step = yStep;
378         for (int y=yStep; y<height; y+=step, step*=4) {
379             int h = step;
380             if (y+h > height) h = height-y;
381             data = wr.getDataElements(0, 0, width, h, data);
382             wr.setDataElements(0, y, width, h, data);
383             y+=h;
384
385             if (h >= height) break;
386             if (y+h > height) h = height-y;
387             wr.setDataElements(0, y, width, h, data);
388             y+=h;
389
390             if (h >= height) break;
391             if (y+h > height) h = height-y;
392             wr.setDataElements(0, y, width, h, data);
393             y+=h;
394         }
395     }
396
397     protected static ColorModel JavaDoc fixColorModel(RenderedImage JavaDoc src,
398                                               boolean alphaPremult) {
399         return GraphicsUtil.coerceColorModel(src.getColorModel(),
400                                              alphaPremult);
401     }
402     
403     /**
404      * This function 'fixes' the source's sample model.
405      * right now it just ensures that the sample model isn't
406      * much larger than my width.
407      */

408     protected static SampleModel JavaDoc fixSampleModel(RenderedImage JavaDoc src,
409                                                 int stepX, int stepY,
410                                                 int width, int height) {
411         int defSz = AbstractTiledRed.getDefaultTileSize();
412         SampleModel JavaDoc sm = src.getSampleModel();
413         int w = sm.getWidth();
414         if (w < defSz) w = defSz;
415         if (w > stepX) w = stepX;
416         // if (w > width) w = width;
417
int h = sm.getHeight();
418         if (h < defSz) h = defSz;
419         if (h > stepY) h = stepY;
420         // if (h > height) h = height;
421
return sm.createCompatibleSampleModel(w, h);
422     }
423 }
424
Popular Tags