Source Code Cross Referenced for LinearGradientPaintContext.java in  » Graphic-Library » batik » org » apache » 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 » Graphic Library » batik » org.apache.batik.ext.awt 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


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