Package org.apache.harmony.awt.gl.linux

Source Code of org.apache.harmony.awt.gl.linux.XBlitter

/*
*  Licensed to the Apache Software Foundation (ASF) under one or more
*  contributor license agreements.  See the NOTICE file distributed with
*  this work for additional information regarding copyright ownership.
*  The ASF licenses this file to You under the Apache License, Version 2.0
*  (the "License"); you may not use this file except in compliance with
*  the License.  You may obtain a copy of the License at
*
*     http://www.apache.org/licenses/LICENSE-2.0
*
*  Unless required by applicable law or agreed to in writing, software
*  distributed under the License is distributed on an "AS IS" BASIS,
*  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*  See the License for the specific language governing permissions and
*  limitations under the License.
*/
/**
* @author Oleg V. Khaschansky
* @version $Revision$
*/

package org.apache.harmony.awt.gl.linux;

import java.awt.geom.AffineTransform;
import java.awt.geom.Rectangle2D;
import java.awt.*;
import java.awt.image.ColorModel;
import java.awt.image.BufferedImage;
import java.awt.image.WritableRaster;
import java.awt.image.AffineTransformOp;

import org.apache.harmony.awt.gl.*;
import org.apache.harmony.awt.gl.render.Blitter;
import org.apache.harmony.awt.gl.render.JavaBlitter;
import org.apache.harmony.awt.gl.render.NativeImageBlitter;
import org.apache.harmony.awt.nativebridge.linux.X11;
import org.apache.harmony.awt.nativebridge.linux.X11Defs;

public class XBlitter implements Blitter {
    static final XBlitter inst = new XBlitter();

    public static XBlitter getInstance(){
        return inst;
    }

    public void blit(
            int srcX, int srcY, Surface srcSurf,
            int dstX, int dstY, Surface dstSurf,
            int width, int height,
            AffineTransform sysxform, AffineTransform xform,
            Composite comp, Color bgcolor, MultiRectArea clip
    ) {
        int type = xform.getType();
        switch (type) {
            case AffineTransform.TYPE_TRANSLATION:
                dstX += xform.getTranslateX();
                dstY += xform.getTranslateY();
            case AffineTransform.TYPE_IDENTITY:
                 blit(srcX, srcY, srcSurf, dstX, dstY, dstSurf,
                         width, height, sysxform, comp, bgcolor, clip);
                break;
            default:
                XSurface xDstSurf = (XSurface) dstSurf;

                BufferedImage compIm;
                int w = srcSurf.getWidth();
                int h = srcSurf.getHeight();

                if (!(srcSurf instanceof ImageSurface)) {
                    compIm = xDstSurf.g2d.xConfig.createCompatibleImage(w, h);

                    NativeImageBlitter.getInstance().blit(
                            srcX, srcY, srcSurf,
                            srcX, srcY,
                            AwtImageBackdoorAccessor.getInstance().getImageSurface(compIm),
                            w, h,
                            AlphaComposite.Src, null, null
                    );
                } else {
                    ColorModel cm = srcSurf.getColorModel();
                    compIm = new BufferedImage(
                            cm,
                            srcSurf.getRaster(),
                            cm.isAlphaPremultiplied(),
                            null
                    );
                }

                WritableRaster compRaster = compIm.getRaster();

                AffineTransform at = (AffineTransform) sysxform.clone();
                at.concatenate(xform);

                // Want to transform without translation to fit into destination image
                // Translation will be added then when blitting to final dest surface
                dstX += at.getTranslateX();
                dstY += at.getTranslateY();
                AffineTransform untranslated =
                        AffineTransform.getTranslateInstance(
                                -at.getTranslateX(),
                                -at.getTranslateY()
                        );
                untranslated.concatenate(at);

                AffineTransformOp atop =
                        new AffineTransformOp(untranslated, xDstSurf.g2d.getRenderingHints());

                Rectangle r = atop.getBounds2D(compRaster).getBounds();
                int tWidth = r.width;
                int tHeight = r.height;

                BufferedImage transformed;
                if (compIm.getColorModel().getTransparency() == Transparency.OPAQUE) {
                    transformed = xDstSurf.g2d.xConfig.createCompatibleImage(tWidth, tHeight);
                } else {
                    ColorModel cm = compIm.getColorModel();
                    transformed =
                            new BufferedImage(
                                    cm,
                                    compIm.getRaster().createCompatibleWritableRaster(
                                            tWidth,
                                            tHeight
                                    ),
                                    cm.isAlphaPremultiplied(),
                                    null
                            );
                }

                atop.filter(compIm, transformed);

                if (dstX < 0){
                    tWidth += dstX;
                    dstX = 0;
                }

                if (dstY < 0){
                    tHeight += dstY;
                    dstY = 0;
                }

                blit(
                        0, 0, AwtImageBackdoorAccessor.getInstance().getImageSurface(transformed),
                        dstX, dstY, dstSurf,
                        tWidth, tHeight,
                        comp, bgcolor, clip
                );
        }
    }

    public void blit(
            int srcX, int srcY, Surface srcSurf,
            int dstX, int dstY, Surface dstSurf,
            int width, int height,
            AffineTransform sysxform,
            Composite comp, Color bgcolor, MultiRectArea clip
    ) {
        int type = sysxform.getType();
        switch (type) {
            case AffineTransform.TYPE_TRANSLATION:
            case AffineTransform.TYPE_IDENTITY:
                 blit(
                         srcX, srcY, srcSurf,
                         dstX + (int) sysxform.getTranslateX(),
                         dstY + (int) sysxform.getTranslateY(),
                         dstSurf,
                         width, height,
                         comp, bgcolor, clip
                 );
                break;
            default:
                ColorModel cm = srcSurf.getColorModel();
                WritableRaster compRaster = srcSurf.getRaster();
                BufferedImage compIm = new BufferedImage(
                        cm,
                        compRaster,
                        cm.isAlphaPremultiplied(),
                        null
                );

                Rectangle transDstBounds = JavaBlitter.getBounds2D(sysxform, new Rectangle(dstX, dstY, width, height)).getBounds();
                int tWidth = transDstBounds.width;
                int tHeight = transDstBounds.height;
                int tX = transDstBounds.x;
                int tY = transDstBounds.y;

                if(tWidth <= 0 || tHeight <= 0) return;
                BufferedImage transformed = new BufferedImage(dstSurf.getWidth(), dstSurf.getHeight(), BufferedImage.TYPE_INT_ARGB);

                Surface transfSurf = Surface.getImageSurface(transformed);
                JavaBlitter.getInstance().blit(srcX, srcY, Surface.getImageSurface(compIm),
                        dstX, dstY, transfSurf, width, height, sysxform, AlphaComposite.Src, null, null);
                blit(
                        tX, tY, transfSurf,
                        tX, tY, dstSurf,
                        tWidth, tHeight,
                        comp, bgcolor, clip
                );

        }
    }

    public void blit(
            int srcX, int srcY, Surface srcSurf,
            int dstX, int dstY, Surface dstSurf,
            int width, int height,
            Composite comp, Color bgcolor, MultiRectArea clip
    ) {

        if (clip == null) {
            clip = new MultiRectArea(new Rectangle(dstX, dstY, width, height));
        } else {
            clip = new MultiRectArea(clip);
        }
        // XXX - todo - need to do smth with bgcolor
        ColorModel srcCM = srcSurf.getColorModel();
        XSurface xDstSurf = (XSurface) dstSurf;

        if (srcSurf.isNativeDrawable() && srcCM.equals(dstSurf.getColorModel())) {
            if (srcSurf instanceof XSurface) { // Blit from native to native
                XSurface xSrcSurf = (XSurface) srcSurf;

                XGraphics2D g2d = xDstSurf.g2d;

                if (comp instanceof AlphaComposite) {
                    switch (((AlphaComposite) comp).getRule()) {
                        case AlphaComposite.SRC:
                        case AlphaComposite.SRC_ATOP:
                        case AlphaComposite.SRC_IN:
                        case AlphaComposite.SRC_OVER:
                            break; // GXCopy - is default
                        case AlphaComposite.DST:
                        case AlphaComposite.DST_ATOP:
                        case AlphaComposite.DST_IN:
                        case AlphaComposite.DST_OVER:
                            g2d.setImageGCFunction(X11Defs.GXnoop);
                            break;
                        case AlphaComposite.SRC_OUT: // Clear
                        case AlphaComposite.DST_OUT: // Clear
                        case AlphaComposite.CLEAR:
                        case AlphaComposite.XOR: // Clear
                            g2d.setImageGCFunction(X11Defs.GXclear);
                            break;
                        default: // Do nothing
                    }
                } else {
                    imBlit(
                            srcX, srcY, srcSurf,
                            dstX, dstY, dstSurf,
                            width, height,
                            comp, bgcolor, clip
                    );
                    return;
                }

                // Get translated clip
                makeClip(dstX, dstY, width, height, clip);

                g2d.setXClip(clip, g2d.imageGC);
                X11 x11 = X11.getInstance();
                x11.XCopyArea(
                        g2d.display,
                        xSrcSurf.g2d.drawable, g2d.drawable,
                        g2d.imageGC,
                        srcX, srcY,
                        width, height,
                        dstX, dstY
                );
                x11.XFlush(g2d.display);
                g2d.resetXClip(g2d.imageGC);

                g2d.setImageGCFunction(X11Defs.GXcopy);
            } else if (srcSurf.getSurfaceType() == BufferedImage.TYPE_CUSTOM) {
                // source is custom image, slow blit
                imBlit(
                        srcX, srcY, srcSurf,
                        dstX, dstY, dstSurf,
                        width, height,
                        comp, bgcolor, clip
                );
            } else { // source could be compatible image
                int srcTransp = srcCM.getTransparency();
                if (srcTransp == Transparency.OPAQUE) {
                    if (comp instanceof AlphaComposite) {
                        AlphaComposite acomp = (AlphaComposite) comp;
                        if (
                                acomp.getRule() == AlphaComposite.SRC ||
                                (acomp.getAlpha() == 1 &&
                                 (acomp.getRule() == AlphaComposite.SRC_OVER ||
                                  acomp.getRule() == AlphaComposite.SRC_ATOP ||
                                  acomp.getRule() == AlphaComposite.SRC_IN)
                                )
                        ) {
                            // Get translated clip
                            makeClip(dstX, dstY, width, height, clip);
                            xDstSurf.putImage(
                                    clip,
                                    srcSurf.getRaster(),
                                    dstX, dstY,
                                    width, height
                            );
                        } else {
                            imBlit(
                                srcX, srcY, srcSurf,
                                dstX, dstY, dstSurf,
                                width, height,
                                comp, bgcolor, clip
                            );
                        }
                    }

                } else if (srcTransp == Transparency.BITMASK) {
                    // todo - XXX - optimize here - use native clip mask
                    imBlit(
                        srcX, srcY, srcSurf,
                        dstX, dstY, dstSurf,
                        width, height,
                        comp, bgcolor, clip
                    );
                } else { // have to compose in java - no native alpha composite
                    imBlit(
                        srcX, srcY, srcSurf,
                        dstX, dstY, dstSurf,
                        width, height,
                        comp, bgcolor, clip
                    );
                }
            }
        } else {
            imBlit(
                    srcX, srcY, srcSurf,
                    dstX, dstY, dstSurf,
                    width, height,
                    comp, bgcolor, clip
            );
        }
    }

    private static void imBlit(
            int srcX, int srcY, Surface srcSurf,
            int dstX, int dstY, Surface dstSurf,
            int width, int height,
            Composite comp,
            Color bgcolor,
            MultiRectArea clip
    ) {

        if(dstX < 0){
            width += dstX;
            dstX = 0;
        }

        if(dstY < 0){
            height += dstY;
            dstY = 0;
        }

        if(width <= 0 || height <= 0) return;

        XSurface xDstSurf = ((XSurface) dstSurf);

        boolean srcNoAlpha =
                srcSurf.getColorModel().getTransparency() == Transparency.OPAQUE;

        if (comp instanceof AlphaComposite) {
            AlphaComposite acomp = (AlphaComposite) comp;
            if (
                    acomp.getRule() == AlphaComposite.SRC ||
                    (srcNoAlpha && acomp.getAlpha() == 1 &&
                     (acomp.getRule() == AlphaComposite.SRC_OVER ||
                      acomp.getRule() == AlphaComposite.SRC_ATOP ||
                      acomp.getRule() == AlphaComposite.SRC_IN)
                    )
            ) {
                xDstSurf.needServerData = false;
            }
        }

        Rectangle2D roi = new Rectangle2D.Float(dstX, dstY, width, height);
        xDstSurf.setRoi(roi);
        NativeImageBlitter.getInstance().blit(
                srcX, srcY, srcSurf,
                0, 0, xDstSurf.getImageSurface(),
                width, height,
                comp, bgcolor, null
        );

        if (xDstSurf.needServerData) {
            xDstSurf.putImage(clip,
                    (int) (roi.getX()),
                    (int) (roi.getY()),
                    (int) roi.getWidth(),
                    (int) roi.getHeight()
            );

        } else {
            xDstSurf.putImage(clip, dstX, dstY, width, height);
        }

        xDstSurf.needServerData = true;
    }

    private static void makeClip(
            int dstX, int dstY,
            int width, int height,
            MultiRectArea clip
    ) {
        Rectangle destRect = new Rectangle(dstX, dstY, width, height);
        clip.intersect(destRect);
    }
}
TOP

Related Classes of org.apache.harmony.awt.gl.linux.XBlitter

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.