/* * Copyright 2010-2014 Laszlo Balazs-Csiki * * This file is part of Pixelitor. Pixelitor is free software: you * can redistribute it and/or modify it under the terms of the GNU * General Public License, version 3 as published by the Free * Software Foundation. * * Pixelitor is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with Pixelitor. If not, see <http://www.gnu.org/licenses/>. */ package pixelitor.utils.test; import java.awt.Composite; import java.awt.CompositeContext; import java.awt.RenderingHints; import java.awt.image.ColorModel; import java.awt.image.DataBufferInt; import java.awt.image.Raster; import java.awt.image.WritableRaster; /** * */ public class FadingComposite implements Composite { private final Composite realComposite; private final float fadeFactor; public FadingComposite(Composite realComposite, float fadeFactor) { this.realComposite = realComposite; this.fadeFactor = fadeFactor; } @Override public CompositeContext createContext(ColorModel srcColorModel, ColorModel dstColorModel, RenderingHints hints) { return new FadingCompositeContext(realComposite, srcColorModel, dstColorModel, hints, fadeFactor); } } class FadingCompositeContext implements CompositeContext { private final Composite realComposite; private final ColorModel srcColorModel; private final ColorModel dstColorModel; private final RenderingHints hints; private final float fadeFactor; FadingCompositeContext(Composite realComposite, ColorModel srcColorModel, ColorModel dstColorModel, RenderingHints hints, float fadeFactor) { this.realComposite = realComposite; this.srcColorModel = srcColorModel; this.dstColorModel = dstColorModel; this.hints = hints; this.fadeFactor = fadeFactor; } @Override public void dispose() { } @Override public void compose(Raster src, Raster dstIn, WritableRaster dstOut) { realComposite.createContext(srcColorModel, dstColorModel, hints).compose(src, dstIn, dstOut); // now dstOut is filled with the result of the real composite // we still have to fade between the original and this DataBufferInt srcDataBuffer = (DataBufferInt) src.getDataBuffer(); int[] originalPixels = srcDataBuffer.getData(); DataBufferInt dstOutDataBuffer = (DataBufferInt) dstOut.getDataBuffer(); int[] blendedPixels = dstOutDataBuffer.getData(); for (int i = 0; i < blendedPixels.length; i++) { int originalPixel = originalPixels[i]; int origA = (originalPixel >>> 24) & 0xFF; int origR = (originalPixel >>> 16) & 0xFF; int origG = (originalPixel >>> 8) & 0xFF; int origB = (originalPixel) & 0xFF; int blendedPixel = blendedPixels[i]; int blendedA = (blendedPixel >>> 24) & 0xFF; int blendedR = (blendedPixel >>> 16) & 0xFF; int blendedG = (blendedPixel >>> 8) & 0xFF; int blendedB = (blendedPixel) & 0xFF; int outA = (int) (origA + fadeFactor * (blendedA - origA)); int outR = (int) (origR + fadeFactor * (blendedR - origR)); int outG = (int) (origG + fadeFactor * (blendedG - origG)); int outB = (int) (origB + fadeFactor * (blendedB - origB)); blendedPixels[i] = (outA << 24) | (outR << 16) | (outG << 8) | outB; } } }