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:
committed by
Thomas Fitzsimmons
parent
6c65d7577c
commit
02440ca432
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
+1086
-1171
File diff suppressed because it is too large
Load Diff
@@ -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’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)
|
||||
|
||||
Reference in New Issue
Block a user