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

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

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

From-SVN: r114510
This commit is contained in:
Thomas Fitzsimmons 2006-06-09 16:07:07 +00:00 committed by Thomas Fitzsimmons
parent 6c65d7577c
commit 02440ca432
360 changed files with 34743 additions and 9337 deletions

View file

@ -59,7 +59,7 @@ import java.awt.image.WritableRaster;
* />
*
* <p>The above screen shot shows the result of applying six different
* BitwiseXORComposites. They were constructed with the colors colors
* BitwiseXORComposites. They were constructed with the colors
* white, blue, black, orange, green, and brown, respectively. Each
* composite was used to paint a fully white rectangle on top of the
* blue bar in the background.

View file

@ -144,25 +144,7 @@ public final class Buffers
*/
public static Object getData(DataBuffer buffer)
{
if (buffer instanceof DataBufferByte)
return ((DataBufferByte) buffer).getData();
if (buffer instanceof DataBufferShort)
return ((DataBufferShort) buffer).getData();
if (buffer instanceof DataBufferUShort)
return ((DataBufferUShort) buffer).getData();
if (buffer instanceof DataBufferInt)
return ((DataBufferInt) buffer).getData();
if (buffer instanceof DataBufferFloat)
return ((DataBufferFloat) buffer).getData();
if (buffer instanceof DataBufferDouble)
return ((DataBufferDouble) buffer).getData();
throw new ClassCastException("Unknown data buffer type");
return getData(buffer, 0, null, 0, buffer.getSize());
}
@ -172,46 +154,46 @@ public final class Buffers
* given destination array is null.
*/
public static Object getData(DataBuffer src, int srcOffset,
Object dest, int destOffset,
Object dest, int dstOffset,
int length)
{
Object from;
if (src instanceof DataBufferByte)
{
from = ((DataBufferByte) src).getData();
if (dest == null) dest = new byte[length+destOffset];
}
else if (src instanceof DataBufferShort)
{
from = ((DataBufferShort) src).getData();
if (dest == null) dest = new short[length+destOffset];
}
else if (src instanceof DataBufferUShort)
{
from = ((DataBufferUShort) src).getData();
if (dest == null) dest = new short[length+destOffset];
}
else if (src instanceof DataBufferInt)
{
from = ((DataBufferInt) src).getData();
if (dest == null) dest = new int[length+destOffset];
}
else if (src instanceof DataBufferFloat)
{
from = ((DataBufferFloat) src).getData();
if (dest == null) dest = new float[length+destOffset];
}
else if (src instanceof DataBufferDouble)
{
from = ((DataBufferDouble) src).getData();
if (dest == null) dest = new double[length+destOffset];
}
else
switch(src.getDataType())
{
case DataBuffer.TYPE_BYTE:
if (dest == null) dest = new byte[length+dstOffset];
for(int i = 0; i < length; i++)
((byte[])dest)[i + dstOffset] = (byte)src.getElem(i + srcOffset);
break;
case DataBuffer.TYPE_DOUBLE:
if (dest == null) dest = new double[length+dstOffset];
for(int i = 0; i < length; i++)
((double[])dest)[i + dstOffset] = src.getElemDouble(i + srcOffset);
break;
case DataBuffer.TYPE_FLOAT:
if (dest == null) dest = new float[length+dstOffset];
for(int i = 0; i < length; i++)
((float[])dest)[i + dstOffset] = src.getElemFloat(i + srcOffset);
break;
case DataBuffer.TYPE_INT:
if (dest == null) dest = new int[length+dstOffset];
for(int i = 0; i < length; i++)
((int[])dest)[i + dstOffset] = src.getElem(i + srcOffset);
break;
case DataBuffer.TYPE_SHORT:
case DataBuffer.TYPE_USHORT:
if (dest == null) dest = new short[length+dstOffset];
for(int i = 0; i < length; i++)
((short[])dest)[i + dstOffset] = (short)src.getElem(i + srcOffset);
break;
case DataBuffer.TYPE_UNDEFINED:
throw new ClassCastException("Unknown data buffer type");
}
System.arraycopy(from, srcOffset, dest, destOffset, length);
return dest;
}

View file

@ -110,7 +110,7 @@ public class GNUGlyphVector
fontSize = font.getSize2D();
transform = font.getTransform(); // returns a modifiable copy
transform.concatenate(renderContext.getTransform());
//transform.concatenate(renderContext.getTransform());
}

View file

@ -48,7 +48,7 @@ import java.util.Locale;
*
* @author Sascha Brawer (brawer@dandelis.ch)
*/
class NameDecoder
public class NameDecoder
{
public static final int NAME_COPYRIGHT = 0;
@ -122,27 +122,38 @@ class NameDecoder
nameTable.position(0);
/* We understand only format 0 of the name table. */
if (nameTable.getChar() != 0)
if (nameTable.getShort() != 0)
return null;
macLanguage = getMacLanguageCode(locale);
msLanguage = getMicrosoftLanguageCode(locale);
numRecords = nameTable.getChar();
offset = nameTable.getChar();
numRecords = nameTable.getShort();
offset = nameTable.getShort();
for (int i = 0; i < numRecords; i++)
{
namePlatform = nameTable.getChar();
nameEncoding = nameTable.getChar();
nameLanguage = nameTable.getChar();
nameID = nameTable.getChar();
nameLen = nameTable.getChar();
nameStart = offset + nameTable.getChar();
namePlatform = nameTable.getShort();
nameEncoding = nameTable.getShort();
nameLanguage = nameTable.getShort();
nameID = nameTable.getShort();
nameLen = nameTable.getShort();
nameStart = offset + nameTable.getShort();
if (nameID != name)
continue;
// Handle PS seperately as it can be only ASCII, although
// possibly encoded as UTF-16BE
if ( name == NAME_POSTSCRIPT )
{
if( nameTable.get(nameStart) == 0 ) // Peek at top byte
result = decodeName("UTF-16BE", nameTable, nameStart, nameLen);
else
result = decodeName("ASCII", nameTable, nameStart, nameLen);
return result;
}
match = false;
switch (namePlatform)
{
@ -393,14 +404,19 @@ class NameDecoder
private static String decodeName(int platform, int encoding, int language,
ByteBuffer buffer, int offset, int len)
{
byte[] byteBuf;
String charsetName;
int oldPosition;
charsetName = getCharsetName(platform, language, encoding);
String charsetName = getCharsetName(platform, language, encoding);
if (charsetName == null)
return null;
return decodeName(charsetName, buffer, offset, len);
}
private static String decodeName(String charsetName,
ByteBuffer buffer, int offset, int len)
{
byte[] byteBuf;
int oldPosition;
byteBuf = new byte[len];
oldPosition = buffer.position();
try

File diff suppressed because it is too large Load diff

View file

@ -236,7 +236,7 @@ public class AlphaCompositeContext
}
else
{
for (int i = srcComponentsLength - 1; i >= 0; i--)
for (int i = srcComponentsLength - 2; i >= 0; i--)
srcComponents[i] *= srcComponents[srcComponentsLength - 1];
}
if (! dstColorModel.isAlphaPremultiplied())

View file

@ -0,0 +1,192 @@
/* ImagePaint.java -- Supplies the pixels for image rendering
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.java2d;
import java.awt.Paint;
import java.awt.PaintContext;
import java.awt.Rectangle;
import java.awt.RenderingHints;
import java.awt.Transparency;
import java.awt.geom.AffineTransform;
import java.awt.geom.Rectangle2D;
import java.awt.image.ColorModel;
import java.awt.image.Raster;
import java.awt.image.RenderedImage;
import java.awt.image.WritableRaster;
/**
* This class is used as a temporary Paint object to supply the pixel values
* for image rendering using the normal scanline conversion implementation.
*
* @author Roman Kennke (kennke@aicas.com)
*/
public class ImagePaint
implements Paint
{
/**
* The PaintContext implementation for the ImagePaint.
*/
private class ImagePaintContext
implements PaintContext
{
/**
* The target raster.
*/
private WritableRaster target;
/**
* Nothing to do here.
*/
public void dispose()
{
// Nothing to do here.
}
/**
* Returns the color model.
*
* @return the color model
*/
public ColorModel getColorModel()
{
return image.getColorModel();
}
/**
* Supplies the pixel to be rendered.
*
* @see PaintContext#getRaster(int, int, int, int)
*/
public Raster getRaster(int x1, int y1, int w, int h)
{
ensureRasterSize(w, h);
int x2 = x1 + w;
int y2 = y1 + h;
float[] src = new float[2];
float[] dest = new float[2];
Raster source = image.getData();
int minX = source.getMinX();
int maxX = source.getWidth() + minX;
int minY = source.getMinY();
int maxY = source.getHeight() + minY;
Object pixel = null;
for (int y = y1; y < y2; y++)
{
for (int x = x1; x < x2; x++)
{
src[0] = x;
src[1] = y;
transform.transform(src, 0, dest, 0, 1);
int dx = (int) dest[0];
int dy = (int) dest[1];
// Pixels outside the source image are not of interest, skip
// them.
if (dx >= minX && dx < maxX && dy >= minY && dy < maxY)
{
pixel = source.getDataElements(dx, dy, pixel);
target.setDataElements(x - x1, y - y1, pixel);
}
}
}
return target;
}
/**
* Ensures that the target raster exists and has at least the specified
* size.
*
* @param w the requested target width
* @param h the requested target height
*/
private void ensureRasterSize(int w, int h)
{
if (target == null || target.getWidth() < w || target.getHeight() < h)
{
Raster s = image.getData();
target = s.createCompatibleWritableRaster(w, h);
}
}
}
/**
* The image to render.
*/
RenderedImage image;
/**
* The transform from image space to device space. This is the inversed
* transform of the concatenated
* transform image space -> user space -> device space transform.
*/
AffineTransform transform;
/**
* Creates a new ImagePaint for rendering the specified image using the
* specified device space -> image space transform. This transform
* is the inversed transform of the usual image space -> user space -> device
* space transform.
*
* The ImagePaint will only render the image in the specified area of
* interest (which is specified in image space).
*
* @param i the image to render
* @param t the device space to user space transform
*/
ImagePaint(RenderedImage i, AffineTransform t)
{
image = i;
transform = t;
}
public PaintContext createContext(ColorModel cm, Rectangle deviceBounds,
Rectangle2D userBounds,
AffineTransform xform,
RenderingHints hints)
{
return new ImagePaintContext();
}
public int getTransparency()
{
return Transparency.OPAQUE;
}
}

View file

@ -64,6 +64,11 @@ public class PolyEdge
*/
double xIntersection;
/**
* Indicates whether this edge is from the clip or from the target shape.
*/
boolean isClip;
/**
* Creates a new PolyEdge with the specified coordinates.
*
@ -72,8 +77,9 @@ public class PolyEdge
* @param x1 the end point, x coordinate
* @param y1 the end point, y coordinate
*/
PolyEdge(double x0, double y0, double x1, double y1)
PolyEdge(double x0, double y0, double x1, double y1, boolean clip)
{
isClip = clip;
if (y0 < y1)
{
this.x0 = x0;

View file

@ -65,8 +65,10 @@ public class RasterGraphics
public RasterGraphics(WritableRaster r, ColorModel cm)
{
super();
raster = r;
colorModel = cm;
init();
}
/**

View file

@ -0,0 +1,205 @@
/* TexturePaintContext.java -- PaintContext impl for TexturePaint
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.java2d;
import java.awt.AWTError;
import java.awt.PaintContext;
import java.awt.Rectangle;
import java.awt.TexturePaint;
import java.awt.geom.AffineTransform;
import java.awt.geom.NoninvertibleTransformException;
import java.awt.geom.Rectangle2D;
import java.awt.image.BufferedImage;
import java.awt.image.ColorModel;
import java.awt.image.Raster;
import java.awt.image.WritableRaster;
/**
* A {@link PaintContext} implementation for {@link TexturePaint}, done in
* pure Java.
*
* @author Roman Kennke (kennke@aicas.com)
*/
public class TexturePaintContext
implements PaintContext
{
/**
* The TexturePaint object.
*/
private BufferedImage image;
/**
* The Raster that holds the texture.
*/
private WritableRaster paintRaster;
/**
* The transform from userspace into device space.
*/
private AffineTransform transform;
/**
* Creates a new TexturePaintContext for the specified TexturePaint object.
* This initializes the Raster which is returned by
* {@link #getRaster(int, int, int, int)}.
*
* @param t the texture paint object
* @param db the bounds of the target raster in device space
* @param ub the bounds of the target raster in user space
* @param xform the transformation from user space to device space
*/
public TexturePaintContext(TexturePaint t, Rectangle db,
Rectangle2D ub, AffineTransform xform)
{
image = t.getImage();
try
{
// Prepare transform for mapping from device space into image space.
// In order to achieve this we take the transform for userspace->
// devicespace, append the correct scale and translation according
// to the anchor (which gives us the image->userspace->devicespace
// transform), and invert that (which gives use the device->user->image
// transform).
Rectangle2D anchor = t.getAnchorRect();
BufferedImage image = t.getImage();
double scaleX = anchor.getWidth() / image.getWidth();
double scaleY = anchor.getHeight() / image.getHeight();
transform = (AffineTransform) xform.clone();
transform.scale(scaleX, scaleY);
transform.translate(-anchor.getMinX(), -anchor.getMaxX());
transform = transform.createInverse();
}
catch (NoninvertibleTransformException ex)
{
AWTError err =
new AWTError("Unexpected NoninvertibleTransformException");
err.initCause(ex);
throw err;
}
}
/**
* Disposes the PaintContext. Nothing is to do here, since we don't use
* any native resources in that implementation.
*/
public void dispose()
{
// Nothing to do here.
}
/**
* Returns the color model of this PaintContext. This implementation returnes
* the color model used by the BufferedImage in the TexturePaint object,
* this avoids costly color model transformations (at least at this point).
*
* @return the color model of this PaintContext
*/
public ColorModel getColorModel()
{
return image.getColorModel();
}
/**
* Returns the Raster that is used for painting.
*
* @param x1 the x location of the raster inside the user bounds of this paint
* context
* @param y1 the y location of the raster inside the user bounds of this paint
* context
* @param w the width
* @param h the height
*
* @return the Raster that is used for painting
*
*/
public Raster getRaster(int x1, int y1, int w, int h)
{
ensureRasterSize(w, h);
int x2 = x1 + w;
int y2 = y1 + h;
float[] src = new float[2];
float[] dest = new float[2];
Raster source = image.getData();
int minX = source.getMinX();
int width = source.getWidth();
int minY = source.getMinY();
int height = source.getHeight();
Object pixel = null;
for (int y = y1; y < y2; y++)
{
for (int x = x1; x < x2; x++)
{
// Transform the coordinates from device space into image space.
src[0] = x;
src[1] = y;
transform.transform(src, 0, dest, 0, 1);
int dx = (int) dest[0];
int dy = (int) dest[1];
// The modulo operation gives us the replication effect.
dx = ((dx - minX) % width) + minX;
dy = ((dy - minY) % height) + minY;
// Copy the pixel.
pixel = source.getDataElements(dx, dy, pixel);
paintRaster.setDataElements(x - x1, y - y1, pixel);
}
}
return paintRaster;
}
/**
* Ensures that the target raster exists and has at least the specified
* size.
*
* @param w the requested target width
* @param h the requested target height
*/
private void ensureRasterSize(int w, int h)
{
if (paintRaster == null || paintRaster.getWidth() < w
|| paintRaster.getHeight() < h)
{
Raster s = image.getData();
paintRaster = s.createCompatibleWritableRaster(w, h);
}
}
}

View file

@ -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);
}
}

View file

@ -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);
}

View file

@ -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);
}
}

View file

@ -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 );
}
}

View file

@ -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);
}
}

View file

@ -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 );
}
}

View file

@ -40,19 +40,23 @@ package gnu.java.awt.peer.gtk;
import gnu.classpath.Configuration;
import gnu.java.awt.peer.ClasspathFontPeer;
import gnu.java.awt.font.opentype.NameDecoder;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Toolkit;
import java.awt.font.FontRenderContext;
import java.awt.font.GlyphVector;
import java.awt.font.GlyphMetrics;
import java.awt.font.LineMetrics;
import java.awt.geom.Rectangle2D;
import java.awt.geom.Point2D;
import java.text.CharacterIterator;
import java.text.StringCharacterIterator;
import java.util.Locale;
import java.util.Map;
import java.util.ResourceBundle;
import java.nio.ByteBuffer;
public class GdkFontPeer extends ClasspathFontPeer
{
@ -76,17 +80,21 @@ public class GdkFontPeer extends ClasspathFontPeer
}
}
private ByteBuffer nameTable = null;
private native void initState ();
private native void dispose ();
private native void setFont (String family, int style, int size, boolean useGraphics2D);
private native void setFont (String family, int style, int size);
native void getFontMetrics(double [] metrics);
native void getTextMetrics(String str, double [] metrics);
native void releasePeerGraphicsResource();
protected void finalize ()
{
if (GtkToolkit.useGraphics2D ())
GdkGraphics2D.releasePeerGraphicsResource(this);
releasePeerGraphicsResource();
dispose ();
}
@ -136,26 +144,84 @@ public class GdkFontPeer extends ClasspathFontPeer
{
super(name, style, size);
initState ();
setFont (this.familyName, this.style, (int)this.size,
GtkToolkit.useGraphics2D());
setFont (this.familyName, this.style, (int)this.size);
}
public GdkFontPeer (String name, Map attributes)
{
super(name, attributes);
initState ();
setFont (this.familyName, this.style, (int)this.size,
GtkToolkit.useGraphics2D());
}
public String getSubFamilyName(Font font, Locale locale)
{
return null;
setFont (this.familyName, this.style, (int)this.size);
}
/**
* Unneeded, but implemented anyway.
*/
public String getSubFamilyName(Font font, Locale locale)
{
String name;
if (locale == null)
locale = Locale.getDefault();
name = getName(NameDecoder.NAME_SUBFAMILY, locale);
if (name == null)
{
name = getName(NameDecoder.NAME_SUBFAMILY, Locale.ENGLISH);
if ("Regular".equals(name))
name = null;
}
return name;
}
/**
* Returns the bytes belonging to a TrueType/OpenType table,
* Parameters n,a,m,e identify the 4-byte ASCII tag of the table.
*
* Returns null if the font is not TT, the table is nonexistant,
* or if some other unexpected error occured.
*
*/
private native byte[] getTrueTypeTable(byte n, byte a, byte m, byte e);
/**
* Returns the PostScript name of the font, defaults to the familyName if
* a PS name could not be retrieved.
*/
public String getPostScriptName(Font font)
{
return this.familyName;
String name = getName(NameDecoder.NAME_POSTSCRIPT,
/* any language */ null);
if( name == null )
return this.familyName;
return name;
}
/**
* Extracts a String from the font&#x2019;s name table.
*
* @param name the numeric TrueType or OpenType name ID.
*
* @param locale the locale for which names shall be localized, or
* <code>null</code> if the locale does mot matter because the name
* is known to be language-independent (for example, because it is
* the PostScript name).
*/
private String getName(int name, Locale locale)
{
if (nameTable == null)
{
byte[] data = getTrueTypeTable((byte)'n', (byte) 'a',
(byte) 'm', (byte) 'e');
if( data == null )
return null;
nameTable = ByteBuffer.wrap( data );
}
return NameDecoder.getName(nameTable, name, locale);
}
public boolean canDisplay (Font font, char c)
@ -170,23 +236,18 @@ public class GdkFontPeer extends ClasspathFontPeer
return -1;
}
private native GdkGlyphVector getGlyphVector(String txt,
Font f,
FontRenderContext ctx);
public GlyphVector createGlyphVector (Font font,
FontRenderContext ctx,
CharacterIterator i)
{
return getGlyphVector(buildString (i), font, ctx);
return new FreetypeGlyphVector(font, buildString (i), ctx);
}
public GlyphVector createGlyphVector (Font font,
FontRenderContext ctx,
int[] glyphCodes)
{
return null;
// return new GdkGlyphVector (font, this, ctx, glyphCodes);
return new FreetypeGlyphVector(font, glyphCodes, ctx);
}
public byte getBaselineFor (Font font, char c)
@ -262,13 +323,21 @@ public class GdkFontPeer extends ClasspathFontPeer
public int getNumGlyphs (Font font)
{
throw new UnsupportedOperationException ();
byte[] data = getTrueTypeTable((byte)'m', (byte) 'a',
(byte)'x', (byte) 'p');
if( data == null )
return -1;
ByteBuffer buf = ByteBuffer.wrap( data );
return buf.getShort(4);
}
public Rectangle2D getStringBounds (Font font, CharacterIterator ci,
int begin, int limit, FontRenderContext frc)
{
GdkGlyphVector gv = getGlyphVector(buildString (ci, begin, limit), font, frc);
GlyphVector gv = new FreetypeGlyphVector( font,
buildString(ci, begin, limit),
frc);
return gv.getVisualBounds();
}
@ -303,5 +372,4 @@ public class GdkFontPeer extends ClasspathFontPeer
// the metrics cache.
return Toolkit.getDefaultToolkit().getFontMetrics (font);
}
}

View file

@ -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 ();
}
}

View file

@ -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);
}
}

View file

@ -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);
}
}

View file

@ -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 ();
}
}

View file

@ -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 ();
}
}

View file

@ -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();
}

View file

@ -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,

View file

@ -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)
{

View file

@ -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

View file

@ -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 ////////////////////////////////////////////////

View file

@ -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;
}

View file

@ -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;
}
}

View file

@ -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 );
}
}

View file

@ -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

View file

@ -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)

View file

@ -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();

View file

@ -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)

View file

@ -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)
{

View file

@ -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.
}

View file

@ -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)

View file

@ -0,0 +1,518 @@
/* JavaPrinterGraphics.java -- AWT printer rendering class.
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.print;
import gnu.java.awt.peer.gtk.CairoSurface;
import java.awt.Color;
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.geom.AffineTransform;
import java.awt.image.ImageObserver;
import java.awt.image.PixelGrabber;
import java.awt.print.PageFormat;
import java.awt.print.Pageable;
import java.awt.print.Paper;
import java.awt.print.Printable;
import java.awt.print.PrinterException;
import java.awt.print.PrinterGraphics;
import java.awt.print.PrinterJob;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.text.AttributedCharacterIterator;
/**
* Graphics context to draw to PostScript.
*
* @author Sven de Marothy
*/
public class JavaPrinterGraphics extends Graphics implements PrinterGraphics
{
/**
* The used graphics context.
*/
private Graphics g;
/**
* The associated printer job.
*/
private PrinterJob printerJob;
/**
* Rendering resolution
*/
private static final double DPI = 72.0;
/**
* Rendered image size.
*/
private int xSize, ySize;
/**
* The image to render to.
*/
private Image image;
public JavaPrinterGraphics( PrinterJob printerJob )
{
this.printerJob = printerJob;
}
/**
* Spool a document to PostScript.
* If Pageable is non-null, it will print that, otherwise it will use
* the supplied printable and pageFormat.
*/
public SpooledDocument spoolPostScript(Printable printable,
PageFormat pageFormat,
Pageable pageable)
throws PrinterException
{
try
{
// spool to a temporary file
File temp = File.createTempFile("cpspool", ".ps");
temp.deleteOnExit();
PrintWriter out = new PrintWriter
(new BufferedWriter
(new OutputStreamWriter
(new FileOutputStream(temp), "ISO8859_1"), 1000000));
writePSHeader(out);
if(pageable != null)
{
for(int index = 0; index < pageable.getNumberOfPages(); index++)
spoolPage(out, pageable.getPrintable(index),
pageable.getPageFormat(index), index);
}
else
{
int index = 0;
while(spoolPage(out, printable, pageFormat, index++) ==
Printable.PAGE_EXISTS);
}
out.println("%%Trailer");
out.println("%%EOF");
out.close();
return new SpooledDocument( temp );
}
catch (IOException e)
{
PrinterException pe = new PrinterException();
pe.initCause(e);
throw pe;
}
}
/**
* Spools a single page, returns NO_SUCH_PAGE unsuccessful,
* PAGE_EXISTS if it was.
*/
public int spoolPage(PrintWriter out,
Printable printable,
PageFormat pageFormat,
int index) throws IOException, PrinterException
{
initImage( pageFormat );
if(printable.print(this, pageFormat, index) == Printable.NO_SUCH_PAGE)
return Printable.NO_SUCH_PAGE;
g.dispose();
g = null;
writePage( out, pageFormat );
return Printable.PAGE_EXISTS;
}
private void initImage(PageFormat pageFormat)
{
// Create a really big image and draw to that.
xSize = (int)(DPI*pageFormat.getWidth()/72.0);
ySize = (int)(DPI*pageFormat.getHeight()/72.0);
// Swap X and Y sizes if it's a Landscape page.
if( pageFormat.getOrientation() != PageFormat.PORTRAIT )
{
int t = xSize;
xSize = ySize;
ySize = t;
}
// FIXME: This should at least be BufferedImage.
// Fix once we have a working B.I.
// Graphics2D should also be supported of course.
image = CairoSurface.getBufferedImage(xSize, ySize);
g = image.getGraphics();
setColor(Color.white);
fillRect(0, 0, xSize, ySize);
setColor(Color.black);
}
private void writePSHeader(PrintWriter out)
{
out.println("%!PS-Adobe-3.0");
out.println("%%Title: "+printerJob.getJobName());
out.println("%%Creator: GNU Classpath ");
out.println("%%DocumentData: Clean8Bit");
out.println("%%DocumentNeededResources: font Times-Roman Helvetica Courier");
// out.println("%%Pages: "+); // FIXME # pages.
out.println("%%EndComments");
out.println("%%BeginProlog");
out.println("%%EndProlog");
out.println("%%BeginSetup");
// FIXME: Paper name
// E.g. "A4" "Letter"
// out.println("%%BeginFeature: *PageSize A4");
out.println("%%EndFeature");
out.println("%%EndSetup");
// out.println("%%Page: 1 1");
}
private void writePage(PrintWriter out, PageFormat pageFormat)
{
out.println("%%BeginPageSetup");
Paper p = pageFormat.getPaper();
double pWidth = p.getWidth();
double pHeight = p.getHeight();
if( pageFormat.getOrientation() == PageFormat.PORTRAIT )
out.println( "%%Orientation: Portrait" );
else
{
out.println( "%%Orientation: Landscape" );
double t = pWidth;
pWidth = pHeight;
pHeight = t;
}
out.println("gsave % first save");
// 595x842; 612x792 respectively
out.println("<< /PageSize [" +pWidth + " "+pHeight+ "] >> setpagedevice");
// invert the Y axis so that we get screen-like coordinates instead.
AffineTransform pageTransform = new AffineTransform();
if( pageFormat.getOrientation() == PageFormat.REVERSE_LANDSCAPE )
{
pageTransform.translate(pWidth, pHeight);
pageTransform.scale(-1.0, -1.0);
}
concatCTM(out, pageTransform);
out.println("%%EndPageSetup");
out.println("gsave");
// Draw the image
out.println(xSize+" "+ySize+" 8 [1 0 0 -1 0 "+ySize+" ]");
out.println("{currentfile 3 string readhexstring pop} bind");
out.println("false 3 colorimage");
int[] pixels = new int[xSize * ySize];
PixelGrabber pg = new PixelGrabber(image, 0, 0, xSize, ySize, pixels, 0, xSize);
try {
pg.grabPixels();
} catch (InterruptedException e) {
out.println("% Bug getting pixels!");
}
int n = 0;
for (int j = 0; j < ySize; j++) {
for (int i = 0; i < xSize; i++) {
out.print( colorTripleHex(pixels[j * xSize + i]) );
if(((++n)%11) == 0) out.println();
}
}
out.println();
out.println("%%EOF");
out.println("grestore");
out.println("showpage");
}
/**
* Get a nonsperated hex RGB triple, e.g. FFFFFF = white
*/
private String colorTripleHex(int num){
String s = "";
try {
s = Integer.toHexString( ( num & 0x00FFFFFF ) );
if( s.length() < 6 )
{
s = "000000"+s;
return s.substring(s.length()-6);
}
} catch (Exception e){
s = "FFFFFF";
}
return s;
}
private void concatCTM(PrintWriter out, AffineTransform Tx){
double[] matrixElements = new double[6];
Tx.getMatrix(matrixElements);
out.print("[ ");
for(int i=0;i<6;i++)
out.print(matrixElements[i]+" ");
out.println("] concat");
}
//-----------------------------------------------------------------------------
/**
* PrinterGraphics method - Returns the printer job associated with this object.
*/
public PrinterJob getPrinterJob()
{
return printerJob;
}
/**
* The rest of the methods here are just pass-throughs to g.
*/
public void clearRect(int x, int y, int width, int height)
{
g.clearRect(x, y, width, height);
}
public void clipRect(int x, int y, int width, int height)
{
g.clipRect(x, y, width, height);
}
public void copyArea(int x, int y, int width, int height, int dx, int dy)
{
g.copyArea(x, y, width, height, dx, dy);
}
public Graphics create()
{
return g.create();
}
public void dispose()
{
}
public void drawArc(int x, int y, int width, int height, int startAngle,
int arcAngle)
{
g.drawArc(x, y, width, height, startAngle, arcAngle);
}
public boolean drawImage(Image img, int x, int y, Color bgcolor,
ImageObserver observer)
{
return g.drawImage(img, x, y, bgcolor, observer);
}
public boolean drawImage(Image img, int x, int y, ImageObserver observer)
{
return g.drawImage(img, x, y, observer);
}
public boolean drawImage(Image img, int x, int y, int width, int height,
Color bgcolor, ImageObserver observer)
{
return g.drawImage(img, x, y, width, height, bgcolor, observer);
}
public boolean drawImage(Image img, int x, int y, int width, int height,
ImageObserver observer)
{
return g.drawImage(img, x, y, width, height, 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)
{
return g.drawImage(img, dx1, dy1, dx2, dy2,
sx1, sy1, sx2, sy2, bgcolor, observer);
}
public boolean drawImage(Image img, int dx1, int dy1, int dx2, int dy2,
int sx1, int sy1, int sx2, int sy2, ImageObserver observer)
{
return g.drawImage(img, dx1, dy1, dx2, dy2,
sx1, sy1, sx2, sy2, observer);
}
public void drawLine(int x1, int y1, int x2, int y2)
{
g.drawLine(x1, y1, x2, y2);
}
public void drawOval(int x, int y, int width, int height)
{
g.drawOval(x, y, width, height);
}
public void drawPolygon(int[] xPoints, int[] yPoints, int nPoints)
{
g.drawPolygon(xPoints, yPoints, nPoints);
}
public void drawPolyline(int[] xPoints, int[] yPoints, int nPoints)
{
g.drawPolyline(xPoints, yPoints, nPoints);
}
public void drawRoundRect(int x, int y, int width, int height,
int arcWidth, int arcHeight)
{
g.drawRoundRect(x, y, width, height, arcWidth, arcHeight);
}
public void drawString(AttributedCharacterIterator iterator, int x, int y)
{
g.drawString(iterator, x, y);
}
public void drawString(String str, int x, int y)
{
g.drawString(str, x, y);
}
public void fillArc(int x, int y, int width, int height,
int startAngle, int arcAngle)
{
g.fillArc(x, y, width, height, startAngle, arcAngle);
}
public void fillOval(int x, int y, int width, int height)
{
g.fillOval(x, y, width, height);
}
public void fillPolygon(int[] xPoints, int[] yPoints, int nPoints)
{
g.fillPolygon(xPoints, yPoints, nPoints);
}
public void fillRect(int x, int y, int width, int height)
{
g.fillRect(x, y, width, height);
}
public void fillRoundRect(int x, int y, int width, int height,
int arcWidth, int arcHeight)
{
g.fillRoundRect(x, y, width, height, arcWidth, arcHeight);
}
public Shape getClip()
{
return g.getClip();
}
public Rectangle getClipBounds()
{
return g.getClipBounds();
}
public Color getColor()
{
return g.getColor();
}
public Font getFont()
{
return g.getFont();
}
public FontMetrics getFontMetrics(Font f)
{
return g.getFontMetrics(f);
}
public void setClip(int x, int y, int width, int height)
{
g.setClip(x, y, width, height);
}
public void setClip(Shape clip)
{
g.setClip(clip);
}
public void setColor(Color c)
{
g.setColor(c);
}
public void setFont(Font font)
{
g.setFont(font);
}
public void setPaintMode()
{
g.setPaintMode();
}
public void setXORMode(Color c1)
{
g.setXORMode(c1);
}
public void translate(int x, int y)
{
g.translate(x, y);
}
}

View file

@ -0,0 +1,403 @@
/* JavaPrinterJob.java -- AWT printing implemented on javax.print.
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.print;
import java.awt.HeadlessException;
import java.awt.print.PageFormat;
import java.awt.print.Pageable;
import java.awt.print.Printable;
import java.awt.print.PrinterException;
import java.awt.print.PrinterJob;
import java.util.Locale;
import javax.print.CancelablePrintJob;
import javax.print.DocFlavor;
import javax.print.DocPrintJob;
import javax.print.PrintException;
import javax.print.PrintService;
import javax.print.PrintServiceLookup;
import javax.print.ServiceUI;
import javax.print.attribute.HashPrintRequestAttributeSet;
import javax.print.attribute.IntegerSyntax;
import javax.print.attribute.PrintRequestAttributeSet;
import javax.print.attribute.TextSyntax;
import javax.print.attribute.standard.Copies;
import javax.print.attribute.standard.JobName;
import javax.print.attribute.standard.OrientationRequested;
import javax.print.attribute.standard.RequestingUserName;
/**
* This is the default implementation of PrinterJob
*
* @author Sven de Marothy
*/
public class JavaPrinterJob extends PrinterJob
{
/**
* The print service associated with this job
*/
private PrintService printer = null;
/**
* Printing options;
*/
private PrintRequestAttributeSet attributes;
/**
* Available print services
*/
private static PrintService[] services;
/**
* The actual print job.
*/
private DocPrintJob printJob;
/**
* The Printable object to print.
*/
private Printable printable;
/**
* Page format.
*/
private PageFormat pageFormat;
/**
* A pageable, or null
*/
private Pageable pageable = null;
/**
* Cancelled or not
*/
private boolean cancelled = false;
static
{
// lookup all services without any constraints
services = PrintServiceLookup.lookupPrintServices
(DocFlavor.INPUT_STREAM.POSTSCRIPT, null);
}
private static final Class copyClass = (new Copies(1)).getClass();
private static final Class jobNameClass = (new JobName("", null)).getClass();
private static final Class userNameClass = (new RequestingUserName("", null)).getClass();
/**
* Initializes a new instance of <code>PrinterJob</code>.
*/
public JavaPrinterJob()
{
attributes = new HashPrintRequestAttributeSet();
setCopies(1);
setJobName("Java Printing");
pageFormat = new PageFormat(); // default page format.
}
private void getPageAttributes()
{
OrientationRequested orientation = (OrientationRequested)
attributes.get( OrientationRequested.LANDSCAPE.getCategory() );
if( orientation == null)
return;
if( orientation.equals(OrientationRequested.PORTRAIT) )
pageFormat.setOrientation(PageFormat.PORTRAIT);
else if( orientation.equals(OrientationRequested.LANDSCAPE) )
pageFormat.setOrientation(PageFormat.LANDSCAPE);
else if( orientation.equals(OrientationRequested.REVERSE_LANDSCAPE) )
pageFormat.setOrientation(PageFormat.REVERSE_LANDSCAPE);
}
/**
* Returns the number of copies to be printed.
*
* @return The number of copies to be printed.
*/
public int getCopies()
{
return ((IntegerSyntax)attributes.get( jobNameClass )).getValue();
}
/**
* Sets the number of copies to be printed.
*
* @param copies The number of copies to be printed.
*/
public void setCopies(int copies)
{
attributes.add( new Copies( copies ) );
}
/**
* Returns the name of the print job.
*
* @return The name of the print job.
*/
public String getJobName()
{
return ((TextSyntax)attributes.get( jobNameClass )).getValue();
}
/**
* Sets the name of the print job.
*
* @param job_name The name of the print job.
*/
public void setJobName(String job_name)
{
attributes.add( new JobName(job_name, Locale.getDefault()) );
}
/**
* Returns the printing user name.
*
* @return The printing username.
*/
public String getUserName()
{
return ((TextSyntax)attributes.get( userNameClass )).getValue();
}
/**
* Cancels an in progress print job.
*/
public void cancel()
{
try
{
if(printJob != null && (printJob instanceof CancelablePrintJob))
{
((CancelablePrintJob)printJob).cancel();
cancelled = true;
}
}
catch(PrintException pe)
{
}
}
/**
* Tests whether or not this job has been cancelled.
*
* @return <code>true</code> if this job has been cancelled, <code>false</code>
* otherwise.
*/
public boolean isCancelled()
{
return cancelled;
}
/**
* Clones the specified <code>PageFormat</code> object then alters the
* clone so that it represents the default page format.
*
* @param page_format The <code>PageFormat</code> to clone.
*
* @return A new default page format.
*/
public PageFormat defaultPage(PageFormat page_format)
{
return new PageFormat();
}
/**
* Displays a dialog box to the user which allows the page format
* attributes to be modified.
*
* @param page_format The <code>PageFormat</code> object to modify.
*
* @return The modified <code>PageFormat</code>.
*/
public PageFormat pageDialog(PageFormat page_format)
throws HeadlessException
{
return defaultPage(null);
}
/**
* Prints the pages.
*/
public void print() throws PrinterException
{
if( printable == null && pageable == null ) // nothing to print?
return;
PostScriptGraphics2D pg = new PostScriptGraphics2D( this );
SpooledDocument doc = pg.spoolPostScript( printable, pageFormat,
pageable );
cancelled = false;
printJob = printer.createPrintJob();
try
{
printJob.print(doc, attributes);
}
catch (PrintException pe)
{
PrinterException p = new PrinterException();
p.initCause(pe);
throw p;
}
// no printjob active.
printJob = null;
}
/**
* Prints the page with given attributes.
*/
public void print (PrintRequestAttributeSet attributes)
throws PrinterException
{
this.attributes = attributes;
print();
}
/**
* Displays a dialog box to the user which allows the print job
* attributes to be modified.
*
* @return <code>false</code> if the user cancels the dialog box,
* <code>true</code> otherwise.
*/
public boolean printDialog() throws HeadlessException
{
return printDialog( attributes );
}
/**
* Displays a dialog box to the user which allows the print job
* attributes to be modified.
*
* @return <code>false</code> if the user cancels the dialog box,
* <code>true</code> otherwise.
*/
public boolean printDialog(PrintRequestAttributeSet attributes)
throws HeadlessException
{
PrintService chosenPrinter = ServiceUI.printDialog
(null, 50, 50, services, null,
DocFlavor.INPUT_STREAM.POSTSCRIPT, attributes);
getPageAttributes();
if( chosenPrinter != null )
{
try
{
setPrintService( chosenPrinter );
}
catch(PrinterException pe)
{
// Should not happen.
}
return true;
}
return false;
}
/**
* This sets the pages that are to be printed.
*
* @param pageable The pages to be printed, which may not be <code>null</code>.
*/
public void setPageable(Pageable pageable)
{
if( pageable == null )
throw new NullPointerException("Pageable cannot be null.");
this.pageable = pageable;
}
/**
* Sets this specified <code>Printable</code> as the one to use for
* rendering the pages on the print device.
*
* @param printable The <code>Printable</code> for the print job.
*/
public void setPrintable(Printable printable)
{
this.printable = printable;
}
/**
* Sets the <code>Printable</code> and the page format for the pages
* to be printed.
*
* @param printable The <code>Printable</code> for the print job.
* @param page_format The <code>PageFormat</code> for the print job.
*/
public void setPrintable(Printable printable, PageFormat page_format)
{
this.printable = printable;
this.pageFormat = page_format;
}
/**
* Makes any alterations to the specified <code>PageFormat</code>
* necessary to make it work with the current printer. The alterations
* are made to a clone of the input object, which is then returned.
*
* @param page_format The <code>PageFormat</code> to validate.
*
* @return The validated <code>PageFormat</code>.
*/
public PageFormat validatePage(PageFormat page_format)
{
// FIXME
return page_format;
}
/**
* Change the printer for this print job to service. Subclasses that
* support setting the print service override this method. Throws
* PrinterException when the class doesn't support setting the printer,
* the service doesn't support Pageable or Printable interfaces for 2D
* print output.
* @param service The new printer to use.
* @throws PrinterException if service is not valid.
*/
public void setPrintService(PrintService service)
throws PrinterException
{
if(!service.isDocFlavorSupported(DocFlavor.INPUT_STREAM.POSTSCRIPT))
throw new PrinterException("This printer service is not supported.");
printer = service;
}
}

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,91 @@
/* SpooledDocument.java -- Reurgitate a spooled PostScript file
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.print;
import javax.print.Doc;
import javax.print.DocFlavor;
import javax.print.attribute.DocAttributeSet;
import java.io.File;
import java.io.IOException;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.Reader;
import java.io.InputStream;
import java.io.InputStreamReader;
public class SpooledDocument implements Doc
{
private FileInputStream fis;
public SpooledDocument(File file)
{
try
{
fis = new FileInputStream(file);
}
catch (FileNotFoundException ffne)
{
// Shouldn't happen.
}
}
public DocAttributeSet getAttributes()
{
return null;
}
public DocFlavor getDocFlavor()
{
return DocFlavor.INPUT_STREAM.POSTSCRIPT;
}
public Object getPrintData()
{
return fis;
}
public Reader getReaderForText()
{
return new InputStreamReader(fis);
}
public InputStream getStreamForBytes()
{
return fis;
}
}