All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.xhtmlrenderer.swt.SWTOutputDevice Maven / Gradle / Ivy

Go to download

Flying Saucer is a CSS 2.1 renderer written in Java. This artifact supports SWT output.

There is a newer version: 9.11.0
Show newest version
/*
 * {{{ header & license
 * Copyright (c) 2007 Vianney le Clément
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public License
 * as published by the Free Software Foundation; either version 2.1
 * of the License, or (at your option) any later version.
 *
 * This program 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 Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 * }}}
 */
package org.xhtmlrenderer.swt;

import java.awt.*;
import java.awt.RenderingHints.Key;
import java.awt.geom.AffineTransform;
import java.awt.geom.Area;
import java.awt.geom.PathIterator;

import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.*;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.graphics.Color;
import org.xhtmlrenderer.extend.FSImage;
import org.xhtmlrenderer.extend.OutputDevice;
import org.xhtmlrenderer.extend.ReplacedElement;
import org.xhtmlrenderer.render.*;
import org.xhtmlrenderer.simple.xhtml.swt.SWTFormControl;
import org.xhtmlrenderer.css.parser.FSColor;
import org.xhtmlrenderer.css.parser.FSRGBColor;

/**
 * Implementation of {@link OutputDevice} for SWT.
 * 
 * @author Vianney le Clément
 * 
 */
public class SWTOutputDevice extends AbstractOutputDevice {

    private final GC _gc;
    private Path _clippingPath = null;
    private Area _clippingArea = null;
    private Color _color = null;
    private java.awt.Color _awt_color = null;
    private Transform _transform = null;
    private Stroke _stroke = null;

    public SWTOutputDevice(GC gc) {
        _gc = gc;
    }

    /**
     * @return the Graphical Context associated with this OutputDevice
     */
    public GC getGC() {
        return _gc;
    }

    /**
     * Clean used resources.
     */
    public void clean() {
        if (_clippingPath != null) {
            _gc.setClipping((Rectangle) null);
            _clippingPath.dispose();
            _clippingPath = null;
            _clippingArea = null;
        }
        if (_color != null) {
            _color.dispose();
            _color = null;
        }
        if (_transform != null) {
            _gc.setTransform(null);
            _transform.dispose();
        }
    }

    public void clip(Shape s) {
        if (s == null) {
            return;
        }
        if (_clippingArea == null) {
            setClip(s);
        } else {
            Area a = new Area(_clippingArea);
            a.intersect(new Area(s));
            setClip(a);
        }
    }

    public void setClip(Shape s) {
        Path path = convertToPath(s);
        if (path == null) {
            _gc.setClipping((Rectangle) null);
        } else {
            _gc.setClipping(path);
        }
        if (_clippingPath != null) {
            _clippingPath.dispose();
        }
        _clippingPath = path;
        _clippingArea = (s == null ? null : new Area(s));
    }

    public Shape getClip() {
        return _clippingArea;
    }

    protected void drawLine(int x1, int y1, int x2, int y2) {
        _gc.drawLine(x1, y1, x2, y2);
    }

    public void drawBorderLine(Shape bounds, int side,
            int lineWidth, boolean solid) {
        /*int x = bounds.x;
        int y = bounds.y;
        int w = bounds.width;
        int h = bounds.height;

        int adj = solid ? 1 : 0;

        if (side == BorderPainter.TOP) {
            drawLine(x, y + (lineWidth / 2), x + w - adj, y + (lineWidth / 2));
        } else if (side == BorderPainter.LEFT) {
            drawLine(x + (lineWidth / 2), y, x + (lineWidth / 2), y + h - adj);
        } else if (side == BorderPainter.RIGHT) {
            int offset = (lineWidth / 2);
            if (lineWidth % 2 != 0) {
                offset += 1;
            }
            drawLine(x + w - offset, y, x + w - offset, y + h - adj);
        } else if (side == BorderPainter.BOTTOM) {
            int offset = (lineWidth / 2);
            if (lineWidth % 2 != 0) {
                offset += 1;
            }
            drawLine(x, y + h - offset, x + w - adj, y + h - offset);
        }*/
    	draw(bounds);
    }

    public void drawImage(FSImage image, int x, int y) {
        Image img = ((SWTFSImage) image).getImage();
        if (img == null) {
            int width = image.getWidth();
            int height = image.getHeight();
            Color oldBG = _gc.getBackground();
            Color oldFG = _gc.getForeground();
            _gc.setBackground(_gc.getDevice().getSystemColor(SWT.COLOR_WHITE));
            _gc.setForeground(_gc.getDevice().getSystemColor(SWT.COLOR_BLACK));
            _gc.fillRectangle(x, y, width, height);
            _gc.drawRectangle(x, y, width, height);
            _gc.drawLine(x, y, x + width - 1, y + height - 1);
            _gc.drawLine(x, y + height - 1, x + width - 1, y);
            _gc.setBackground(oldBG);
            _gc.setForeground(oldFG);
        } else {
            Rectangle bounds = img.getBounds();
            _gc.drawImage(img, 0, 0, bounds.width, bounds.height, x, y, image
                .getWidth(), image.getHeight());
        }
    }

    public void drawOval(int x, int y, int width, int height) {
        _gc.drawOval(x, y, width, height);
    }

    public void drawRect(int x, int y, int width, int height) {
        _gc.drawRectangle(x, y, width, height);
    }



	public void draw(Shape s) {
        Path p = convertToPath(s);
        _gc.drawPath(p);
        p.dispose();
	}
	
    public void fill(Shape s) {
        Path p = convertToPath(s);
        _gc.fillPath(p);
        p.dispose();
    }

    public void fillOval(int x, int y, int width, int height) {
        _gc.fillOval(x, y, width, height);
    }

    public void fillRect(int x, int y, int width, int height) {
        _gc.fillRectangle(x, y, width, height);
    }

    public void paintReplacedElement(RenderingContext c, BlockBox box) {
        ReplacedElement replaced = box.getReplacedElement();
        java.awt.Point location = replaced.getLocation();
        if (replaced instanceof ImageReplacedElement) {
            drawImage(((ImageReplacedElement) replaced).getImage(), location.x,
                location.y);
        } else if (replaced instanceof FormControlReplacementElement) {
            SWTFormControl swtControl = ((FormControlReplacementElement) replaced)
                .getControl();
            swtControl.getSWTControl().setVisible(true);
        }
    }

    public void setColor(java.awt.Color color) {
        if (color.equals(_awt_color)) {
            return;
        }

        Color col = new Color(_gc.getDevice(), color.getRed(),
            color.getGreen(), color.getBlue());
        _gc.setForeground(col);
        _gc.setBackground(col);
        _gc.setAlpha(color.getAlpha());
        if (_color != null) {
            _color.dispose();
        }
        _color = col;
        _awt_color = color;
    }

    public void setFont(FSFont font) {
        _gc.setFont(((SWTFSFont) font).getSWTFont());
    }

    public void setColor(FSColor color) {
        if (color instanceof FSRGBColor) {
            FSRGBColor rgb = (FSRGBColor)color;
            setColor(new java.awt.Color(rgb.getRed(), rgb.getGreen(), rgb.getBlue()));
        } else {
            throw new RuntimeException("internal error: unsupported color class " + color.getClass().getName());
        }

    }

    public Stroke getStroke() {
        return _stroke;
    }

    public void setStroke(Stroke s) {
        _stroke = s;

        /*
         * Code borrowed from SwingWT
         */
        if (s == null) {
            _gc.setLineWidth(1);
            _gc.setLineCap(SWT.CAP_SQUARE);
            _gc.setLineJoin(SWT.JOIN_MITER);
            _gc.setLineDash(null);
            return;
        }

        if (!(s instanceof BasicStroke)) {
            return;
        }

        BasicStroke bs = (BasicStroke) s;

        // Setup the line width
        _gc.setLineWidth((int) bs.getLineWidth());

        // Setup the line cap
        int gcCap = SWT.CAP_SQUARE;
        switch (bs.getEndCap()) {
        case BasicStroke.CAP_BUTT:
            gcCap = SWT.CAP_FLAT;
            break;
        case BasicStroke.CAP_ROUND:
            gcCap = SWT.CAP_ROUND;
            break;
        case BasicStroke.CAP_SQUARE:
            gcCap = SWT.CAP_SQUARE;
            break;
        }
        _gc.setLineCap(gcCap);

        // Setup the line Join
        int gcJoin = SWT.JOIN_MITER;
        switch (bs.getLineJoin()) {
        case BasicStroke.JOIN_BEVEL:
            gcJoin = SWT.JOIN_BEVEL;
            break;
        case BasicStroke.JOIN_MITER:
            gcJoin = SWT.JOIN_MITER;
            break;
        case BasicStroke.JOIN_ROUND:
            gcJoin = SWT.JOIN_ROUND;
        }
        _gc.setLineJoin(gcJoin);

        float d[] = bs.getDashArray();
        int[] dashes = null;
        if (d != null) {
            dashes = new int[d.length];
            for (int i = 0; i < d.length; i++) {
                dashes[i] = (int) d[i];
            }
        }
        _gc.setLineDash(dashes);
    }

    public void translate(double tx, double ty) {
        if (_transform == null) {
            _transform = new Transform(_gc.getDevice());
        }
        _transform.translate((int) tx, (int) ty);
        _gc.setTransform(_transform);
        if (_clippingArea != null) {
            AffineTransform t = new AffineTransform();
            t.translate(-tx, -ty);
            _clippingArea.transform(t);
        }
    }

    public Object getRenderingHint(Key key) {
        if (RenderingHints.KEY_ANTIALIASING.equals(key)) {
            switch (_gc.getAntialias()) {
            case SWT.DEFAULT:
                return RenderingHints.VALUE_ANTIALIAS_DEFAULT;
            case SWT.OFF:
                return RenderingHints.VALUE_ANTIALIAS_OFF;
            case SWT.ON:
                return RenderingHints.VALUE_ANTIALIAS_ON;
            }
        }
        return null;
    }

    public void setRenderingHint(Key key, Object value) {
        if (RenderingHints.KEY_ANTIALIASING.equals(key)) {
            int antialias = SWT.DEFAULT;
            if (RenderingHints.VALUE_ANTIALIAS_OFF.equals(value)) {
                antialias = SWT.OFF;
            } else if (RenderingHints.VALUE_ANTIALIAS_ON.equals(value)) {
                antialias = SWT.ON;
            }
            _gc.setAntialias(antialias);
        }
    }

    /**
     * Convert an AWT Shape to an SWT Path.
     * 
     * @param shape
     * @return the SWT Path or null if shape == null
     */
    private Path convertToPath(Shape shape) {
        if (shape == null) {
            return null;
        }
        Path path = new Path(_gc.getDevice());
        PathIterator iter = shape.getPathIterator(null);
        float[] coords = new float[6];
        while (!iter.isDone()) {
            int op = iter.currentSegment(coords);
            switch (op) {
            case PathIterator.SEG_MOVETO:
                path.moveTo(coords[0], coords[1]);
                break;
            case PathIterator.SEG_LINETO:
                path.lineTo(coords[0], coords[1]);
                break;
            case PathIterator.SEG_QUADTO:
                path.quadTo(coords[0], coords[1], coords[2], coords[3]);
                break;
            case PathIterator.SEG_CUBICTO:
                path.cubicTo(coords[0], coords[1], coords[2], coords[3],
                    coords[4], coords[5]);
                break;
            case PathIterator.SEG_CLOSE:
                path.close();
                break;
            }
            iter.next();
        }
        return path;
    }

    public void drawSelection(RenderingContext c, InlineText inlineText) {
        // TODO support selection drawing
    }

    public boolean isSupportsSelection() {
        // TODO support selection drawing
        return false;
    }

    public boolean isSupportsCMYKColors() {
        return false;  //To change body of implemented methods use File | Settings | File Templates.
    }

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy