/* * java-gnome, a UI library for writing GTK and GNOME programs from Java! * * Copyright © 2007-2011 Operational Dynamics Consulting, Pty Ltd * * The code in this file, and the program it is a part of, is made available * to you by its authors as open source software: you can redistribute it * and/or modify it under the terms of the GNU General Public License version * 2 ("GPL") as published by the Free Software Foundation. * * 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 GPL for more details. * * You should have received a copy of the GPL along with this program. If not, * see http://www.gnu.org/licenses/. The authors of this program may be * contacted through http://java-gnome.sourceforge.net/. * * Linking this library statically or dynamically with other modules is making * a combined work based on this library. Thus, the terms and conditions of * the GPL cover the whole combination. As a special exception (the * "Claspath Exception"), the copyright holders of this library give you * permission to link this library with independent modules to produce an * executable, regardless of the license terms of these independent modules, * and to copy and distribute the resulting executable under terms of your * choice, provided that you also meet, for each linked independent module, * the terms and conditions of the license of that module. An independent * module is a module which is not derived from or based on this library. If * you modify this library, you may extend the Classpath Exception to your * version of the library, but you are not obligated to do so. If you do not * wish to do so, delete this exception statement from your version. */ package org.freedesktop.cairo; import java.io.IOException; /** * The thing that Cairo will draw on/to. This is the base class for several * concrete back ends. * * @author Andrew Cowie * @since 4.0.7 */ public abstract class Surface extends Entity { protected Surface(long pointer) { super(pointer); } protected void release() { CairoSurface.destroy(this); } /** * Indicate to Cairo that you are finished drawing on this Surface and * that it can release the resources that Cairo has used in association * with it. After you call this, the Surface and any Contexts associated * with it will be in-operative. * *
* While the virtual machine will of course finalize this object when you * no longer have strong Java references to it, garbage collection is * non-deterministic and often takes place long after drawing is * completed. Calling this can allow the underlying library to get on with * releasing the resources involved in what is, after all, meant to be a * very fast and transient operation. * * @since 4.0.7 */ public void finish() { CairoSurface.finish(this); } /** * Complete any pending drawing operations. If your Surface comes from a * subsystem whose resources are shared with other drawing libraries, then * you need to call this before letting control return to a point where * those libraries might draw on the same backing Surface. * *
* Quoting Carl Worth, the original author of Cairo,
This is * really only necessary to call if you want to switch from Cairo-based * rendering to non-Cairo-based rendering to the same underlying thingy * under the Surface (Window, Pixmap, data buffer, etc.).* *
* In other words, if you are the only one drawing on the Surface, then
* you don't need this. And that is indeed the case if you are drawing on
* your own custom Widget in its Widget.Draw signal handler.
*
*
* See also {@link #finish() finish()} if you're just trying to say "I'm * done". * *
* Clearly, "thingy" is an advanced graphics term. * * @since 4.0.7 */ public void flush() { CairoSurface.flush(this); } /** * Output the contents of this Surface to the specified file. * * @throws IOException * If the file can't be written. * * @since 4.0.7 */ public void writeToPNG(String filename) throws IOException { final Status status; status = CairoSurface.writeToPng(this, filename); if (status == Status.WRITE_ERROR) { throw new IOException("You cannot write to file " + filename); } checkStatus(status); } protected void checkStatus() { checkStatus(CairoSurface.status(this)); } /** * Emit the current page and clear the Surface, allowing you to continue * drawing with your Context but to a new blank page. * *
* If you want to render the current page, but keep the page content in * your Context, then call {@link #copyPage() copyPage()} instead. * *
* This method only applies to Surfaces which are paginated, which in * practise means the PDF backend. * * @since 4.0.10 */ /* * While Cairo treats these as a no-op for backends which are not * paginated, throwing UnsupportedOperationException is the more * traditional and accepted Java way of dealing with the case of base * classes which expose a method for which many subclasses do not take * action. Obviously this should be overridden by concrete subclasses * representing backends which are actually paginated. */ public void showPage() { throw new UnsupportedOperationException(); } /** * Emit the current page, but keep the content of the Surface as the * starting point for the next page. * * @since 4.0.10 */ public void copyPage() { throw new UnsupportedOperationException(); } /** * Create a new Surface based on this one. * *
* surface.createSimilar(Content.COLOR_ALPHA, 800, 600);
*
*
* * This has enormous application when drawing with image heavy content to * screen. * * @since 4.0.10 */ public Surface createSimilar(Content type, int width, int height) { return CairoSurface.createSimilar(this, type, width, height); } /** * Attach original image data to a surface. When drawing an image into a * vector Surface such as PDF or SVG, Cairo will draw the decoded image as * a bitmap. Which is hugely inefficient. This method allows you to * add the original image to the surface, and when drawing out Cairo will * use this if it can. * *
* Keep in mind that you attach the data to the intermediate * Surface which is painted onto the target, not the final target Surface * itself. * *
* pixbuf = new Pixbuf(data);
*
* intermediate = new ImageSurface(Format.ARGB32, width, height);
*
* second = new Context(intermediate);
* second.setSource(pixbuf, 0, 0);
* second.paint();
* intermediate.setMimeData(MimeType.JPEG, data);
*
* cr.setSource(intermediate, 0, 0);
* cr.paint();
*
*
* or you can go through the implicitly created Pattern:
*
*
* pixbuf = new Pixbuf(data);
*
* cr.setSource(pixbuf, 0, 0);
* pattern = cr.getSource();
* implicit = pattern.getSurface();
* implicit.setMimeData(MimeType.JPEG, data);
*
* cr.paint();
*
*
* which seems a bit easier.
*
*
* NOTE:
* You must not make any changes to the intermediate surface after setting
* the image data or you will lose the effect of this call.
*
*
* It would be nice if gdk_cairo_set_source_pixbuf() just did this for * us. * * * @since 4.0.18 */ public void setMimeData(MimeType type, byte[] data) { CairoSurfaceOverride.setMimeData(this, type, data); } /** * Set a filename as the MIME data for this surface. * * @since Unstable */ /* * FIXME How does this work? Are you supposed to use URI, or the actual * file type, or? */ public void setMimeData(MimeType type, String filename) { final byte[] data; data = filename.getBytes(); CairoSurfaceOverride.setMimeData(this, type, data); } }