Source Code Cross Referenced for LinearGradientPaintContext.java in  » XML-UI » xui32 » com » xoetrope » batik » ext » awt » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » XML UI » xui32 » com.xoetrope.batik.ext.awt 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /*
002:
003:           Copyright 2001-2004  The Apache Software Foundation 
004:
005:           Licensed under the Apache License, Version 2.0 (the "License");
006:           you may not use this file except in compliance with the License.
007:           You may obtain a copy of the License at
008:
009:               http://www.apache.org/licenses/LICENSE-2.0
010:
011:           Unless required by applicable law or agreed to in writing, software
012:           distributed under the License is distributed on an "AS IS" BASIS,
013:           WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014:           See the License for the specific language governing permissions and
015:           limitations under the License.
016:
017:         */
018:        package com.xoetrope.batik.ext.awt;
019:
020:        import java.awt.Color;
021:        import java.awt.Rectangle;
022:        import java.awt.RenderingHints;
023:        import java.awt.geom.AffineTransform;
024:        import java.awt.geom.NoninvertibleTransformException;
025:        import java.awt.geom.Point2D;
026:        import java.awt.geom.Rectangle2D;
027:        import java.awt.image.ColorModel;
028:
029:        /**
030:         * Provides the actual implementation for the LinearGradientPaint
031:         * This is where the pixel processing is done.
032:         * 
033:         * @author Nicholas Talian, Vincent Hardy, Jim Graham, Jerry Evans
034:         * @author <a href="mailto:vincent.hardy@eng.sun.com">Vincent Hardy</a>
035:         * @version $Id: LinearGradientPaintContext.java,v 1.2 2006/08/31 09:28:43 val Exp $
036:         * @see java.awt.PaintContext
037:         * @see java.awt.Paint
038:         * @see java.awt.GradientPaint
039:         */
040:        final class LinearGradientPaintContext extends
041:                MultipleGradientPaintContext {
042:
043:            /**
044:             * The following invariants are used to process the gradient value from 
045:             * a device space coordinate, (X, Y):
046:             * g(X, Y) = dgdX*X + dgdY*Y + gc
047:             */
048:            private float dgdX, dgdY, gc, pixSz;
049:
050:            private static final int DEFAULT_IMPL = 1;
051:            private static final int ANTI_ALIAS_IMPL = 3;
052:
053:            private int fillMethod;
054:
055:            /** 
056:             * Constructor for LinearGradientPaintContext.
057:             *
058:             *  @param cm {@link ColorModel} that receives
059:             *  the <code>Paint</code> data. This is used only as a hint.
060:             *
061:             *  @param deviceBounds the device space bounding box of the 
062:             *  graphics primitive being rendered
063:             *
064:             *  @param userBounds the user space bounding box of the 
065:             *  graphics primitive being rendered
066:             * 
067:             *  @param t the {@link AffineTransform} from user
068:             *  space into device space (gradientTransform should be 
069:             *  concatenated with this)
070:             *
071:             *  @param hints the hints that the context object uses to choose
072:             *  between rendering alternatives
073:             *
074:             *  @param dStart gradient start point, in user space
075:             *
076:             *  @param dEnd gradient end point, in user space
077:             *
078:             *  @param fractions the fractions specifying the gradient distribution
079:             *
080:             *  @param colors the gradient colors
081:             *
082:             *  @param cycleMethod either NO_CYCLE, REFLECT, or REPEAT
083:             *
084:             *  @param colorSpace which colorspace to use for interpolation, 
085:             *  either SRGB or LINEAR_RGB
086:             *
087:             */
088:            public LinearGradientPaintContext(ColorModel cm,
089:                    Rectangle deviceBounds, Rectangle2D userBounds,
090:                    AffineTransform t, RenderingHints hints, Point2D dStart,
091:                    Point2D dEnd, float[] fractions, Color[] colors,
092:                    MultipleGradientPaint.CycleMethodEnum cycleMethod,
093:                    MultipleGradientPaint.ColorSpaceEnum colorSpace)
094:                    throws NoninvertibleTransformException {
095:                super (cm, deviceBounds, userBounds, t, hints, fractions,
096:                        colors, cycleMethod, colorSpace);
097:
098:                // Use single precision floating points
099:                Point2D.Float start = new Point2D.Float((float) dStart.getX(),
100:                        (float) dStart.getY());
101:                Point2D.Float end = new Point2D.Float((float) dEnd.getX(),
102:                        (float) dEnd.getY());
103:
104:                // A given point in the raster should take on the same color as its
105:                // projection onto the gradient vector.
106:                // Thus, we want the projection of the current position vector
107:                // onto the gradient vector, then normalized with respect to the
108:                // length of the gradient vector, giving a value which can be mapped into
109:                // the range 0-1.
110:                // projection = currentVector dot gradientVector / length(gradientVector)
111:                // normalized = projection / length(gradientVector)
112:
113:                float dx = end.x - start.x; // change in x from start to end
114:                float dy = end.y - start.y; // change in y from start to end
115:                float dSq = dx * dx + dy * dy; // total distance squared
116:
117:                //avoid repeated calculations by doing these divides once.
118:                float constX = dx / dSq;
119:                float constY = dy / dSq;
120:
121:                //incremental change along gradient for +x
122:                dgdX = a00 * constX + a10 * constY;
123:                //incremental change along gradient for +y
124:                dgdY = a01 * constX + a11 * constY;
125:
126:                float dgdXAbs = Math.abs(dgdX);
127:                float dgdYAbs = Math.abs(dgdY);
128:                if (dgdXAbs > dgdYAbs)
129:                    pixSz = dgdXAbs;
130:                else
131:                    pixSz = dgdYAbs;
132:
133:                //constant, incorporates the translation components from the matrix
134:                gc = (a02 - start.x) * constX + (a12 - start.y) * constY;
135:
136:                Object colorRend = hints
137:                        .get(RenderingHints.KEY_COLOR_RENDERING);
138:                Object rend = hints.get(RenderingHints.KEY_RENDERING);
139:
140:                fillMethod = DEFAULT_IMPL;
141:
142:                if ((cycleMethod == MultipleGradientPaint.REPEAT)
143:                        || hasDiscontinuity) {
144:                    if (rend == RenderingHints.VALUE_RENDER_QUALITY)
145:                        fillMethod = ANTI_ALIAS_IMPL;
146:                    // ColorRend overrides rend.
147:                    if (colorRend == RenderingHints.VALUE_COLOR_RENDER_SPEED)
148:                        fillMethod = DEFAULT_IMPL;
149:                    else if (colorRend == RenderingHints.VALUE_COLOR_RENDER_QUALITY)
150:                        fillMethod = ANTI_ALIAS_IMPL;
151:                }
152:            }
153:
154:            protected void fillHardNoCycle(int[] pixels, int off, int adjust,
155:                    int x, int y, int w, int h) {
156:
157:                //constant which can be pulled out of the inner loop
158:                final float initConst = (dgdX * x) + gc;
159:
160:                for (int i = 0; i < h; i++) { //for every row
161:                    //initialize current value to be start.
162:                    float g = initConst + dgdY * (y + i);
163:                    final int rowLimit = off + w; // end of row iteration
164:
165:                    if (dgdX == 0) {
166:                        // System.out.println("In fillHard: " + g);
167:                        final int val;
168:                        if (g <= 0)
169:                            val = gradientUnderflow;
170:                        else if (g >= 1)
171:                            val = gradientOverflow;
172:                        else {
173:                            // Could be a binary search...
174:                            int gradIdx = 0;
175:                            while (gradIdx < gradientsLength - 1) {
176:                                if (g < fractions[gradIdx + 1])
177:                                    break;
178:                                gradIdx++;
179:                            }
180:                            float delta = (g - fractions[gradIdx]);
181:                            float idx = ((delta * GRADIENT_SIZE_INDEX) / normalizedIntervals[gradIdx]) + 0.5f;
182:                            val = gradients[gradIdx][(int) idx];
183:                        }
184:
185:                        while (off < rowLimit) {
186:                            pixels[off++] = val;
187:                        }
188:                    } else {
189:                        // System.out.println("In fillHard2: " + g);
190:                        int gradSteps;
191:                        int preGradSteps;
192:                        final int preVal, postVal;
193:
194:                        float gradStepsF;
195:                        float preGradStepsF;
196:                        if (dgdX >= 0) {
197:                            gradStepsF = ((1 - g) / dgdX);
198:                            preGradStepsF = (float) Math.ceil((0 - g) / dgdX);
199:                            preVal = gradientUnderflow;
200:                            postVal = gradientOverflow;
201:                        } else { // dgdX < 0
202:                            gradStepsF = ((0 - g) / dgdX);
203:                            preGradStepsF = (float) Math.ceil((1 - g) / dgdX);
204:                            preVal = gradientOverflow;
205:                            postVal = gradientUnderflow;
206:                        }
207:
208:                        if (gradStepsF > w)
209:                            gradSteps = w;
210:                        else
211:                            gradSteps = (int) gradStepsF;
212:                        if (preGradStepsF > w)
213:                            preGradSteps = w;
214:                        else
215:                            preGradSteps = (int) preGradStepsF;
216:
217:                        final int gradLimit = off + gradSteps;
218:                        if (preGradSteps > 0) {
219:                            final int preGradLimit = off + preGradSteps;
220:
221:                            while (off < preGradLimit) {
222:                                pixels[off++] = preVal;
223:                            }
224:                            g += dgdX * preGradSteps;
225:                        }
226:
227:                        if (dgdX > 0) {
228:                            // Could be a binary search...
229:                            int gradIdx = 0;
230:                            while (gradIdx < gradientsLength - 1) {
231:                                if (g < fractions[gradIdx + 1])
232:                                    break;
233:                                gradIdx++;
234:                            }
235:
236:                            while (off < gradLimit) {
237:                                float delta = (g - fractions[gradIdx]);
238:                                final int[] grad = gradients[gradIdx];
239:
240:                                double stepsD = Math
241:                                        .ceil((fractions[gradIdx + 1] - g)
242:                                                / dgdX);
243:                                int steps;
244:                                if (stepsD > w)
245:                                    steps = w;
246:                                else
247:                                    steps = (int) stepsD;
248:                                int subGradLimit = off + steps;
249:                                if (subGradLimit > gradLimit)
250:                                    subGradLimit = gradLimit;
251:
252:                                int idx = (int) (((delta * GRADIENT_SIZE_INDEX) / normalizedIntervals[gradIdx]) * (1 << 16))
253:                                        + (1 << 15);
254:                                int step = (int) (((dgdX * GRADIENT_SIZE_INDEX) / normalizedIntervals[gradIdx]) * (1 << 16));
255:                                while (off < subGradLimit) {
256:                                    pixels[off++] = grad[idx >> 16];
257:                                    idx += step;
258:                                }
259:                                g += dgdX * stepsD;
260:                                gradIdx++;
261:                            }
262:                        } else {
263:                            // Could be a binary search...
264:                            int gradIdx = gradientsLength - 1;
265:                            while (gradIdx > 0) {
266:                                if (g > fractions[gradIdx])
267:                                    break;
268:                                gradIdx--;
269:                            }
270:
271:                            while (off < gradLimit) {
272:                                float delta = (g - fractions[gradIdx]);
273:                                final int[] grad = gradients[gradIdx];
274:
275:                                double stepsD = Math.ceil(delta / -dgdX);
276:                                int steps;
277:                                if (stepsD > w)
278:                                    steps = w;
279:                                else
280:                                    steps = (int) stepsD;
281:                                int subGradLimit = off + steps;
282:                                if (subGradLimit > gradLimit)
283:                                    subGradLimit = gradLimit;
284:
285:                                int idx = (int) (((delta * GRADIENT_SIZE_INDEX) / normalizedIntervals[gradIdx]) * (1 << 16))
286:                                        + (1 << 15);
287:                                int step = (int) (((dgdX * GRADIENT_SIZE_INDEX) / normalizedIntervals[gradIdx]) * (1 << 16));
288:                                while (off < subGradLimit) {
289:                                    pixels[off++] = grad[idx >> 16];
290:                                    idx += step;
291:                                }
292:                                g += dgdX * stepsD;
293:                                gradIdx--;
294:                            }
295:                        }
296:
297:                        while (off < rowLimit) {
298:                            pixels[off++] = postVal;
299:                        }
300:                    }
301:                    off += adjust; //change in off from row to row
302:                }
303:            }
304:
305:            protected void fillSimpleNoCycle(int[] pixels, int off, int adjust,
306:                    int x, int y, int w, int h) {
307:                //constant which can be pulled out of the inner loop
308:                final float initConst = (dgdX * x) + gc;
309:                final float step = dgdX * fastGradientArraySize;
310:                final int fpStep = (int) (step * (1 << 16)); // fix point step
311:
312:                final int[] grad = gradient;
313:
314:                for (int i = 0; i < h; i++) { //for every row
315:                    //initialize current value to be start.
316:                    float g = initConst + dgdY * (y + i);
317:                    g *= fastGradientArraySize;
318:                    g += 0.5; // rounding factor...
319:
320:                    final int rowLimit = off + w; // end of row iteration
321:
322:                    float check = dgdX * fastGradientArraySize * w;
323:                    if (check < 0)
324:                        check = -check;
325:                    if (check < .3) {
326:                        // System.out.println("In fillSimpleNC: " + g);
327:                        final int val;
328:                        if (g <= 0)
329:                            val = gradientUnderflow;
330:                        else if (g >= fastGradientArraySize)
331:                            val = gradientOverflow;
332:                        else
333:                            val = grad[(int) g];
334:                        while (off < rowLimit) {
335:                            pixels[off++] = val;
336:                        }
337:                    } else {
338:                        // System.out.println("In fillSimpleNC2: " + g);
339:                        int gradSteps;
340:                        int preGradSteps;
341:                        final int preVal, postVal;
342:                        if (dgdX > 0) {
343:                            gradSteps = (int) ((fastGradientArraySize - g) / step);
344:                            preGradSteps = (int) Math.ceil(0 - g / step);
345:                            preVal = gradientUnderflow;
346:                            postVal = gradientOverflow;
347:
348:                        } else { // dgdX < 0
349:                            gradSteps = (int) ((0 - g) / step);
350:                            preGradSteps = (int) Math
351:                                    .ceil((fastGradientArraySize - g) / step);
352:                            preVal = gradientOverflow;
353:                            postVal = gradientUnderflow;
354:                        }
355:
356:                        if (gradSteps > w)
357:                            gradSteps = w;
358:                        final int gradLimit = off + gradSteps;
359:
360:                        if (preGradSteps > 0) {
361:                            if (preGradSteps > w)
362:                                preGradSteps = w;
363:                            final int preGradLimit = off + preGradSteps;
364:
365:                            while (off < preGradLimit) {
366:                                pixels[off++] = preVal;
367:                            }
368:                            g += step * preGradSteps;
369:                        }
370:
371:                        int fpG = (int) (g * (1 << 16));
372:                        while (off < gradLimit) {
373:                            pixels[off++] = grad[fpG >> 16];
374:                            fpG += fpStep;
375:                        }
376:
377:                        while (off < rowLimit) {
378:                            pixels[off++] = postVal;
379:                        }
380:                    }
381:                    off += adjust; //change in off from row to row
382:                }
383:            }
384:
385:            protected void fillSimpleRepeat(int[] pixels, int off, int adjust,
386:                    int x, int y, int w, int h) {
387:
388:                final float initConst = (dgdX * x) + gc;
389:
390:                // Limit step to fractional part of
391:                // fastGradientArraySize (the non fractional part has
392:                // no affect anyways, and would mess up lots of stuff
393:                // below).
394:                float step = (dgdX - (int) dgdX) * fastGradientArraySize;
395:
396:                // Make it a Positive step (a small negative step is
397:                // the same as a positive step slightly less than
398:                // fastGradientArraySize.
399:                if (step < 0)
400:                    step += fastGradientArraySize;
401:
402:                final int[] grad = gradient;
403:
404:                for (int i = 0; i < h; i++) { //for every row
405:                    //initialize current value to be start.
406:                    float g = initConst + dgdY * (y + i);
407:
408:                    // now Limited between -1 and 1.
409:                    g = g - (int) g;
410:                    // put in the positive side.
411:                    if (g < 0)
412:                        g += 1;
413:
414:                    // scale for gradient array... 
415:                    g *= fastGradientArraySize;
416:                    g += 0.5; // rounding factor
417:                    final int rowLimit = off + w; // end of row iteration
418:                    while (off < rowLimit) {
419:                        int idx = (int) g;
420:                        if (idx >= fastGradientArraySize) {
421:                            g -= fastGradientArraySize;
422:                            idx -= fastGradientArraySize;
423:                        }
424:                        pixels[off++] = grad[idx];
425:                        g += step;
426:                    }
427:
428:                    off += adjust; //change in off from row to row
429:                }
430:            }
431:
432:            protected void fillSimpleReflect(int[] pixels, int off, int adjust,
433:                    int x, int y, int w, int h) {
434:                final float initConst = (dgdX * x) + gc;
435:
436:                final int[] grad = gradient;
437:
438:                for (int i = 0; i < h; i++) { //for every row
439:                    //initialize current value to be start.
440:                    float g = initConst + dgdY * (y + i);
441:
442:                    // now limited g to -2<->2
443:                    g = g - 2 * ((int) (g / 2.0f));
444:
445:                    float step = dgdX;
446:                    // Pull it into the positive half
447:                    if (g < 0) {
448:                        g = -g; //take absolute value
449:                        step = -step; // Change direction..
450:                    }
451:
452:                    // Now do the same for dgdX. This is safe because
453:                    // any step that is a multiple of 2.0 has no
454:                    // affect, hence we can remove it which the first
455:                    // part does.  The second part simply adds 2.0
456:                    // (which has no affect due to the cylcle) to move
457:                    // all negative step values into the positive
458:                    // side.
459:                    step = step - 2 * ((int) step / 2.0f);
460:                    if (step < 0)
461:                        step += 2.0;
462:                    final int reflectMax = 2 * fastGradientArraySize;
463:
464:                    // Scale for gradient array.
465:                    g *= fastGradientArraySize;
466:                    g += 0.5;
467:                    step *= fastGradientArraySize;
468:                    final int rowLimit = off + w; // end of row iteration
469:                    while (off < rowLimit) {
470:                        int idx = (int) g;
471:                        if (idx >= reflectMax) {
472:                            g -= reflectMax;
473:                            idx -= reflectMax;
474:                        }
475:
476:                        if (idx <= fastGradientArraySize)
477:                            pixels[off++] = grad[idx];
478:                        else
479:                            pixels[off++] = grad[reflectMax - idx];
480:                        g += step;
481:                    }
482:
483:                    off += adjust; //change in off from row to row
484:                }
485:            }
486:
487:            /**
488:             * Return a Raster containing the colors generated for the graphics
489:             * operation.  This is where the area is filled with colors distributed
490:             * linearly.
491:             *
492:             * @param x,y,w,h The area in device space for which colors are
493:             * generated.
494:             *
495:             */
496:            protected void fillRaster(int[] pixels, int off, int adjust, int x,
497:                    int y, int w, int h) {
498:
499:                //constant which can be pulled out of the inner loop
500:                final float initConst = (dgdX * x) + gc;
501:
502:                if (fillMethod == ANTI_ALIAS_IMPL) {
503:                    //initialize current value to be start.
504:                    for (int i = 0; i < h; i++) { //for every row
505:                        float g = initConst + dgdY * (y + i);
506:
507:                        final int rowLimit = off + w; // end of row iteration
508:                        while (off < rowLimit) { //for every pixel in this row.
509:                            //get the color
510:                            pixels[off++] = indexGradientAntiAlias(g, pixSz);
511:                            g += dgdX; //incremental change in g
512:                        }
513:                        off += adjust; //change in off from row to row
514:                    }
515:                } else if (!isSimpleLookup) {
516:                    if (cycleMethod == MultipleGradientPaint.NO_CYCLE) {
517:                        fillHardNoCycle(pixels, off, adjust, x, y, w, h);
518:                    } else {
519:                        //initialize current value to be start.
520:                        for (int i = 0; i < h; i++) { //for every row
521:                            float g = initConst + dgdY * (y + i);
522:
523:                            final int rowLimit = off + w; // end of row iteration
524:                            while (off < rowLimit) { //for every pixel in this row.
525:                                //get the color
526:                                pixels[off++] = indexIntoGradientsArrays(g);
527:                                g += dgdX; //incremental change in g
528:                            }
529:                            off += adjust; //change in off from row to row
530:                        }
531:                    }
532:                } else {
533:                    // Simple implementations: just scale index by array size
534:
535:                    if (cycleMethod == MultipleGradientPaint.NO_CYCLE)
536:                        fillSimpleNoCycle(pixels, off, adjust, x, y, w, h);
537:                    else if (cycleMethod == MultipleGradientPaint.REPEAT)
538:                        fillSimpleRepeat(pixels, off, adjust, x, y, w, h);
539:                    else
540:                        //cycleMethod == MultipleGradientPaint.REFLECT
541:                        fillSimpleReflect(pixels, off, adjust, x, y, w, h);
542:                }
543:            }
544:
545:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.