KickJava   Java API By Example, From Geeks To Geeks.

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


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.Rectangle JavaDoc;
21 import java.awt.RenderingHints JavaDoc;
22 import java.awt.image.DataBufferInt JavaDoc;
23 import java.awt.image.SampleModel JavaDoc;
24 import java.awt.image.SinglePixelPackedSampleModel JavaDoc;
25 import java.awt.image.WritableRaster JavaDoc;
26
27 import org.apache.batik.ext.awt.image.GraphicsUtil;
28 import org.apache.batik.ext.awt.image.PadMode;
29
30
31 /**
32  * This is an implementation of a Pad operation as a RenderedImage.
33  *
34  * @author <a HREF="mailto:Thomas.DeWeeese@Kodak.com">Thomas DeWeese</a>
35  * @version $Id: PadRed.java,v 1.14 2004/08/18 07:14:08 vhardy Exp $ */

36 public class PadRed extends AbstractRed {
37
38     static final boolean DEBUG=false;
39
40     PadMode padMode;
41     RenderingHints JavaDoc hints;
42
43     /**
44      * Construct A Rendered Pad operation. If the pad is smaller than
45      * the original image size then this devolves to a Crop.
46      *
47      * @param src The image to pad/crop
48      * @param bounds The bounds of the result (same coord system as src).
49      * @param padMode The pad mode to use (currently ignored).
50      * @param hints The hints to use for drawing 'pad' area.
51      */

52     public PadRed(CachableRed src,
53                   Rectangle JavaDoc bounds,
54                   PadMode padMode,
55                   RenderingHints JavaDoc hints) {
56         super(src,bounds,src.getColorModel(),
57               fixSampleModel(src, bounds),
58               bounds.x, bounds.y,
59               null);
60
61         this.padMode = padMode;
62
63         if (DEBUG) {
64             System.out.println("Src: " + src + " Bounds: " + bounds +
65                                " Off: " +
66                                src.getTileGridXOffset() + ", " +
67                                src.getTileGridYOffset());
68         }
69         this.hints = hints;
70
71     }
72
73     public WritableRaster JavaDoc copyData(WritableRaster JavaDoc wr) {
74         // Get my source.
75
CachableRed src = (CachableRed)getSources().get(0);
76
77         Rectangle JavaDoc srcR = src.getBounds();
78         Rectangle JavaDoc wrR = wr.getBounds();
79
80         if (wrR.intersects(srcR)) {
81             Rectangle JavaDoc r = wrR.intersection(srcR);
82         
83             // Limit the raster I send to my source to his rect.
84
WritableRaster JavaDoc srcWR;
85             srcWR = wr.createWritableChild(r.x, r.y, r.width, r.height,
86                                            r.x, r.y, null);
87             src.copyData(srcWR);
88         }
89
90         if (padMode == PadMode.ZERO_PAD) {
91             handleZero(wr);
92         } else if (padMode == PadMode.REPLICATE) {
93             handleReplicate(wr);
94         } else if (padMode == PadMode.WRAP) {
95             handleWrap(wr);
96         }
97
98         return wr;
99     }
100
101     protected static class ZeroRecter {
102         WritableRaster JavaDoc wr;
103         int bands;
104         static int [] zeros=null;
105         public ZeroRecter(WritableRaster JavaDoc wr) {
106             this.wr = wr;
107             this.bands = wr.getSampleModel().getNumBands();
108         }
109         public void zeroRect(Rectangle JavaDoc r) {
110             synchronized (this) {
111                 if ((zeros == null) || (zeros.length <r.width*bands))
112                     zeros = new int[r.width*bands];
113             }
114
115             for (int y=0; y<r.height; y++) {
116                 wr.setPixels(r.x, r.y+y, r.width, 1, zeros);
117             }
118         }
119
120         public static ZeroRecter getZeroRecter(WritableRaster JavaDoc wr) {
121             if (GraphicsUtil.is_INT_PACK_Data(wr.getSampleModel(), false))
122                 return new ZeroRecter_INT_PACK(wr);
123             else
124                 return new ZeroRecter(wr);
125         }
126
127         public static void zeroRect(WritableRaster JavaDoc wr) {
128             ZeroRecter zr = getZeroRecter(wr);
129             zr.zeroRect(wr.getBounds());
130         }
131
132     }
133
134     protected static class ZeroRecter_INT_PACK extends ZeroRecter {
135         final int base;
136         final int scanStride;
137         final int pixels[];
138         final int zeros[];
139         final int x0, y0;
140
141         public ZeroRecter_INT_PACK(WritableRaster JavaDoc wr) {
142             super(wr);
143
144             SinglePixelPackedSampleModel JavaDoc sppsm;
145             sppsm = (SinglePixelPackedSampleModel JavaDoc)wr.getSampleModel();
146
147             scanStride = sppsm.getScanlineStride();
148             DataBufferInt JavaDoc db = (DataBufferInt JavaDoc)wr.getDataBuffer();
149             x0 = wr.getMinY();
150             y0 = wr.getMinX();
151             base = (db.getOffset() +
152                     sppsm.getOffset(x0-wr.getSampleModelTranslateX(),
153                                     y0-wr.getSampleModelTranslateY()));
154
155             pixels = db.getBankData()[0];
156             if (wr.getWidth() > 10)
157                 zeros = new int[wr.getWidth()];
158             else
159                 zeros = null;
160         }
161
162         public void zeroRect(Rectangle JavaDoc r) {
163             final int rbase = base+(r.x-x0) + (r.y-y0)*scanStride;
164
165             if (r.width > 10) {
166                 // Longer runs use arraycopy...
167
for (int y=0; y<r.height; y++) {
168                     int sp = rbase + y*scanStride;
169                     System.arraycopy(zeros, 0, pixels, sp, r.width);
170                 }
171             } else {
172                 // Small runs quicker to avoid func call.
173
int sp = rbase;
174                 int end = sp +r.width;
175                 int adj = scanStride-r.width;
176                 for (int y=0; y<r.height; y++) {
177                     while (sp < end)
178                         pixels[sp++] = 0;
179                     sp += adj;
180                     end += scanStride;
181                 }
182             }
183         }
184     }
185
186     protected void handleZero(WritableRaster JavaDoc wr) {
187         // Get my source.
188
CachableRed src = (CachableRed)getSources().get(0);
189         Rectangle JavaDoc srcR = src.getBounds();
190         Rectangle JavaDoc wrR = wr.getBounds();
191
192         ZeroRecter zr = ZeroRecter.getZeroRecter(wr);
193
194         // area rect (covers the area left to handle).
195
Rectangle JavaDoc ar = new Rectangle JavaDoc(wrR.x, wrR.y, wrR.width, wrR.height);
196         // draw rect (used for calls to zeroRect);
197
Rectangle JavaDoc dr = new Rectangle JavaDoc(wrR.x, wrR.y, wrR.width, wrR.height);
198
199         // We split the edge drawing up into four parts.
200
//
201
// +-----------------------------+
202
// | 1 | 2 |
203
// | +---------------+------|
204
// / / /4 /
205
// / / / /
206
// / / / /
207
// / / / /
208
// | +---------------+------|
209
// | | 3 |
210
// +-----------------------------+
211
//
212
// We update our x,y, width, height as we go along so
213
// we 'forget' about the parts we have already painted...
214

215         // Draw #1
216
if (DEBUG) {
217             System.out.println("WrR: " + wrR + " srcR: " + srcR);
218             // g2d.setColor(new Color(255,0,0,128));
219
}
220         if (ar.x < srcR.x) {
221             int w = srcR.x-ar.x;
222             if (w > ar.width) w=ar.width;
223             // g2d.fillRect(x, y, w, height);
224
dr.width = w;
225             zr.zeroRect(dr);
226
227             ar.x+=w;
228             ar.width-=w;
229         }
230
231         // Draw #2
232
if (DEBUG) {
233             System.out.println("WrR: [" +
234                                ar.x + "," + ar.y + "," +
235                                ar.width + "," + ar.height +
236                                "] s rcR: " + srcR);
237             // g2d.setColor(new Color(0,0,255,128));
238
}
239         if (ar.y < srcR.y) {
240             int h = srcR.y-ar.y;
241             if (h > ar.height) h=ar.height;
242             // g2d.fillRect(x, y, width, h);
243
dr.x = ar.x;
244             dr.y = ar.y;
245             dr.width = ar.width;
246             dr.height = h;
247             zr.zeroRect(dr);
248
249             ar.y +=h;
250             ar.height-=h;
251         }
252
253         // Draw #3
254
if (DEBUG) {
255             System.out.println("WrR: [" +
256                                ar.x + "," + ar.y + "," +
257                                ar.width + "," + ar.height +
258                                "] srcR: " + srcR);
259             // g2d.setColor(new Color(0,255,0,128));
260
}
261         if (ar.y+ar.height > srcR.y+srcR.height) {
262             int h = (ar.y+ar.height) - (srcR.y+srcR.height);
263             if (h > ar.height) h=ar.height;
264
265             int y0 = ar.y+ar.height-h; // the +/-1 cancel (?)
266

267             // g2d.fillRect(x, y0, width, h);
268
dr.x = ar.x;
269             dr.y = y0;
270             dr.width = ar.width;
271             dr.height = h;
272             zr.zeroRect(dr);
273
274             ar.height -= h;
275         }
276
277         // Draw #4
278
if (DEBUG) {
279             System.out.println("WrR: [" +
280                                ar.x + "," + ar.y + "," +
281                                ar.width + "," + ar.height +
282                                "] srcR: " + srcR);
283             // g2d.setColor(new Color(255,255,0,128));
284
}
285         if (ar.x+ar.width > srcR.x+srcR.width) {
286             int w = (ar.x+ar.width) - (srcR.x+srcR.width);
287             if (w > ar.width) w=ar.width;
288             int x0 = ar.x+ar.width-w; // the +/-1 cancel (?)
289

290             // g2d.fillRect(x0, y, w, height);
291
dr.x = x0;
292             dr.y = ar.y;
293             dr.width = w;
294             dr.height = ar.height;
295             zr.zeroRect(dr);
296             
297             ar.width-=w;
298         }
299     }
300
301
302     protected void handleReplicate(WritableRaster JavaDoc wr) {
303         // Get my source.
304
CachableRed src = (CachableRed)getSources().get(0);
305         Rectangle JavaDoc srcR = src.getBounds();
306         Rectangle JavaDoc wrR = wr.getBounds();
307
308         int x = wrR.x;
309         int y = wrR.y;
310         int width = wrR.width;
311         int height = wrR.height;
312
313         Rectangle JavaDoc r;
314         {
315             // Calculate an intersection that makes some sense
316
// even when the rects don't really intersect
317
// (The x and y ranges will be correct if they
318
// overlap in one dimension even if they don't
319
// intersect in both dimensions).
320
int minX = (srcR.x > x) ? srcR.x : x;
321             int maxX = (((srcR.x+srcR.width-1) < (x+width-1)) ?
322                         ( srcR.x+srcR.width-1) : (x+width-1));
323             int minY = (srcR.y > y) ? srcR.y : y;
324             int maxY = (((srcR.y+srcR.height-1) < (y+height-1)) ?
325                         ( srcR.y+srcR.height-1) : (y+height-1));
326
327             int x0 = minX;
328             int w = maxX-minX+1;
329             int y0 = minY;
330             int h = maxY-minY+1;
331             if (w <0 ) { x0 = 0; w = 0; }
332             if (h <0 ) { y0 = 0; h = 0; }
333             r = new Rectangle JavaDoc(x0, y0, w, h);
334         }
335
336         // We split the edge drawing up into four parts.
337
//
338
// +-----------------------------+
339
// | 3 | 1 | 4 |
340
// | +---------------+ |
341
// / / / /
342
// / / src / /
343
// / / / /
344
// / / / /
345
// | +---------------+ |
346
// | | 2 | |
347
// +-----------------------------+
348
//
349

350         // Draw #1
351
if (y < srcR.y) {
352             int repW = r.width;
353             int repX = r.x;
354             int wrX = r.x;
355             int wrY = y;
356             if (x+width-1 <= srcR.x) {
357                 // we are off to the left of src. so set repX to the
358
// left most pixel...
359
repW = 1;
360                 repX = srcR.x;
361                 wrX = x+width-1;
362             } else if (x >= srcR.x+srcR.width) {
363                 // we are off to the right of src, so set repX to
364
// the right most pixel
365
repW = 1;
366                 repX = srcR.x+srcR.width-1;
367                 wrX = x;
368             }
369
370             // This fills the top row of section 1 from src (we
371
// go to src instead of getting the data from wr because
372
// in some cases wr will be completely off the top of src
373
WritableRaster JavaDoc wr1 = wr.createWritableChild(wrX, wrY,
374                                                         repW, 1,
375                                                         repX, srcR.y, null);
376             src.copyData(wr1);
377             wrY++;
378
379             int endY = srcR.y;
380             if (y+height < endY) endY = y+height;
381
382             if (wrY < endY) {
383                 int [] pixels = wr.getPixels(wrX, wrY-1,
384                                              repW, 1, (int [])null);
385                 while (wrY < srcR.y) {
386                     wr.setPixels(wrX, wrY, repW, 1, pixels);
387                     wrY++;
388                 }
389             }
390         }
391         
392         // Draw #2
393
if ((y+height) > (srcR.y+srcR.height)) {
394             int repW = r.width;
395             int repX = r.x;
396             int repY = srcR.y+srcR.height-1;
397
398             int wrX = r.x;
399             int wrY = srcR.y+srcR.height;
400             if (wrY < y) wrY = y;
401
402             if (x+width <= srcR.x) {
403                 // we are off to the left of src. so set repX to the
404
// left most pixel...
405
repW = 1;
406                 repX = srcR.x;
407                 wrX = x+width-1;
408             } else if (x >= srcR.x+srcR.width) {
409                 // we are off to the right of src, so set repX to
410
// the right most pixel
411
repW = 1;
412                 repX = srcR.x+srcR.width-1;
413                 wrX = x;
414             }
415
416             if (DEBUG) {
417                 System.out.println("wr: " + wr.getBounds());
418                 System.out.println("req: [" + wrX + ", " + wrY + ", " +
419                                    repW + ", 1]");
420             }
421
422             // First we get the top row of pixels from src. (we
423
// go to src instead of getting the data from wr because
424
// in some cases wr will be completely off the bottom of src).
425
WritableRaster JavaDoc wr1 = wr.createWritableChild(wrX, wrY,
426                                                         repW, 1,
427                                                         repX, repY, null);
428             // This fills the top row of section 2 from src
429
src.copyData(wr1);
430             wrY++;
431
432             int endY = y+height;
433             if (wrY < endY) {
434                 // This fills the rest of section 2 from the first line.
435
int [] pixels = wr.getPixels(wrX, wrY-1,
436                                              repW, 1, (int [])null);
437                 while (wrY < endY) {
438                     wr.setPixels(wrX, wrY, repW, 1, pixels);
439                     wrY++;
440                 }
441             }
442         }
443                                                         
444         // Draw #3
445
if (x < srcR.x) {
446             // We are garunteed that we have a column of pixels down
447
// the edge of 1 and src. We simply replicate this column
448
// out to the edges of 2.
449
int wrX = srcR.x;
450             if (x+width <= srcR.x) {
451                 wrX = x+width-1;
452             }
453
454             int xLoc = x;
455             int [] pixels = wr.getPixels(wrX, y, 1, height, (int [])null);
456             while (xLoc < wrX) {
457                 wr.setPixels(xLoc, y, 1, height, pixels);
458                 xLoc++;
459             }
460         }
461
462         // Draw #4
463
if (x+width > srcR.x+srcR.width) {
464             // We are garunteed that we have a column of pixels down
465
// the edge of 1 and src. We simply replicate this column
466
// out to the edges of 3.
467
int wrX = srcR.x+srcR.width-1;
468             if (x >= srcR.x+srcR.width) {
469                 wrX = x;
470             }
471
472             int xLoc = wrX+1;
473             int endX = x+width-1;
474             int [] pixels = wr.getPixels(wrX, y, 1, height, (int [])null);
475             while (xLoc < endX) {
476                 wr.setPixels(xLoc, y, 1, height, pixels);
477                 xLoc++;
478             }
479         }
480     }
481
482     protected void handleWrap(WritableRaster JavaDoc wr) {
483
484         handleZero(wr);
485     }
486
487         /**
488          * This function 'fixes' the source's sample model.
489          * right now it just ensures that the sample model isn't
490          * much larger than my width.
491          */

492     protected static SampleModel JavaDoc fixSampleModel(CachableRed src,
493                                                 Rectangle JavaDoc bounds) {
494         int defSz = AbstractTiledRed.getDefaultTileSize();
495
496         SampleModel JavaDoc sm = src.getSampleModel();
497         int w = sm.getWidth();
498         if (w < defSz) w = defSz;
499         if (w > bounds.width) w = bounds.width;
500         int h = sm.getHeight();
501         if (h < defSz) h = defSz;
502         if (h > bounds.height) h = bounds.height;
503
504         // System.out.println("Pad SMSz: " + w + "x" + h);
505

506         return sm.createCompatibleSampleModel(w, h);
507     }
508 }
509
Popular Tags