All pastes #2076961 Raw Edit

Something

public text v1 · immutable
#2076961 ·published 2011-06-08 21:41 UTC
rendered paste body
/*******************************************************************************
 * Copyright (c) 2004 - 2010 IBM Corporation and others.
 * All rights reserved. This program and the accompanying materials 
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 * 
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *     Tom Schindl     - modification to be os independent
 *******************************************************************************/

package org.eclipse.nebula.effects.stw;


import org.eclipse.swt.graphics.*;
import org.eclipse.swt.widgets.*;

/**
 * Image Capture
 */
public class ImageCapture {

    public static void drawOnImage(Image myImage, Control control, int maxWidth, int maxHeight, boolean includeChildren) {
        // We need to be able to handle right-to-left coordinates too. In that case the bounds rectangle will be reversed from what we
        // think. We think the origin is upper-left, but the origin is really upper-right. To get out of this thinking we will
        // instead convert all bounds to display bounds so that they will all be left-to-right.
        if (myImage != null) {
            // Get the images of all of the children
            if (includeChildren && control instanceof Composite) {
                Display display = control.getDisplay();
                Rectangle parentBounds = control.getParent() == null ? control.getBounds() : display.map(control.getParent(), null, control.getBounds());
                // Need to clip the bounds to the size of the image so we get just what we need.
                Rectangle imgBounds = myImage.getBounds();
                parentBounds.width = imgBounds.width;
                parentBounds.height = imgBounds.height;
                int parentRight = parentBounds.width+parentBounds.x;
                int parentBottom = parentBounds.height+parentBounds.y;
                Control[] children = ((Composite) control).getChildren();
                GC myImageGC = new GC(myImage);
                try {
                    int i = children.length;
                    while (--i >= 0) {
                        Control child = children[i];
                        // If the child is not visible then don't try and get its image
                        // An example of where this would cause a problem is TabFolder where all the controls
                        // for each page are children of the TabFolder, but only the visible one is being shown on the active page
                        if (!child.isVisible())
                            continue;
                        Rectangle childBounds = display.map(control, null, child.getBounds());
                        if (!parentBounds.intersects(childBounds))
                            continue; // Child is completely outside parent.
                        Image childImage = getImage(child, parentRight - childBounds.x, parentBottom - childBounds.y, true);
                        if (childImage != null) {
                            try {
                                // Paint the child image on top of our one
                                // Since the child bounds and parent bounds are both in display coors, the difference between
                                // the two is the offset of the child from the parent.
                                myImageGC.drawImage(childImage, childBounds.x-parentBounds.x, childBounds.y-parentBounds.y);
                            } finally {
                                childImage.dispose();
                            }
                        }
                    }
                } finally {
                    myImageGC.dispose();
                }
            }
        }
    }
    
    public static Image getImage(Control control, int maxWidth, int maxHeight, boolean includeChildren) {
        Image myImage = getImage(control, maxWidth, maxHeight);
        drawOnImage(myImage, control, maxWidth, maxHeight, includeChildren);
        return myImage;
    }

    /**
     * Return the image of the argument. This includes the client and non-client area, but does not include any child controls. To get child control
     * use {@link ImageCapture#getImage(Control, int, int, boolean)}.
     * 
     * @param aControl
     * @param maxWidth
     * @param maxHeight
     * @return image or <code>null</code> if not valid for some reason. (Like not yet sized).
     * 
     * @since 1.1.0
     */
    public static Image getImage(Control aControl, int maxWidth, int maxHeight) {

        Rectangle rect = aControl.getBounds();
        if (rect.width <= 0 || rect.height <= 0)
            return null;

        Image image = new Image(aControl.getDisplay(), Math.min(rect.width, maxWidth), Math.min(rect.height, maxHeight));
        GC gc = new GC(image);
        
        // Need to handle cases where the GC font isn't automatically set by the control's image (e.g. CLabel)
        // see bug 98830 (https://bugs.eclipse.org/bugs/show_bug.cgi?id=98830)
        Font f = aControl.getFont();
        if (f != null)
            gc.setFont(f);
        aControl.print(gc);
        
        gc.dispose();
        return image;
    }
}