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