001    /*
002    *
003    
004    Licensed under the Apache License, Version 2.0 (the "License");
005    you may not use this file except in compliance with the License.
006    You may obtain a copy of the License at
007    
008       http://www.apache.org/licenses/LICENSE-2.0
009    
010    Unless required by applicable law or agreed to in writing, software
011    distributed under the License is distributed on an "AS IS" BASIS,
012    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013    See the License for the specific language governing permissions and
014    limitations under the License.
015    */
016    
017    package railo.runtime.img.composite;
018    
019    import java.awt.CompositeContext;
020    import java.awt.RenderingHints;
021    import java.awt.image.ColorModel;
022    
023    public final class OverlayComposite extends RGBComposite {
024    
025            public OverlayComposite( float alpha ) {
026            super( alpha );
027            }
028    
029            public CompositeContext createContext( ColorModel srcColorModel, ColorModel dstColorModel, RenderingHints hints ) {
030                    return new Context( extraAlpha, srcColorModel, dstColorModel );
031            }
032    
033        static class Context extends RGBCompositeContext {
034            public Context( float alpha, ColorModel srcColorModel, ColorModel dstColorModel ) {
035                super( alpha, srcColorModel, dstColorModel );
036            }
037    
038            public void composeRGB( int[] src, int[] dst, float alpha ) {
039                int w = src.length;
040    
041                for ( int i = 0; i < w; i += 4 ) {
042                    int sr = src[i];
043                    int dir = dst[i];
044                    int sg = src[i+1];
045                    int dig = dst[i+1];
046                    int sb = src[i+2];
047                    int dib = dst[i+2];
048                    int sa = src[i+3];
049                    int dia = dst[i+3];
050                    int dor, dog, dob;
051    
052                    int t;
053                    if ( dir < 128 ) {
054                        t = dir * sr + 0x80;
055                        dor = 2 * (((t >> 8) + t) >> 8);
056                    } else {
057                        t = (255-dir) * (255-sr) + 0x80;
058                        dor = 2 * (255 - ( ((t >> 8) + t) >> 8 ));
059                    }
060                    if ( dig < 128 ) {
061                        t = dig * sg + 0x80;
062                        dog = 2 * (((t >> 8) + t) >> 8);
063                    } else {
064                        t = (255-dig) * (255-sg) + 0x80;
065                        dog = 2 * (255 - ( ((t >> 8) + t) >> 8 ));
066                    }
067                    if ( dib < 128 ) {
068                        t = dib * sb + 0x80;
069                        dob = 2 * (((t >> 8) + t) >> 8);
070                    } else {
071                        t = (255-dib) * (255-sb) + 0x80;
072                        dob = 2 * (255 - ( ((t >> 8) + t) >> 8 ));
073                    }
074    
075                    float a = alpha*sa/255f;
076                    float ac = 1-a;
077    
078                    dst[i] = (int)(a*dor + ac*dir);
079                    dst[i+1] = (int)(a*dog + ac*dig);
080                    dst[i+2] = (int)(a*dob + ac*dib);
081                    dst[i+3] = (int)(sa*alpha + dia*ac);
082                }
083            }
084        }
085    
086    }