String.java, [...]: Merge from GNU Classpath HEAD.

2006-06-09  Thomas Fitzsimmons  <fitzsim@redhat.com>

	* java/lang/String.java, classpath/native/jni/classpath/jcl.h,
	classpath/native/jni/qt-peer/eventmethods.h,
	classpath/native/jni/qt-peer/qtmenupeer.cpp,
	classpath/native/jni/qt-peer/.cvsignore,
	classpath/native/jni/gtk-peer/gdkdisplay.h,
	classpath/native/jni/gtk-peer/cairographics2d.h,
	classpath/native/jni/gtk-peer/gnu_java_awt_peer_gtk_CairoGraphics2D.c,
	classpath/native/jni/gtk-peer/gnu_java_awt_peer_gtk_GdkFontPeer.c,
	classpath/native/jni/gtk-peer/gnu_java_awt_peer_gtk_FreetypeGlyphVector.c,
	classpath/native/jni/gtk-peer/gnu_java_awt_peer_gtk_GdkGraphicsEnvironment.c,
	classpath/native/jni/gtk-peer/gnu_java_awt_peer_gtk_ComponentGraphicsCopy.c,
	classpath/native/jni/gtk-peer/gnu_java_awt_peer_gtk_ComponentGraphics.c,
	classpath/native/jni/gtk-peer/.cvsignore,
	classpath/native/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkImage.c,
	classpath/native/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkVolatileImage.c,
	classpath/native/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkToolkit.c,
	classpath/native/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkCanvasPeer.c,
	classpath/native/jni/gtk-peer/gtkpeer.h,
	classpath/native/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkClipboard.c,
	classpath/native/jni/gtk-peer/gnu_java_awt_peer_gtk_CairoSurface.c,
	classpath/native/jni/gtk-peer/gnu_java_awt_peer_gtk_GdkScreenGraphicsDevice.c,
	classpath/native/jni/gtk-peer/gnu_java_awt_peer_gtk_GdkTextLayout.c,
	classpath/native/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkFramePeer.c,
	classpath/native/jni/gtk-peer/Makefile.am,
	classpath/native/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkComponentPeer.c,
	classpath/native/jawt/Makefile.am,
	classpath/native/jawt/.cvsignore,
	classpath/native/target/Linux/Makefile.in,
	classpath/native/plugin/gcjwebplugin.cc,
	classpath/native/plugin/Makefile.am,
	classpath/native/plugin/.cvsignore,
	classpath/resource/Makefile.in,
	classpath/gnu/java/awt/peer/gtk/VolatileImageGraphics.java,
	classpath/gnu/java/awt/peer/gtk/CairoGraphics2D.java,
	classpath/gnu/java/awt/peer/gtk/CairoSurface.java,
	classpath/gnu/java/awt/peer/gtk/GdkFontPeer.java,
	classpath/gnu/java/awt/peer/gtk/GdkPixbufDecoder.java,
	classpath/gnu/java/awt/peer/gtk/FreetypeGlyphVector.java,
	classpath/gnu/java/awt/peer/gtk/GdkGraphicsEnvironment.java,
	classpath/gnu/java/awt/peer/gtk/GdkGraphics2D.java,
	classpath/gnu/java/awt/peer/gtk/ComponentGraphicsCopy.java,
	classpath/gnu/java/awt/peer/gtk/GtkComponentPeer.java,
	classpath/gnu/java/awt/peer/gtk/GdkGraphics.java,
	classpath/gnu/java/awt/peer/gtk/GtkToolkit.java,
	classpath/gnu/java/awt/peer/gtk/GdkScreenGraphicsDevice.java,
	classpath/gnu/java/awt/peer/gtk/BufferedImageGraphics.java,
	classpath/gnu/java/awt/peer/gtk/GdkTextLayout.java,
	classpath/gnu/java/awt/peer/gtk/GdkGraphicsConfiguration.java,
	classpath/gnu/java/awt/peer/gtk/ComponentGraphics.java,
	classpath/gnu/java/awt/peer/gtk/CairoSurfaceGraphics.java,
	classpath/gnu/java/awt/peer/gtk/GtkImage.java,
	classpath/gnu/java/awt/peer/gtk/GtkVolatileImage.java,
	classpath/gnu/java/awt/peer/gtk/GdkGlyphVector.java,
	classpath/gnu/java/awt/peer/gtk/GtkCanvasPeer.java,
	classpath/gnu/java/awt/peer/swing/SwingContainerPeer.java,
	classpath/gnu/java/awt/peer/swing/SwingComponent.java,
	classpath/gnu/java/awt/peer/swing/SwingTextFieldPeer.java,
	classpath/gnu/java/awt/peer/swing/SwingMenuBarPeer.java,
	classpath/gnu/java/awt/peer/swing/SwingFramePeer.java,
	classpath/gnu/java/awt/peer/swing/SwingComponentPeer.java,
	classpath/gnu/java/awt/peer/swing/SwingWindowPeer.java,
	classpath/gnu/java/awt/print/JavaPrinterJob.java,
	classpath/gnu/java/awt/print/PostScriptGraphics2D.java,
	classpath/gnu/java/awt/print/SpooledDocument.java,
	classpath/gnu/java/awt/print/JavaPrinterGraphics.java,
	classpath/gnu/java/awt/BitwiseXORComposite.java,
	classpath/gnu/java/awt/font/GNUGlyphVector.java,
	classpath/gnu/java/awt/font/opentype/NameDecoder.java,
	classpath/gnu/java/awt/java2d/RasterGraphics.java,
	classpath/gnu/java/awt/java2d/TexturePaintContext.java,
	classpath/gnu/java/awt/java2d/PolyEdge.java,
	classpath/gnu/java/awt/java2d/AbstractGraphics2D.java,
	classpath/gnu/java/awt/java2d/AlphaCompositeContext.java,
	classpath/gnu/java/awt/java2d/ImagePaint.java,
	classpath/gnu/java/awt/Buffers.java,
	classpath/gnu/classpath/Configuration.java.in,
	classpath/gnu/javax/swing/text/html/CombinedAttributes.java,
	classpath/gnu/javax/swing/text/html/CharacterAttributeTranslator.java,
	classpath/gnu/javax/swing/text/html/parser/htmlAttributeSet.java,
	classpath/gnu/javax/swing/text/html/parser/SmallHtmlAttributeSet.java,
	classpath/gnu/javax/swing/text/html/ImageViewIconFactory.java,
	classpath/tools/toolwrapper.c,
	classpath/tools/gnu/classpath/tools/native2ascii/Native2ASCII.java,
	classpath/tools/gnu/classpath/tools/native2ascii/Messages.java,
	classpath/tools/gnu/classpath/tools/getopt/FileArgumentCallback.java,
	classpath/tools/gnu/classpath/tools/getopt/OptionGroup.java,
	classpath/tools/gnu/classpath/tools/getopt/OptionException.java,
	classpath/tools/gnu/classpath/tools/getopt/Messages.java,
	classpath/tools/gnu/classpath/tools/getopt/Option.java,
	classpath/tools/gnu/classpath/tools/getopt/Parser.java,
	classpath/tools/gnu/classpath/tools/getopt/ClasspathToolParser.java,
	classpath/tools/gnu/classpath/tools/jarsigner/JarSigner.java,
	classpath/tools/gnu/classpath/tools/jarsigner/Main.java,
	classpath/tools/gnu/classpath/tools/jarsigner/Messages.java,
	classpath/tools/gnu/classpath/tools/jarsigner/package.html,
	classpath/tools/gnu/classpath/tools/keytool/ListCmd.java,
	classpath/tools/gnu/classpath/tools/keytool/StorePasswdCmd.java,
	classpath/tools/gnu/classpath/tools/keytool/ExportCmd.java,
	classpath/tools/gnu/classpath/tools/keytool/GenKeyCmd.java,
	classpath/tools/gnu/classpath/tools/keytool/Messages.java,
	classpath/tools/gnu/classpath/tools/keytool/package.html,
	classpath/tools/gnu/classpath/tools/keytool/Command.java,
	classpath/tools/gnu/classpath/tools/keytool/IdentityDBCmd.java,
	classpath/tools/gnu/classpath/tools/keytool/Main.java,
	classpath/tools/gnu/classpath/tools/keytool/DeleteCmd.java,
	classpath/tools/gnu/classpath/tools/keytool/CertReqCmd.java,
	classpath/tools/gnu/classpath/tools/keytool/SelfCertCmd.java,
	classpath/tools/gnu/classpath/tools/keytool/KeyCloneCmd.java,
	classpath/tools/gnu/classpath/tools/keytool/KeyPasswdCmd.java,
	classpath/tools/gnu/classpath/tools/keytool/ImportCmd.java,
	classpath/tools/gnu/classpath/tools/keytool/PrintCertCmd.java,
	classpath/tools/gnu/classpath/tools/rmi/registry/package.html,
	classpath/tools/gnu/classpath/tools/rmi/RMIC.txt,
	classpath/tools/gnu/classpath/tools/rmi/RMIC.java,
	classpath/tools/gnu/classpath/tools/appletviewer/ErrorApplet.java,
	classpath/tools/gnu/classpath/tools/appletviewer/AppletClassLoader.java,
	classpath/tools/gnu/classpath/tools/appletviewer/CommonAppletContext.java,
	classpath/tools/gnu/classpath/tools/appletviewer/StandaloneAppletContext.java,
	classpath/tools/gnu/classpath/tools/appletviewer/AppletSecurityManager.java,
	classpath/tools/gnu/classpath/tools/appletviewer/PluginAppletContext.java,
	classpath/tools/gnu/classpath/tools/appletviewer/AppletWarning.java,
	classpath/tools/gnu/classpath/tools/appletviewer/StandaloneAppletViewer.java,
	classpath/tools/gnu/classpath/tools/appletviewer/AppletTag.java,
	classpath/tools/gnu/classpath/tools/appletviewer/ConsoleDialog.java,
	classpath/tools/gnu/classpath/tools/appletviewer/Main.java,
	classpath/tools/gnu/classpath/tools/appletviewer/StandaloneAppletWindow.java,
	classpath/tools/gnu/classpath/tools/appletviewer/PluginAppletViewer.java,
	classpath/tools/gnu/classpath/tools/appletviewer/TagParser.java,
	classpath/tools/gnu/classpath/tools/appletviewer/PluginAppletWindow.java,
	classpath/tools/gnu/classpath/tools/appletviewer/CommonAppletStub.java,
	classpath/tools/gnu/classpath/tools/serialver/Messages.java,
	classpath/tools/gnu/classpath/tools/serialver/SerialVer.java,
	classpath/tools/gnu/classpath/tools/jar/Creator.java,
	classpath/tools/gnu/classpath/tools/jar/Entry.java,
	classpath/tools/gnu/classpath/tools/jar/Lister.java,
	classpath/tools/gnu/classpath/tools/jar/Main.java,
	classpath/tools/gnu/classpath/tools/jar/Updater.java,
	classpath/tools/gnu/classpath/tools/jar/Messages.java,
	classpath/tools/gnu/classpath/tools/jar/Extractor.java,
	classpath/tools/gnu/classpath/tools/jar/Action.java,
	classpath/tools/gnu/classpath/tools/jar/Indexer.java,
	classpath/tools/gnu/classpath/tools/jar/WorkSet.java,
	classpath/tools/gnu/classpath/tools/giop/GRMIC.txt,
	classpath/tools/gnu/classpath/tools/giop/grmic/GiopRmicCompiler.java,
	classpath/tools/gnu/classpath/tools/giop/GRMIC.java,
	classpath/tools/Makefile.am, classpath/tools/jarsigner.in,
	classpath/tools/keytool.in, classpath/tools/appletviewer.in,
	classpath/tools/.cvsignore, classpath/configure.ac,
	classpath/javax/swing/JTabbedPane.java,
	classpath/javax/swing/AbstractButton.java,
	classpath/javax/swing/JViewport.java,
	classpath/javax/swing/KeyboardManager.java,
	classpath/javax/swing/JMenuItem.java,
	classpath/javax/swing/JMenuBar.java,
	classpath/javax/swing/MenuSelectionManager.java,
	classpath/javax/swing/JOptionPane.java,
	classpath/javax/swing/JSpinner.java,
	classpath/javax/swing/JCheckBoxMenuItem.java,
	classpath/javax/swing/JEditorPane.java,
	classpath/javax/swing/JFormattedTextField.java,
	classpath/javax/swing/JTree.java,
	classpath/javax/swing/CellRendererPane.java,
	classpath/javax/swing/JScrollPane.java,
	classpath/javax/swing/tree/VariableHeightLayoutCache.java,
	classpath/javax/swing/tree/TreeNode.java,
	classpath/javax/swing/tree/FixedHeightLayoutCache.java,
	classpath/javax/swing/tree/DefaultTreeCellEditor.java,
	classpath/javax/swing/tree/TreePath.java,
	classpath/javax/swing/tree/RowMapper.java,
	classpath/javax/swing/tree/DefaultMutableTreeNode.java,
	classpath/javax/swing/tree/DefaultTreeModel.java,
	classpath/javax/swing/tree/AbstractLayoutCache.java,
	classpath/javax/swing/tree/TreeSelectionModel.java,
	classpath/javax/swing/tree/DefaultTreeSelectionModel.java,
	classpath/javax/swing/tree/DefaultTreeCellRenderer.java,
	classpath/javax/swing/tree/ExpandVetoException.java,
	classpath/javax/swing/JList.java,
	classpath/javax/swing/table/JTableHeader.java,
	classpath/javax/swing/table/AbstractTableModel.java,
	classpath/javax/swing/table/DefaultTableModel.java,
	classpath/javax/swing/table/TableCellEditor.java,
	classpath/javax/swing/table/TableCellRenderer.java,
	classpath/javax/swing/ProgressMonitor.java,
	classpath/javax/swing/JToolBar.java,
	classpath/javax/swing/TransferHandler.java,
	classpath/javax/swing/DefaultCellEditor.java,
	classpath/javax/swing/DefaultButtonModel.java,
	classpath/javax/swing/JLayeredPane.java,
	classpath/javax/swing/text/DefaultEditorKit.java,
	classpath/javax/swing/text/DefaultCaret.java,
	classpath/javax/swing/text/FieldView.java,
	classpath/javax/swing/text/JTextComponent.java,
	classpath/javax/swing/text/TextAction.java,
	classpath/javax/swing/text/StyleContext.java,
	classpath/javax/swing/text/html/HTMLDocument.java,
	classpath/javax/swing/text/html/MinimalHTMLWriter.java,
	classpath/javax/swing/text/html/ImageView.java,
	classpath/javax/swing/text/html/HTMLEditorKit.java,
	classpath/javax/swing/text/AbstractWriter.java,
	classpath/javax/swing/text/GapContent.java,
	classpath/javax/swing/text/Utilities.java,
	classpath/javax/swing/text/PlainView.java,
	classpath/javax/swing/UIManager.java,
	classpath/javax/swing/JSplitPane.java,
	classpath/javax/swing/JComponent.java,
	classpath/javax/swing/SwingUtilities.java,
	classpath/javax/swing/border/AbstractBorder.java,
	classpath/javax/swing/border/CompoundBorder.java,
	classpath/javax/swing/border/TitledBorder.java,
	classpath/javax/swing/border/MatteBorder.java,
	classpath/javax/swing/border/BevelBorder.java,
	classpath/javax/swing/RepaintManager.java,
	classpath/javax/swing/JTable.java,
	classpath/javax/swing/UIDefaults.java,
	classpath/javax/swing/DefaultDesktopManager.java,
	classpath/javax/swing/JMenu.java,
	classpath/javax/swing/JLabel.java,
	classpath/javax/swing/JSlider.java,
	classpath/javax/swing/plaf/basic/BasicToolBarUI.java,
	classpath/javax/swing/plaf/basic/BasicButtonUI.java,
	classpath/javax/swing/plaf/basic/BasicOptionPaneUI.java,
	classpath/javax/swing/plaf/basic/BasicTextAreaUI.java,
	classpath/javax/swing/plaf/basic/BasicToggleButtonUI.java,
	classpath/javax/swing/plaf/basic/BasicSpinnerUI.java,
	classpath/javax/swing/plaf/basic/BasicSliderUI.java,
	classpath/javax/swing/plaf/basic/BasicTabbedPaneUI.java,
	classpath/javax/swing/plaf/basic/BasicComboPopup.java,
	classpath/javax/swing/plaf/basic/BasicCheckBoxUI.java,
	classpath/javax/swing/plaf/basic/BasicInternalFrameUI.java,
	classpath/javax/swing/plaf/basic/BasicProgressBarUI.java,
	classpath/javax/swing/plaf/basic/BasicRadioButtonUI.java,
	classpath/javax/swing/plaf/basic/BasicPanelUI.java,
	classpath/javax/swing/plaf/basic/BasicSplitPaneUI.java,
	classpath/javax/swing/plaf/basic/BasicTreeUI.java,
	classpath/javax/swing/plaf/basic/BasicTableHeaderUI.java,
	classpath/javax/swing/plaf/basic/BasicFileChooserUI.java,
	classpath/javax/swing/plaf/basic/BasicScrollPaneUI.java,
	classpath/javax/swing/plaf/basic/BasicComboBoxUI.java,
	classpath/javax/swing/plaf/basic/BasicListUI.java,
	classpath/javax/swing/plaf/basic/BasicIconFactory.java,
	classpath/javax/swing/plaf/basic/BasicTextUI.java,
	classpath/javax/swing/plaf/basic/BasicLookAndFeel.java,
	classpath/javax/swing/plaf/basic/BasicDirectoryModel.java,
	classpath/javax/swing/plaf/basic/BasicRootPaneUI.java,
	classpath/javax/swing/plaf/basic/BasicTableUI.java,
	classpath/javax/swing/plaf/basic/SharedUIDefaults.java,
	classpath/javax/swing/plaf/multi/MultiComboBoxUI.java,
	classpath/javax/swing/plaf/multi/MultiListUI.java,
	classpath/javax/swing/plaf/multi/MultiSplitPaneUI.java,
	classpath/javax/swing/plaf/multi/MultiFileChooserUI.java,
	classpath/javax/swing/plaf/multi/MultiOptionPaneUI.java,
	classpath/javax/swing/plaf/multi/MultiTabbedPaneUI.java,
	classpath/javax/swing/plaf/multi/MultiLookAndFeel.java,
	classpath/javax/swing/plaf/metal/MetalSliderUI.java,
	classpath/javax/swing/plaf/metal/MetalIconFactory.java,
	classpath/javax/swing/plaf/metal/MetalComboBoxIcon.java,
	classpath/javax/swing/plaf/metal/MetalTabbedPaneUI.java,
	classpath/javax/swing/plaf/metal/MetalLookAndFeel.java,
	classpath/javax/swing/plaf/metal/MetalCheckBoxUI.java,
	classpath/javax/swing/plaf/metal/MetalSeparatorUI.java,
	classpath/javax/swing/plaf/metal/MetalBorders.java,
	classpath/javax/swing/plaf/metal/MetalSplitPaneDivider.java,
	classpath/javax/swing/plaf/metal/MetalScrollBarUI.java,
	classpath/javax/swing/plaf/metal/MetalRootPaneUI.java,
	classpath/javax/swing/plaf/metal/MetalInternalFrameUI.java,
	classpath/javax/swing/plaf/metal/MetalRadioButtonUI.java,
	classpath/javax/swing/plaf/metal/MetalToolTipUI.java,
	classpath/javax/swing/plaf/metal/MetalInternalFrameTitlePane.java,
	classpath/javax/swing/plaf/metal/MetalFileChooserUI.java,
	classpath/javax/swing/plaf/metal/MetalUtils.java,
	classpath/javax/swing/plaf/metal/MetalComboBoxButton.java,
	classpath/javax/swing/plaf/metal/MetalPopupMenuSeparatorUI.java,
	classpath/javax/swing/plaf/metal/MetalButtonUI.java,
	classpath/javax/swing/JPopupMenu.java,
	classpath/javax/swing/JProgressBar.java,
	classpath/javax/swing/WindowConstants.java,
	classpath/javax/swing/JFrame.java,
	classpath/javax/swing/JFileChooser.java,
	classpath/javax/swing/JComboBox.java,
	classpath/javax/swing/event/EventListenerList.java,
	classpath/javax/swing/ListSelectionModel.java,
	classpath/javax/swing/JScrollBar.java,
	classpath/java/text/SimpleDateFormat.java,
	classpath/java/text/NumberFormat.java,
	classpath/java/text/class-dependencies.conf,
	classpath/java/awt/image/ColorModel.java,
	classpath/java/awt/image/BufferedImage.java,
	classpath/java/awt/Window.java,
	classpath/java/awt/ContainerOrderFocusTraversalPolicy.java,
	classpath/java/awt/LightweightDispatcher.java,
	classpath/java/awt/EventDispatchThread.java,
	classpath/java/awt/BasicStroke.java,
	classpath/java/awt/ColorPaintContext.java,
	classpath/java/awt/Container.java,
	classpath/java/awt/TexturePaint.java,
	classpath/java/awt/Component.java, classpath/java/awt/Font.java,
	classpath/java/awt/GraphicsConfiguration.java,
	classpath/java/awt/DefaultKeyboardFocusManager.java,
	classpath/java/awt/print/PrinterJob.java,
	classpath/java/awt/im/InputContext.java,
	classpath/java/awt/dnd/DragGestureRecognizer.java,
	classpath/java/awt/Toolkit.java,
	classpath/java/awt/font/GraphicAttribute.java,
	classpath/java/awt/font/ImageGraphicAttribute.java,
	classpath/java/awt/font/GlyphVector.java,
	classpath/java/awt/font/GlyphMetrics.java,
	classpath/java/awt/font/ShapeGraphicAttribute.java,
	classpath/java/awt/Graphics2D.java,
	classpath/include/gnu_java_awt_peer_gtk_GdkGraphicsEnvironment.h,
	classpath/include/gnu_java_awt_peer_gtk_ComponentGraphics.h,
	classpath/include/gnu_java_awt_peer_gtk_CairoGraphics2D.h,
	classpath/include/gnu_java_awt_peer_gtk_FreetypeGlyphVector.h,
	classpath/include/gnu_java_awt_peer_gtk_GtkCanvasPeer.h,
	classpath/include/config.h.in,
	classpath/include/gnu_java_awt_peer_gtk_GdkTextLayout.h,
	classpath/include/gnu_java_awt_peer_gtk_GtkComponentPeer.h,
	classpath/include/gnu_java_awt_peer_gtk_GdkFontPeer.h,
	classpath/include/gnu_java_awt_peer_gtk_ComponentGraphicsCopy.h,
	classpath/include/gnu_java_awt_peer_gtk_GtkVolatileImage.h,
	classpath/include/gnu_java_awt_peer_gtk_GtkImage.h,
	classpath/include/gnu_java_awt_peer_gtk_CairoSurface.h,
	classpath/include/gnu_java_awt_peer_gtk_GdkScreenGraphicsDevice.h:
	Merge from GNU Classpath HEAD.

From-SVN: r114510
This commit is contained in:
Thomas Fitzsimmons
2006-06-09 16:07:07 +00:00
committed by Thomas Fitzsimmons
parent 6c65d7577c
commit 02440ca432
360 changed files with 34743 additions and 9337 deletions
@@ -0,0 +1,258 @@
/* BufferedImageGraphics.java
Copyright (C) 2006 Free Software Foundation, Inc.
This file is part of GNU Classpath.
GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
GNU Classpath 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 GNU Classpath; see the file COPYING. If not, write to the
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA.
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 GNU General Public License cover the whole
combination.
As a special 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
this 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 gnu.java.awt.peer.gtk;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GraphicsConfiguration;
import java.awt.Image;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.Shape;
import java.awt.font.GlyphVector;
import java.awt.geom.AffineTransform;
import java.awt.geom.Rectangle2D;
import java.awt.image.BufferedImage;
import java.awt.image.DataBuffer;
import java.awt.image.DataBufferInt;
import java.awt.image.ColorModel;
import java.awt.image.DirectColorModel;
import java.awt.image.RenderedImage;
import java.awt.image.ImageObserver;
import java.util.WeakHashMap;
/**
* Implementation of Graphics2D on a Cairo surface.
*
* Simutanously maintains a CairoSurface and updates the
* BufferedImage from that after each drawing operation.
*/
public class BufferedImageGraphics extends CairoGraphics2D
{
/**
* the buffered Image.
*/
private BufferedImage image;
/**
* Image size.
*/
private int imageWidth, imageHeight;
/**
* The cairo surface that we actually draw on.
*/
CairoSurface surface;
/**
* Cache BufferedImageGraphics surfaces.
*/
static WeakHashMap bufferedImages = new WeakHashMap();
/**
* Its corresponding cairo_t.
*/
private long cairo_t;
/**
* Colormodels we recognize for fast copying.
*/
static ColorModel rgb32 = new DirectColorModel(32, 0xFF0000, 0xFF00, 0xFF);
static ColorModel argb32 = new DirectColorModel(32, 0xFF0000, 0xFF00, 0xFF,
0xFF000000);
private boolean hasFastCM;
private boolean hasAlpha;
public BufferedImageGraphics(BufferedImage bi)
{
this.image = bi;
imageWidth = bi.getWidth();
imageHeight = bi.getHeight();
if(bi.getColorModel().equals(rgb32))
{
hasFastCM = true;
hasAlpha = false;
}
else if(bi.getColorModel().equals(argb32))
{
hasFastCM = true;
hasAlpha = false;
}
else
hasFastCM = false;
// Cache surfaces.
if( bufferedImages.get( bi ) != null )
surface = (CairoSurface)bufferedImages.get( bi );
else
{
surface = new CairoSurface( imageWidth, imageHeight );
bufferedImages.put(bi, surface);
}
cairo_t = surface.newCairoContext();
DataBuffer db = bi.getRaster().getDataBuffer();
int[] pixels;
// get pixels
if(db instanceof CairoSurface)
pixels = ((CairoSurface)db).getPixels(imageWidth * imageHeight);
else
{
if( hasFastCM )
{
pixels = ((DataBufferInt)db).getData();
if( !hasAlpha )
for(int i = 0; i < pixels.length; i++)
pixels[i] &= 0xFFFFFFFF;
}
else
{
pixels = CairoGraphics2D.findSimpleIntegerArray
(image.getColorModel(),image.getData());
}
}
surface.setPixels( pixels );
setup( cairo_t );
setClip(0, 0, imageWidth, imageHeight);
}
BufferedImageGraphics(BufferedImageGraphics copyFrom)
{
surface = copyFrom.surface;
cairo_t = surface.newCairoContext();
imageWidth = copyFrom.imageWidth;
imageHeight = copyFrom.imageHeight;
copy( copyFrom, cairo_t );
setClip(0, 0, surface.width, surface.height);
}
/**
* Update a rectangle of the bufferedImage. This can be improved upon a lot.
*/
private void updateBufferedImage(int x, int y, int width, int height)
{
int[] pixels = surface.getPixels(imageWidth * imageHeight);
if( x > imageWidth || y > imageHeight )
return;
// Clip edges.
if( x < 0 ){ width = width + x; x = 0; }
if( y < 0 ){ height = height + y; y = 0; }
if( x + width > imageWidth )
width = imageWidth - x;
if( y + height > imageHeight )
height = imageHeight - y;
if( !hasFastCM )
image.setRGB(x, y, width, height, pixels,
x + y * imageWidth, imageWidth);
else
System.arraycopy(pixels, y * imageWidth,
((DataBufferInt)image.getRaster().getDataBuffer()).
getData(), y * imageWidth, height * imageWidth);
}
/**
* Abstract methods.
*/
public Graphics create()
{
return new BufferedImageGraphics(this);
}
public GraphicsConfiguration getDeviceConfiguration()
{
return null;
}
protected Rectangle2D getRealBounds()
{
return new Rectangle2D.Double(0.0, 0.0, imageWidth, imageHeight);
}
public void copyAreaImpl(int x, int y, int width, int height, int dx, int dy)
{
surface.copyAreaNative(x, y, width, height, dx, dy, surface.width);
updateBufferedImage(x + dx, y + dy, width, height);
}
/**
* Overloaded methods that do actual drawing need to enter the gdk threads
* and also do certain things before and after.
*/
public void draw(Shape s)
{
super.draw(s);
Rectangle r = s.getBounds();
updateBufferedImage(r.x, r.y, r.width, r.height);
}
public void fill(Shape s)
{
super.fill(s);
Rectangle r = s.getBounds();
updateBufferedImage(r.x, r.y, r.width, r.height);
}
public void drawRenderedImage(RenderedImage image, AffineTransform xform)
{
super.drawRenderedImage(image, xform);
updateBufferedImage(0, 0, imageWidth, imageHeight);
}
protected boolean drawImage(Image img, AffineTransform xform,
Color bgcolor, ImageObserver obs)
{
boolean rv = super.drawImage(img, xform, bgcolor, obs);
updateBufferedImage(0, 0, imageWidth, imageHeight);
return rv;
}
public void drawGlyphVector(GlyphVector gv, float x, float y)
{
super.drawGlyphVector(gv, x, y);
updateBufferedImage(0, 0, imageWidth, imageHeight);
}
}
@@ -0,0 +1,288 @@
/* CairoSurface.java
Copyright (C) 2006 Free Software Foundation, Inc.
This file is part of GNU Classpath.
GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
GNU Classpath 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 GNU Classpath; see the file COPYING. If not, write to the
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA.
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 GNU General Public License cover the whole
combination.
As a special 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
this 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 gnu.java.awt.peer.gtk;
import java.awt.Graphics;
import java.awt.Color;
import java.awt.Image;
import java.awt.Point;
import java.awt.Graphics2D;
import java.awt.GraphicsConfiguration;
import java.awt.image.DataBuffer;
import java.awt.image.Raster;
import java.awt.image.WritableRaster;
import java.awt.image.BufferedImage;
import java.awt.image.ColorModel;
import java.awt.image.DirectColorModel;
import java.io.File;
import java.io.IOException;
import java.util.Hashtable;
import java.util.Vector;
import java.io.ByteArrayOutputStream;
import java.io.BufferedInputStream;
import java.net.URL;
import gnu.classpath.Pointer;
/**
* CairoSurface - wraps a Cairo surface.
*
* @author Sven de Marothy
*/
public class CairoSurface extends DataBuffer
{
int width = -1, height = -1;
/**
* The native pointer to the Cairo surface.
*/
long surfacePointer;
/**
* The native pointer to the image's data buffer
*/
long bufferPointer;
static ColorModel nativeModel = new DirectColorModel(32,
0x000000FF,
0x0000FF00,
0x00FF0000,
0xFF000000);
/**
* Allocates and clears the buffer and creates the cairo surface.
* @param width, height - the image size
* @param stride - the buffer row stride.
*/
private native void create(int width, int height, int stride);
/**
* Destroys the cairo surface and frees the buffer.
*/
private native void destroy();
/**
* Gets buffer elements
*/
private native int nativeGetElem(int i);
/**
* Sets buffer elements.
*/
private native void nativeSetElem(int i, int val);
/**
* Draws this image to a given CairoGraphics context,
* with an affine transform given by i2u.
*/
public native void drawSurface(CairoGraphics2D context, double[] i2u);
/**
* getPixels -return the pixels as a java array.
*/
native int[] getPixels(int size);
/**
* getPixels -return the pixels as a java array.
*/
native void setPixels(int[] pixels);
native long getFlippedBuffer(int size);
/**
* Create a cairo_surface_t with specified width and height.
* The format will be ARGB32 with premultiplied alpha and native bit
* and word ordering.
*/
CairoSurface(int width, int height)
{
super(DataBuffer.TYPE_INT, width * height);
if(width <= 0 || height <= 0)
throw new IllegalArgumentException("Image must be at least 1x1 pixels.");
this.width = width;
this.height = height;
create(width, height, width * 4);
if(surfacePointer == 0 || bufferPointer == 0)
throw new Error("Could not allocate bitmap.");
}
/**
* Create a cairo_surface_t from a GtkImage instance.
* (data is copied, not shared)
*/
CairoSurface(GtkImage image)
{
super(DataBuffer.TYPE_INT, image.width * image.height);
if(image.width <= 0 || image.height <= 0)
throw new IllegalArgumentException("Image must be at least 1x1 pixels.");
width = image.width;
height = image.height;
create(width, height, width * 4);
if(surfacePointer == 0 || bufferPointer == 0)
throw new Error("Could not allocate bitmap.");
// Copy the pixel data from the GtkImage.
int[] data = image.getPixels();
// Swap ordering from GdkPixbuf to Cairo
for(int i = 0; i < data.length; i++ )
{
int alpha = (data[i] & 0xFF000000) >> 24;
if( alpha == 0 ) // I do not know why we need this, but it works.
data[i] = 0;
else
{
int r = (((data[i] & 0x00FF0000) >> 16) );
int g = (((data[i] & 0x0000FF00) >> 8) );
int b = ((data[i] & 0x000000FF) );
data[i] = (( alpha << 24 ) & 0xFF000000)
| (( b << 16 ) & 0x00FF0000)
| (( g << 8 ) & 0x0000FF00)
| ( r & 0x000000FF);
}
}
setPixels( data );
}
/**
* Dispose of the native data.
*/
public void dispose()
{
if(surfacePointer != 0)
destroy();
}
/**
* Call dispose() to clean up any native resources allocated.
*/
protected void finalize()
{
dispose();
}
/**
* Return a GtkImage from this Cairo surface.
*/
public GtkImage getGtkImage()
{
return new GtkImage( width, height, getFlippedBuffer( width * height ));
}
/**
* Returns a BufferedImage backed by a Cairo surface.
*/
public static BufferedImage getBufferedImage(int width, int height)
{
return getBufferedImage(new CairoSurface(width, height));
}
/**
* Returns a BufferedImage backed by a Cairo surface,
* created from a GtkImage.
*/
public static BufferedImage getBufferedImage(GtkImage image)
{
return getBufferedImage(new CairoSurface(image));
}
/**
* Returns a BufferedImage backed by a Cairo surface.
*/
public static BufferedImage getBufferedImage(CairoSurface surface)
{
WritableRaster raster = Raster.createPackedRaster
(surface, surface.width, surface.height, surface.width,
new int[]{ 0x000000FF, 0x0000FF00, 0x00FF0000, 0xFF000000 },
new Point(0,0));
return new BufferedImage(nativeModel, raster, true, new Hashtable());
}
/**
* DataBank.getElem implementation
*/
public int getElem(int bank, int i)
{
if(bank != 0 || i < 0 || i >= width*height)
throw new IndexOutOfBoundsException(i+" size: "+width*height);
return nativeGetElem(i);
}
/**
* DataBank.setElem implementation
*/
public void setElem(int bank, int i, int val)
{
if(bank != 0 || i < 0 || i >= width*height)
throw new IndexOutOfBoundsException(i+" size: "+width*height);
nativeSetElem(i, val);
}
/**
* Return a Graphics2D drawing to the CairoSurface.
*/
public Graphics2D getGraphics()
{
return new CairoSurfaceGraphics(this);
}
///// Methods used by CairoSurfaceGraphics /////
/**
* Creates a cairo_t drawing context, returns the pointer as a long.
* Used by CairoSurfaceGraphics.
*/
native long newCairoContext();
/**
* Copy an area of the surface. Expects parameters must be within bounds.
* Count on a segfault otherwise.
*/
native void copyAreaNative(int x, int y, int width, int height,
int dx, int dy, int stride);
}
@@ -0,0 +1,100 @@
/* CairoSurfaceGraphics.java
Copyright (C) 2006 Free Software Foundation, Inc.
This file is part of GNU Classpath.
GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
GNU Classpath 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 GNU Classpath; see the file COPYING. If not, write to the
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA.
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 GNU General Public License cover the whole
combination.
As a special 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
this 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 gnu.java.awt.peer.gtk;
import java.awt.Graphics;
import java.awt.Color;
import java.awt.Image;
import java.awt.Point;
import java.awt.Graphics2D;
import java.awt.GraphicsConfiguration;
import java.awt.geom.Rectangle2D;
import java.awt.image.*;
/**
* Implementation of Graphics2D on a Cairo surface.
*/
public class CairoSurfaceGraphics extends CairoGraphics2D
{
protected CairoSurface surface;
private long cairo_t;
/**
* Create a graphics context from a cairo surface
*/
public CairoSurfaceGraphics(CairoSurface surface)
{
this.surface = surface;
cairo_t = surface.newCairoContext();
setup( cairo_t );
setClip(0, 0, surface.width, surface.height);
}
/**
* Creates another context from a surface.
* Used by create().
*/
private CairoSurfaceGraphics(CairoSurfaceGraphics copyFrom)
{
surface = copyFrom.surface;
cairo_t = surface.newCairoContext();
copy( copyFrom, cairo_t );
setClip(0, 0, surface.width, surface.height);
}
public Graphics create()
{
return new CairoSurfaceGraphics(this);
}
public GraphicsConfiguration getDeviceConfiguration()
{
throw new UnsupportedOperationException();
}
protected Rectangle2D getRealBounds()
{
return new Rectangle2D.Double(0.0, 0.0, surface.width, surface.height);
}
public void copyAreaImpl(int x, int y, int width, int height, int dx, int dy)
{
surface.copyAreaNative(x, y, width, height, dx, dy, surface.width);
}
}
@@ -0,0 +1,243 @@
/* ComponentGraphics.java --
Copyright (C) 2006 Free Software Foundation, Inc.
This file is part of GNU Classpath.
GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
GNU Classpath 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 GNU Classpath; see the file COPYING. If not, write to the
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA.
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 GNU General Public License cover the whole
combination.
As a special 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
this 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 gnu.java.awt.peer.gtk;
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GraphicsConfiguration;
import java.awt.Image;
import java.awt.Rectangle;
import java.awt.Shape;
import java.awt.Point;
import java.awt.font.FontRenderContext;
import java.awt.font.GlyphVector;
import java.awt.geom.AffineTransform;
import java.awt.geom.Rectangle2D;
import java.awt.image.BufferedImage;
import java.awt.image.ImageObserver;
import java.awt.image.ImagingOpException;
import java.awt.image.RenderedImage;
/**
* ComponentGraphics - context for drawing directly to a component,
* as this is an X drawable, it requires that we use GTK locks.
*
* This context draws directly to the drawable and requires xrender.
*/
public class ComponentGraphics extends CairoGraphics2D
{
private GtkComponentPeer component;
protected long cairo_t;
ComponentGraphics()
{
}
private ComponentGraphics(GtkComponentPeer component)
{
this.component = component;
cairo_t = initState(component);
setup( cairo_t );
Rectangle bounds = component.awtComponent.getBounds();
setClip( new Rectangle( 0, 0, bounds.width, bounds.height) );
setBackground(component.awtComponent.getBackground());
setColor(component.awtComponent.getForeground());
}
private ComponentGraphics(ComponentGraphics cg)
{
component = cg.component;
cairo_t = initState(component);
copy( cg, cairo_t );
Rectangle bounds = component.awtComponent.getBounds();
setClip( new Rectangle( 0, 0, bounds.width, bounds.height) );
setBackground(component.awtComponent.getBackground());
setColor(component.awtComponent.getForeground());
}
/**
* Creates a cairo_t for the component surface and return it.
*/
private native long initState(GtkComponentPeer component);
/**
* Destroys the component surface and calls dispose on the cairo
* graphics2d to destroy any super class resources.
*/
public void dispose()
{
disposeSurface(nativePointer);
super.dispose();
}
/**
* Destroys the component surface.
*/
private native void disposeSurface(long nativePointer);
/**
* Creates a cairo_t for a volatile image
*/
protected native long initFromVolatile( long pixmapPtr, int width, int height);
/**
* Grab lock
*/
private native void start_gdk_drawing();
/**
* Release lock
*/
private native void end_gdk_drawing();
/**
* Query if the system has the XRender extension.
*/
public static native boolean hasXRender();
private native void copyAreaNative(GtkComponentPeer component, int x, int y,
int width, int height, int dx, int dy);
private native void drawVolatile(GtkComponentPeer component,
Image vimg, int x, int y,
int width, int height);
/**
* Returns a Graphics2D object for a component, either an instance of this
* class (if xrender is supported), or a context which copies.
*/
public static Graphics2D getComponentGraphics(GtkComponentPeer component)
{
if( hasXRender() )
return new ComponentGraphics(component);
Rectangle r = component.awtComponent.getBounds();
return new ComponentGraphicsCopy(r.width, r.height, component);
}
public GraphicsConfiguration getDeviceConfiguration()
{
return component.getGraphicsConfiguration();
}
public Graphics create()
{
return new ComponentGraphics(this);
}
protected Rectangle2D getRealBounds()
{
return component.awtComponent.getBounds();
}
public void copyAreaImpl(int x, int y, int width, int height, int dx, int dy)
{
copyAreaNative(component, x, y, width, height, dx, dy);
}
/**
* Overloaded methods that do actual drawing need to enter the gdk threads
* and also do certain things before and after.
*/
public void draw(Shape s)
{
start_gdk_drawing();
super.draw(s);
end_gdk_drawing();
}
public void fill(Shape s)
{
start_gdk_drawing();
super.fill(s);
end_gdk_drawing();
}
public void drawRenderedImage(RenderedImage image, AffineTransform xform)
{
start_gdk_drawing();
super.drawRenderedImage(image, xform);
end_gdk_drawing();
}
protected boolean drawImage(Image img, AffineTransform xform,
Color bgcolor, ImageObserver obs)
{
start_gdk_drawing();
boolean rv = super.drawImage(img, xform, bgcolor, obs);
end_gdk_drawing();
return rv;
}
public void drawGlyphVector(GlyphVector gv, float x, float y)
{
start_gdk_drawing();
super.drawGlyphVector(gv, x, y);
end_gdk_drawing();
}
public boolean drawImage(Image img, int x, int y, ImageObserver observer)
{
if( img instanceof GtkVolatileImage )
{
drawVolatile( component, img, x, y - 20,
((GtkVolatileImage)img).width,
((GtkVolatileImage)img).height );
return true;
}
return super.drawImage( img, x, y, observer );
}
public boolean drawImage(Image img, int x, int y, int width, int height,
ImageObserver observer)
{
if( img instanceof GtkVolatileImage )
{
drawVolatile( component, img, x, y - 20,
width, height );
return true;
}
return super.drawImage( img, x, y, width, height, observer );
}
}
@@ -0,0 +1,129 @@
/* ComponentGraphicsCopy.java
Copyright (C) 2006 Free Software Foundation, Inc.
This file is part of GNU Classpath.
GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
GNU Classpath 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 GNU Classpath; see the file COPYING. If not, write to the
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA.
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 GNU General Public License cover the whole
combination.
As a special 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
this 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 gnu.java.awt.peer.gtk;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GraphicsConfiguration;
import java.awt.Image;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.Shape;
import java.awt.font.GlyphVector;
import java.awt.geom.AffineTransform;
import java.awt.image.BufferedImage;
import java.awt.image.DataBuffer;
import java.awt.image.RenderedImage;
import java.awt.image.ImageObserver;
/**
* Implementation of Graphics2D for Components for servers which
* do not have xrender.
*
* A mirrored GtkImage of the component is stored in memory
* and copied back. Yay.
*/
public class ComponentGraphicsCopy extends CairoSurfaceGraphics
{
private GtkComponentPeer component;
/**
* GtkImage sharing its data buffer with this Cairo surface.
*/
private GtkImage gtkimage;
private int width, height;
native void getPixbuf( GtkComponentPeer component, GtkImage image );
native void copyPixbuf( GtkComponentPeer component, GtkImage image,
int x, int y, int w, int h );
public ComponentGraphicsCopy(int width, int height,
GtkComponentPeer component)
{
super( new CairoSurface( width, height ) );
this.component = component;
this.width = width;
this.height = height;
gtkimage = surface.getGtkImage();
getPixbuf( component, gtkimage );
}
/**
* Overloaded methods that do actual drawing need to enter the gdk threads
* and also do certain things before and after.
*/
public void draw(Shape s)
{
super.draw(s);
Rectangle r = s.getBounds();
copyPixbuf(component, gtkimage, r.x, r.y, r.width, r.height);
}
public void fill(Shape s)
{
super.fill(s);
Rectangle r = s.getBounds();
copyPixbuf(component, gtkimage, r.x, r.y, r.width, r.height);
}
public void drawRenderedImage(RenderedImage image, AffineTransform xform)
{
super.drawRenderedImage(image, xform);
copyPixbuf(component, gtkimage, 0, 0, width, height);
}
protected boolean drawImage(Image img, AffineTransform xform,
Color bgcolor, ImageObserver obs)
{
boolean rv = super.drawImage(img, xform, bgcolor, obs);
copyPixbuf(component, gtkimage, 0, 0, width, height);
return rv;
}
public void drawGlyphVector(GlyphVector gv, float x, float y)
{
super.drawGlyphVector(gv, x, y);
Rectangle r = gv.getPixelBounds(getFontRenderContext(), x , y);
copyPixbuf(component, gtkimage, r.x, r.y, r.width, r.height);
}
}
@@ -0,0 +1,392 @@
/* FreetypeGlyphVector.java
Copyright (C) 2006 Free Software Foundation, Inc.
This file is part of GNU Classpath.
GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
GNU Classpath 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 GNU Classpath; see the file COPYING. If not, write to the
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA.
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 GNU General Public License cover the whole
combination.
As a special 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
this 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 gnu.java.awt.peer.gtk;
import java.awt.Font;
import java.awt.Shape;
import java.awt.geom.AffineTransform;
import java.awt.geom.Point2D;
import java.awt.geom.Rectangle2D;
import java.awt.geom.GeneralPath;
import java.awt.font.GlyphJustificationInfo;
import java.awt.font.GlyphMetrics;
import java.awt.font.GlyphVector;
import java.awt.font.FontRenderContext;
public class FreetypeGlyphVector extends GlyphVector
{
/**
* The associated font and its peer.
*/
private Font font;
private GdkFontPeer peer; // ATTN: Accessed from native code.
/**
* The string represented by this GlyphVector.
*/
private String s;
/**
* The font render context
*/
private FontRenderContext frc;
/**
* The total # of glyphs.
*/
private int nGlyphs;
/**
* The glyph codes
*/
private int[] glyphCodes;
/**
* Glyph transforms. (de facto only the translation is used)
*/
private AffineTransform[] glyphTransforms;
/**
* Create a glyphvector from a given (Freetype) font and a String.
*/
public FreetypeGlyphVector(Font f, String s, FontRenderContext frc)
{
this.s = s;
this.font = f;
this.frc = frc;
if( !(font.getPeer() instanceof GdkFontPeer ) )
throw new IllegalArgumentException("Not a valid font.");
peer = (GdkFontPeer)font.getPeer();
getGlyphs();
performDefaultLayout();
}
/**
* Create a glyphvector from a given set of glyph codes.
*/
public FreetypeGlyphVector(Font f, int[] codes, FontRenderContext frc)
{
this.font = f;
this.frc = frc;
if( !(font.getPeer() instanceof GdkFontPeer ) )
throw new IllegalArgumentException("Not a valid font.");
peer = (GdkFontPeer)font.getPeer();
glyphCodes = new int[ codes.length ];
System.arraycopy(codes, 0, glyphCodes, 0, codes.length);
nGlyphs = glyphCodes.length;
performDefaultLayout();
}
/**
* Create the array of glyph codes.
*/
private void getGlyphs()
{
nGlyphs = s.codePointCount( 0, s.length() );
glyphCodes = new int[ nGlyphs ];
int stringIndex = 0;
for(int i = 0; i < nGlyphs; i++)
{
glyphCodes[i] = getGlyph( s.codePointAt(stringIndex) );
// UTF32 surrogate handling
if( s.codePointAt( stringIndex ) != (int)s.charAt( stringIndex ) )
stringIndex ++;
stringIndex ++;
}
}
/**
* Returns the glyph code within the font for a given character
*/
public native int getGlyph(int codepoint);
/**
* Returns the kerning of a glyph pair
*/
private native Point2D getKerning(int leftGlyph, int rightGlyph);
private native double[] getMetricsNative( int glyphCode );
private native GeneralPath getGlyphOutlineNative(int glyphIndex);
/**
* Duh, compares two instances.
*/
public boolean equals(GlyphVector gv)
{
if( ! (gv instanceof FreetypeGlyphVector) )
return false;
return (((FreetypeGlyphVector)gv).font.equals(font) &&
((FreetypeGlyphVector)gv).frc.equals(frc)
&& ((FreetypeGlyphVector)gv).s.equals(s));
}
/**
* Returns the associated Font
*/
public Font getFont()
{
return font;
}
/**
* Returns the associated FontRenderContext
*/
public FontRenderContext getFontRenderContext()
{
return frc;
}
/**
* Layout the glyphs.
*/
public void performDefaultLayout()
{
glyphTransforms = new AffineTransform[ nGlyphs ];
double x = 0;
for(int i = 0; i < nGlyphs; i++)
{
GlyphMetrics gm = getGlyphMetrics( i );
Rectangle2D r = gm.getBounds2D();
glyphTransforms[ i ] = AffineTransform.getTranslateInstance(x, 0);
x += gm.getAdvanceX();
if( i > 0 )
{
Point2D p = getKerning( glyphCodes[ i - 1 ], glyphCodes[ i ] );
x += p.getX();
}
}
}
/**
* Returns the code of the glyph at glyphIndex;
*/
public int getGlyphCode(int glyphIndex)
{
return glyphCodes[ glyphIndex ];
}
/**
* Returns multiple glyphcodes.
*/
public int[] getGlyphCodes(int beginGlyphIndex, int numEntries,
int[] codeReturn)
{
int[] rval;
if( codeReturn == null )
rval = new int[ numEntries ];
else
rval = codeReturn;
System.arraycopy(glyphCodes, beginGlyphIndex, rval, 0, numEntries);
return rval;
}
/**
* FIXME: Implement me.
*/
public Shape getGlyphLogicalBounds(int glyphIndex)
{
GlyphMetrics gm = getGlyphMetrics( glyphIndex );
if( gm == null )
return null;
Rectangle2D r = gm.getBounds2D();
return new Rectangle2D.Double( r.getX() - gm.getLSB(), r.getY(),
gm.getAdvanceX(), r.getHeight() );
}
/**
* Returns the metrics of a single glyph.
*/
public GlyphMetrics getGlyphMetrics(int glyphIndex)
{
double[] val = getMetricsNative( glyphCodes[ glyphIndex ] );
if( val == null )
return null;
return new GlyphMetrics( true, (float)val[1], (float)val[2],
new Rectangle2D.Double( val[3], val[4],
val[5], val[6] ),
GlyphMetrics.STANDARD );
}
/**
* Returns the outline of a single glyph.
*/
public Shape getGlyphOutline(int glyphIndex)
{
GeneralPath gp = getGlyphOutlineNative( glyphCodes[ glyphIndex ] );
gp.transform( glyphTransforms[ glyphIndex ] );
return gp;
}
/**
* Returns the position of a single glyph.
*/
public Point2D getGlyphPosition(int glyphIndex)
{
return glyphTransforms[ glyphIndex ].transform( new Point2D.Double(0, 0),
null );
}
/**
* Returns the positions of multiple glyphs.
*/
public float[] getGlyphPositions(int beginGlyphIndex, int numEntries,
float[] positionReturn)
{
float[] rval;
if( positionReturn == null )
rval = new float[2 * numEntries];
else
rval = positionReturn;
for( int i = beginGlyphIndex; i < numEntries; i++ )
{
Point2D p = getGlyphPosition( i );
rval[i * 2] = (float)p.getX();
rval[i * 2 + 1] = (float)p.getY();
}
return rval;
}
/**
* Returns the transform of a glyph.
*/
public AffineTransform getGlyphTransform(int glyphIndex)
{
return new AffineTransform( glyphTransforms[ glyphIndex ] );
}
/**
* Returns the visual bounds of a glyph
* May be off by a pixel or two due to hinting/rasterization.
*/
public Shape getGlyphVisualBounds(int glyphIndex)
{
return getGlyphOutline( glyphIndex ).getBounds2D();
}
/**
* Return the logical bounds of the whole thing.
*/
public Rectangle2D getLogicalBounds()
{
if( nGlyphs == 0 )
return new Rectangle2D.Double(0, 0, 0, 0);
Rectangle2D rect = (Rectangle2D)getGlyphLogicalBounds( 0 );
for( int i = 1; i < nGlyphs; i++ )
rect = rect.createUnion( (Rectangle2D)getGlyphLogicalBounds( i ) );
return rect;
}
/**
* Returns the number of glyphs.
*/
public int getNumGlyphs()
{
return glyphCodes.length;
}
/**
* Returns the outline of the entire GlyphVector.
*/
public Shape getOutline()
{
GeneralPath path = new GeneralPath();
for( int i = 0; i < getNumGlyphs(); i++ )
path.append( getGlyphOutline( i ), false );
return path;
}
/**
* TODO:
* FreeType does not currently have an API for the JSTF table. We should
* probably get the table ourselves from FT and pass it to some parser
* which the native font peers will need.
*/
public GlyphJustificationInfo getGlyphJustificationInfo(int glyphIndex)
{
return null;
}
/**
* Returns the outline of the entire vector, drawn at (x,y).
*/
public Shape getOutline(float x, float y)
{
AffineTransform tx = AffineTransform.getTranslateInstance( x, y );
return tx.createTransformedShape( getOutline() );
}
/**
* Returns the visual bounds of the entire GlyphVector.
* May be off by a pixel or two due to hinting/rasterization.
*/
public Rectangle2D getVisualBounds()
{
return getOutline().getBounds2D();
}
/**
* Sets the position of a glyph.
*/
public void setGlyphPosition(int glyphIndex, Point2D newPos)
{
// FIXME: Scaling, etc.?
glyphTransforms[ glyphIndex ].setToTranslation( newPos.getX(),
newPos.getY() );
}
/**
* Sets the transform of a single glyph.
*/
public void setGlyphTransform(int glyphIndex, AffineTransform newTX)
{
glyphTransforms[ glyphIndex ].setTransform( newTX );
}
}
@@ -40,19 +40,23 @@ package gnu.java.awt.peer.gtk;
import gnu.classpath.Configuration;
import gnu.java.awt.peer.ClasspathFontPeer;
import gnu.java.awt.font.opentype.NameDecoder;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Toolkit;
import java.awt.font.FontRenderContext;
import java.awt.font.GlyphVector;
import java.awt.font.GlyphMetrics;
import java.awt.font.LineMetrics;
import java.awt.geom.Rectangle2D;
import java.awt.geom.Point2D;
import java.text.CharacterIterator;
import java.text.StringCharacterIterator;
import java.util.Locale;
import java.util.Map;
import java.util.ResourceBundle;
import java.nio.ByteBuffer;
public class GdkFontPeer extends ClasspathFontPeer
{
@@ -76,17 +80,21 @@ public class GdkFontPeer extends ClasspathFontPeer
}
}
private ByteBuffer nameTable = null;
private native void initState ();
private native void dispose ();
private native void setFont (String family, int style, int size, boolean useGraphics2D);
private native void setFont (String family, int style, int size);
native void getFontMetrics(double [] metrics);
native void getTextMetrics(String str, double [] metrics);
native void releasePeerGraphicsResource();
protected void finalize ()
{
if (GtkToolkit.useGraphics2D ())
GdkGraphics2D.releasePeerGraphicsResource(this);
releasePeerGraphicsResource();
dispose ();
}
@@ -136,26 +144,84 @@ public class GdkFontPeer extends ClasspathFontPeer
{
super(name, style, size);
initState ();
setFont (this.familyName, this.style, (int)this.size,
GtkToolkit.useGraphics2D());
setFont (this.familyName, this.style, (int)this.size);
}
public GdkFontPeer (String name, Map attributes)
{
super(name, attributes);
initState ();
setFont (this.familyName, this.style, (int)this.size,
GtkToolkit.useGraphics2D());
}
public String getSubFamilyName(Font font, Locale locale)
{
return null;
setFont (this.familyName, this.style, (int)this.size);
}
/**
* Unneeded, but implemented anyway.
*/
public String getSubFamilyName(Font font, Locale locale)
{
String name;
if (locale == null)
locale = Locale.getDefault();
name = getName(NameDecoder.NAME_SUBFAMILY, locale);
if (name == null)
{
name = getName(NameDecoder.NAME_SUBFAMILY, Locale.ENGLISH);
if ("Regular".equals(name))
name = null;
}
return name;
}
/**
* Returns the bytes belonging to a TrueType/OpenType table,
* Parameters n,a,m,e identify the 4-byte ASCII tag of the table.
*
* Returns null if the font is not TT, the table is nonexistant,
* or if some other unexpected error occured.
*
*/
private native byte[] getTrueTypeTable(byte n, byte a, byte m, byte e);
/**
* Returns the PostScript name of the font, defaults to the familyName if
* a PS name could not be retrieved.
*/
public String getPostScriptName(Font font)
{
return this.familyName;
String name = getName(NameDecoder.NAME_POSTSCRIPT,
/* any language */ null);
if( name == null )
return this.familyName;
return name;
}
/**
* Extracts a String from the font&#x2019;s name table.
*
* @param name the numeric TrueType or OpenType name ID.
*
* @param locale the locale for which names shall be localized, or
* <code>null</code> if the locale does mot matter because the name
* is known to be language-independent (for example, because it is
* the PostScript name).
*/
private String getName(int name, Locale locale)
{
if (nameTable == null)
{
byte[] data = getTrueTypeTable((byte)'n', (byte) 'a',
(byte) 'm', (byte) 'e');
if( data == null )
return null;
nameTable = ByteBuffer.wrap( data );
}
return NameDecoder.getName(nameTable, name, locale);
}
public boolean canDisplay (Font font, char c)
@@ -170,23 +236,18 @@ public class GdkFontPeer extends ClasspathFontPeer
return -1;
}
private native GdkGlyphVector getGlyphVector(String txt,
Font f,
FontRenderContext ctx);
public GlyphVector createGlyphVector (Font font,
FontRenderContext ctx,
CharacterIterator i)
{
return getGlyphVector(buildString (i), font, ctx);
return new FreetypeGlyphVector(font, buildString (i), ctx);
}
public GlyphVector createGlyphVector (Font font,
FontRenderContext ctx,
int[] glyphCodes)
{
return null;
// return new GdkGlyphVector (font, this, ctx, glyphCodes);
return new FreetypeGlyphVector(font, glyphCodes, ctx);
}
public byte getBaselineFor (Font font, char c)
@@ -262,13 +323,21 @@ public class GdkFontPeer extends ClasspathFontPeer
public int getNumGlyphs (Font font)
{
throw new UnsupportedOperationException ();
byte[] data = getTrueTypeTable((byte)'m', (byte) 'a',
(byte)'x', (byte) 'p');
if( data == null )
return -1;
ByteBuffer buf = ByteBuffer.wrap( data );
return buf.getShort(4);
}
public Rectangle2D getStringBounds (Font font, CharacterIterator ci,
int begin, int limit, FontRenderContext frc)
{
GdkGlyphVector gv = getGlyphVector(buildString (ci, begin, limit), font, frc);
GlyphVector gv = new FreetypeGlyphVector( font,
buildString(ci, begin, limit),
frc);
return gv.getVisualBounds();
}
@@ -303,5 +372,4 @@ public class GdkFontPeer extends ClasspathFontPeer
// the metrics cache.
return Toolkit.getDefaultToolkit().getFontMetrics (font);
}
}
@@ -1,359 +0,0 @@
/* GdkGlyphVector.java -- Glyph vector object
Copyright (C) 2003, 2004, 2005 Free Software Foundation, Inc.
This file is part of GNU Classpath.
GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
GNU Classpath 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 GNU Classpath; see the file COPYING. If not, write to the
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA.
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 GNU General Public License cover the whole
combination.
As a special 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
this 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 gnu.java.awt.peer.gtk;
import java.awt.Font;
import java.awt.Rectangle;
import java.awt.Shape;
import java.awt.font.FontRenderContext;
import java.awt.font.GlyphJustificationInfo;
import java.awt.font.GlyphMetrics;
import java.awt.font.GlyphVector;
import java.awt.geom.AffineTransform;
import java.awt.geom.Point2D;
import java.awt.geom.Rectangle2D;
public class GdkGlyphVector extends GlyphVector
{
/* We use a simple representation for glyph vectors here. Glyph i
* consumes 8 doubles:
*
* logical x: extents[ 10*i ]
* logical y: extents[ 10*i + 1 ]
* logical width: extents[ 10*i + 2 ]
* logical height: extents[ 10*i + 3 ]
*
* visual x: extents[ 10*i + 4 ]
* visual y: extents[ 10*i + 5 ]
* visual width: extents[ 10*i + 6 ]
* visual height: extents[ 10*i + 7 ]
*
* origin pos x: extents[ 10*i + 8 ]
* origin pos y: extents[ 10*i + 9 ]
*
* as well as one int, code[i], representing the glyph code in the font.
*/
double [] extents;
int [] codes;
Font font;
FontRenderContext fontRenderContext;
Rectangle2D allLogical;
Rectangle2D allVisual;
public GdkGlyphVector(double[] extents, int[] codes, Font font, FontRenderContext frc)
{
this.extents = extents;
this.codes = codes;
this.font = font;
this.fontRenderContext = frc;
allLogical = new Rectangle2D.Double();
allVisual = new Rectangle2D.Double();
for (int i = 0; i < codes.length; ++i)
{
allLogical.add (new Rectangle2D.Double(extents[10*i ] + extents[10*i + 8],
extents[10*i + 1] + extents[10*i + 9],
extents[10*i + 2],
extents[10*i + 3]));
allVisual.add (new Rectangle2D.Double(extents[10*i + 4] + extents[10*i + 8],
extents[10*i + 5] + extents[10*i + 9],
extents[10*i + 6],
extents[10*i + 7]));
}
}
/*
geometric notes:
the FRC contains a mapping from points -> pixels.
typographics points are typically 1/72 of an inch.
pixel displays are often around 72 dpi.
so the FRC can get away with using an identity transform on a screen,
often. behavior is documented by sun to fall back to an identity
transform if the internal transformation is null.
coordinates coming up from pango are expressed as floats -- in device
space, so basically pixels-with-fractional-bits -- derived from their
storage format in pango (1024ths of pixels).
it is not clear from the javadocs whether the results of methods like
getGlyphPositions ought to return coordinates in device space, or
"point" space, or what. for now I'm returning them in device space.
*/
public double[] getExtents()
{
return extents;
}
public int[] getCodes()
{
return codes;
}
public Font getFont ()
{
return font;
}
public FontRenderContext getFontRenderContext ()
{
return fontRenderContext;
}
public int getGlyphCharIndex (int glyphIndex)
{
// FIXME: currently pango does not provide glyph-by-glyph
// reverse mapping information, so we assume a broken 1:1
// glyph model here. This is plainly wrong.
return glyphIndex;
}
public int[] getGlyphCharIndices (int beginGlyphIndex,
int numEntries,
int[] codeReturn)
{
int ix[] = codeReturn;
if (ix == null)
ix = new int[numEntries];
for (int i = 0; i < numEntries; i++)
ix[i] = getGlyphCharIndex (beginGlyphIndex + i);
return ix;
}
public int getGlyphCode (int glyphIndex)
{
return codes[glyphIndex];
}
public int[] getGlyphCodes (int beginGlyphIndex, int numEntries,
int[] codeReturn)
{
if (codeReturn == null)
codeReturn = new int[numEntries];
System.arraycopy(codes, beginGlyphIndex, codeReturn, 0, numEntries);
return codeReturn;
}
public Shape getGlyphLogicalBounds (int i)
{
return new Rectangle2D.Double (extents[8*i], extents[8*i + 1],
extents[8*i + 2], extents[8*i + 3]);
}
public GlyphMetrics getGlyphMetrics (int i)
{
// FIXME: pango does not yield vertical layout information at the
// moment.
boolean is_horizontal = true;
double advanceX = extents[8*i + 2]; // "logical width" == advanceX
double advanceY = 0;
return new GlyphMetrics (is_horizontal,
(float) advanceX, (float) advanceY,
(Rectangle2D) getGlyphVisualBounds(i),
GlyphMetrics.STANDARD);
}
public Shape getGlyphOutline (int glyphIndex)
{
throw new UnsupportedOperationException ();
}
public Shape getGlyphOutline (int glyphIndex, float x, float y)
{
throw new UnsupportedOperationException ();
}
public Rectangle getGlyphPixelBounds (int i,
FontRenderContext renderFRC,
float x, float y)
{
return new Rectangle((int) x, (int) y,
(int) extents[8*i + 6], (int) extents[8*i + 7]);
}
public Point2D getGlyphPosition (int i)
{
return new Point2D.Double (extents[10*i + 8],
extents[10*i + 9]);
}
public float[] getGlyphPositions (int beginGlyphIndex,
int numEntries,
float[] positionReturn)
{
float fx[] = positionReturn;
if (fx == null)
fx = new float[numEntries * 2];
for (int i = 0; i < numEntries; ++i)
{
fx[2*i ] = (float) extents[10*i + 8];
fx[2*i + 1] = (float) extents[10*i + 9];
}
return fx;
}
public AffineTransform getGlyphTransform (int glyphIndex)
{
// Glyphs don't have independent transforms in these simple glyph
// vectors; docs specify null is an ok return here.
return null;
}
public Shape getGlyphVisualBounds (int i)
{
return new Rectangle2D.Double(extents[8*i + 4], extents[8*i + 5],
extents[8*i + 6], extents[8*i + 7]);
}
public int getLayoutFlags ()
{
return 0;
}
public Rectangle2D getLogicalBounds ()
{
return allLogical;
}
public int getNumGlyphs ()
{
return codes.length;
}
public Shape getOutline ()
{
throw new UnsupportedOperationException ();
}
public Rectangle getPixelBounds (FontRenderContext renderFRC,
float x, float y)
{
return new Rectangle((int)x,
(int)y,
(int) allVisual.getWidth(),
(int) allVisual.getHeight());
}
public Rectangle2D getVisualBounds ()
{
return allVisual;
}
public void performDefaultLayout ()
{
}
public void setGlyphPosition (int i, Point2D newPos)
{
extents[8*i ] = newPos.getX();
extents[8*i + 1] = newPos.getY();
extents[8*i + 4] = newPos.getX();
extents[8*i + 5] = newPos.getY();
}
public void setGlyphTransform (int glyphIndex,
AffineTransform newTX)
{
// not yet.. maybe not ever?
throw new UnsupportedOperationException ();
}
public boolean equals(GlyphVector gv)
{
if (gv == null)
return false;
if (! (gv instanceof GdkGlyphVector))
return false;
GdkGlyphVector ggv = (GdkGlyphVector) gv;
if ((ggv.codes.length != this.codes.length)
|| (ggv.extents.length != this.extents.length))
return false;
if ((ggv.font == null && this.font != null)
|| (ggv.font != null && this.font == null)
|| (!ggv.font.equals(this.font)))
return false;
if ((ggv.fontRenderContext == null && this.fontRenderContext != null)
|| (ggv.fontRenderContext != null && this.fontRenderContext == null)
|| (!ggv.fontRenderContext.equals(this.fontRenderContext)))
return false;
for (int i = 0; i < ggv.codes.length; ++i)
if (ggv.codes[i] != this.codes[i])
return false;
for (int i = 0; i < ggv.extents.length; ++i)
if (ggv.extents[i] != this.extents[i])
return false;
return true;
}
public GlyphJustificationInfo getGlyphJustificationInfo(int idx)
{
throw new UnsupportedOperationException ();
}
public Shape getOutline(float x, float y)
{
throw new UnsupportedOperationException ();
}
}
@@ -1,494 +0,0 @@
/* GdkGraphics.java
Copyright (C) 1998, 1999, 2002, 2005 Free Software Foundation, Inc.
This file is part of GNU Classpath.
GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
GNU Classpath 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 GNU Classpath; see the file COPYING. If not, write to the
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA.
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 GNU General Public License cover the whole
combination.
As a special 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
this 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 gnu.java.awt.peer.gtk;
import gnu.classpath.Configuration;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.Rectangle;
import java.awt.Shape;
import java.awt.Toolkit;
import java.awt.image.ImageObserver;
import java.text.AttributedCharacterIterator;
public class GdkGraphics extends Graphics
{
static
{
System.loadLibrary("gtkpeer");
initStaticState ();
}
static native void initStaticState();
private final int native_state = GtkGenericPeer.getUniqueInteger ();
Color color, xorColor;
GtkComponentPeer component;
Font font = new Font ("Dialog", Font.PLAIN, 12);
Rectangle clip;
GtkImage image;
int xOffset = 0;
int yOffset = 0;
static final int GDK_COPY = 0, GDK_XOR = 2;
native void initState (GtkComponentPeer component);
native void initStateUnlocked (GtkComponentPeer component);
native void initState (int width, int height);
native void initFromImage (GtkImage image);
native void nativeCopyState (GdkGraphics g);
/**
* A cached instance that is used by {@link #create} in order to avoid
* massive allocation of graphics contexts.
*/
GdkGraphics cached = null;
/**
* A link to the parent context. This is used in {@link #dispose} to put
* this graphics context into the cache.
*/
GdkGraphics parent = null;
GdkGraphics (GdkGraphics g)
{
parent = g;
copyState (g);
}
GdkGraphics (int width, int height)
{
initState (width, height);
color = Color.black;
clip = new Rectangle (0, 0, width, height);
font = new Font ("Dialog", Font.PLAIN, 12);
}
GdkGraphics (GtkImage image)
{
this.image = image;
initFromImage (image);
color = Color.black;
clip = new Rectangle (0, 0,
image.getWidth(null), image.getHeight(null));
font = new Font ("Dialog", Font.PLAIN, 12);
}
GdkGraphics (GtkComponentPeer component)
{
this.component = component;
color = Color.black;
if (component.isRealized ())
initComponentGraphics ();
else
connectSignals (component);
}
void initComponentGraphics ()
{
initState (component);
color = component.awtComponent.getForeground ();
if (color == null)
color = Color.BLACK;
Dimension d = component.awtComponent.getSize ();
clip = new Rectangle (0, 0, d.width, d.height);
}
// called back by native side: realize_cb
void initComponentGraphicsUnlocked ()
{
initStateUnlocked (component);
color = component.awtComponent.getForeground ();
if (color == null)
color = Color.BLACK;
Dimension d = component.awtComponent.getSize ();
clip = new Rectangle (0, 0, d.width, d.height);
}
native void connectSignals (GtkComponentPeer component);
public native void clearRect(int x, int y, int width, int height);
public void clipRect (int x, int y, int width, int height)
{
if (component != null && ! component.isRealized ())
return;
clip = clip.intersection (new Rectangle (x, y, width, height));
setClipRectangle (clip.x, clip.y, clip.width, clip.height);
}
public native void copyArea(int x, int y, int width, int height,
int dx, int dy);
/**
* Creates a copy of this GdkGraphics instance. This implementation can
* reuse a cached instance to avoid massive instantiation of Graphics objects
* during painting.
*
* @return a copy of this graphics context
*/
public Graphics create()
{
GdkGraphics copy = cached;
if (copy == null)
copy = new GdkGraphics(this);
else
{
copy.copyState(this);
cached = null;
}
return copy;
}
public native void nativeDispose();
/**
* Disposes this graphics object. This puts this graphics context into the
* cache of its parent graphics if there is one.
*/
public void dispose()
{
if (parent != null)
{
parent.cached = this;
parent = null;
}
else
nativeDispose();
}
/**
* This is called when this object gets finalized by the garbage collector.
* In addition to {@link Graphics#finalize()} this calls nativeDispose() to
* make sure the native resources are freed before the graphics context is
* thrown away.
*/
public void finalize()
{
super.finalize();
nativeDispose();
}
public boolean drawImage (Image img, int x, int y,
Color bgcolor, ImageObserver observer)
{
if (img != null)
return drawImage(img, x, y, img.getWidth(null), img.getHeight(null),
bgcolor, observer);
return false;
}
public boolean drawImage (Image img, int x, int y, ImageObserver observer)
{
return drawImage (img, x, y, null, observer);
}
public boolean drawImage(Image img, int x, int y, int width, int height,
Color bgcolor, ImageObserver observer)
{
if (img != null)
{
if (img instanceof GtkImage)
return ((GtkImage) img).drawImage(this, x, y, width, height, bgcolor,
observer);
return (new GtkImage(img.getSource())).drawImage(this, x, y, width,
height, bgcolor,
observer);
}
return false;
}
public boolean drawImage (Image img, int x, int y, int width, int height,
ImageObserver observer)
{
return drawImage (img, x, y, width, height, null, observer);
}
public boolean drawImage (Image img, int dx1, int dy1, int dx2, int dy2,
int sx1, int sy1, int sx2, int sy2,
Color bgcolor, ImageObserver observer)
{
if (img != null)
{
if (img instanceof GtkImage)
return ((GtkImage) img).drawImage(this, dx1, dy1, dx2, dy2, sx1, sy1,
sx2, sy2, bgcolor, observer);
return (new GtkImage(img.getSource())).drawImage(this, dx1, dy1, dx2,
dy2, sx1, sy1, sx2,
sy2, bgcolor, observer);
}
return false;
}
public boolean drawImage (Image img, int dx1, int dy1, int dx2, int dy2,
int sx1, int sy1, int sx2, int sy2,
ImageObserver observer)
{
return drawImage (img, dx1, dy1, dx2, dy2,
sx1, sy1, sx2, sy2,
null, observer);
}
public native void drawLine(int x1, int y1, int x2, int y2);
public native void drawArc(int x, int y, int width, int height,
int startAngle, int arcAngle);
public native void fillArc(int x, int y, int width, int height,
int startAngle, int arcAngle);
public native void drawOval(int x, int y, int width, int height);
public native void fillOval(int x, int y, int width, int height);
public native void drawPolygon(int[] xPoints, int[] yPoints, int nPoints);
public native void fillPolygon(int[] xPoints, int[] yPoints, int nPoints);
public native void drawPolyline(int[] xPoints, int[] yPoints, int nPoints);
public native void drawRect(int x, int y, int width, int height);
public native void fillRect(int x, int y, int width, int height);
GdkFontPeer getFontPeer()
{
return (GdkFontPeer) getFont().getPeer();
}
native void drawString (GdkFontPeer f, String str, int x, int y);
public void drawString (String str, int x, int y)
{
drawString(getFontPeer(), str, x, y);
}
public void drawString (AttributedCharacterIterator ci, int x, int y)
{
throw new Error ("not implemented");
}
public void drawRoundRect(int x, int y, int width, int height,
int arcWidth, int arcHeight)
{
if (arcWidth > width)
arcWidth = width;
if (arcHeight > height)
arcHeight = height;
int xx = x + width - arcWidth;
int yy = y + height - arcHeight;
drawArc (x, y, arcWidth, arcHeight, 90, 90);
drawArc (xx, y, arcWidth, arcHeight, 0, 90);
drawArc (xx, yy, arcWidth, arcHeight, 270, 90);
drawArc (x, yy, arcWidth, arcHeight, 180, 90);
int y1 = y + arcHeight / 2;
int y2 = y + height - arcHeight / 2;
drawLine (x, y1, x, y2);
drawLine (x + width, y1, x + width, y2);
int x1 = x + arcWidth / 2;
int x2 = x + width - arcWidth / 2;
drawLine (x1, y, x2, y);
drawLine (x1, y + height, x2, y + height);
}
public void fillRoundRect (int x, int y, int width, int height,
int arcWidth, int arcHeight)
{
if (arcWidth > width)
arcWidth = width;
if (arcHeight > height)
arcHeight = height;
int xx = x + width - arcWidth;
int yy = y + height - arcHeight;
fillArc (x, y, arcWidth, arcHeight, 90, 90);
fillArc (xx, y, arcWidth, arcHeight, 0, 90);
fillArc (xx, yy, arcWidth, arcHeight, 270, 90);
fillArc (x, yy, arcWidth, arcHeight, 180, 90);
fillRect (x, y + arcHeight / 2, width, height - arcHeight + 1);
fillRect (x + arcWidth / 2, y, width - arcWidth + 1, height);
}
public Shape getClip ()
{
return getClipBounds ();
}
public Rectangle getClipBounds ()
{
if (clip == null)
return null;
else
return clip.getBounds();
}
public Color getColor ()
{
return color;
}
public Font getFont ()
{
return font;
}
public FontMetrics getFontMetrics (Font font)
{
// Get the font metrics through GtkToolkit to take advantage of
// the metrics cache.
return Toolkit.getDefaultToolkit().getFontMetrics (font);
}
native void setClipRectangle (int x, int y, int width, int height);
public void setClip (int x, int y, int width, int height)
{
if ((component != null && ! component.isRealized ())
|| clip == null)
return;
clip.x = x;
clip.y = y;
clip.width = width;
clip.height = height;
setClipRectangle (x, y, width, height);
}
public void setClip (Rectangle clip)
{
setClip (clip.x, clip.y, clip.width, clip.height);
}
public void setClip (Shape clip)
{
if (clip == null)
{
// Reset clipping.
Dimension d = component.awtComponent.getSize();
setClip(new Rectangle (0, 0, d.width, d.height));
}
else
setClip(clip.getBounds());
}
private native void setFGColor(int red, int green, int blue);
public void setColor (Color c)
{
if (c == null)
color = Color.BLACK;
else
color = c;
if (xorColor == null) /* paint mode */
setFGColor (color.getRed (), color.getGreen (), color.getBlue ());
else /* xor mode */
setFGColor (color.getRed () ^ xorColor.getRed (),
color.getGreen () ^ xorColor.getGreen (),
color.getBlue () ^ xorColor.getBlue ());
}
public void setFont (Font font)
{
if (font != null)
this.font = font;
}
native void setFunction (int gdk_func);
public void setPaintMode ()
{
xorColor = null;
setFunction (GDK_COPY);
setFGColor (color.getRed (), color.getGreen (), color.getBlue ());
}
public void setXORMode (Color c)
{
xorColor = c;
setFunction (GDK_XOR);
setFGColor (color.getRed () ^ xorColor.getRed (),
color.getGreen () ^ xorColor.getGreen (),
color.getBlue () ^ xorColor.getBlue ());
}
public native void translateNative(int x, int y);
public void translate (int x, int y)
{
if (component != null && ! component.isRealized ())
return;
clip.x -= x;
clip.y -= y;
translateNative (x, y);
}
/**
* Copies over the state of another GdkGraphics to this instance. This is
* used by the {@link #GdkGraphics(GdkGraphics)} constructor and the
* {@link #create()} method.
*
* @param g the GdkGraphics object to copy the state from
*/
private void copyState(GdkGraphics g)
{
color = g.color;
xorColor = g.xorColor;
font = g.font;
if (font == null)
font = new Font ("Dialog", Font.PLAIN, 12);
clip = new Rectangle (g.clip);
component = g.component;
nativeCopyState(g);
}
}
@@ -1,5 +1,5 @@
/* GdkGraphicsConfiguration.java -- describes characteristics of graphics
Copyright (C) 2000, 2001, 2002, 2003, 2004 Free Software Foundation
Copyright (C) 2000, 2001, 2002, 2003, 2004, 2006 Free Software Foundation
This file is part of GNU Classpath.
@@ -42,26 +42,33 @@ import java.awt.GraphicsConfiguration;
import java.awt.GraphicsDevice;
import java.awt.ImageCapabilities;
import java.awt.Rectangle;
import java.awt.Toolkit;
import java.awt.Transparency;
import java.awt.geom.AffineTransform;
import java.awt.image.BufferedImage;
import java.awt.image.ColorModel;
import java.awt.image.DirectColorModel;
import java.awt.image.VolatileImage;
public class GdkGraphicsConfiguration
extends GraphicsConfiguration
{
GdkScreenGraphicsDevice gdkScreenGraphicsDevice;
ColorModel cm;
Rectangle bounds;
ColorModel opaqueColorModel;
ColorModel bitmaskColorModel;
ColorModel translucentColorModel;
public GdkGraphicsConfiguration(GdkScreenGraphicsDevice dev)
{
this.gdkScreenGraphicsDevice = dev;
cm = new BufferedImage(1, 1, BufferedImage.TYPE_INT_ARGB).getColorModel();
bounds = ((GtkToolkit) Toolkit.getDefaultToolkit()).getBounds();
gdkScreenGraphicsDevice = dev;
opaqueColorModel = new DirectColorModel(32, 0xFF0000, 0xFF00, 0xFF, 0);
bitmaskColorModel = new DirectColorModel(32, 0xFF0000, 0xFF00, 0xFF, 0x1000000);
translucentColorModel = new DirectColorModel(32, 0xFF0000, 0xFF00, 0xFF, 0xFF000000);
}
public GraphicsDevice getDevice()
@@ -94,12 +101,21 @@ public class GdkGraphicsConfiguration
public ColorModel getColorModel()
{
return cm;
return opaqueColorModel;
}
public ColorModel getColorModel(int transparency)
{
return getColorModel();
switch (transparency)
{
case Transparency.OPAQUE:
return opaqueColorModel;
case Transparency.BITMASK:
return bitmaskColorModel;
default:
case Transparency.TRANSLUCENT:
return translucentColorModel;
}
}
public AffineTransform getDefaultTransform()
@@ -116,7 +132,7 @@ public class GdkGraphicsConfiguration
public Rectangle getBounds()
{
return bounds;
return gdkScreenGraphicsDevice.getBounds();
}
public BufferCapabilities getBufferCapabilities()
@@ -133,8 +149,8 @@ public class GdkGraphicsConfiguration
public VolatileImage createCompatibleVolatileImage(int width, int height, int transparency)
{
// FIXME: implement
return null;
// FIXME: support the transparency argument
return new GtkVolatileImage(width, height);
}
}
@@ -1,5 +1,5 @@
/* GdkGraphicsEnvironment.java -- information about the graphics environment
Copyright (C) 2004, 2005 Free Software Foundation, Inc.
Copyright (C) 2004, 2005, 2006 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -43,33 +43,80 @@ import java.awt.Graphics2D;
import java.awt.GraphicsDevice;
import java.awt.GraphicsEnvironment;
import java.awt.HeadlessException;
import java.awt.Toolkit;
import java.awt.image.BufferedImage;
import java.awt.image.DataBuffer;
import java.util.Locale;
public class GdkGraphicsEnvironment extends GraphicsEnvironment
{
private final int native_state = GtkGenericPeer.getUniqueInteger ();
private GdkScreenGraphicsDevice defaultDevice;
private GdkScreenGraphicsDevice[] devices;
static
{
System.loadLibrary("gtkpeer");
initStaticState ();
}
static native void initStaticState();
public GdkGraphicsEnvironment ()
{
nativeInitState();
}
native void nativeInitState();
public GraphicsDevice[] getScreenDevices ()
{
// FIXME: Support multiple screens, since GDK can.
return new GraphicsDevice[] { new GdkScreenGraphicsDevice (this) };
if (devices == null)
{
devices = nativeGetScreenDevices();
}
return (GraphicsDevice[]) devices.clone();
}
private native GdkScreenGraphicsDevice[] nativeGetScreenDevices();
public GraphicsDevice getDefaultScreenDevice ()
{
if (GraphicsEnvironment.isHeadless ())
throw new HeadlessException ();
return new GdkScreenGraphicsDevice (this);
// GCJ LOCAL: workaround a GCJ problem accessing
// GdkGraphicsEnvironment.class
try
{
synchronized (Class.forName ("gnu.java.awt.peer.gtk.GdkGraphicsEnvironment"))
{
if (defaultDevice == null)
{
defaultDevice = nativeGetDefaultScreenDevice();
}
}
}
catch (Exception e)
{
e.printStackTrace();
}
return defaultDevice;
}
private native GdkScreenGraphicsDevice nativeGetDefaultScreenDevice();
public Graphics2D createGraphics (BufferedImage image)
{
return new GdkGraphics2D (image);
DataBuffer db = image.getRaster().getDataBuffer();
if(db instanceof CairoSurface)
return ((CairoSurface)db).getGraphics();
return new BufferedImageGraphics( image );
}
private native int nativeGetNumFontFamilies();
@@ -80,20 +127,21 @@ public class GdkGraphicsEnvironment extends GraphicsEnvironment
throw new java.lang.UnsupportedOperationException ();
}
public String[] getAvailableFontFamilyNames ()
{
String[] family_names;
int array_size;
public String[] getAvailableFontFamilyNames ()
{
String[] family_names;
int array_size;
array_size = nativeGetNumFontFamilies();
family_names = new String[array_size];
array_size = nativeGetNumFontFamilies();
family_names = new String[array_size];
nativeGetFontFamilies(family_names);
return family_names;
}
nativeGetFontFamilies(family_names);
return family_names;
}
public String[] getAvailableFontFamilyNames (Locale l)
{
throw new java.lang.UnsupportedOperationException ();
}
}
@@ -247,12 +247,23 @@ public class GdkPixbufDecoder extends gnu.java.awt.image.ImageDecoder
public static ImageFormatSpec registerFormat(String name, boolean writable)
{
ImageFormatSpec ifs = new ImageFormatSpec(name, writable);
synchronized(GdkPixbufDecoder.class)
// GCJ LOCAL: workaround a GCJ problem accessing
// GdkPixbufDecoder.class
try
{
synchronized(Class.forName ("gnu.java.awt.peer.gtk.GdkPixbufDecoder"))
{
if (imageFormatSpecs == null)
imageFormatSpecs = new ArrayList();
imageFormatSpecs.add(ifs);
}
}
catch (Exception e)
{
e.printStackTrace();
}
return ifs;
}
@@ -502,19 +513,19 @@ public class GdkPixbufDecoder extends gnu.java.awt.image.ImageDecoder
int width = ras.getWidth();
int height = ras.getHeight();
ColorModel model = image.getColorModel();
int[] pixels = GdkGraphics2D.findSimpleIntegerArray (image.getColorModel(), ras);
int[] pixels = CairoGraphics2D.findSimpleIntegerArray (image.getColorModel(), ras);
if (pixels == null)
{
BufferedImage img = new BufferedImage(width, height,
(model != null && model.hasAlpha() ?
BufferedImage.TYPE_INT_ARGB
: BufferedImage.TYPE_INT_RGB));
BufferedImage img;
if(model != null && model.hasAlpha())
img = CairoSurface.getBufferedImage(width, height);
img = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
int[] pix = new int[4];
for (int y = 0; y < height; ++y)
for (int x = 0; x < width; ++x)
img.setRGB(x, y, model.getRGB(ras.getPixel(x, y, pix)));
pixels = GdkGraphics2D.findSimpleIntegerArray (img.getColorModel(),
pixels = CairoGraphics2D.findSimpleIntegerArray (img.getColorModel(),
img.getRaster());
model = img.getColorModel();
}
@@ -584,9 +595,10 @@ public class GdkPixbufDecoder extends gnu.java.awt.image.ImageDecoder
if (bufferedImage == null)
{
bufferedImage = new BufferedImage (width, height, (model != null && model.hasAlpha() ?
BufferedImage.TYPE_INT_ARGB
: BufferedImage.TYPE_INT_RGB));
if(model != null && model.hasAlpha())
bufferedImage = new BufferedImage (width, height, BufferedImage.TYPE_INT_ARGB);
else
bufferedImage = new BufferedImage (width, height, BufferedImage.TYPE_INT_RGB);
}
int pixels2[];
@@ -680,43 +692,4 @@ public class GdkPixbufDecoder extends gnu.java.awt.image.ImageDecoder
return getBufferedImage ();
}
}
// remaining helper class and static method is a convenience for the Gtk
// peers, for loading a BufferedImage in off a disk file without going
// through the whole imageio system.
public static BufferedImage createBufferedImage (String filename)
{
GdkPixbufReader r = new GdkPixbufReader (getReaderSpi(),
"png", // reader auto-detects, doesn't matter
new GdkPixbufDecoder (filename));
return r.getBufferedImage ();
}
public static BufferedImage createBufferedImage (URL u)
{
GdkPixbufReader r = new GdkPixbufReader (getReaderSpi(),
"png", // reader auto-detects, doesn't matter
new GdkPixbufDecoder (u));
return r.getBufferedImage ();
}
public static BufferedImage createBufferedImage (byte[] imagedata, int imageoffset,
int imagelength)
{
GdkPixbufReader r = new GdkPixbufReader (getReaderSpi(),
"png", // reader auto-detects, doesn't matter
new GdkPixbufDecoder (imagedata,
imageoffset,
imagelength));
return r.getBufferedImage ();
}
public static BufferedImage createBufferedImage (ImageProducer producer)
{
GdkPixbufReader r = new GdkPixbufReader (getReaderSpi(), "png" /* ignored */, null);
producer.startProduction(r);
return r.getBufferedImage ();
}
}
@@ -1,5 +1,5 @@
/* GdkScreenGraphicsDevice.java -- information about a screen device
Copyright (C) 2004, 2005 Free Software Foundation, Inc.
Copyright (C) 2004, 2005, 2006 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -38,44 +38,110 @@ exception statement from your version. */
package gnu.java.awt.peer.gtk;
import java.awt.Dimension;
import java.awt.DisplayMode;
import java.awt.Frame;
import java.awt.GraphicsConfiguration;
import java.awt.GraphicsDevice;
import java.awt.Toolkit;
import java.awt.Rectangle;
import java.awt.Window;
import java.util.ArrayList;
public class GdkScreenGraphicsDevice extends GraphicsDevice
class GdkScreenGraphicsDevice extends GraphicsDevice
{
private final int native_state = GtkGenericPeer.getUniqueInteger ();
private Window fullscreenWindow;
private boolean oldWindowDecorationState;
private Rectangle oldWindowBounds;
private Rectangle bounds;
private GdkGraphicsConfiguration[] configurations;
/** The <code>GdkGraphicsEnvironment</code> instance that created this
* <code>GdkScreenGraphicsDevice</code>. This is only needed for native
* methods which need to access the 'native_state' field storing a pointer
* to a GdkDisplay object.
*/
GdkGraphicsEnvironment env;
/** An identifier that is created by Gdk
*/
String idString;
/** The display modes supported by this <code>GdkScreenGraphicsDevice</code>.
* If the array is <code>null</code> <code>nativeGetDisplayModes</code> has
* to be called.
*/
X11DisplayMode[] displayModes;
public GdkScreenGraphicsDevice (GdkGraphicsEnvironment e)
{
super ();
/** The non-changeable display mode of this <code>GdkScreenGraphicsDevice
* </code>. This field gets initialized by the {@link #init()} method. If it
* is still <code>null</code> afterwards, the XRandR extension is available
* and display mode changes are possible. If it is non-null XRandR is not
* available, no display mode changes are possible and no other native
* method must be called.
*/
DisplayMode fixedDisplayMode;
static
{
System.loadLibrary("gtkpeer");
initStaticState ();
}
static native void initStaticState();
GdkScreenGraphicsDevice (GdkGraphicsEnvironment e)
{
super();
env = e;
configurations = new GdkGraphicsConfiguration[1];
configurations[0] = new GdkGraphicsConfiguration(this);
}
/** This method is called from the native side immediately after
* the constructor is run.
*/
void init()
{
fixedDisplayMode = nativeGetFixedDisplayMode(env);
}
/** Depending on the availability of the XRandR extension the method returns
* the screens' non-changeable display mode or null, meaning that XRandR can
* handle display mode changes.
*/
native DisplayMode nativeGetFixedDisplayMode(GdkGraphicsEnvironment env);
public int getType ()
{
// Gdk manages only raster screens.
return GraphicsDevice.TYPE_RASTER_SCREEN;
}
public String getIDstring ()
{
// FIXME: query X for this string
return "default GDK device ID string";
if (idString == null)
idString = nativeGetIDString();
return idString;
}
private native String nativeGetIDString();
public GraphicsConfiguration[] getConfigurations ()
{
// FIXME: query X for the list of possible configurations
return new GraphicsConfiguration [] { new GdkGraphicsConfiguration(this) };
return (GraphicsConfiguration[]) configurations.clone();
}
public GraphicsConfiguration getDefaultConfiguration ()
{
// FIXME: query X for default configuration
return new GdkGraphicsConfiguration(this);
return configurations[0];
}
@@ -89,23 +155,193 @@ public class GdkScreenGraphicsDevice extends GraphicsDevice
*/
public DisplayMode getDisplayMode()
{
// determine display mode
Dimension dim = Toolkit.getDefaultToolkit().getScreenSize();
DisplayMode mode = new DisplayMode(dim.width, dim.height, 0,
DisplayMode.REFRESH_RATE_UNKNOWN);
return mode;
if (fixedDisplayMode != null)
return fixedDisplayMode;
synchronized (this)
{
if (displayModes == null)
displayModes = nativeGetDisplayModes(env);
}
int index = nativeGetDisplayModeIndex(env);
int rate = nativeGetDisplayModeRate(env);
return new DisplayMode(displayModes[index].width,
displayModes[index].height,
DisplayMode.BIT_DEPTH_MULTI,
rate);
}
native int nativeGetDisplayModeIndex(GdkGraphicsEnvironment env);
native int nativeGetDisplayModeRate(GdkGraphicsEnvironment env);
public DisplayMode[] getDisplayModes()
{
if (fixedDisplayMode != null)
return new DisplayMode[] { fixedDisplayMode };
synchronized (this)
{
if (displayModes == null)
displayModes = nativeGetDisplayModes(env);
}
ArrayList list = new ArrayList();
for(int i=0;i<displayModes.length;i++)
for(int j=0;j<displayModes[i].rates.length;j++)
list.add(new DisplayMode(displayModes[i].width,
displayModes[i].height,
DisplayMode.BIT_DEPTH_MULTI,
displayModes[i].rates[j]));
return (DisplayMode[]) list.toArray(new DisplayMode[list.size()]);
}
native X11DisplayMode[] nativeGetDisplayModes(GdkGraphicsEnvironment env);
/**
* This device does not yet support fullscreen exclusive mode, so this
* returns <code>false</code>.
* Real fullscreen exclusive mode is not supported.
*
* @return <code>false</code>
* @since 1.4
*/
public boolean isFullScreenSupported()
{
return false;
return true;
}
public boolean isDisplayChangeSupported()
{
return fixedDisplayMode == null;
}
public void setDisplayMode(DisplayMode dm)
{
if (fixedDisplayMode != null)
throw new UnsupportedOperationException("Cannnot change display mode.");
if (dm == null)
throw new IllegalArgumentException("DisplayMode must not be null.");
synchronized (this)
{
if (displayModes == null)
displayModes = nativeGetDisplayModes(env);
}
for (int i=0; i<displayModes.length; i++)
if (displayModes[i].width == dm.getWidth()
&& displayModes[i].height == dm.getHeight())
{
synchronized (this)
{
nativeSetDisplayMode(env,
i,
(short) dm.getRefreshRate());
bounds = null;
}
return;
}
throw new IllegalArgumentException("Mode not supported by this device.");
}
native void nativeSetDisplayMode(GdkGraphicsEnvironment env,
int index, short rate);
/** A class that simply encapsulates the X11 display mode data.
*/
static class X11DisplayMode
{
short[] rates;
int width;
int height;
X11DisplayMode(int width, int height, short[] rates)
{
this.width = width;
this.height = height;
this.rates = rates;
}
}
public void setFullScreenWindow(Window w)
{
// Bring old fullscreen window back into its original state.
if (fullscreenWindow != null && w != fullscreenWindow)
{
if (fullscreenWindow instanceof Frame)
{
// Decoration state can only be switched when the peer is
// non-existent. That means we have to dispose the
// Frame.
Frame f = (Frame) fullscreenWindow;
if (oldWindowDecorationState != f.isUndecorated())
{
f.dispose();
f.setUndecorated(oldWindowDecorationState);
}
}
fullscreenWindow.setBounds(oldWindowBounds);
if (!fullscreenWindow.isVisible())
fullscreenWindow.setVisible(true);
}
// If applicable remove decoration, then maximize the window and
// bring it to the foreground.
if (w != null)
{
if (w instanceof Frame)
{
Frame f = (Frame) w;
oldWindowDecorationState = f.isUndecorated();
if (!oldWindowDecorationState)
{
f.dispose();
f.setUndecorated(true);
}
}
oldWindowBounds = w.getBounds();
DisplayMode dm = getDisplayMode();
w.setBounds(0, 0, dm.getWidth(), dm.getHeight());
if (!w.isVisible())
w.setVisible(true);
w.requestFocus();
w.toFront();
}
fullscreenWindow = w;
}
public Window getFullScreenWindow()
{
return fullscreenWindow;
}
Rectangle getBounds()
{
synchronized(this)
{
if (bounds == null)
bounds = nativeGetBounds();
}
return bounds;
}
native Rectangle nativeGetBounds();
}
@@ -75,13 +75,21 @@ public class GdkTextLayout
initStaticState ();
}
private native void setText(String str);
private native void setFont(GdkFontPeer font);
private native void getExtents(double[] inkExtents,
double[] logExtents);
private native void indexToPos(int idx, double[] pos);
private native void initState ();
private native void dispose ();
private native void cairoDrawGdkTextLayout(CairoGraphics2D g, float x, float y);
static native void initStaticState();
private final int native_state = GtkGenericPeer.getUniqueInteger ();
protected void finalize ()
{
dispose ();
@@ -97,6 +105,15 @@ public class GdkTextLayout
initState();
attributedString = str;
fontRenderContext = frc;
AttributedCharacterIterator aci = str.getIterator();
char[] chars = new char[aci.getEndIndex() - aci.getBeginIndex()];
for(int i = aci.getBeginIndex(); i < aci.getEndIndex(); i++)
chars[i] = aci.setIndex(i);
setText(new String(chars));
Object fnt = aci.getAttribute(TextAttribute.FONT);
if (fnt != null && fnt instanceof Font)
setFont( (GdkFontPeer) ((Font)fnt).getPeer() );
}
protected class CharacterIteratorProxy
@@ -199,60 +216,7 @@ public class GdkTextLayout
public void draw (Graphics2D g2, float x, float y)
{
if (g2 instanceof GdkGraphics2D)
{
// we share pango structures directly with GdkGraphics2D
// when legal
GdkGraphics2D gg2 = (GdkGraphics2D) g2;
gg2.drawGdkTextLayout(this, x, y);
}
else
{
// falling back to a rather tedious layout algorithm when
// not legal
AttributedCharacterIterator ci = attributedString.getIterator ();
CharacterIteratorProxy proxy = new CharacterIteratorProxy (ci);
Font defFont = g2.getFont ();
/* Note: this implementation currently only interprets FONT text
* attributes. There is a reasonable argument to be made for some
* attributes being interpreted out here, where we have control of the
* Graphics2D and can construct or derive new fonts, and some
* attributes being interpreted by the GlyphVector itself. So far, for
* all attributes except FONT we do neither.
*/
for (char c = ci.first ();
c != CharacterIterator.DONE;
c = ci.next ())
{
proxy.begin = ci.getIndex ();
proxy.limit = ci.getRunLimit(TextAttribute.FONT);
if (proxy.limit <= proxy.begin)
continue;
proxy.index = proxy.begin;
Object fnt = ci.getAttribute(TextAttribute.FONT);
GlyphVector gv;
if (fnt instanceof Font)
gv = ((Font)fnt).createGlyphVector (fontRenderContext, proxy);
else
gv = defFont.createGlyphVector (fontRenderContext, proxy);
g2.drawGlyphVector (gv, x, y);
int n = gv.getNumGlyphs ();
for (int i = 0; i < n; ++i)
{
GlyphMetrics gm = gv.getGlyphMetrics (i);
if (gm.getAdvanceX() == gm.getAdvance ())
x += gm.getAdvanceX ();
else
y += gm.getAdvanceY ();
}
}
}
cairoDrawGdkTextLayout((CairoGraphics2D)g2, x, y);
}
public TextHitInfo getStrongCaret (TextHitInfo hit1,
@@ -45,7 +45,6 @@ import java.awt.peer.CanvasPeer;
public class GtkCanvasPeer extends GtkComponentPeer implements CanvasPeer
{
native void create ();
native void realize ();
public GtkCanvasPeer (Canvas c)
{
@@ -109,14 +109,7 @@ public class GtkComponentPeer extends GtkGenericPeer
native void gtkWidgetRequestFocus ();
native void gtkWidgetDispatchKeyEvent (int id, long when, int mods,
int keyCode, int keyLocation);
native boolean isRealized ();
void realize ()
{
// Default implementation does nothing
}
native void realize();
native void setNativeEventMask ();
void create ()
@@ -149,6 +142,9 @@ public class GtkComponentPeer extends GtkGenericPeer
setNativeEventMask ();
// This peer is guaranteed to have an X window upon construction.
// That is, native methods such as those in GdkGraphics can rely
// on this component's widget->window field being non-null.
realize ();
if (awtComponent.isCursorSet())
@@ -211,16 +207,7 @@ public class GtkComponentPeer extends GtkGenericPeer
public Image createImage (int width, int height)
{
Image image;
if (GtkToolkit.useGraphics2D ())
image = new BufferedImage (width, height, BufferedImage.TYPE_INT_RGB);
else
image = new GtkImage (width, height);
Graphics g = image.getGraphics();
g.setColor(getBackground());
g.fillRect(0, 0, width, height);
return image;
return CairoSurface.getBufferedImage(width, height);
}
public void disable ()
@@ -247,10 +234,7 @@ public class GtkComponentPeer extends GtkGenericPeer
// never return null.
public Graphics getGraphics ()
{
if (GtkToolkit.useGraphics2D ())
return new GdkGraphics2D (this);
else
return new GdkGraphics (this);
return ComponentGraphics.getComponentGraphics(this);
}
public Point getLocationOnScreen ()
@@ -713,7 +697,7 @@ public class GtkComponentPeer extends GtkGenericPeer
// on which this component is displayed.
public VolatileImage createVolatileImage (int width, int height)
{
return new GtkVolatileImage (width, height);
return new GtkVolatileImage (this, width, height, null);
}
// Creates buffers used in a buffering strategy.
@@ -723,7 +707,7 @@ public class GtkComponentPeer extends GtkGenericPeer
// numBuffers == 2 implies double-buffering, meaning one back
// buffer and one front buffer.
if (numBuffers == 2)
backBuffer = new GtkVolatileImage(awtComponent.getWidth(),
backBuffer = new GtkVolatileImage(this, awtComponent.getWidth(),
awtComponent.getHeight(),
caps.getBackBufferCapabilities());
else
@@ -57,14 +57,7 @@ import java.net.URL;
import gnu.classpath.Pointer;
/**
* GtkImage - wraps a GdkPixbuf or GdkPixmap.
*
* The constructor GtkImage(int, int) creates an 'off-screen' GdkPixmap,
* this can be drawn to (it's a GdkDrawable), and correspondingly, you can
* create a GdkGraphics object for it.
*
* This corresponds to the Image implementation returned by
* Component.createImage(int, int).
* GtkImage - wraps a GdkPixbuf.
*
* A GdkPixbuf is 'on-screen' and the gdk cannot draw to it,
* this is used for the other constructors (and other createImage methods), and
@@ -88,20 +81,16 @@ public class GtkImage extends Image
boolean isLoaded;
/**
* Pointer to the GdkPixbuf
* Pointer to the GdkPixbuf -
* don't change the name without changing the native code.
*/
Pointer pixmap;
Pointer pixbuf;
/**
* Observer queue.
*/
Vector observers;
/**
* If offScreen is set, a GdkBitmap is wrapped and not a Pixbuf.
*/
boolean offScreen;
/**
* Error flag for loading.
*/
@@ -122,71 +111,64 @@ public class GtkImage extends Image
0xFF000000);
/**
* Returns a copy of the pixel data as a java array.
* Should be called with the GdkPixbufDecoder.pixbufLock held.
* The singleton GtkImage that is returned on errors by GtkToolkit.
*/
private native int[] getPixels();
private static GtkImage errorImage;
/**
* Lock that should be held for all gdkpixbuf operations. We don't use
* the global gdk_threads_enter/leave functions in most places since
* most gdkpixbuf operations can be done in parallel to drawing and
* manipulating gtk widgets.
*/
static Object pixbufLock = new Object();
/**
* Allocate a PixBuf from a given ARGB32 buffer pointer.
*/
private native void initFromBuffer( long bufferPointer );
/**
* Returns a copy of the pixel data as a java array.
* Should be called with the pixbufLock held.
*/
native int[] getPixels();
/**
* Sets the pixel data from a java array.
* Should be called with the GdkPixbufDecoder.pixbufLock held.
* Should be called with the pixbufLock held.
*/
private native void setPixels(int[] pixels);
/**
* Loads an image using gdk-pixbuf from a file.
* Should be called with the GdkPixbufDecoder.pixbufLock held.
* Should be called with the pixbufLock held.
*/
private native boolean loadPixbuf(String name);
/**
* Loads an image using gdk-pixbuf from data.
* Should be called with the GdkPixbufDecoder.pixbufLock held.
* Should be called with the pixbufLock held.
*/
private native boolean loadImageFromData(byte[] data);
/**
* Allocates a Gtk Pixbuf or pixmap
* Should be called with the GdkPixbufDecoder.pixbufLock held.
* Allocates a Gtk Pixbuf
* Should be called with the pixbufLock held.
*/
private native void createPixmap();
private native void createPixbuf();
/**
* Frees the above.
* Should be called with the GdkPixbufDecoder.pixbufLock held.
* Should be called with the pixbufLock held.
*/
private native void freePixmap();
private native void freePixbuf();
/**
* Sets the pixmap to scaled copy of src image. hints are rendering hints.
* Should be called with the GdkPixbufDecoder.pixbufLock held.
* Sets the pixbuf to scaled copy of src image. hints are rendering hints.
* Should be called with the pixbufLock held.
*/
private native void createScaledPixmap(GtkImage src, int hints);
/**
* Draws the image, optionally scaled and composited.
* Should be called with the GdkPixbufDecoder.pixbufLock held.
* Also acquires global gdk lock for drawing.
*/
private native void drawPixelsScaled (GdkGraphics gc,
int bg_red, int bg_green, int bg_blue,
int x, int y, int width, int height,
boolean composite);
/**
* Draws the image, optionally scaled flipped and composited.
* Should be called with the GdkPixbufDecoder.pixbufLock held.
* Also acquires global gdk lock for drawing.
*/
private native void drawPixelsScaledFlipped (GdkGraphics gc,
int bg_red, int bg_green,
int bg_blue,
boolean flipX, boolean flipY,
int srcX, int srcY,
int srcWidth, int srcHeight,
int dstX, int dstY,
int dstWidth, int dstHeight,
boolean composite);
private native void createScaledPixbuf(GtkImage src, int hints);
/**
* Constructs a GtkImage from an ImageProducer. Asynchronity is handled in
@@ -202,7 +184,6 @@ public class GtkImage extends Image
source = producer;
errorLoading = false;
source.startProduction(new GtkImageConsumer(this, source));
offScreen = false;
}
/**
@@ -215,7 +196,6 @@ public class GtkImage extends Image
{
isLoaded = true;
observers = null;
offScreen = false;
props = new Hashtable();
errorLoading = false;
}
@@ -231,7 +211,7 @@ public class GtkImage extends Image
try
{
String path = f.getCanonicalPath();
synchronized(GdkPixbufDecoder.pixbufLock)
synchronized(pixbufLock)
{
if (loadPixbuf(f.getCanonicalPath()) != true)
throw new IllegalArgumentException("Couldn't load image: "
@@ -249,7 +229,6 @@ public class GtkImage extends Image
isLoaded = true;
observers = null;
offScreen = false;
props = new Hashtable();
}
@@ -261,7 +240,7 @@ public class GtkImage extends Image
*/
public GtkImage (byte[] data)
{
synchronized(GdkPixbufDecoder.pixbufLock)
synchronized(pixbufLock)
{
if (loadImageFromData (data) != true)
throw new IllegalArgumentException ("Couldn't load image.");
@@ -269,7 +248,6 @@ public class GtkImage extends Image
isLoaded = true;
observers = null;
offScreen = false;
props = new Hashtable();
errorLoading = false;
}
@@ -301,7 +279,7 @@ public class GtkImage extends Image
throw new IllegalArgumentException ("Couldn't load image.");
}
byte[] array = baos.toByteArray();
synchronized(GdkPixbufDecoder.pixbufLock)
synchronized(pixbufLock)
{
if (loadImageFromData(array) != true)
throw new IllegalArgumentException ("Couldn't load image.");
@@ -312,23 +290,6 @@ public class GtkImage extends Image
props = new Hashtable();
}
/**
* Constructs an empty GtkImage.
*/
public GtkImage (int width, int height)
{
this.width = width;
this.height = height;
props = new Hashtable();
isLoaded = true;
observers = null;
offScreen = true;
synchronized(GdkPixbufDecoder.pixbufLock)
{
createPixmap();
}
}
/**
* Constructs a scaled version of the src bitmap, using the GDK.
*/
@@ -339,12 +300,11 @@ public class GtkImage extends Image
props = new Hashtable();
isLoaded = true;
observers = null;
offScreen = false;
// Use the GDK scaling method.
synchronized(GdkPixbufDecoder.pixbufLock)
synchronized(pixbufLock)
{
createScaledPixmap(src, hints);
createScaledPixbuf(src, hints);
}
}
@@ -354,19 +314,30 @@ public class GtkImage extends Image
*/
GtkImage (Pointer pixbuf)
{
pixmap = pixbuf;
synchronized(GdkPixbufDecoder.pixbufLock)
this.pixbuf = pixbuf;
synchronized(pixbufLock)
{
createFromPixbuf();
}
isLoaded = true;
observers = null;
offScreen = false;
props = new Hashtable();
}
// The singleton GtkImage that is returned on errors by GtkToolkit.
private static GtkImage errorImage;
/**
* Wraps a buffer with a GtkImage.
*
* @param bufferPointer a pointer to an ARGB32 buffer
*/
GtkImage(int width, int height, long bufferPointer)
{
this.width = width;
this.height = height;
props = new Hashtable();
isLoaded = true;
observers = null;
initFromBuffer( bufferPointer );
}
/**
* Returns an empty GtkImage with the errorLoading flag set.
@@ -385,7 +356,7 @@ public class GtkImage extends Image
/**
* Native helper function for constructor that takes a pixbuf Pointer.
* Should be called with the GdkPixbufDecoder.pixbufLock held.
* Should be called with the pixbufLock held.
*/
private native void createFromPixbuf();
@@ -407,9 +378,9 @@ public class GtkImage extends Image
isLoaded = true;
deliver();
synchronized(GdkPixbufDecoder.pixbufLock)
synchronized(pixbufLock)
{
createPixmap();
createPixbuf();
setPixels(pixels);
}
}
@@ -450,30 +421,28 @@ public class GtkImage extends Image
return null;
int[] pixels;
synchronized(GdkPixbufDecoder.pixbufLock)
synchronized (pixbufLock)
{
pixels = getPixels();
if (!errorLoading)
pixels = getPixels();
else
return null;
}
return new MemoryImageSource(width, height, nativeModel, pixels,
0, width);
}
/**
* Creates a GdkGraphics context for this pixmap.
* Does nothing. Should not be called.
*/
public Graphics getGraphics ()
{
if (!isLoaded)
return null;
if (offScreen)
return new GdkGraphics(this);
else
throw new IllegalAccessError("This method only works for off-screen"
+" Images.");
throw new IllegalAccessError("This method only works for off-screen"
+" Images.");
}
/**
* Returns a scaled instance of this pixmap.
* Returns a scaled instance of this pixbuf.
*/
public Image getScaledInstance(int width,
int height,
@@ -500,9 +469,9 @@ public class GtkImage extends Image
{
observers = new Vector();
isLoaded = false;
synchronized(GdkPixbufDecoder.pixbufLock)
synchronized(pixbufLock)
{
freePixmap();
freePixbuf();
}
source.startProduction(new GtkImageConsumer(this, source));
}
@@ -512,9 +481,9 @@ public class GtkImage extends Image
{
if (isLoaded)
{
synchronized(GdkPixbufDecoder.pixbufLock)
synchronized(pixbufLock)
{
freePixmap();
freePixbuf();
}
}
}
@@ -535,104 +504,6 @@ public class GtkImage extends Image
return ImageObserver.ALLBITS | ImageObserver.WIDTH | ImageObserver.HEIGHT;
}
// Drawing methods ////////////////////////////////////////////////
/**
* Draws an image with eventual scaling/transforming.
*/
public boolean drawImage (GdkGraphics g, int dx1, int dy1, int dx2, int dy2,
int sx1, int sy1, int sx2, int sy2,
Color bgcolor, ImageObserver observer)
{
if (addObserver(observer))
return false;
boolean flipX = (dx1 > dx2)^(sx1 > sx2);
boolean flipY = (dy1 > dy2)^(sy1 > sy2);
int dstWidth = Math.abs (dx2 - dx1);
int dstHeight = Math.abs (dy2 - dy1);
int srcWidth = Math.abs (sx2 - sx1);
int srcHeight = Math.abs (sy2 - sy1);
int srcX = (sx1 < sx2) ? sx1 : sx2;
int srcY = (sy1 < sy2) ? sy1 : sy2;
int dstX = (dx1 < dx2) ? dx1 : dx2;
int dstY = (dy1 < dy2) ? dy1 : dy2;
// Clipping. This requires the dst to be scaled as well,
if (srcWidth > width)
{
dstWidth = (int)((double)dstWidth*((double)width/(double)srcWidth));
srcWidth = width - srcX;
}
if (srcHeight > height)
{
dstHeight = (int)((double)dstHeight*((double)height/(double)srcHeight));
srcHeight = height - srcY;
}
if (srcWidth + srcX > width)
{
dstWidth = (int)((double)dstWidth * (double)(width - srcX)/(double)srcWidth);
srcWidth = width - srcX;
}
if (srcHeight + srcY > height)
{
dstHeight = (int)((double)dstHeight * (double)(width - srcY)/(double)srcHeight);
srcHeight = height - srcY;
}
if ( this.width <= 0 || this.height <= 0 )
return true;
if ( srcWidth <= 0 || srcHeight <= 0 || dstWidth <= 0 || dstHeight <= 0)
return true;
synchronized(GdkPixbufDecoder.pixbufLock)
{
if(bgcolor != null)
drawPixelsScaledFlipped (g, bgcolor.getRed (), bgcolor.getGreen (),
bgcolor.getBlue (),
flipX, flipY,
srcX, srcY,
srcWidth, srcHeight,
dstX, dstY,
dstWidth, dstHeight,
true);
else
drawPixelsScaledFlipped (g, 0, 0, 0, flipX, flipY,
srcX, srcY, srcWidth, srcHeight,
dstX, dstY, dstWidth, dstHeight,
false);
}
return true;
}
/**
* Draws an image to the GdkGraphics context, at (x,y) scaled to
* width and height, with optional compositing with a background color.
*/
public boolean drawImage (GdkGraphics g, int x, int y, int width, int height,
Color bgcolor, ImageObserver observer)
{
if (addObserver(observer))
return false;
if ( this.width <= 0 || this.height <= 0 )
return true;
synchronized(GdkPixbufDecoder.pixbufLock)
{
if(bgcolor != null)
drawPixelsScaled(g, bgcolor.getRed (), bgcolor.getGreen (),
bgcolor.getBlue (), x, y, width, height, true);
else
drawPixelsScaled(g, 0, 0, 0, x, y, width, height, false);
}
return true;
}
// Private methods ////////////////////////////////////////////////
@@ -78,31 +78,12 @@ import javax.imageio.spi.IIORegistry;
this class. If getPeer() ever goes away, we can implement a hash table
that will keep up with every window's peer, but for now this is faster. */
/**
* This class accesses a system property called
* <tt>gnu.java.awt.peer.gtk.Graphics</tt>. If the property is defined and
* equal to "Graphics2D", the cairo-based GdkGraphics2D will be used in
* drawing contexts. Any other value will cause the older GdkGraphics
* object to be used.
*/
public class GtkToolkit extends gnu.java.awt.ClasspathToolkit
{
Hashtable containers = new Hashtable();
static EventQueue q;
static boolean useGraphics2dSet;
static boolean useGraphics2d;
static Thread mainThread;
public static boolean useGraphics2D()
{
if (useGraphics2dSet)
return useGraphics2d;
useGraphics2d = System.getProperty("gnu.java.awt.peer.gtk.Graphics",
"Graphics").equals("Graphics2D");
useGraphics2dSet = true;
return useGraphics2d;
}
static native void gtkInit(int portableNativeSync);
static
@@ -178,10 +159,7 @@ public class GtkToolkit extends gnu.java.awt.ClasspathToolkit
Image image;
try
{
if (useGraphics2D())
image = GdkPixbufDecoder.createBufferedImage(filename);
else
image = new GtkImage(filename);
image = CairoSurface.getBufferedImage( new GtkImage( filename ) );
}
catch (IllegalArgumentException iae)
{
@@ -195,10 +173,7 @@ public class GtkToolkit extends gnu.java.awt.ClasspathToolkit
Image image;
try
{
if (useGraphics2D())
image = GdkPixbufDecoder.createBufferedImage(url);
else
image = new GtkImage(url);
image = CairoSurface.getBufferedImage( new GtkImage( url ) );
}
catch (IllegalArgumentException iae)
{
@@ -209,13 +184,13 @@ public class GtkToolkit extends gnu.java.awt.ClasspathToolkit
public Image createImage (ImageProducer producer)
{
if (producer == null)
return null;
Image image;
try
{
if (useGraphics2D())
image = GdkPixbufDecoder.createBufferedImage(producer);
else
image = new GtkImage(producer);
image = CairoSurface.getBufferedImage( new GtkImage( producer ) );
}
catch (IllegalArgumentException iae)
{
@@ -230,16 +205,9 @@ public class GtkToolkit extends gnu.java.awt.ClasspathToolkit
Image image;
try
{
if (useGraphics2D())
image = GdkPixbufDecoder.createBufferedImage(imagedata,
imageoffset,
imagelength);
else
{
byte[] datacopy = new byte[imagelength];
System.arraycopy(imagedata, imageoffset, datacopy, 0, imagelength);
return new GtkImage(datacopy);
}
byte[] data = new byte[ imagelength ];
System.arraycopy(imagedata, imageoffset, data, 0, imagelength);
image = CairoSurface.getBufferedImage( new GtkImage( data ) );
}
catch (IllegalArgumentException iae)
{
@@ -256,7 +224,7 @@ public class GtkToolkit extends gnu.java.awt.ClasspathToolkit
*/
public ImageProducer createImageProducer(URL url)
{
return new GdkPixbufDecoder(url);
return createImage( url ).getSource();
}
/**
@@ -568,13 +536,23 @@ public class GtkToolkit extends gnu.java.awt.ClasspathToolkit
protected EventQueue getSystemEventQueueImpl()
{
synchronized (GtkToolkit.class)
// GCJ LOCAL: workaround a GCJ problem accessing
// GtkToolkit.class
try
{
synchronized (Class.forName ("gnu.java.awt.peer.gtk.GtkToolkit"))
{
if (q == null)
{
q = new EventQueue();
}
}
}
catch (Exception e)
{
e.printStackTrace();
}
return q;
}
@@ -1,4 +1,4 @@
/* GtkVolatileImage.java -- a hardware-accelerated image buffer
/* GtkVolatileImage.java -- wraps an X pixmap
Copyright (C) 2005 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -38,6 +38,7 @@ exception statement from your version. */
package gnu.java.awt.peer.gtk;
import java.awt.ImageCapabilities;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GraphicsConfiguration;
import java.awt.image.BufferedImage;
@@ -46,44 +47,68 @@ import java.awt.image.VolatileImage;
public class GtkVolatileImage extends VolatileImage
{
private int width;
private int height;
int width, height;
private ImageCapabilities caps;
public GtkVolatileImage(int width, int height)
{
this(width, height, null);
}
/**
* Don't touch, accessed from native code.
*/
long nativePointer;
public GtkVolatileImage(int width, int height, ImageCapabilities caps)
native long init(GtkComponentPeer component, int width, int height);
native void destroy();
native int[] getPixels();
native void copyArea( int x, int y, int w, int h, int dx, int dy );
native void drawVolatile( long ptr, int x, int y, int w, int h );
public GtkVolatileImage(GtkComponentPeer component,
int width, int height, ImageCapabilities caps)
{
this.width = width;
this.height = height;
this.caps = caps;
nativePointer = init( component, width, height );
}
public GtkVolatileImage(int width, int height, ImageCapabilities caps)
{
this(null, width, height, caps);
}
public GtkVolatileImage(int width, int height)
{
this(null, width, height, null);
}
public void finalize()
{
dispose();
}
public void dispose()
{
destroy();
}
// FIXME: should return a buffered image snapshot of the accelerated
// visual
public BufferedImage getSnapshot()
{
return null;
CairoSurface cs = new CairoSurface( width, height );
cs.setPixels( getPixels() );
return CairoSurface.getBufferedImage( cs );
}
public int getWidth()
public Graphics getGraphics()
{
return width;
return createGraphics();
}
public int getHeight()
{
return height;
}
// FIXME: should return a graphics wrapper around this image's
// visual
public Graphics2D createGraphics()
{
return null;
return new VolatileImageGraphics( this );
}
public int validate(GraphicsConfiguration gc)
@@ -101,18 +126,28 @@ public class GtkVolatileImage extends VolatileImage
return caps;
}
public synchronized Object getProperty (String name, ImageObserver observer)
public int getWidth()
{
return null;
return width;
}
public synchronized int getWidth (ImageObserver observer)
public int getHeight()
{
return height;
}
public int getWidth(java.awt.image.ImageObserver observer)
{
return width;
}
public synchronized int getHeight (ImageObserver observer)
public int getHeight(java.awt.image.ImageObserver observer)
{
return height;
}
public Object getProperty(String name, ImageObserver observer)
{
return null;
}
}
@@ -0,0 +1,122 @@
/* VolatileImageGraphics.java
Copyright (C) 2006 Free Software Foundation, Inc.
This file is part of GNU Classpath.
GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
GNU Classpath 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 GNU Classpath; see the file COPYING. If not, write to the
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA.
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 GNU General Public License cover the whole
combination.
As a special 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
this 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 gnu.java.awt.peer.gtk;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GraphicsConfiguration;
import java.awt.Image;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.Shape;
import java.awt.font.GlyphVector;
import java.awt.geom.AffineTransform;
import java.awt.geom.Rectangle2D;
import java.awt.image.BufferedImage;
import java.awt.image.DataBuffer;
import java.awt.image.DataBufferInt;
import java.awt.image.ColorModel;
import java.awt.image.DirectColorModel;
import java.awt.image.RenderedImage;
import java.awt.image.ImageObserver;
import java.util.WeakHashMap;
public class VolatileImageGraphics extends ComponentGraphics
{
private GtkVolatileImage owner;
public VolatileImageGraphics(GtkVolatileImage img)
{
this.owner = img;
cairo_t = initFromVolatile( owner.nativePointer, img.width, img.height );
setup( cairo_t );
setClip( new Rectangle( 0, 0, img.width, img.height) );
}
private VolatileImageGraphics(VolatileImageGraphics copy)
{
this.owner = copy.owner;
initFromVolatile( owner.nativePointer, owner.width, owner.height );
setClip( new Rectangle( 0, 0, owner.width, owner.height) );
copy( copy, cairo_t );
}
public void copyAreaImpl(int x, int y, int width, int height, int dx, int dy)
{
owner.copyArea(x, y, width, height, dx, dy);
}
public GraphicsConfiguration getDeviceConfiguration()
{
return null;
}
public Graphics create()
{
return new VolatileImageGraphics( this );
}
public boolean drawImage(Image img, int x, int y, ImageObserver observer)
{
if( img instanceof GtkVolatileImage )
{
owner.drawVolatile( ((GtkVolatileImage)img).nativePointer,
x, y,
((GtkVolatileImage)img).width,
((GtkVolatileImage)img).height );
return true;
}
return super.drawImage( img, x, y, observer );
}
public boolean drawImage(Image img, int x, int y, int width, int height,
ImageObserver observer)
{
if( img instanceof GtkVolatileImage )
{
owner.drawVolatile( ((GtkVolatileImage)img).nativePointer,
x, y, width, height );
return true;
}
return super.drawImage( img, x, y, width, height, observer );
}
}
@@ -62,7 +62,7 @@ public interface SwingComponent
/**
* Handles a mouse event. This is usually forwarded to
* {@link Component#processMouseMotionEvent(MouseEvent)} of the swing
* {@link java.awt.Component#processMouseMotionEvent(MouseEvent)} of the swing
* component.
*
* @param ev the mouse event
@@ -71,7 +71,7 @@ public interface SwingComponent
/**
* Handles a mouse motion event. This is usually forwarded to
* {@link Component#processMouseEvent(MouseEvent)} of the swing
* {@link java.awt.Component#processMouseEvent(MouseEvent)} of the swing
* component.
*
* @param ev the mouse motion event
@@ -80,7 +80,7 @@ public interface SwingComponent
/**
* Handles a key event. This is usually forwarded to
* {@link Component#processKeyEvent(KeyEvent)} of the swing
* {@link java.awt.Component#processKeyEvent(KeyEvent)} of the swing
* component.
*
* @param ev the key event
@@ -48,6 +48,8 @@ import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.GraphicsConfiguration;
import java.awt.GraphicsDevice;
import java.awt.GraphicsEnvironment;
import java.awt.Image;
import java.awt.Point;
import java.awt.Rectangle;
@@ -98,8 +100,9 @@ public class SwingComponentPeer
/**
* Creates a SwingComponentPeer instance. Subclasses are expected to call
* this constructor and thereafter call {@link #init(Component, JComponent)}
* in order to setup the AWT and Swing components properly.
* this constructor and thereafter call
* {@link #init(Component, SwingComponent)} in order to setup the AWT and
* Swing components properly.
*/
protected SwingComponentPeer()
{
@@ -164,9 +167,12 @@ public class SwingComponentPeer
*/
public Image createImage(int width, int height)
{
Component parent = awtComponent.getParent();
ComponentPeer parentPeer = parent.getPeer();
return parentPeer.createImage(width, height);
GraphicsEnvironment graphicsEnv =
GraphicsEnvironment.getLocalGraphicsEnvironment();
GraphicsDevice dev = graphicsEnv.getDefaultScreenDevice();
GraphicsConfiguration conf = dev.getDefaultConfiguration();
Image image = conf.createCompatibleImage(width, height);
return image;
}
/**
@@ -442,20 +448,6 @@ public class SwingComponentPeer
return retVal;
}
/**
* Prepares an image for rendering on this component. This is called by
* {@link Component#prepareImage(Image, int, int, ImageObserver)}.
*
* @param img the image to prepare
* @param width the desired width of the rendered image
* @param height the desired height of the rendered image
* @param ob the image observer to be notified of updates in the preparation
* process
*
* @return <code>true</code> if the image has been fully prepared,
* <code>false</code> otherwise (in which case the image observer
* receives updates)
*/
public void paint(Graphics graphics)
{
// FIXME: I don't know what this method is supposed to do.
@@ -478,8 +470,17 @@ public class SwingComponentPeer
public boolean prepareImage(Image img, int width, int height, ImageObserver ob)
{
Component parent = awtComponent.getParent();
ComponentPeer parentPeer = parent.getPeer();
return parentPeer.prepareImage(img, width, height, ob);
boolean res;
if(parent != null)
{
ComponentPeer parentPeer = parent.getPeer();
res = parentPeer.prepareImage(img, width, height, ob);
}
else
{
res = Toolkit.getDefaultToolkit().prepareImage(img, width, height, ob);
}
return res;
}
public void print(Graphics graphics)
@@ -92,7 +92,12 @@ public class SwingContainerPeer
*/
public Insets getInsets()
{
return insets();
Insets retVal;
if (swingComponent != null)
retVal = swingComponent.getJComponent().getInsets();
else
retVal = new Insets(0, 0, 0, 0);
return retVal;
}
/**
@@ -209,6 +214,8 @@ public class SwingContainerPeer
protected void handleMouseEvent(MouseEvent ev)
{
Component comp = awtComponent.getComponentAt(ev.getPoint());
if(comp == null)
comp = awtComponent;
if (comp != null)
{
ComponentPeer peer = comp.getPeer();
@@ -53,9 +53,9 @@ import java.awt.peer.FramePeer;
* As a minimum, a subclass must implement all the remaining abstract methods
* as well as the following methods:
* <ul>
* <li>{@link ComponentPeer#getLocationOnScreen()}</li>
* <li>{@link ComponentPeer#getGraphics()}</li>
* <li>{@link ComponentPeer#createImage(int, int)}</li>
* <li>{@link java.awt.peer.ComponentPeer#getLocationOnScreen()}</li>
* <li>{@link java.awt.peer.ComponentPeer#getGraphics()}</li>
* <li>{@link java.awt.peer.ComponentPeer#createImage(int, int)}</li>
* </ul>
*
* @author Roman Kennke (kennke@aicas.com)
@@ -174,7 +174,7 @@ public class SwingMenuBarPeer
/**
* Adds a help menu to the menu bar.
*
* @param m the menu to add
* @param menu the menu to add
*/
public void addHelpMenu(Menu menu)
{
@@ -283,7 +283,7 @@ public class SwingTextFieldPeer
* @param startPos the start index of the selection
* @param endPos the start index of the selection
*/
public void select(int start_pos, int endPos)
public void select(int startPos, int endPos)
{
// TODO: Must be implemented.
}
@@ -48,9 +48,9 @@ import java.awt.peer.WindowPeer;
* As a minimum, a subclass must implement all the remaining abstract methods
* as well as the following methods:
* <ul>
* <li>{@link ComponentPeer#getLocationOnScreen()}</li>
* <li>{@link ComponentPeer#getGraphics()}</li>
* <li>{@link ComponentPeer#createImage(int, int)}</li>
* <li>{@link java.awt.peer.ComponentPeer#getLocationOnScreen()}</li>
* <li>{@link java.awt.peer.ComponentPeer#getGraphics()}</li>
* <li>{@link java.awt.peer.ComponentPeer#createImage(int, int)}</li>
* </ul>
*
* @author Roman Kennke (kennke@aicas.com)